landed the code for doing post attachments (the infamous paperclip)
This commit is contained in:
		
							parent
							
								
									66b7fea53b
								
							
						
					
					
						commit
						70774ead7d
					
				
							
								
								
									
										26
									
								
								TODO
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								TODO
									
									
									
									
									
								
							@ -25,17 +25,27 @@ Lots!
 | 
			
		||||
  statements in the case of joined queries (no need to SELECT table.column
 | 
			
		||||
  AS name).
 | 
			
		||||
 | 
			
		||||
- Getting conferencing in there - but still not there yet.  We need topic and
 | 
			
		||||
  post implementations, and UI.
 | 
			
		||||
- Functions still to do on conferencing "posts" page:
 | 
			
		||||
  Hide/Show Topic
 | 
			
		||||
  Next & Keep New (make it actually Keep New)
 | 
			
		||||
  Freeze/Unfreeze Topic
 | 
			
		||||
  Archive/Unarchive Topic
 | 
			
		||||
  Delete Topic
 | 
			
		||||
  Make number of "viewable" posts per page a config option
 | 
			
		||||
  Display the message locator (i.e. <Playground.56.123>) above each message
 | 
			
		||||
  Hide/Show Post
 | 
			
		||||
  Scribble Post
 | 
			
		||||
  Nuke Post
 | 
			
		||||
  Put the HTML Guide in (for all pages w/post boxes)
 | 
			
		||||
 | 
			
		||||
- Slippage during posting is still untested.
 | 
			
		||||
 | 
			
		||||
- Functions still to do on conferencing "topics" page:
 | 
			
		||||
  Manage Conference
 | 
			
		||||
  Add Conference To Hotlist
 | 
			
		||||
 | 
			
		||||
- Implement conference hotlist for users.
 | 
			
		||||
 | 
			
		||||
- The HTML checker is back together and almost all integrated into the
 | 
			
		||||
  Venice engine, but I still need to initialize the dictionary.  It's going
 | 
			
		||||
  to require configuration entries in the Venice XML config file, and the
 | 
			
		||||
  use of LazyLexicon (to load the dictionary in the background while people
 | 
			
		||||
  log in).
 | 
			
		||||
 | 
			
		||||
- Not everybody likes purple.  Provide a way to change the default colors.
 | 
			
		||||
  Probably via entries in render-config.xml.  Of course, if we go to a
 | 
			
		||||
  different rendering system eventually, we won't need this.
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										13
									
								
								etc/web.xml
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								etc/web.xml
									
									
									
									
									
								
							@ -150,6 +150,14 @@
 | 
			
		||||
    <servlet-class>com.silverwrist.venice.servlets.PostMessage</servlet-class>
 | 
			
		||||
  </servlet>
 | 
			
		||||
 | 
			
		||||
  <servlet>
 | 
			
		||||
    <servlet-name>attachment</servlet-name>
 | 
			
		||||
    <description>
 | 
			
		||||
      Andles downloading and uploading attachments.
 | 
			
		||||
    </description>
 | 
			
		||||
    <servlet-class>com.silverwrist.venice.servlets.Attachment</servlet-class>
 | 
			
		||||
  </servlet>
 | 
			
		||||
 | 
			
		||||
  <!-- the following are test servlets, they should go away -->
 | 
			
		||||
 | 
			
		||||
  <servlet>
 | 
			
		||||
@ -213,6 +221,11 @@
 | 
			
		||||
    <url-pattern>/post</url-pattern>
 | 
			
		||||
  </servlet-mapping>
 | 
			
		||||
 | 
			
		||||
  <servlet-mapping>
 | 
			
		||||
    <servlet-name>attachment</servlet-name>
 | 
			
		||||
    <url-pattern>/attachment</url-pattern>
 | 
			
		||||
  </servlet-mapping>
 | 
			
		||||
 | 
			
		||||
  <!-- the following are test servlets, they should go away -->
 | 
			
		||||
  <servlet-mapping>
 | 
			
		||||
    <servlet-name>testformdata</servlet-name>
 | 
			
		||||
 | 
			
		||||
@ -420,6 +420,7 @@ INSERT INTO refaudit (type, descr) VALUES
 | 
			
		||||
    (311,     'Hide Message'),
 | 
			
		||||
    (312,     'Scribble Message'),
 | 
			
		||||
    (313,     'Nuke Message'),
 | 
			
		||||
    (314,     'Upload Message Attachment'),
 | 
			
		||||
    (9999999, 'DUMMY');
 | 
			
		||||
 | 
			
		||||
# The ISO 3166 two-letter country codes.  Source is
 | 
			
		||||
 | 
			
		||||
@ -7,7 +7,7 @@
 | 
			
		||||
 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
 | 
			
		||||
 * language governing rights and limitations under the License.
 | 
			
		||||
 * 
 | 
			
		||||
 * The Original Code is the Venice Web Community System.
 | 
			
		||||
 * The Original Code is the Venice Web Communities System.
 | 
			
		||||
 * 
 | 
			
		||||
 * The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
 | 
			
		||||
 * for Silverwrist Design Studios.  Portions created by Eric J. Bowersox are
 | 
			
		||||
@ -32,9 +32,10 @@ import javax.servlet.*;
 | 
			
		||||
 | 
			
		||||
