first draft of message importing and exporting to/from conferences (new host

tools)
This commit is contained in:
Eric J. Bowersox
2004-06-09 04:10:52 +00:00
parent f6d3d9494d
commit e6e94f3427
25 changed files with 2422 additions and 29 deletions

View File

@@ -0,0 +1,194 @@
/*
* 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@ricochet.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2004 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.util;
import java.io.*;
import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.*;
public class Base64EncodeInputStream extends FilterInputStream
{
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
private static Logger logger = Logger.getLogger(Base64EncodeInputStream.class);
private static final int NREAD = 768; // must be divisible by three
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private byte[] m_coded_data = null;
private int m_ptr = 0;
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
public Base64EncodeInputStream(InputStream inner)
{
super(inner);
} // end constructor
/*--------------------------------------------------------------------------------
* Internal operations
*--------------------------------------------------------------------------------
*/
private boolean backfill() throws IOException
{
if ((m_coded_data!=null) && (m_coded_data.length<=m_ptr))
{ // the buffer is empty - clear it
logger.debug("buffer drained");
m_coded_data = null;
} // end if
if (m_coded_data==null)
{ // read in a chunk from the underlying stream
byte[] data = new byte[NREAD];
int nr = in.read(data);
if (nr<=0)
{ // done with underlying stream
logger.debug("B64EIS - underlying stream at EOF");
return true;
} // end if
if (logger.isDebugEnabled())
logger.debug("read " + nr + " bytes from underlying stream");
if (nr<NREAD)
{ // shorten the read-in array
byte[] data2 = new byte[nr];
System.arraycopy(data,0,data2,0,nr);
data = data2;
} // end if
m_coded_data = Base64.encodeBase64(data);
m_ptr = 0;
if (logger.isDebugEnabled())
logger.debug("reset buffer - now have " + m_coded_data.length + " bytes");
} // end if
return false;
} // end backfill
/*--------------------------------------------------------------------------------
* Overrides from class FilterInputStream
*--------------------------------------------------------------------------------
*/
public synchronized int read() throws IOException
{
if (backfill())
return -1; // end of file
return (int)(m_coded_data[m_ptr++]);
} // end read
public synchronized int read(byte[] b, int off, int len) throws IOException
{
if (b==null)
throw new NullPointerException("null array");
if (off<0)
throw new IndexOutOfBoundsException("negative offset");
if (len<0)
throw new IndexOutOfBoundsException("negative length");
if ((off + len)>b.length)
throw new IndexOutOfBoundsException("off right end of array");
if (len==0)
return 0;
int rc = 0;
while (len>0)
{ // force a backfill before copying
if (backfill())
break; // end of the underlying file
int ncpy = Math.min(len,m_coded_data.length - m_ptr);
System.arraycopy(m_coded_data,m_ptr,b,off,ncpy);
m_ptr += ncpy;
off += ncpy;
rc += ncpy;
len -= ncpy;
} // end while
if (rc==0)
rc = -1; // EOF
return rc;
} // end read
public synchronized long skip(long n) throws IOException
{
long rc = 0;
while (n>0)
{ // force a backfill before skipping
if (backfill())
break; // end of the underlying file
long nskp = Math.min(n,m_coded_data.length - m_ptr);
m_ptr += (int)nskp;
rc += nskp;
n -= nskp;
} // end while
return rc;
} // end skip
public void close() throws IOException
{
in.close();
m_coded_data = null;
} // end close
public synchronized int available() throws IOException
{
if (backfill())
return 0; // at end of file
return (m_coded_data.length - m_ptr) + (in.available() * 4 / 3);
} // end available
public void mark(int readLimit)
{ // do nothing
} // end mark
public void reset()
{ // do nothing
} // end reset
public boolean markSupported()
{
return false;
} // end markSupported
} // end class Base64EncodeInputStream

View File

