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…
Reference in New Issue
Block a user