public class ServletMultipartHandler
 | 
			
		||||
{
 | 
			
		||||
  private MimeMultipart multipart;     // holds all the multipart data
 | 
			
		||||
  private Hashtable param_byname;      // parameters by name
 | 
			
		||||
  private Vector param_order;          // parameters in order
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Internal wrapper around the ServletRequest that implements DataSource
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  class ServletDataSource implements DataSource
 | 
			
		||||
  {
 | 
			
		||||
@ -75,6 +76,11 @@ public class ServletMultipartHandler
 | 
			
		||||
 | 
			
		||||
  } // end class ServletDataSource
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Internal class representing a data value
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  static class MultipartDataValue implements Blob
 | 
			
		||||
  {
 | 
			
		||||
    private byte[] actual_data;  // the actual data we contain
 | 
			
		||||
@ -83,7 +89,7 @@ public class ServletMultipartHandler
 | 
			
		||||
    {
 | 
			
		||||
      InputStream in = part.getInputStream();
 | 
			
		||||
      ByteArrayOutputStream out = new ByteArrayOutputStream();
 | 
			
		||||
      byte[] copybuf = new byte[1024];
 | 
			
		||||
      byte[] copybuf = new byte[4096];
 | 
			
		||||
      int ct = in.read(copybuf);
 | 
			
		||||
      while (ct>=0)
 | 
			
		||||
      { // do a simple read and write
 | 
			
		||||
@ -133,6 +139,11 @@ public class ServletMultipartHandler
 | 
			
		||||
 | 
			
		||||
  } // end class MultipartDataValue
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Internal class representing a request parameter
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  class MultipartParameter
 | 
			
		||||
  {
 | 
			
		||||
    private MimeBodyPart part;   // the actual body part data
 | 
			
		||||
@ -178,7 +189,8 @@ public class ServletMultipartHandler
 | 
			
		||||
    public String getValue()
 | 
			
		||||
    {
 | 
			
		||||
      if (filename!=null)
 | 
			
		||||
	return filename;
 | 
			
		||||
	return filename;  // "value" for file parts is the filename
 | 
			
		||||
 | 
			
		||||
      try
 | 
			
		||||
      { // Retrieve the part's actual content and convert it to a String.  (Since non-file
 | 
			
		||||
	// fields are of type text/plain, the Object "val" should actually be a String, in
 | 
			
		||||
@ -228,7 +240,7 @@ public class ServletMultipartHandler
 | 
			
		||||
    public MultipartDataValue getContent() throws ServletMultipartException
 | 
			
		||||
    {
 | 
			
		||||
      if (filename==null)
 | 
			
		||||
	return null;
 | 
			
		||||
	return null;  // not a file parameter
 | 
			
		||||
 | 
			
		||||
      if (cached_value==null)
 | 
			
		||||
      { // we don't have the value cached yet
 | 
			
		||||
@ -256,6 +268,20 @@ public class ServletMultipartHandler
 | 
			
		||||
 | 
			
		||||
  } // end class MultipartParameter
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Attributes
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  private MimeMultipart multipart;     // holds all the multipart data
 | 
			
		||||
  private Hashtable param_byname;      // parameters by name
 | 
			
		||||
  private Vector param_order;          // parameters in order
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Constructor
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  public ServletMultipartHandler(ServletRequest request) throws ServletMultipartException
 | 
			
		||||
  {
 | 
			
		||||
    if (!canHandle(request))
 | 
			
		||||
@ -286,6 +312,11 @@ public class ServletMultipartHandler
 | 
			
		||||
 | 
			
		||||
  } // end constructor
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * External static operations
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns <CODE>true</CODE> if the given <CODE>ServletRequest</CODE> can be handled by
 | 
			
		||||
   * the <CODE>ServletMultipartHandler</CODE>, <CODE>false</CODE> if not.
 | 
			
		||||
@ -301,6 +332,11 @@ public class ServletMultipartHandler
 | 
			
		||||
 | 
			
		||||
  } // end canHandle
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * External operations
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  public Enumeration getNames()
 | 
			
		||||
  {
 | 
			
		||||
    Vector tmp_vector = new Vector();
 | 
			
		||||
 | 
			
		||||
@ -112,4 +112,6 @@ public interface ConferenceContext
 | 
			
		||||
  public abstract TopicContext addTopic(String title, String zp_pseud, String zp_text)
 | 
			
		||||
      throws DataException, AccessError;
 | 
			
		||||
 | 
			
		||||
  public abstract TopicMessageContext getMessageByPostID(long postid) throws DataException, AccessError;
 | 
			
		||||
 | 
			
		||||
} // end interface ConferenceContext
 | 
			
		||||
 | 
			
		||||
@ -66,6 +66,8 @@ public interface TopicContext
 | 
			
		||||
 | 
			
		||||
  public abstract List getMessages(int low, int high) throws DataException, AccessError;
 | 
			
		||||
 | 
			
		||||
  public abstract TopicMessageContext getMessage(int number) throws DataException, AccessError;
 | 
			
		||||
 | 
			
		||||
  public abstract TopicMessageContext postNewMessage(long parent, String pseud, String text)
 | 
			
		||||
      throws DataException, AccessError;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -17,6 +17,7 @@
 | 
			
		||||
 */
 | 
			
		||||
package com.silverwrist.venice.core;
 | 
			
		||||
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
 | 
			
		||||
public interface TopicMessageContext
 | 
			
		||||
@ -49,6 +50,14 @@ public interface TopicMessageContext
 | 
			
		||||
 | 
			
		||||
  public abstract boolean hasAttachment();
 | 
			
		||||
 | 
			
		||||
  public abstract String getAttachmentType();
 | 
			
		||||
 | 
			
		||||
  public abstract String getAttachmentFilename();
 | 
			
		||||
 | 
			
		||||
  public abstract int getAttachmentLength();
 | 
			
		||||
 | 
			
		||||
  public abstract InputStream getAttachmentData() throws AccessError, DataException;
 | 
			
		||||
 | 
			
		||||
  public abstract boolean canHide();
 | 
			
		||||
 | 
			
		||||
  public abstract boolean canScribble();
 | 
			
		||||
@ -61,4 +70,7 @@ public interface TopicMessageContext
 | 
			
		||||
 | 
			
		||||
  public abstract void nuke() throws DataException, AccessError;
 | 
			
		||||
 | 
			
		||||
  public abstract void attachData(String m_type, String file, int length, InputStream data)
 | 
			
		||||
      throws AccessError, DataException;
 | 
			
		||||
 | 
			
		||||
} // end interface TopicMessageContext
 | 
			
		||||
 | 
			
		||||
@ -884,6 +884,20 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
 | 
			
		||||
 | 
			
		||||
  } // end addTopic
 | 
			
		||||
 | 
			
		||||
  public TopicMessageContext getMessageByPostID(long postid) throws DataException, AccessError
 | 
			
		||||
  {
 | 
			
		||||
    if (!(getConferenceData().canReadConference(level)))
 | 
			
		||||
    { // the luser can't even read the conference...
 | 
			
		||||
      logger.error("user not permitted to change membership");
 | 
			
		||||
      throw new AccessError("You are not permitted to read this conference.");
 | 
			
		||||
 | 
			
		||||
    } // end if
 | 
			
		||||
 | 
			
		||||
    // call down to the static function level
 | 
			
		||||
    return TopicMessageUserContextImpl.getMessage(engine,this,datapool,postid);
 | 
			
		||||
 | 
			
		||||
  } // end getMessageByPostID
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Implementations from interface UserBackend
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
@ -17,9 +17,11 @@
 | 
			
		||||
 */
 | 
			
		||||
package com.silverwrist.venice.core.impl;
 | 
			
		||||
 | 
			
		||||
import java.io.*;
 | 
			
		||||
import java.sql.*;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
import org.apache.log4j.*;
 | 
			
		||||
import com.silverwrist.util.StringUtil;
 | 
			
		||||
import com.silverwrist.venice.db.*;
 | 
			
		||||
import com.silverwrist.venice.security.AuditRecord;
 | 
			
		||||
import com.silverwrist.venice.core.*;
 | 
			
		||||
@ -33,6 +35,8 @@ class TopicMessageUserContextImpl implements TopicMessageContext
 | 
			
		||||
 | 
			
		||||
  private static Category logger = Category.getInstance(TopicMessageUserContextImpl.class.getName());
 | 
			
		||||
 | 
			
		||||
  private static final int MAX_ATTACH = 1048576;  // TODO: should be a configurable parameter
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Attributes
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
@ -329,6 +333,113 @@ class TopicMessageUserContextImpl implements TopicMessageContext
 | 
			
		||||
 | 
			
		||||
  } // end hasAttachment
 | 
			
		||||
 | 
			
		||||
  public String getAttachmentType()
 | 
			
		||||
  {
 | 
			
		||||
    return mimetype;
 | 
			
		||||
 | 
			
		||||
  } // end getAttachmentType
 | 
			
		||||
 | 
			
		||||
  public String getAttachmentFilename()
 | 
			
		||||
  {
 | 
			
		||||
    return ((mimetype!=null) ? filename : null);
 | 
			
		||||
 | 
			
		||||
  } // end getAttachmentFilename
 | 
			
		||||
 | 
			
		||||
  public int getAttachmentLength()
 | 
			
		||||
  {
 | 
			
		||||
    return ((mimetype!=null) ? datalen : 0);
 | 
			
		||||
 | 
			
		||||
  } // end getAttachmentLength
 | 
			
		||||
 | 
			
		||||
  public InputStream getAttachmentData() throws AccessError, DataException
 | 
			
		||||
  {
 | 
			
		||||
    if (nuked || (scribble_date!=null))
 | 
			
		||||
    { // this would be an exercise in futility!
 | 
			
		||||
      logger.error("cannot attach to a nuked or scribbled message");
 | 
			
		||||
      throw new AccessError("You cannot attach data to a message that no longer exists.");
 | 
			
		||||
 | 
			
		||||
    } // end if
 | 
			
		||||
 | 
			
		||||
    Connection conn = null;
 | 
			
		||||
    InputStream rc = null;
 | 
			
		||||
    try
 | 
			
		||||
    { // open up a database connection
 | 
			
		||||
      conn = datapool.getConnection();
 | 
			
		||||
 | 
			
		||||
      // make sure we have current data
 | 
			
		||||
      refresh(conn);
 | 
			
		||||
      if (nuked || (scribble_date!=null))
 | 
			
		||||
      { // this would be an exercise in futility!
 | 
			
		||||
	logger.error("cannot attach to a nuked or scribbled message");
 | 
			
		||||
	throw new AccessError("You cannot attach data to a message that no longer exists.");
 | 
			
		||||
 | 
			
		||||
      } // end if
 | 
			
		||||
 | 
			
		||||
      if (mimetype==null)
 | 
			
		||||
      { // there is no attachment data!
 | 
			
		||||
	logger.error("no attachment data to get");
 | 
			
		||||
	throw new AccessError("There is no attachment data for this message.");
 | 
			
		||||
 | 
			
		||||
      } // end if
 | 
			
		||||
 | 
			
		||||
      // Create the statement and the SQL we need to retrieve the attachment.
 | 
			
		||||
      Statement stmt = conn.createStatement();
 | 
			
		||||
      StringBuffer sql = new StringBuffer("SELECT data FROM postattach WHERE postid = ");
 | 
			
		||||
      sql.append(postid).append(';');
 | 
			
		||||
 | 
			
		||||
      // Execute the query!
 | 
			
		||||
      ResultSet rs = stmt.executeQuery(sql.toString());
 | 
			
		||||
      if (!(rs.next()))
 | 
			
		||||
      { // there is no attachment data!
 | 
			
		||||
	logger.error("no attachment data to get");
 | 
			
		||||
	throw new AccessError("There is no attachment data for this message.");
 | 
			
		||||
 | 
			
		||||
      } // end if
 | 
			
		||||
 | 
			
		||||
      // Since the InputStream we get from JDBC will probably go away when the connection is dropped, we
 | 
			
		||||
      // need to make a temporary copy of it, to a ByteArrayOutputStream.  (Attachments can only be
 | 
			
		||||
      // 1 Mb in size, so this shouldn't be a big problem.)
 | 
			
		||||
      InputStream sqldata = rs.getBinaryStream(1);
 | 
			
		||||
      ByteArrayOutputStream copy = new ByteArrayOutputStream(datalen);
 | 
			
		||||
      byte[] buffer = new byte[4096];
 | 
			
		||||
      int rd = sqldata.read(buffer);
 | 
			
		||||
      while (rd>=0)
 | 
			
		||||
      { // write, then read again
 | 
			
		||||
	if (rd>0)
 | 
			
		||||
	  copy.write(buffer,0,rd);
 | 
			
		||||
	rd = sqldata.read(buffer);
 | 
			
		||||
 | 
			
		||||
      } // end while
 | 
			
		||||
 | 
			
		||||
      // Close both our streams, making sure we create the stream we need for the return value.
 | 
			
		||||
      sqldata.close();
 | 
			
		||||
      rc = new ByteArrayInputStream(copy.toByteArray());
 | 
			
		||||
      copy.close();
 | 
			
		||||
 | 
			
		||||
    } // end try
 | 
			
		||||
    catch (SQLException e)
 | 
			
		||||
    { // turn this into a DataException
 | 
			
		||||
      logger.error("DB error retrieving attachment: " + e.getMessage(),e);
 | 
			
		||||
      throw new DataException("unable to retrieve attachment data: " + e.getMessage(),e);
 | 
			
		||||
 | 
			
		||||
    } // end catch
 | 
			
		||||
    catch (IOException e)
 | 
			
		||||
    { // turn this into a DataException too
 | 
			
		||||
      logger.error("I/O error copying attachment data: " + e.getMessage(),e);
 | 
			
		||||
      throw new DataException("unable to retrieve attachment data: " + e.getMessage(),e);
 | 
			
		||||
 | 
			
		||||
    } // end catch
 | 
			
		||||
    finally
 | 
			
		||||
    { // make sure we release the connection before we go
 | 
			
		||||
      if (conn!=null)
 | 
			
		||||
	datapool.releaseConnection(conn);
 | 
			
		||||
 | 
			
		||||
    } // end finally
 | 
			
		||||
 | 
			
		||||
    return rc;
 | 
			
		||||
 | 
			
		||||
  } // end getAttachmentData
 | 
			
		||||
 | 
			
		||||
  public boolean canHide()
 | 
			
		||||
  {
 | 
			
		||||
    return ((creator_uid==conf.realUID()) || conf.userCanHide());
 | 
			
		||||
@ -641,6 +752,125 @@ class TopicMessageUserContextImpl implements TopicMessageContext
 | 
			
		||||
 | 
			
		||||
  } // end nuke
 | 
			
		||||
 | 
			
		||||
  public void attachData(String m_type, String file, int length, InputStream data)
 | 
			
		||||
      throws AccessError, DataException
 | 
			
		||||
  {
 | 
			
		||||
    if (mimetype!=null)
 | 
			
		||||
    { // the message already has an attachment
 | 
			
		||||
      logger.error("tried to attach data to a message that already has it!");
 | 
			
		||||
      throw new AccessError("This message already has an attachment.");
 | 
			
		||||
 | 
			
		||||
    } // end if
 | 
			
		||||
 | 
			
		||||
    if (creator_uid!=conf.realUID())
 | 
			
		||||
    { // you can't attach to this message!
 | 
			
		||||
      logger.error("tried to attach data to a message that's not yours!");
 | 
			
		||||
      throw new AccessError("You are not permitted to add an attachment to this message.");
 | 
			
		||||
 | 
			
		||||
    } // end if
 | 
			
		||||
 | 
			
		||||
    if (nuked || (scribble_date!=null))
 | 
			
		||||
    { // this would be an exercise in futility!
 | 
			
		||||
      logger.error("cannot attach to a nuked or scribbled message");
 | 
			
		||||
      throw new AccessError("You cannot attach data to a message that no longer exists.");
 | 
			
		||||
 | 
			
		||||
    } // end if
 | 
			
		||||
 | 
			
		||||
    if (StringUtil.isStringEmpty(m_type))
 | 
			
		||||
    { // no MIME type specified
 | 
			
		||||
      logger.error("no MIME type specified for attachment");
 | 
			
		||||
      throw new AccessError("MIME type of attachment data not specified.");
 | 
			
		||||
 | 
			
		||||
    } // end if
 | 
			
		||||
 | 
			
		||||
    if (StringUtil.isStringEmpty(file))
 | 
			
		||||
    { // no MIME type specified
 | 
			
		||||
      logger.error("no filename specified for attachment");
 | 
			
		||||
      throw new AccessError("Filename of attachment data not specified.");
 | 
			
		||||
 | 
			
		||||
    } // end if
 | 
			
		||||
 | 
			
		||||
    if (length<=0)
 | 
			
		||||
    { // a length of 0 or less is just WRONG
 | 
			
		||||
      logger.error("non-positive length specified for attachment");
 | 
			
		||||
      throw new AccessError("Invalid attachment length.");
 | 
			
		||||
 | 
			
		||||
    } // end if
 | 
			
		||||
    else if (length>MAX_ATTACH)
 | 
			
		||||
    { // the attachment is too damn long!
 | 
			
		||||
      logger.error("attachment is too long (" + String.valueOf(length) + " bytes)");
 | 
			
		||||
      throw new AccessError("The attachment is too long to store.  Maximum available length is "
 | 
			
		||||
			    + String.valueOf(MAX_ATTACH) + " bytes.");
 | 
			
		||||
 | 
			
		||||
    } // end else if
 | 
			
		||||
 | 
			
		||||
    Connection conn = null;
 | 
			
		||||
    AuditRecord ar = null;
 | 
			
		||||
 | 
			
		||||
    try
 | 
			
		||||
    { // open up a database connection
 | 
			
		||||
      conn = datapool.getConnection();
 | 
			
		||||
 | 
			
		||||
      // make sure we have the right status to upload
 | 
			
		||||
      refresh(conn);
 | 
			
		||||
      if (nuked || (scribble_date!=null))
 | 
			
		||||
      { // this would be an exercise in futility!
 | 
			
		||||
	logger.error("cannot attach to a nuked or scribbled message");
 | 
			
		||||
	throw new AccessError("You cannot attach data to a message that no longer exists.");
 | 
			
		||||
 | 
			
		||||
      } // end if
 | 
			
		||||
 | 
			
		||||
      // Build the SQL statement that inserts the attachment.  Note the use of the "?" to specify the
 | 
			
		||||
      // BLOB parameter (the attachment data itself); this comes later.
 | 
			
		||||
      StringBuffer sql =
 | 
			
		||||
          new StringBuffer("INSERT INTO postattach (postid, datalen, filename, mimetype, data) VALUES (");
 | 
			
		||||
      sql.append(postid).append(", ").append(length).append(", '").append(SQLUtil.encodeString(file));
 | 
			
		||||
      sql.append("', '").append(SQLUtil.encodeString(m_type)).append("', ?);");
 | 
			
		||||
 | 
			
		||||
      // Prepare the statement, set the BLOB parameter, and execute it.
 | 
			
		||||
      PreparedStatement stmt = conn.prepareStatement(sql.toString());
 | 
			
		||||
      stmt.setBinaryStream(1,data,length);
 | 
			
		||||
      stmt.executeUpdate();
 | 
			
		||||
 | 
			
		||||
      // Save off the local attachment values.
 | 
			
		||||
      datalen = length;
 | 
			
		||||
      filename = file;
 | 
			
		||||
      mimetype = m_type;
 | 
			
		||||
 | 
			
		||||
      // Generate an audit record indicating what we did.
 | 
			
		||||
      ar = new AuditRecord(AuditRecord.UPLOAD_ATTACHMENT,conf.realUID(),conf.userRemoteAddress(),
 | 
			
		||||
			   conf.realSIGID(),"conf=" + String.valueOf(conf.realConfID()) + ",post="
 | 
			
		||||
			   + String.valueOf(postid),"len=" + String.valueOf(length) + ",type=" + m_type
 | 
			
		||||
			   + ",name=" + file);
 | 
			
		||||
 | 
			
		||||
    } // end try
 | 
			
		||||
    catch (SQLException e)
 | 
			
		||||
    { // turn this into a DataException
 | 
			
		||||
      logger.error("DB error saving attachment: " + e.getMessage(),e);
 | 
			
		||||
      throw new DataException("unable to save attachment data: " + e.getMessage(),e);
 | 
			
		||||
 | 
			
		||||
    } // end catch
 | 
			
		||||
    finally
 | 
			
		||||
    { // make sure we release the connection before we go
 | 
			
		||||
      try
 | 
			
		||||
      { // save off the audit record before we go, though
 | 
			
		||||
	if ((ar!=null) && (conn!=null))
 | 
			
		||||
	  ar.store(conn);
 | 
			
		||||
 | 
			
		||||
      } // end try
 | 
			
		||||
      catch (SQLException e)
 | 
			
		||||
      { // we couldn't store the audit record!
 | 
			
		||||
	logger.error("DB error saving audit record: " + e.getMessage(),e);
 | 
			
		||||
 | 
			
		||||
      } // end catch
 | 
			
		||||
 | 
			
		||||
      if (conn!=null)
 | 
			
		||||
	datapool.releaseConnection(conn);
 | 
			
		||||
 | 
			
		||||
    } // end finally
 | 
			
		||||
 | 
			
		||||
  } // end attachData
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * External static operations
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
@ -703,4 +933,105 @@ class TopicMessageUserContextImpl implements TopicMessageContext
 | 
			
		||||
 | 
			
		||||
  } // end loadMessageRange
 | 
			
		||||
 | 
			
		||||
  static TopicMessageContext loadMessage(EngineBackend engine, ConferenceBackend conf, DataPool datapool,
 | 
			
		||||
					 int topicid, int message_num) throws DataException
 | 
			
		||||
  {
 | 
			
		||||
    if (logger.isDebugEnabled())
 | 
			
		||||
      logger.debug("loadMessage for conf # " + String.valueOf(conf.realConfID()) + ", topic #"
 | 
			
		||||
		   + String.valueOf(topicid) + ", message " + String.valueOf(message_num));
 | 
			
		||||
 | 
			
		||||
    Connection conn = null;      // pooled database connection
 | 
			
		||||
 | 
			
		||||
    try
 | 
			
		||||
    { // get a database connection
 | 
			
		||||
      conn = datapool.getConnection();
 | 
			
		||||
      Statement stmt = conn.createStatement();
 | 
			
		||||
 | 
			
		||||
      // run a query to get all the posts in a particular topic
 | 
			
		||||
      StringBuffer sql =
 | 
			
		||||
	  new StringBuffer("SELECT p.postid, p.parent, p.num, p.linecount, p.creator_uid, p.posted, "
 | 
			
		||||
			   + "p.hidden, p.scribble_uid,	p.scribble_date, p.pseud, a.datalen, a.filename, "
 | 
			
		||||
			   + "a.mimetype FROM posts p LEFT JOIN postattach a ON p.postid = a.postid "
 | 
			
		||||
			   + "WHERE p.topicid = ");
 | 
			
		||||
      sql.append(topicid).append(" AND p.num = ").append(message_num).append(';');
 | 
			
		||||
      if (logger.isDebugEnabled())
 | 
			
		||||
	logger.debug("SQL: " + sql.toString());
 | 
			
		||||
      ResultSet rs = stmt.executeQuery(sql.toString());
 | 
			
		||||
 | 
			
		||||
      if (rs.next())  // create an object reference and return it
 | 
			
		||||
	return new TopicMessageUserContextImpl(engine,conf,datapool,rs.getLong(1),rs.getLong(2),rs.getInt(3),
 | 
			
		||||
		                               rs.getInt(4),rs.getInt(5),SQLUtil.getFullDateTime(rs,6),
 | 
			
		||||
					       rs.getBoolean(7),rs.getInt(8),SQLUtil.getFullDateTime(rs,9),
 | 
			
		||||
					       rs.getString(10),rs.getInt(11),rs.getString(12),
 | 
			
		||||
					       rs.getString(13));
 | 
			
		||||
 | 
			
		||||
      // indicates an error...
 | 
			
		||||
      throw new DataException("Message not found.");
 | 
			
		||||
 | 
			
		||||
    } // end try
 | 
			
		||||
    catch (SQLException e)
 | 
			
		||||
    { // turn SQLException into data exception
 | 
			
		||||
      logger.error("DB error reading message entry: " + e.getMessage(),e);
 | 
			
		||||
      throw new DataException("unable to retrieve message: " + e.getMessage(),e);
 | 
			
		||||
 | 
			
		||||
    } // end catch
 | 
			
		||||
    finally
 | 
			
		||||
    { // make sure we release the connection before we go
 | 
			
		||||
      if (conn!=null)
 | 
			
		||||
	datapool.releaseConnection(conn);
 | 
			
		||||
 | 
			
		||||
    } // end finally
 | 
			
		||||
 | 
			
		||||
  } // end loadMessage
 | 
			
		||||
 | 
			
		||||
  static TopicMessageContext getMessage(EngineBackend engine, ConferenceBackend conf, DataPool datapool,
 | 
			
		||||
					long postid) throws DataException
 | 
			
		||||
  {
 | 
			
		||||
    if (logger.isDebugEnabled())
 | 
			
		||||
      logger.debug("getMessage for conf # " + String.valueOf(conf.realConfID()) + ", post #"
 | 
			
		||||
		   + String.valueOf(postid));
 | 
			
		||||
 | 
			
		||||
    Connection conn = null;      // pooled database connection
 | 
			
		||||
 | 
			
		||||
    try
 | 
			
		||||
    { // get a database connection
 | 
			
		||||
      conn = datapool.getConnection();
 | 
			
		||||
      Statement stmt = conn.createStatement();
 | 
			
		||||
 | 
			
		||||
      StringBuffer sql =
 | 
			
		||||
	  new StringBuffer("SELECT p.postid, p.parent, p.num, p.linecount, p.creator_uid, p.posted, "
 | 
			
		||||
			   + "p.hidden, p.scribble_uid,	p.scribble_date, p.pseud, a.datalen, a.filename, "
 | 
			
		||||
			   + "a.mimetype FROM topics t, posts p LEFT JOIN postattach a ON p.postid = a.postid "
 | 
			
		||||
			   + "WHERE t.topicid = p.topicid AND t.confid = ");
 | 
			
		||||
      sql.append(conf.realConfID()).append(" AND p.postid = ").append(postid).append(';');
 | 
			
		||||
      if (logger.isDebugEnabled())
 | 
			
		||||
	logger.debug("SQL: " + sql.toString());
 | 
			
		||||
      ResultSet rs = stmt.executeQuery(sql.toString());
 | 
			
		||||
 | 
			
		||||
      if (rs.next())  // create an object reference and return it
 | 
			
		||||
	return new TopicMessageUserContextImpl(engine,conf,datapool,rs.getLong(1),rs.getLong(2),rs.getInt(3),
 | 
			
		||||
		                               rs.getInt(4),rs.getInt(5),SQLUtil.getFullDateTime(rs,6),
 | 
			
		||||
					       rs.getBoolean(7),rs.getInt(8),SQLUtil.getFullDateTime(rs,9),
 | 
			
		||||
					       rs.getString(10),rs.getInt(11),rs.getString(12),
 | 
			
		||||
					       rs.getString(13));
 | 
			
		||||
 | 
			
		||||
      // indicates an error...
 | 
			
		||||
      throw new DataException("Message not found.");
 | 
			
		||||
 | 
			
		||||
    } // end try    
 | 
			
		||||
    catch (SQLException e)
 | 
			
		||||
    { // turn SQLException into data exception
 | 
			
		||||
      logger.error("DB error reading message entries: " + e.getMessage(),e);
 | 
			
		||||
      throw new DataException("unable to retrieve messages: " + e.getMessage(),e);
 | 
			
		||||
 | 
			
		||||
    } // end catch
 | 
			
		||||
    finally
 | 
			
		||||
    { // make sure we release the connection before we go
 | 
			
		||||
      if (conn!=null)
 | 
			
		||||
	datapool.releaseConnection(conn);
 | 
			
		||||
 | 
			
		||||
    } // end finally
 | 
			
		||||
 | 
			
		||||
  } // end getMessage
 | 
			
		||||
 | 
			
		||||
} // end class TopicMessageUserContextImpl
 | 
			
		||||
 | 
			
		||||
@ -569,6 +569,20 @@ class TopicUserContextImpl implements TopicContext
 | 
			
		||||
 | 
			
		||||
  } // end getMessages
 | 
			
		||||
 | 
			
		||||
  public TopicMessageContext getMessage(int number) throws DataException, AccessError
 | 
			
		||||
  {
 | 
			
		||||
    if (!(conf.userCanRead()))
 | 
			
		||||
    { // they can't read messages in this topic!
 | 
			
		||||
      logger.error("trying to read postings w/o permission!");
 | 
			
		||||
      throw new AccessError("You do not have permission to read messages in this conference.");
 | 
			
		||||
 | 
			
		||||
    } // end if
 | 
			
		||||
 | 
			
		||||
    // pass down to one of our static functiions to return this
 | 
			
		||||
    return TopicMessageUserContextImpl.loadMessage(engine,conf,datapool,topicid,number);
 | 
			
		||||
 | 
			
		||||
  } // end getMessage
 | 
			
		||||
 | 
			
		||||
  public TopicMessageContext postNewMessage(long parent, String pseud, String text)
 | 
			
		||||
      throws DataException, AccessError
 | 
			
		||||
  {
 | 
			
		||||
 | 
			
		||||
@ -58,5 +58,6 @@ public interface Audit
 | 
			
		||||
  public static final int HIDE_MESSAGE = 311;
 | 
			
		||||
  public static final int SCRIBBLE_MESSAGE = 312;
 | 
			
		||||
  public static final int NUKE_MESSAGE = 313;
 | 
			
		||||
  public static final int UPLOAD_ATTACHMENT = 314;
 | 
			
		||||
 | 
			
		||||
} // end interface Audit
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										427
									
								
								src/com/silverwrist/venice/servlets/Attachment.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										427
									
								
								src/com/silverwrist/venice/servlets/Attachment.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,427 @@
 | 
			
		||||