@@ -9,9 +9,9 @@
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@ricochet.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
* Copyright (C) 2001-2004 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
@@ -125,20 +125,25 @@ public class IOUtil
* @param input The stream to copy binary data from.
* @param output The stream to copy binary data to.
* @param bufsize The size of the buffer to allocate for copying.
* @return The total number of bytes copied.
* @exception java.io.IOException If an exception occurred while reading or writing data.
*/
public static void copy(InputStream input, OutputStream output, int bufsize) throws IOException
public static int copy(InputStream input, OutputStream output, int bufsize) throws IOException
{
byte[] buffer = new byte[bufsize];
int rc = 0;
int rd = input.read(buffer);
while (rd>=0)
{ // simple read-write loop to shove data out the door
if (rd>0)
output.write(buffer,0,rd);
rc += rd;
rd = input.read(buffer);
} // end while
return rc;
} // end copy
/**
@@ -147,13 +152,14 @@ public class IOUtil
*
* @param input The stream to copy binary data from.
* @param output The stream to copy binary data to.
* @return The total number of bytes copied.
* @exception java.io.IOException If an exception occurred while reading or writing data.
* @see #DEFAULT_BUFSIZE
* @see #copy(java.io.InputStream,java.io.OutputStream,int)
*/
public static void copy(InputStream input, OutputStream output) throws IOException
public static int copy(InputStream input, OutputStream output) throws IOException
{
copy(input,output,DEFAULT_BUFSIZE);
return copy(input,output,DEFAULT_BUFSIZE);
} // end copy
@@ -246,20 +252,25 @@ public class IOUtil
* @param input The reader to copy character data from.
* @param output The writer to copy character data to.
* @param bufsize The size of the buffer to allocate for copying.
* @return The number of characters copied.
* @exception java.io.IOException If an exception occurred while reading or writing data.
*/
public static void copy(Reader input, Writer output, int bufsize) throws IOException
public static int copy(Reader input, Writer output, int bufsize) throws IOException
{
char[] buffer = new char[bufsize];
int rc = 0;
int rd = input.read(buffer);
while (rd>=0)
{ // simple read-write loop to shove data out the door
if (rd>0)
output.write(buffer,0,rd);
rc += rd;
rd = input.read(buffer);
} // end while
return rc;
} // end copy
/**
@@ -268,13 +279,14 @@ public class IOUtil
*
* @param input The reader to copy character data from.
* @param output The writer to copy character data to.
* @return The number of characters copied.
* @exception java.io.IOException If an exception occurred while reading or writing data.
* @see #DEFAULT_BUFSIZE
* @see #copy(java.io.Reader,java.io.Writer,int)
*/
public static void copy(Reader input, Writer output) throws IOException
public static int copy(Reader input, Writer output) throws IOException
{
copy(input,output,DEFAULT_BUFSIZE);
return copy(input,output,DEFAULT_BUFSIZE);
} // end copy

View File

@@ -9,16 +9,19 @@
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@ricochet.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
* Copyright (C) 2001-2004 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.venice.core;
import java.io.InputStream;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Set;
import com.silverwrist.venice.except.AccessError;
import com.silverwrist.venice.except.DataException;
import com.silverwrist.venice.except.EmailException;
@@ -43,6 +46,9 @@ public interface ConferenceContext
public static final int CUST_BLOCK_TOP = 0;
public static final int CUST_BLOCK_BOTTOM = 1;
public static final int IMPORT_MATCH_NUM = 0;
public static final int IMPORT_MATCH_NAME = 1;
public abstract int getConfID();
public abstract String getName();
@@ -192,4 +198,9 @@ public interface ConferenceContext
public abstract String getPostLink() throws DataException;
public abstract String exportTopics(Set select_topics) throws AccessError, DataException, IOException;
public abstract List importMessages(InputStream xmlstream, int match_method, boolean create_new)
throws AccessError, DataException;
} // end interface ConferenceContext

View File

@@ -18,6 +18,8 @@
package com.silverwrist.venice.core;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
import com.silverwrist.venice.except.AccessError;
import com.silverwrist.venice.except.DataException;
@@ -60,6 +62,8 @@ public interface TopicMessageContext
public abstract InputStream getAttachmentData() throws AccessError, DataException;
public abstract int getAttachmentData(OutputStream here) throws AccessError, DataException, IOException;
public abstract boolean canHide();
public abstract boolean canScribble();

View File

