landed the code for doing post attachments (the infamous paperclip)

This commit is contained in:
Eric J. Bowersox
2001-02-08 22:43:58 +00:00
parent 66b7fea53b
commit 70774ead7d
20 changed files with 1075 additions and 25 deletions

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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
*--------------------------------------------------------------------------------

View File

@@ -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

View File

@@ -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
{

View File

@@ -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

View 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

View File

@@ -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

View File

@@ -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

View 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

View File

@@ -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