/*
 | 
			
		||||
 * The contents of this file are subject to the Mozilla Public License Version 1.1
 | 
			
		||||
 * (the "License"); you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
 | 
			
		||||
 * 
 | 
			
		||||
 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
 | 
			
		||||
 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
 | 
			
		||||
 * language governing rights and limitations under the License.
 | 
			
		||||
 * 
 | 
			
		||||
 * The Original Code is the Venice Web Communities System.
 | 
			
		||||
 * 
 | 
			
		||||
 * The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
 | 
			
		||||
 * for Silverwrist Design Studios.  Portions created by Eric J. Bowersox are
 | 
			
		||||
 * Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios.  All Rights Reserved.
 | 
			
		||||
 * 
 | 
			
		||||
 * Contributor(s): 
 | 
			
		||||
 */
 | 
			
		||||
package com.silverwrist.venice.servlets;
 | 
			
		||||
 | 
			
		||||
import java.io.*;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
import javax.servlet.*;
 | 
			
		||||
import javax.servlet.http.*;
 | 
			
		||||
import org.apache.log4j.*;
 | 
			
		||||
import com.silverwrist.util.StringUtil;
 | 
			
		||||
import com.silverwrist.util.ServletMultipartHandler;
 | 
			
		||||
import com.silverwrist.util.ServletMultipartException;
 | 
			
		||||