@@ -9,14 +9,15 @@
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@ricochet.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001-02 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
* Copyright (C) 2001-2004 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.venice.core.impl;
import java.io.*;
import java.sql.*;
import java.util.*;
import org.apache.log4j.*;
@@ -1778,6 +1779,95 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
} // end getPostLink
public String exportTopics(Set select_topics) throws AccessError, DataException, IOException
{
if (logger.isDebugEnabled())
logger.debug("exportTopics(" + select_topics.toString() + ") entry");
if (!(getConferenceData().canChangeConference(level)))
throw new AccessError("You are not permitted to export posts from this conference.");
if (deleted)
throw new DataException("Cannot export posts from a deleted conference.");
// "Normalize" the topic selection set.
HashSet norm_select_topics = null;
if (select_topics!=null)
{ // build the normalized set
norm_select_topics = new HashSet();
for (Iterator it=select_topics.iterator(); it.hasNext(); )
{ // get each object out in turn
Object o = it.next();
if (o==null)
continue;
if (o instanceof Integer)
{ // it's already an integer
norm_select_topics.add(o);
continue;
} // end if
if (o instanceof Number)
{ // convert to Integer and add it
norm_select_topics.add(new Integer(((Number)o).intValue()));
continue;
} // end if
try
{ // append integer equivalent to set
norm_select_topics.add(new Integer(o.toString()));
} // end try
catch (NumberFormatException e)
{ // do nothing
} // end catch
} // end for
} // end if
ConferencingExporter xprt = new ConferencingExporter();
xprt.setTopics(norm_select_topics);
return xprt.exportConference(this);
} // end exportTopics
public List importMessages(InputStream xmlstream, int match_method, boolean create_new)
throws AccessError, DataException
{
if (xmlstream==null)
throw new NullPointerException("bad input stream");
if ((match_method!=IMPORT_MATCH_NUM) && (match_method!=IMPORT_MATCH_NAME))
throw new IndexOutOfBoundsException("invalid match method specified");
if (!(getConferenceData().canChangeConference(level)))
throw new AccessError("You are not permitted to import posts to this conference.");
if (deleted)
throw new DataException("Cannot import messages to a deleted conference.");
Connection conn = null;
try
{ // get a connection and create the worker
conn = env.getConnection();
ConferencingImporter worker = new ConferencingImporter(env.getUserID(),confid,match_method,create_new,conn,
env.getEngine());
// run it!
return worker.importMessages(xmlstream);
} // end try
catch (SQLException e)
{ // translate SQLException to DataException
throw new DataException("Error getting database connection: " + e.getMessage(),e);
} // end catch
finally
{ // shut down the connection
SQLUtil.shutdown(conn);
} // end finally
} // end importMessages
/*--------------------------------------------------------------------------------
* Implementations from interface ConferenceBackend
*--------------------------------------------------------------------------------

View File

@@ -0,0 +1,220 @@
/*
* 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@ricochet.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2004 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.venice.core.impl;
import java.io.*;
import java.text.*;
import java.util.*;
import org.apache.log4j.*;
import com.silverwrist.util.*;
import com.silverwrist.venice.core.*;
import com.silverwrist.venice.except.*;
class ConferencingExporter
{
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
private static Logger logger = Logger.getLogger(ConferencingExporter.class);
private static final DateFormat s_datefmt;
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private StringWriter m_buffer = null;
private PrintWriter m_wr = null;
private Set m_include = null;
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
ConferencingExporter()
{ // do nothing
} // end constructor
/*--------------------------------------------------------------------------------
* Internal operations
*--------------------------------------------------------------------------------
*/
private void visit(TopicMessageUserContextImpl msg) throws DataException, AccessError, IOException
{
if (logger.isDebugEnabled())
logger.debug("exporting post #" + msg.getPostNumber());
m_wr.write("<post id=\"");
m_wr.print(msg.getPostID());
m_wr.write("\" parent=\"");
m_wr.print(msg.getParentPostID());
m_wr.write("\" index=\"");
m_wr.print(msg.getPostNumber());
m_wr.write("\" lines=\"");
m_wr.print(msg.getNumLines());
m_wr.write("\" author=\"");
m_wr.write(msg.getCreatorName());
m_wr.write("\" date=\"");
m_wr.write(s_datefmt.format(msg.getPostDate()));
m_wr.write("\" hidden=\"");
m_wr.write(msg.isHidden() ? "true" : "false");
m_wr.write("\">\n");
if (msg.isScribbled())
{ // write out the scribble information
m_wr.write("<scribbled by=\"");
m_wr.write(msg.getScribblingUser());
m_wr.write("\" date=\"");
m_wr.write(s_datefmt.format(msg.getScribbleDate()));
m_wr.write("\"/>\n");
} // end if
m_wr.write("<pseud><![CDATA[");
m_wr.write(msg.getPseud());
m_wr.write("]]></pseud>\n<text><![CDATA[");
m_wr.write(msg.getBodyText());
m_wr.write("]]></text>\n");
if (msg.hasAttachment())
{ // write out the attachment information
if (logger.isDebugEnabled())
logger.debug("exporting attachment for post #" + msg.getPostNumber());
m_wr.write("<attachment length=\"");
m_wr.print(msg.getAttachmentLength());
m_wr.write("\" type=\"");
m_wr.write(msg.getAttachmentType());
m_wr.write("\" filename=\"");
m_wr.write(msg.getAttachmentFilename());
m_wr.write("\">");
Reader r = null;
try
{ // copy the attachment data into the output
r = new BufferedReader(new InputStreamReader(new Base64EncodeInputStream(msg.getAttachmentData()),
"US-ASCII"));
IOUtil.copy(r,m_wr);
} // end try
catch (UnsupportedEncodingException e)
{ // whoops!
throw new InternalStateError("Encoding not supported?");
} // end catch
catch (IOException e)
{ // what happened here?
logger.error("I/O exception",e);
throw e;
} // end catch
finally
{ // close down our reader when we're done
IOUtil.shutdown(r);
} // end finally
m_wr.write("</attachment>\n");
} // end if
m_wr.write("</post>\n");
} // end visit
private void visit(TopicUserContextImpl topic) throws DataException, AccessError, IOException
{
if ((m_include!=null) && !(m_include.contains(new Integer(topic.getTopicNumber()))))
return; // skip this topic
if (logger.isDebugEnabled())
logger.debug("exporting topic \"" + topic.getName() + "\"");
// write the main topic information
m_wr.write("<topic index=\"");
m_wr.print(topic.getTopicNumber());
m_wr.write("\" frozen=\"");
m_wr.write(topic.isFrozen() ? "true" : "false");
m_wr.write("\" archived=\"");
m_wr.write(topic.isArchived() ? "true" : "false");
m_wr.write("\">\n<topicname><![CDATA[");
m_wr.write(topic.getName());
m_wr.write("]]></topicname>\n");
// get the posts and write them out
List l = topic.getMessages(0,topic.getTopMessage());
for (Iterator it=l.iterator(); it.hasNext(); )
visit((TopicMessageUserContextImpl)(it.next()));
// done with the topic
m_wr.write("</topic>\n");
} // end visit
/*--------------------------------------------------------------------------------
* External operations
*--------------------------------------------------------------------------------
*/
void setTopics(Set s)
{
m_include = s;
} // end setTopics
String exportConference(ConferenceUserContextImpl conf) throws DataException, AccessError, IOException
{
if (logger.isDebugEnabled())
logger.debug("exporting conference \"" + conf.getName() + "\"");
m_buffer = new StringWriter();
m_wr = new PrintWriter(m_buffer);
m_wr.write("<?xml version=\"1.0\"?>\n<vcif>\n");
List l = conf.getTopicList(ConferenceContext.GET_ALL,ConferenceContext.SORT_NUMBER);
for (Iterator it=l.iterator(); it.hasNext(); )
visit((TopicUserContextImpl)(it.next()));
m_wr.write("</vcif>\n");
m_wr.flush();
// Return the finished buffer.
String rc = m_buffer.toString();
m_wr.close();
m_wr = null;
m_buffer = null;
return rc;
} // end exportConference
/*--------------------------------------------------------------------------------
* Static initializer
*--------------------------------------------------------------------------------
*/
static
{ // create an ISO 8601 date formatter
SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
df.setTimeZone(new SimpleTimeZone(0,"UTC"));
s_datefmt = df;
} // end static initializer
} // end class ConferencingExporter