import com.silverwrist.venice.ValidationException;
 | 
			
		||||
import com.silverwrist.venice.core.*;
 | 
			
		||||
import com.silverwrist.venice.servlets.format.*;
 | 
			
		||||
 | 
			
		||||
public class Attachment extends VeniceServlet
 | 
			
		||||
{
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Static data members
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  private static Category logger = Category.getInstance(Attachment.class.getName());
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Internal functions
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  private static SIGContext getSIGParameter(String str, UserContext user)
 | 
			
		||||
      throws ValidationException, DataException
 | 
			
		||||
  {
 | 
			
		||||
    if (str==null)
 | 
			
		||||
    { // no SIG parameter - bail out now!
 | 
			
		||||
      logger.error("SIG parameter not specified!");
 | 
			
		||||
      throw new ValidationException("No SIG specified.");
 | 
			
		||||
 | 
			
		||||
    } // end if
 | 
			
		||||
 | 
			
		||||
    try
 | 
			
		||||
    { // turn the string into a SIGID, and thence to a SIGContext
 | 
			
		||||
      int sigid = Integer.parseInt(str);
 | 
			
		||||
      return user.getSIGContext(sigid);
 | 
			
		||||
 | 
			
		||||
    } // end try
 | 
			
		||||
    catch (NumberFormatException nfe)
 | 
			
		||||
    { // error in Integer.parseInt
 | 
			
		||||
      logger.error("Cannot convert SIG parameter '" + str + "'!");
 | 
			
		||||
      throw new ValidationException("Invalid SIG parameter.");
 | 
			
		||||
 | 
			
		||||
    } // end catch
 | 
			
		||||
 | 
			
		||||
  } // end getSIGParameter
 | 
			
		||||
 | 
			
		||||
  private static SIGContext getSIGParameter(ServletRequest request, UserContext user)
 | 
			
		||||
      throws ValidationException, DataException
 | 
			
		||||
  {
 | 
			
		||||
    return getSIGParameter(request.getParameter("sig"),user);
 | 
			
		||||
 | 
			
		||||
  } // end getSIGParameter
 | 
			
		||||
 | 
			
		||||
  private static SIGContext getSIGParameter(ServletMultipartHandler mphandler, UserContext user)
 | 
			
		||||
      throws ValidationException, DataException
 | 
			
		||||
  {
 | 
			
		||||
    if (mphandler.isFileParam("sig"))
 | 
			
		||||
      throw new ValidationException("Internal Error: SIG should be a normal param");
 | 
			
		||||
    return getSIGParameter(mphandler.getValue("sig"),user);
 | 
			
		||||
 | 
			
		||||
  } // end getSIGParameter
 | 
			
		||||
 | 
			
		||||
  private static ConferenceContext getConferenceParameter(String str, SIGContext sig)
 | 
			
		||||
      throws ValidationException, DataException, AccessError
 | 
			
		||||
  {
 | 
			
		||||
    if (str==null)
 | 
			
		||||
    { // no conference parameter - bail out now!
 | 
			
		||||
      logger.error("Conference parameter not specified!");
 | 
			
		||||
      throw new ValidationException("No conference specified.");
 | 
			
		||||
 | 
			
		||||
    } // end if
 | 
			
		||||
 | 
			
		||||
    try
 | 
			
		||||
    { // turn the string into a ConfID, and thence to a ConferenceContext
 | 
			
		||||
      int confid = Integer.parseInt(str);
 | 
			
		||||
      return sig.getConferenceContext(confid);
 | 
			
		||||
 | 
			
		||||
    } // end try
 | 
			
		||||
    catch (NumberFormatException nfe)
 | 
			
		||||
    { // error in Integer.parseInt
 | 
			
		||||
      logger.error("Cannot convert conference parameter '" + str + "'!");
 | 
			
		||||
      throw new ValidationException("Invalid conference parameter.");
 | 
			
		||||
 | 
			
		||||
    } // end catch
 | 
			
		||||
 | 
			
		||||
  } // end getConferenceParameter
 | 
			
		||||
 | 
			
		||||
  private static ConferenceContext getConferenceParameter(ServletRequest request, SIGContext sig)
 | 
			
		||||
      throws ValidationException, DataException, AccessError
 | 
			
		||||
  {
 | 
			
		||||
    return getConferenceParameter(request.getParameter("conf"),sig);
 | 
			
		||||
 | 
			
		||||
  } // end getConferenceParameter
 | 
			
		||||
 | 
			
		||||
  private static ConferenceContext getConferenceParameter(ServletMultipartHandler mphandler, SIGContext sig)
 | 
			
		||||
      throws ValidationException, DataException, AccessError
 | 
			
		||||
  {
 | 
			
		||||
    if (mphandler.isFileParam("conf"))
 | 
			
		||||
      throw new ValidationException("Internal Error: conference should be a normal param");
 | 
			
		||||
    return getConferenceParameter(mphandler.getValue("conf"),sig);
 | 
			
		||||
 | 
			
		||||
  } // end getConferenceParameter
 | 
			
		||||
 | 
			
		||||
  private static TopicMessageContext getMessageParameter(String str, ConferenceContext conf)
 | 
			
		||||
      throws ValidationException, DataException, AccessError
 | 
			
		||||
  {
 | 
			
		||||
    if (str==null)
 | 
			
		||||
    { // no conference parameter - bail out now!
 | 
			
		||||
      logger.error("Message parameter not specified!");
 | 
			
		||||
      throw new ValidationException("No message specified.");
 | 
			
		||||
 | 
			
		||||
    } // end if
 | 
			
		||||
 | 
			
		||||
    try
 | 
			
		||||
    { // turn the string into a postid, and thence to a TopicMessageContext
 | 
			
		||||
      long postid = Long.parseLong(str);
 | 
			
		||||
      return conf.getMessageByPostID(postid);
 | 
			
		||||
 | 
			
		||||
    } // end try
 | 
			
		||||
    catch (NumberFormatException nfe)
 | 
			
		||||
    { // error in Integer.parseInt
 | 
			
		||||
      logger.error("Cannot convert message parameter '" + str + "'!");
 | 
			
		||||
      throw new ValidationException("Invalid message parameter.");
 | 
			
		||||
 | 
			
		||||
    } // end catch
 | 
			
		||||
 | 
			
		||||
  } // end getMessageParameter
 | 
			
		||||
 | 
			
		||||
  private static TopicMessageContext getMessageParameter(ServletRequest request, ConferenceContext conf)
 | 
			
		||||
      throws ValidationException, DataException, AccessError
 | 
			
		||||
  {
 | 
			
		||||
    return getMessageParameter(request.getParameter("msg"),conf);
 | 
			
		||||
 | 
			
		||||
  } // end getMessageParameter
 | 
			
		||||
 | 
			
		||||
  private static TopicMessageContext getMessageParameter(ServletMultipartHandler mphandler,
 | 
			
		||||
							 ConferenceContext conf)
 | 
			
		||||
      throws ValidationException, DataException, AccessError
 | 
			
		||||
  {
 | 
			
		||||
    if (mphandler.isFileParam("msg"))
 | 
			
		||||
      throw new ValidationException("Internal Error: message should be a normal param");
 | 
			
		||||
    return getMessageParameter(mphandler.getValue("msg"),conf);
 | 
			
		||||
 | 
			
		||||
  } // end getMessageParameter
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Overrides from class HttpServlet
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  public String getServletInfo()
 | 
			
		||||
  {
 | 
			
		||||
    String rc = "Attachment servlet - Handles uploading and downloading attachments\n"
 | 
			
		||||
              + "Part of the Venice Web Communities System\n";
 | 
			
		||||
    return rc;
 | 
			
		||||
 | 
			
		||||
  } // end getServletInfo
 | 
			
		||||
 | 
			
		||||
  public void doGet(HttpServletRequest request, HttpServletResponse response)
 | 
			
		||||
    throws ServletException, IOException
 | 
			
		||||
  {
 | 
			
		||||
    UserContext user = getUserContext(request);
 | 
			
		||||
    RenderData rdat = createRenderData(request,response);
 | 
			
		||||
    String page_title = null;
 | 
			
		||||
    Object content = null;
 | 
			
		||||
    SIGContext sig = null;            // SIG context
 | 
			
		||||
    ConferenceContext conf = null;    // conference context
 | 
			
		||||
    TopicMessageContext msg = null;   // message context
 | 
			
		||||
 | 
			
		||||
    try
 | 
			
		||||
    { // this outer try is to catch ValidationException
 | 
			
		||||
      try
 | 
			
		||||
      { // all commands require a SIG parameter
 | 
			
		||||
	sig = getSIGParameter(request,user);
 | 
			
		||||
	changeMenuSIG(request,sig);
 | 
			
		||||
	if (logger.isDebugEnabled())
 | 
			
		||||
	  logger.debug("found SIG #" + String.valueOf(sig.getSIGID()));
 | 
			
		||||
 | 
			
		||||
      } // end try
 | 
			
		||||
      catch (DataException de)
 | 
			
		||||
      { // error looking up the SIG
 | 
			
		||||
	page_title = "Database Error";
 | 
			
		||||
	content = new ErrorBox(page_title,"Database error finding SIG: " + de.getMessage(),"top");
 | 
			
		||||
 | 
			
		||||
      } // end catch
 | 
			
		||||
 | 
			
		||||
      if (content==null)
 | 
			
		||||
      { // we got the SIG parameter OK
 | 
			
		||||
	try
 | 
			
		||||
	{ // all commands require a conference parameter
 | 
			
		||||
	  conf = getConferenceParameter(request,sig);
 | 
			
		||||
	  if (logger.isDebugEnabled())
 | 
			
		||||
	    logger.debug("found conf #" + String.valueOf(conf.getConfID()));
 | 
			
		||||
	  
 | 
			
		||||
	} // end try
 | 
			
		||||
	catch (DataException de)
 | 
			
		||||
	{ // error looking up the conference
 | 
			
		||||
	  page_title = "Database Error";
 | 
			
		||||
	  content = new ErrorBox(page_title,"Database error finding conference: " + de.getMessage(),"top");
 | 
			
		||||
 | 
			
		||||
	} // end catch
 | 
			
		||||
 | 
			
		||||
      } // end if
 | 
			
		||||
 | 
			
		||||
      if (content==null)
 | 
			
		||||
      { // we got the conference parameter OK
 | 
			
		||||
	try
 | 
			
		||||
	{ // now we need a message parameter
 | 
			
		||||
	  msg = getMessageParameter(request,conf);
 | 
			
		||||
	  if (logger.isDebugEnabled())
 | 
			
		||||
	    logger.debug("found post #" + String.valueOf(msg.getPostID()));
 | 
			
		||||
 | 
			
		||||
	} // end try
 | 
			
		||||
	catch (DataException de)
 | 
			
		||||
	{ // error looking up the conference
 | 
			
		||||
	  page_title = "Database Error";
 | 
			
		||||
	  content = new ErrorBox(page_title,"Database error finding message: " + de.getMessage(),"top");
 | 
			
		||||
 | 
			
		||||
	} // end catch
 | 
			
		||||
 | 
			
		||||
      } // end if
 | 
			
		||||
 | 
			
		||||
    } // end try
 | 
			
		||||
    catch (ValidationException ve)
 | 
			
		||||
    { // these all get handled in pretty much the same way
 | 
			
		||||
      page_title = "Error";
 | 
			
		||||
      content = new ErrorBox(null,ve.getMessage(),"top");
 | 
			
		||||
 | 
			
		||||
    } // end catch
 | 
			
		||||
    catch (AccessError ae)
 | 
			
		||||
    { // these all get handled in pretty much the same way
 | 
			
		||||
      page_title = "Access Error";
 | 
			
		||||
      content = new ErrorBox(page_title,ae.getMessage(),"top");
 | 
			
		||||
 | 
			
		||||
    } // end catch
 | 
			
		||||
 | 
			
		||||
    if (content==null)
 | 
			
		||||
    { // extract the attachment data from the message and send it out
 | 
			
		||||
      try
 | 
			
		||||
      { // extract the attachment data and send it out!
 | 
			
		||||
	rdat.sendBinaryData(msg.getAttachmentType(),msg.getAttachmentFilename(),
 | 
			
		||||
			    msg.getAttachmentLength(),msg.getAttachmentData());
 | 
			
		||||
	return;  // now we're all done!
 | 
			
		||||
 | 
			
		||||
      } // end try
 | 
			
		||||
      catch (AccessError ae)
 | 
			
		||||
      { // these all get handled in pretty much the same way
 | 
			
		||||
	page_title = "Access Error";
 | 
			
		||||
	content = new ErrorBox(page_title,ae.getMessage(),"top");
 | 
			
		||||
 | 
			
		||||
      } // end catch
 | 
			
		||||
      catch (DataException de)
 | 
			
		||||
      { // error looking up the conference
 | 
			
		||||
	page_title = "Database Error";
 | 
			
		||||
	content = new ErrorBox(page_title,"Database error retrieving attachment: " + de.getMessage(),"top");
 | 
			
		||||
 | 
			
		||||
      } // end catch
 | 
			
		||||
 | 
			
		||||
    } // end if
 | 
			
		||||
 | 
			
		||||
    // we only get here if there were an error
 | 
			
		||||
    BaseJSPData basedat = new BaseJSPData(page_title,"top",content);
 | 
			
		||||
    basedat.transfer(getServletContext(),rdat);
 | 
			
		||||
 | 
			
		||||
  } // end doGet
 | 
			
		||||
 | 
			
		||||
  public void doPost(HttpServletRequest request, HttpServletResponse response)
 | 
			
		||||
    throws ServletException, IOException
 | 
			
		||||
  {
 | 
			
		||||
    UserContext user = getUserContext(request);
 | 
			
		||||
    RenderData rdat = createRenderData(request,response);
 | 
			
		||||
    ServletMultipartHandler mphandler = null;
 | 
			
		||||
    String target = "top";
 | 
			
		||||
    String page_title = null;
 | 
			
		||||
    Object content = null;
 | 
			
		||||
    SIGContext sig = null;            // SIG context
 | 
			
		||||
    ConferenceContext conf = null;    // conference context
 | 
			
		||||
    TopicMessageContext msg = null;   // message context
 | 
			
		||||
 | 
			
		||||
    try
 | 
			
		||||
    { // this outer try is to catch ValidationException
 | 
			
		||||
      mphandler = new ServletMultipartHandler(request);
 | 
			
		||||
 | 
			
		||||
      if (mphandler.isFileParam("target"))
 | 
			
		||||
	throw new ValidationException("Internal Error: 'target' should be a normal param");
 | 
			
		||||
      target = mphandler.getValue("target");
 | 
			
		||||
 | 
			
		||||
      try
 | 
			
		||||
      { // all commands require a SIG parameter
 | 
			
		||||
	sig = getSIGParameter(mphandler,user);
 | 
			
		||||
	changeMenuSIG(request,sig);
 | 
			
		||||
	if (logger.isDebugEnabled())
 | 
			
		||||
	  logger.debug("found SIG #" + String.valueOf(sig.getSIGID()));
 | 
			
		||||
 | 
			
		||||
      } // end try
 | 
			
		||||
      catch (DataException de)
 | 
			
		||||
      { // error looking up the SIG
 | 
			
		||||
	page_title = "Database Error";
 | 
			
		||||
	content = new ErrorBox(page_title,"Database error finding SIG: " + de.getMessage(),target);
 | 
			
		||||
 | 
			
		||||
      } // end catch
 | 
			
		||||
 | 
			
		||||
      if (content==null)
 | 
			
		||||
      { // we got the SIG parameter OK
 | 
			
		||||
	try
 | 
			
		||||
	{ // all commands require a conference parameter
 | 
			
		||||
	  conf = getConferenceParameter(mphandler,sig);
 | 
			
		||||
	  if (logger.isDebugEnabled())
 | 
			
		||||
	    logger.debug("found conf #" + String.valueOf(conf.getConfID()));
 | 
			
		||||
	  
 | 
			
		||||
	} // end try
 | 
			
		||||
	catch (DataException de)
 | 
			
		||||
	{ // error looking up the conference
 | 
			
		||||
	  page_title = "Database Error";
 | 
			
		||||
	  content = new ErrorBox(page_title,"Database error finding conference: " + de.getMessage(),target);
 | 
			
		||||
 | 
			
		||||
	} // end catch
 | 
			
		||||
 | 
			
		||||
      } // end if
 | 
			
		||||
 | 
			
		||||
      if (content==null)
 | 
			
		||||
      { // we got the conference parameter OK
 | 
			
		||||
	try
 | 
			
		||||
	{ // now we need a message parameter
 | 
			
		||||
	  msg = getMessageParameter(mphandler,conf);
 | 
			
		||||
	  if (logger.isDebugEnabled())
 | 
			
		||||
	    logger.debug("found post #" + String.valueOf(msg.getPostID()));
 | 
			
		||||
 | 
			
		||||
	} // end try
 | 
			
		||||
	catch (DataException de)
 | 
			
		||||
	{ // error looking up the conference
 | 
			
		||||
	  page_title = "Database Error";
 | 
			
		||||
	  content = new ErrorBox(page_title,"Database error finding message: " + de.getMessage(),target);
 | 
			
		||||
 | 
			
		||||
	} // end catch
 | 
			
		||||
 | 
			
		||||
      } // end if
 | 
			
		||||
 | 
			
		||||
      // also check on file and target parameter status
 | 
			
		||||
      if (!(mphandler.isFileParam("thefile")))
 | 
			
		||||
	throw new ValidationException("Internal error: 'thefile' should be a file param");
 | 
			
		||||
      
 | 
			
		||||
 | 
			
		||||
    } // end try
 | 
			
		||||
    catch (ValidationException ve)
 | 
			
		||||
    { // these all get handled in pretty much the same way
 | 
			
		||||
      page_title = "Error";
 | 
			
		||||
      content = new ErrorBox(null,ve.getMessage(),target);
 | 
			
		||||
 | 
			
		||||
    } // end catch
 | 
			
		||||
    catch (AccessError ae)
 | 
			
		||||
    { // these all get handled in pretty much the same way
 | 
			
		||||
      page_title = "Access Error";
 | 
			
		||||
      content = new ErrorBox(page_title,ae.getMessage(),target);
 | 
			
		||||
 | 
			
		||||
    } // end catch
 | 
			
		||||
    catch (ServletMultipartException smpe)
 | 
			
		||||
    { // this is kind of a special case
 | 
			
		||||
      page_title = "Error";
 | 
			
		||||
      content = new ErrorBox(page_title,"Internal Error: " + smpe.getMessage(),target);
 | 
			
		||||
 | 
			
		||||
    } // end catch
 | 
			
		||||
 | 
			
		||||
    if (content==null)
 | 
			
		||||
    { // we're ready to get the data and attach it
 | 
			
		||||
      try
 | 
			
		||||
      { // attach the data to the message!
 | 
			
		||||
	msg.attachData(mphandler.getContentType("thefile"),mphandler.getValue("thefile"),
 | 
			
		||||
		       mphandler.getContentSize("thefile"),mphandler.getFileContentStream("thefile"));
 | 
			
		||||
 | 
			
		||||
	// go back to where we should have gone before we uploaded the message
 | 
			
		||||
	rdat.redirectTo(target);
 | 
			
		||||
	return;
 | 
			
		||||
 | 
			
		||||
      } // end try
 | 
			
		||||
      catch (ServletMultipartException smpe)
 | 
			
		||||
      { // this is kind of a special case
 | 
			
		||||
	page_title = "Error";
 | 
			
		||||
	content = new ErrorBox(page_title,"Internal Error: " + smpe.getMessage(),target);
 | 
			
		||||
 | 
			
		||||
      } // end catch
 | 
			
		||||
      catch (AccessError ae)
 | 
			
		||||
      { // these all get handled in pretty much the same way
 | 
			
		||||
	page_title = "Access Error";
 | 
			
		||||
	content = new ErrorBox(page_title,ae.getMessage(),target);
 | 
			
		||||
 | 
			
		||||
      } // end catch
 | 
			
		||||
      catch (DataException de)
 | 
			
		||||
      { // error looking up the conference
 | 
			
		||||
	page_title = "Database Error";
 | 
			
		||||
	content = new ErrorBox(page_title,"Database error storing attachment: " + de.getMessage(),target);
 | 
			
		||||
 | 
			
		||||
      } // end catch
 | 
			
		||||
 | 
			
		||||
    } // end if (we got all the parameters OK)
 | 
			
		||||
 | 
			
		||||
    // we only get here if there were an error
 | 
			
		||||
    BaseJSPData basedat = new BaseJSPData(page_title,target,content);
 | 
			
		||||
    basedat.transfer(getServletContext(),rdat);
 | 
			
		||||
 | 
			
		||||
  } // end doPost
 | 
			
		||||
 | 
			
		||||
} // end class Attachment
 | 
			
		||||
@ -453,9 +453,10 @@ public class ConfOperations extends VeniceServlet
 | 
			
		||||
	      final String yes = "Y";
 | 
			
		||||
	      if (yes.equals(request.getParameter("attach")))
 | 
			
		||||
	      { // we need to upload an attachment for this post
 | 
			
		||||
		// TODO: jump somewhere to upload an attachment
 | 
			
		||||
		rdat.redirectTo(on_error);
 | 
			
		||||
		return;
 | 
			
		||||
		TopicMessageContext msg = topic.getMessage(0);  // load the "zero post"
 | 
			
		||||
 | 
			
		||||
		content = new AttachmentForm(sig,conf,msg,on_error);
 | 
			
		||||
		page_title = "Upload Attachment";
 | 
			
		||||
 | 
			
		||||
	      } // end if
 | 
			
		||||
	      else
 | 
			
		||||
 | 
			
		||||
@ -276,12 +276,12 @@ public class PostMessage extends VeniceServlet
 | 
			
		||||
	  { // no slippage - post the message!!!
 | 
			
		||||
	    TopicMessageContext msg = topic.postNewMessage(0,request.getParameter("pseud"),raw_postdata);
 | 
			
		||||
	    if (yes.equals(request.getParameter("attach")))
 | 
			
		||||
	    { // we have an attachment to upload...
 | 
			
		||||
	      // TODO: do something to upload the attachment
 | 
			
		||||
	      rdat.redirectTo("confdisp?sig=" + String.valueOf(sig.getSIGID()) + "&conf="
 | 
			
		||||
			      + String.valueOf(conf.getConfID()) + "&top="
 | 
			
		||||
			      + String.valueOf(topic.getTopicNumber()) + "&rnm=1");
 | 
			
		||||
	      return;
 | 
			
		||||
	    { // we have an attachment to upload...display the "Upload Attachment" form
 | 
			
		||||
	      String target = "confdisp?sig=" + String.valueOf(sig.getSIGID()) + "&conf="
 | 
			
		||||
		            + String.valueOf(conf.getConfID()) + "&top="
 | 
			
		||||
		            + String.valueOf(topic.getTopicNumber()) + "&rnm=1";
 | 
			
		||||
	      content = new AttachmentForm(sig,conf,msg,target);
 | 
			
		||||
	      page_title = "Upload Attachment";
 | 
			
		||||
 | 
			
		||||
	    } // end if
 | 
			
		||||
	    else
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										118
									
								
								src/com/silverwrist/venice/servlets/format/AttachmentForm.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								src/com/silverwrist/venice/servlets/format/AttachmentForm.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,118 @@
 | 
			
		||||
/*
 | 
			
		||||
 * The contents of this file are subject to the Mozilla Public License Version 1.1
 | 
			
		||||
 * (the "License"); you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
 | 
			
		||||
 * 
 | 
			
		||||
 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
 | 
			
		||||
 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
 | 
			
		||||
 * language governing rights and limitations under the License.
 | 
			
		||||
 * 
 | 
			
		||||
 * The Original Code is the Venice Web Communities System.
 | 
			
		||||
 * 
 | 
			
		||||
 * The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
 | 
			
		||||
 * for Silverwrist Design Studios.  Portions created by Eric J. Bowersox are
 | 
			
		||||
 * Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios.  All Rights Reserved.
 | 
			
		||||
 * 
 | 
			
		||||
 * Contributor(s): 
 | 
			
		||||
 */
 | 
			
		||||
package com.silverwrist.venice.servlets.format;
 | 
			
		||||
 | 
			
		||||
import java.util.*;
 | 
			
		||||
import javax.servlet.*;
 | 
			
		||||
import javax.servlet.http.*;
 | 
			
		||||
import com.silverwrist.util.StringUtil;
 | 
			
		||||
import com.silverwrist.venice.htmlcheck.*;
 | 
			
		||||
import com.silverwrist.venice.core.*;
 | 
			
		||||
 | 
			
		||||
public class AttachmentForm implements JSPRender
 | 
			
		||||
{
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Static data members
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  // Attribute name for request attribute
 | 
			
		||||
  protected static final String ATTR_NAME = "com.silverwrist.venice.content.AttachmentForm";
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Attributes
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  private int sigid;
 | 
			
		||||
  private int confid;
 | 
			
		||||
  private long postid;
 | 
			
		||||
  private String target;
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Constructor
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  public AttachmentForm(SIGContext sig, ConferenceContext conf, TopicMessageContext msg, String target)
 | 
			
		||||
  {
 | 
			
		||||
    this.sigid = sig.getSIGID();
 | 
			
		||||
    this.confid = conf.getConfID();
 | 
			
		||||
    this.postid = msg.getPostID();
 | 
			
		||||
    this.target = target;
 | 
			
		||||
 | 
			
		||||
  } // end constructor
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * External static functions
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  public static AttachmentForm retrieve(ServletRequest request)
 | 
			
		||||
  {
 | 
			
		||||
    return (AttachmentForm)(request.getAttribute(ATTR_NAME));
 | 
			
		||||
 | 
			
		||||
  } // end retrieve
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Implementations from interface JSPRender
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  public void store(ServletRequest request)
 | 
			
		||||
  {
 | 
			
		||||
    request.setAttribute(ATTR_NAME,this);
 | 
			
		||||
 | 
			
		||||
  } // end store
 | 
			
		||||
 | 
			
		||||
  public String getTargetJSPName()
 | 
			
		||||
  {
 | 
			
		||||
    return "attach_form.jsp";
 | 
			
		||||
 | 
			
		||||
  } // end getTargetJSPName
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * External operations
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  public int getSIGID()
 | 
			
		||||
  {
 | 
			
		||||
    return sigid;
 | 
			
		||||
 | 
			
		||||
  } // end getSIGID
 | 
			
		||||
 | 
			
		||||
  public int getConfID()
 | 
			
		||||
  {
 | 
			
		||||
    return confid;
 | 
			
		||||
 | 
			
		||||
  } // end getConfID
 | 
			
		||||
 | 
			
		||||
  public long getPostID()
 | 
			
		||||
  {
 | 
			
		||||
    return postid;
 | 
			
		||||
 | 
			
		||||
  } // end getPostID
 | 
			
		||||
 | 
			
		||||
  public String getTarget()
 | 
			
		||||
  {
 | 
			
		||||
    return target;
 | 
			
		||||
 | 
			
		||||
  } // end getTarget
 | 
			
		||||
 | 
			
		||||
} // end class AttachmentForm
 | 
			
		||||
@ -299,4 +299,25 @@ public class RenderData
 | 
			
		||||
 | 
			
		||||
  } // end nullResponse
 | 
			
		||||
 | 
			
		||||
  public void sendBinaryData(String type, String filename, int length, InputStream data) throws IOException
 | 
			
		||||
  {
 | 
			
		||||
    response.setContentType(type);
 | 
			
		||||
    response.setContentLength(length);
 | 
			
		||||
    if (filename!=null)  // make sure we pass the filename along, too
 | 
			
		||||
      response.setHeader("Content-Disposition","attachment; filename=\"" + filename + "\";");
 | 
			
		||||
 | 
			
		||||
    // Copy the contents of the "data" stream to the output.
 | 
			
		||||
    ServletOutputStream stm = response.getOutputStream();
 | 
			
		||||
    byte[] buffer = new byte[4096];
 | 
			
		||||
    int rd = data.read(buffer);
 | 
			
		||||
    while (rd>=0)
 | 
			
		||||
    { // simple read-write loop to shove data out the door
 | 
			
		||||
      if (rd>0)
 | 
			
		||||
	stm.write(buffer,0,rd);
 | 
			
		||||
      rd = data.read(buffer);
 | 
			
		||||
 | 
			
		||||
    } // end while
 | 
			
		||||
 | 
			
		||||
  } // end sendBinaryData
 | 
			
		||||
 | 
			
		||||
} // end class RenderData
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										41
									
								
								web/format/attach_form.jsp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								web/format/attach_form.jsp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,41 @@
 | 
			
		||||