File diff suppressed because it is too large Load Diff

View File

@@ -9,9 +9,9 @@
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@ricochet.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001-02 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
* Copyright (C) 2001-2004 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
@@ -293,6 +293,13 @@ class PublishedMessageImpl implements TopicMessageContext
} // end getAttachmentData
public int getAttachmentData(OutputStream here) throws AccessError, DataException, IOException
{
// FUTURE: allow publishing paperclips?
throw new AccessError("There is no attachment data for this message.");
} // end getAttachmentData
public boolean canHide()
{
return false;

View File

@@ -9,9 +9,9 @@
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@ricochet.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001-02 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
* Copyright (C) 2001-2004 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
@@ -200,6 +200,40 @@ class TopicMessageUserContextImpl implements TopicMessageContext
} // end refresh
/*--------------------------------------------------------------------------------
* Semi-internal operations
*--------------------------------------------------------------------------------
*/
final String getScribblingUser() throws DataException
{
if (scribble_uid==-1)
return null;
Connection conn = null;
try
{ // use a database connection to get the user name
conn = env.getConnection();
refresh(conn);
if (nuked)
return null; // post nuked!
return quickGetUserName(conn,scribble_uid);
} // end try
catch (SQLException e)
{ // turn this into a DataException
logger.error("DB error reading user name: " + e.getMessage(),e);
throw new DataException("unable to retrieve user name: " + e.getMessage(),e);
} // end catch
finally
{ // make sure we release the connection before we go
SQLUtil.shutdown(conn);
} // end finally
} // end getScribblingUser
/*--------------------------------------------------------------------------------
* Implementations from interface TopicMessageContext
*--------------------------------------------------------------------------------
@@ -392,6 +426,8 @@ class TopicMessageUserContextImpl implements TopicMessageContext
public InputStream getAttachmentData() throws AccessError, DataException
{
if (logger.isDebugEnabled())
logger.debug("getAttachmentData() for post " + postid);
if (nuked || (scribble_date!=null))
{ // this would be an exercise in futility!
logger.error("cannot attach to a nuked or scribbled message");
@@ -401,6 +437,7 @@ class TopicMessageUserContextImpl implements TopicMessageContext
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
InputStream rc = null;
try
{ // open up a database connection
@@ -434,7 +471,7 @@ class TopicMessageUserContextImpl implements TopicMessageContext
sql.append("SELECT data FROM postattach WHERE postid = ").append(postid).append(';');
// Execute the query!
ResultSet rs = stmt.executeQuery(sql.toString());
rs = stmt.executeQuery(sql.toString());
if (!(rs.next()))
{ // there is no attachment data!
logger.error("no attachment data to get");
@@ -450,10 +487,12 @@ class TopicMessageUserContextImpl implements TopicMessageContext
switch (stgmethod)
{ // where's our input really coming from
case 0: // copy verbatim
logger.debug("stgmethod 0 = straight copy");
real_input = sqldata;
break;
case 1: // gunzip it first
logger.debug("stgmethod 1 = GZIP decompress");
real_input = new GZIPInputStream(sqldata);
break;
@@ -463,7 +502,10 @@ class TopicMessageUserContextImpl implements TopicMessageContext
} // end switch
// Copy to a new stream.
rc = new ByteArrayInputStream(IOUtil.load(real_input));
byte[] ary = IOUtil.load(real_input);
if (logger.isDebugEnabled())
logger.debug("loaded data of length " + ary.length);
rc = new ByteArrayInputStream(ary);
} // end try
catch (SQLException e)
@@ -480,6 +522,7 @@ class TopicMessageUserContextImpl implements TopicMessageContext
} // end catch
finally
{ // make sure we release the connection before we go
SQLUtil.shutdown(rs);
SQLUtil.shutdown(stmt);
SQLUtil.shutdown(conn);
@@ -489,6 +532,102 @@ class TopicMessageUserContextImpl implements TopicMessageContext
} // end getAttachmentData
public int getAttachmentData(OutputStream here) throws AccessError, DataException, IOException
{
if (logger.isDebugEnabled())
logger.debug("getAttachmentData() for post " + postid);
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;
Statement stmt = null;
ResultSet rs = null;
try
{ // open up a database connection
conn = env.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
// This will cause a "hit" on the attachment data. Update that record.
stmt = conn.createStatement();
StringBuffer sql = new StringBuffer("UPDATE postattach SET hits = hits + 1, last_hit = '");
sql.append(SQLUtil.encodeDate(new java.util.Date())).append("' WHERE postid = ").append(postid);
sql.append(';');
stmt.executeUpdate(sql.toString());
// Create the SQL we need to retrieve the attachment.
sql.setLength(0);
sql.append("SELECT data FROM postattach WHERE postid = ").append(postid).append(';');
// Execute the query!
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);
InputStream real_input;
switch (stgmethod)
{ // where's our input really coming from
case 0: // copy verbatim
logger.debug("stgmethod 0 = straight copy");
real_input = sqldata;
break;
case 1: // gunzip it first
logger.debug("stgmethod 1 = GZIP decompress");
real_input = new GZIPInputStream(sqldata);
break;
default:
throw new DataException("Unknown storage method value: " + stgmethod);
} // end switch
// copy the data and return number of bytes copied
return IOUtil.copy(real_input,here);
} // 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
finally
{ // make sure we release the connection before we go
SQLUtil.shutdown(rs);
SQLUtil.shutdown(stmt);
SQLUtil.shutdown(conn);
} // end finally
} // end getAttachmentData
public boolean canHide()
{
return ( ((creator_uid==env.getUserID()) && (!env.isAnonymous()))

View File

@@ -9,9 +9,9 @@
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@ricochet.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001-02 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
* Copyright (C) 2001-2004 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
@@ -201,6 +201,17 @@ class TopicUserContextImpl implements TopicContext
} // end loadBozo
/*--------------------------------------------------------------------------------
* Semi-internal functions
*--------------------------------------------------------------------------------
*/
final int getTopMessage()
{
return top_message;
} // end getTopMessage
/*--------------------------------------------------------------------------------
* Implementations from interface TopicContext
*--------------------------------------------------------------------------------

View File

@@ -9,9 +9,9 @@
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@ricochet.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001-02 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
* Copyright (C) 2001-2004 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/

View File

@@ -17,11 +17,9 @@
*/
package com.silverwrist.venice.ui.conf;
import java.io.InputStream;
import java.io.IOException;
import java.io.*;
import com.silverwrist.venice.core.TopicMessageContext;
import com.silverwrist.venice.except.AccessError;
import com.silverwrist.venice.except.DataException;
import com.silverwrist.venice.except.*;
import com.silverwrist.venice.ui.ContentExecute;
import com.silverwrist.venice.ui.LinkTypes;
import com.silverwrist.venice.ui.RequestExec;
@@ -40,7 +38,7 @@ public class AttachmentContent extends ThrowableContent implements ContentExecut
private InputStream stm;
/*--------------------------------------------------------------------------------
* Constructor
* Constructors
*--------------------------------------------------------------------------------
*/
@@ -54,6 +52,26 @@ public class AttachmentContent extends ThrowableContent implements ContentExecut
} // end constructor
public AttachmentContent(String data, String type, String filename)
{
super();
this.type = type;
this.filename = filename;
try
{ // get the string data and output it
byte[] d = data.getBytes("UTF-8");
this.length = d.length;
this.stm = new ByteArrayInputStream(d);
} // end try
catch (UnsupportedEncodingException e)
{ // this is not supposed to happen
throw new InternalStateError("encoding not found?!?!?!?");
} // end catch
} // end constructor
/*--------------------------------------------------------------------------------
* Implementations from interface ContentExecute
*--------------------------------------------------------------------------------

View File

@@ -9,9 +9,9 @@
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@ricochet.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001-04 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
* Copyright (C) 2001-2004 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
@@ -166,6 +166,21 @@ public abstract class BaseServlet extends HttpServlet
my_output = new ErrorBox("Internal Error!",
"No content returned for request: " + the_request.getVerb() + ": /"
+ default_location,null);
else if (my_output instanceof RuntimeException)
{ // throw all RuntimeExceptions we get at this level
logger.error("BaseServlet caught runtime exception" + my_output.getClass().getName()
+ " in commonProcess",(Throwable)my_output);
throw new ServletException((Throwable)my_output);
} // end else if
else if (my_output instanceof VirtualMachineError)
{ // OutOfMemoryError, StackOverflowError, and such come here
System.gc(); // garbage collect so we have enough space to handle the error
logger.error("Virtual machine failure " + my_output.getClass().getName() + " in commonProcess",
(Throwable)my_output);
throw new ServletException((Throwable)my_output);
} // end else if
} // end try
catch (ThrowableContent tc)