<%--
 | 
			
		||||
  The contents of this file are subject to the Mozilla Public License Version 1.1
 | 
			
		||||
  (the "License"); you may not use this file except in compliance with the License.
 | 
			
		||||
  You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
 | 
			
		||||
 | 
			
		||||
  Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
 | 
			
		||||
  WARRANTY OF ANY KIND, either express or implied. See the License for the specific
 | 
			
		||||
  language governing rights and limitations under the License.
 | 
			
		||||
  
 | 
			
		||||
  The Original Code is the Venice Web Communities System.
 | 
			
		||||
  
 | 
			
		||||
  The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
 | 
			
		||||
  for Silverwrist Design Studios.  Portions created by Eric J. Bowersox are
 | 
			
		||||
  Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios.  All Rights Reserved.
 | 
			
		||||
 | 
			
		||||
  Contributor(s): 
 | 
			
		||||
--%>
 | 
			
		||||
<%@ page import = "java.util.*" %>
 | 
			
		||||
<%@ page import = "com.silverwrist.util.StringUtil" %>
 | 
			
		||||
<%@ page import = "com.silverwrist.venice.core.*" %>
 | 
			
		||||
<%@ page import = "com.silverwrist.venice.servlets.Variables" %>
 | 
			
		||||
<%@ page import = "com.silverwrist.venice.servlets.format.*" %>
 | 
			
		||||
<%
 | 
			
		||||
  AttachmentForm data = AttachmentForm.retrieve(request);
 | 
			
		||||
  Variables.failIfNull(data);
 | 
			
		||||
  RenderData rdat = RenderConfig.createRenderData(application,request,response);
 | 
			
		||||
%>
 | 
			
		||||
<% rdat.writeContentHeader(out,"Upload Your Attachment",null); %>
 | 
			
		||||
<%= rdat.getStdFontTag(null,2) %>
 | 
			
		||||
  Your attachment may be no more than <B>1 megabyte</B> in size.<P>
 | 
			
		||||
  <FORM METHOD="POST" ENCTYPE="multipart/form-data" ACTION="<%= rdat.getEncodedServletPath("attachment") %>">
 | 
			
		||||
    <INPUT TYPE=HIDDEN NAME="sig" VALUE="<%= data.getSIGID() %>">
 | 
			
		||||
    <INPUT TYPE=HIDDEN NAME="conf" VALUE="<%= data.getConfID() %>">
 | 
			
		||||
    <INPUT TYPE=HIDDEN NAME="msg" VALUE="<%= data.getPostID() %>">
 | 
			
		||||
    <INPUT TYPE=HIDDEN NAME="target" VALUE="<%= data.getTarget() %>">
 | 
			
		||||
    File to attach: <INPUT TYPE="FILE" NAME="thefile"><BR>
 | 
			
		||||
    <INPUT TYPE=IMAGE SRC="<%= rdat.getFullImagePath("bn_upload.gif") %>" NAME="upload" ALT="Upload"
 | 
			
		||||
     WIDTH=80 HEIGHT=24 BORDER=0>
 | 
			
		||||
  </FORM><P>
 | 
			
		||||
</FONT>
 | 
			
		||||
<% rdat.writeFooter(out); %>
 | 
			
		||||
@ -171,7 +171,13 @@
 | 
			
		||||
      <A HREF="<%= rdat.getEncodedServletPath("user/" + poster) %>" TARGET="_blank"><%= poster %></A>,
 | 
			
		||||
      <%= rdat.formatDateForDisplay(msg.getPostDate()) %>
 | 
			
		||||
    </EM>)
 | 
			
		||||
    <%-- TODO: paperclip goes here if we have an attachment --%>
 | 
			
		||||
    <% if (msg.hasAttachment()) { %>
 | 
			
		||||
      <A HREF="<%= rdat.getEncodedServletPath("attachment?" + data.getConfLocator() + "&msg="
 | 
			
		||||
                                              + String.valueOf(msg.getPostID())) %>"><IMG
 | 
			
		||||
       SRC="<%= rdat.getFullImagePath("attachment.gif") %>"
 | 
			
		||||
       ALT="(Attachment <%= msg.getAttachmentFilename() %> - <%= msg.getAttachmentLength() %> bytes)"
 | 
			
		||||
       WIDTH=16 HEIGHT=16 BORDER=0></A>
 | 
			
		||||
    <% } // end if %>
 | 
			
		||||
  </FONT><P>
 | 
			
		||||
  <% if (msg.isScribbled()) { %>
 | 
			
		||||
    <TT><EM><B>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								web/images/attachment.gif
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								web/images/attachment.gif
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 102 B  | 
							
								
								
									
										
											BIN
										
									
								
								web/images/bn_upload.gif
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								web/images/bn_upload.gif
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 942 B  | 
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user