added default JSP file and statistics measurement for attachment downloads

This commit is contained in:
Eric J. Bowersox 2001-04-03 05:22:18 +00:00
parent 7e72407b84
commit 257537e869
6 changed files with 137 additions and 30 deletions

View File

@ -312,6 +312,12 @@
<url-pattern>/dump/*</url-pattern> <url-pattern>/dump/*</url-pattern>
</servlet-mapping> </servlet-mapping>
<!-- The list of "welcome files" for the application -->
<welcome-file-list>
<welcome-file>default.jsp</welcome-file>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<!-- Global parameters for the HTTP session --> <!-- Global parameters for the HTTP session -->
<session-config> <session-config>
<session-timeout>60</session-timeout> <!-- 1 hour --> <session-timeout>60</session-timeout> <!-- 1 hour -->

View File

@ -377,9 +377,12 @@ CREATE TABLE postdata (
CREATE TABLE postattach ( CREATE TABLE postattach (
postid BIGINT NOT NULL PRIMARY KEY, postid BIGINT NOT NULL PRIMARY KEY,
datalen INT, datalen INT,
hits INT DEFAULT 0,
last_hit DATETIME,
stgmethod SMALLINT DEFAULT 0,
priority SMALLINT DEFAULT 0,
filename VARCHAR(255), filename VARCHAR(255),
mimetype VARCHAR(128), mimetype VARCHAR(128),
stgmethod SMALLINT DEFAULT 0,
data MEDIUMBLOB data MEDIUMBLOB
); );

View File

@ -20,6 +20,7 @@ package com.silverwrist.venice.core.impl;
import java.io.*; import java.io.*;
import java.sql.*; import java.sql.*;
import java.util.*; import java.util.*;
import java.util.zip.*;
import org.apache.log4j.*; import org.apache.log4j.*;
import com.silverwrist.util.StringUtil; import com.silverwrist.util.StringUtil;
import com.silverwrist.util.collections.*; import com.silverwrist.util.collections.*;
@ -60,6 +61,7 @@ class TopicMessageUserContextImpl implements TopicMessageContext
private int datalen; private int datalen;
private String filename; private String filename;
private String mimetype; private String mimetype;
private int stgmethod;
private boolean nuked = false; private boolean nuked = false;
private String creator_cache = null; private String creator_cache = null;
private String text_cache = null; private String text_cache = null;
@ -73,7 +75,7 @@ class TopicMessageUserContextImpl implements TopicMessageContext
long postid, long parent, int num, int linecount, int creator_uid, long postid, long parent, int num, int linecount, int creator_uid,
java.util.Date posted, boolean hidden, int scribble_uid, java.util.Date posted, boolean hidden, int scribble_uid,
java.util.Date scribble_date, String pseud, int datalen, java.util.Date scribble_date, String pseud, int datalen,
String filename, String mimetype) String filename, String mimetype, int stgmethod)
{ {
this.engine = engine; this.engine = engine;
this.conf = conf; this.conf = conf;
@ -91,6 +93,7 @@ class TopicMessageUserContextImpl implements TopicMessageContext
this.datalen = datalen; this.datalen = datalen;
this.filename = filename; this.filename = filename;
this.mimetype = mimetype; this.mimetype = mimetype;
this.stgmethod = stgmethod;
} // end constructor } // end constructor
@ -114,6 +117,7 @@ class TopicMessageUserContextImpl implements TopicMessageContext
this.datalen = 0; this.datalen = 0;
this.filename = null; this.filename = null;
this.mimetype = null; this.mimetype = null;
this.stgmethod = -1;
} // end constructor } // end constructor
@ -138,8 +142,9 @@ class TopicMessageUserContextImpl implements TopicMessageContext
Statement stmt = conn.createStatement(); Statement stmt = conn.createStatement();
StringBuffer sql = new StringBuffer("SELECT posts.hidden, posts.scribble_uid, posts.scribble_date, " StringBuffer sql = new StringBuffer("SELECT posts.hidden, posts.scribble_uid, posts.scribble_date, "
+ "posts.pseud, postattach.datalen, postattach.filename, " + "posts.pseud, postattach.datalen, postattach.filename, "
+ "postattach.mimetype FROM posts LEFT JOIN postattach ON " + "postattach.mimetype, postattach.stgmethod FROM posts "
+ "posts.postid = postattach.postid WHERE posts.postid = "); + "LEFT JOIN postattach ON posts.postid = postattach.postid "
+ "WHERE posts.postid = ");
sql.append(postid).append(';'); sql.append(postid).append(';');
ResultSet rs = stmt.executeQuery(sql.toString()); ResultSet rs = stmt.executeQuery(sql.toString());
if (rs.next()) if (rs.next())
@ -151,6 +156,9 @@ class TopicMessageUserContextImpl implements TopicMessageContext
datalen = rs.getInt(5); datalen = rs.getInt(5);
filename = rs.getString(6); filename = rs.getString(6);
mimetype = rs.getString(7); mimetype = rs.getString(7);
stgmethod = rs.getInt(8);
if (rs.wasNull())
stgmethod = -1;
} // end if } // end if
else else
@ -165,6 +173,7 @@ class TopicMessageUserContextImpl implements TopicMessageContext
datalen = 0; datalen = 0;
filename = null; filename = null;
mimetype = null; mimetype = null;
stgmethod = -1;
nuked = true; nuked = true;
creator_cache = null; creator_cache = null;
text_cache = null; text_cache = null;
@ -384,10 +393,16 @@ class TopicMessageUserContextImpl implements TopicMessageContext
} // end if } // end if
// Create the statement and the SQL we need to retrieve the attachment. // This will cause a "hit" on the attachment data. Update that record.
Statement stmt = conn.createStatement(); Statement stmt = conn.createStatement();
StringBuffer sql = new StringBuffer("SELECT data FROM postattach WHERE postid = "); StringBuffer sql = new StringBuffer("UPDATE postattach SET hits = hits + 1, last_hit = '");
sql.append(postid).append(';'); 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! // Execute the query!
ResultSet rs = stmt.executeQuery(sql.toString()); ResultSet rs = stmt.executeQuery(sql.toString());
@ -402,19 +417,35 @@ class TopicMessageUserContextImpl implements TopicMessageContext
// need to make a temporary copy of it, to a ByteArrayOutputStream. (Attachments can only be // 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.) // 1 Mb in size, so this shouldn't be a big problem.)
InputStream sqldata = rs.getBinaryStream(1); InputStream sqldata = rs.getBinaryStream(1);
InputStream real_input;
switch (stgmethod)
{ // where's our input really coming from
case 0: // copy verbatim
real_input = sqldata;
break;
case 1: // gunzip it first
real_input = new GZIPInputStream(sqldata);
break;
default:
throw new DataException("Unknown storage method value: " + stgmethod);
} // end switch
ByteArrayOutputStream copy = new ByteArrayOutputStream(datalen); ByteArrayOutputStream copy = new ByteArrayOutputStream(datalen);
byte[] buffer = new byte[4096]; byte[] buffer = new byte[4096];
int rd = sqldata.read(buffer); int rd = real_input.read(buffer);
while (rd>=0) while (rd>=0)
{ // write, then read again { // write, then read again
if (rd>0) if (rd>0)
copy.write(buffer,0,rd); copy.write(buffer,0,rd);
rd = sqldata.read(buffer); rd = real_input.read(buffer);
} // end while } // end while
// Close both our streams, making sure we create the stream we need for the return value. // Close both our streams, making sure we create the stream we need for the return value.
sqldata.close(); real_input.close();
rc = new ByteArrayInputStream(copy.toByteArray()); rc = new ByteArrayInputStream(copy.toByteArray());
copy.close(); copy.close();
@ -816,6 +847,40 @@ class TopicMessageUserContextImpl implements TopicMessageContext
} // end else if } // end else if
// Compress the attachment data in memory.
InputStream real_data = null;
int real_length = 0;
try
{ // create a compressor into a memory buffer
ByteArrayOutputStream bytestm = new ByteArrayOutputStream(length);
GZIPOutputStream gzipstm = new GZIPOutputStream(bytestm);
// do the usual read/write loop to get the data compressed
byte[] buffer = new byte[4096];
int rd = data.read(buffer);
while (rd>=0)
{ // write, then read
if (rd>0)
gzipstm.write(buffer,0,rd);
rd = data.read(buffer);
} // end while
// finish compression, then get the data and the real length
gzipstm.finish();
buffer = bytestm.toByteArray();
real_length = buffer.length;
real_data = new ByteArrayInputStream(buffer);
gzipstm.close();
} // end try
catch (IOException ioe)
{ // the big error
logger.error("IOException in compressor loop: " + ioe.getMessage(),ioe);
throw new DataException("Failure in compressing read data: " + ioe.getMessage());
} // end catch
Connection conn = null; Connection conn = null;
AuditRecord ar = null; AuditRecord ar = null;
@ -834,20 +899,23 @@ class TopicMessageUserContextImpl implements TopicMessageContext
// Build the SQL statement that inserts the attachment. Note the use of the "?" to specify the // 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. // BLOB parameter (the attachment data itself); this comes later.
StringBuffer sql = StringBuffer sql = new StringBuffer("INSERT INTO postattach (postid, datalen, last_hit, stgmethod, "
new StringBuffer("INSERT INTO postattach (postid, datalen, filename, mimetype, data) VALUES ("); + "filename, mimetype, data) VALUES (");
sql.append(postid).append(", ").append(length).append(", '").append(SQLUtil.encodeString(file)); sql.append(postid).append(", ").append(length).append(", '");
sql.append("', '").append(SQLUtil.encodeString(m_type)).append("', ?);"); sql.append(SQLUtil.encodeDate(new java.util.Date())).append("', 1, '");
sql.append(SQLUtil.encodeString(file)).append("', '").append(SQLUtil.encodeString(m_type));
sql.append("', ?);");
// Prepare the statement, set the BLOB parameter, and execute it. // Prepare the statement, set the BLOB parameter, and execute it.
PreparedStatement stmt = conn.prepareStatement(sql.toString()); PreparedStatement stmt = conn.prepareStatement(sql.toString());
stmt.setBinaryStream(1,data,length); stmt.setBinaryStream(1,real_data,real_length);
stmt.executeUpdate(); stmt.executeUpdate();
// Save off the local attachment values. // Save off the local attachment values.
datalen = length; datalen = length;
filename = file; filename = file;
mimetype = m_type; mimetype = m_type;
stgmethod = 1;
// Generate an audit record indicating what we did. // Generate an audit record indicating what we did.
ar = new AuditRecord(AuditRecord.UPLOAD_ATTACHMENT,conf.realUID(),conf.userRemoteAddress(), ar = new AuditRecord(AuditRecord.UPLOAD_ATTACHMENT,conf.realUID(),conf.userRemoteAddress(),
@ -1036,8 +1104,8 @@ class TopicMessageUserContextImpl implements TopicMessageContext
StringBuffer sql = StringBuffer sql =
new StringBuffer("SELECT p.postid, p.parent, p.num, p.linecount, p.creator_uid, p.posted, " 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, " + "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 " + "a.mimetype, a.stgmethod FROM posts p LEFT JOIN postattach a ON "
+ "WHERE p.topicid = "); + "p.postid = a.postid WHERE p.topicid = ");
sql.append(topicid).append(" AND p.num >= ").append(post_low).append(" AND p.num <= "); sql.append(topicid).append(" AND p.num >= ").append(post_low).append(" AND p.num <= ");
sql.append(post_high).append(" ORDER BY p.num ASC;"); sql.append(post_high).append(" ORDER BY p.num ASC;");
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
@ -1050,7 +1118,8 @@ class TopicMessageUserContextImpl implements TopicMessageContext
new TopicMessageUserContextImpl(engine,conf,datapool,rs.getLong(1),rs.getLong(2),rs.getInt(3), 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.getInt(4),rs.getInt(5),SQLUtil.getFullDateTime(rs,6),
rs.getBoolean(7),rs.getInt(8),SQLUtil.getFullDateTime(rs,9), rs.getBoolean(7),rs.getInt(8),SQLUtil.getFullDateTime(rs,9),
rs.getString(10),rs.getInt(11),rs.getString(12),rs.getString(13)); rs.getString(10),rs.getInt(11),rs.getString(12),rs.getString(13),
rs.getInt(14));
rc.add(val); rc.add(val);
} // end while } // end while
@ -1091,8 +1160,8 @@ class TopicMessageUserContextImpl implements TopicMessageContext
StringBuffer sql = StringBuffer sql =
new StringBuffer("SELECT p.postid, p.parent, p.num, p.linecount, p.creator_uid, p.posted, " 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, " + "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 " + "a.mimetype, a.stgmethod FROM posts p LEFT JOIN postattach a ON "
+ "WHERE p.topicid = "); + "p.postid = a.postid WHERE p.topicid = ");
sql.append(topicid).append(" AND p.num = ").append(message_num).append(';'); sql.append(topicid).append(" AND p.num = ").append(message_num).append(';');
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("SQL: " + sql.toString()); logger.debug("SQL: " + sql.toString());
@ -1103,7 +1172,7 @@ class TopicMessageUserContextImpl implements TopicMessageContext
rs.getInt(4),rs.getInt(5),SQLUtil.getFullDateTime(rs,6), rs.getInt(4),rs.getInt(5),SQLUtil.getFullDateTime(rs,6),
rs.getBoolean(7),rs.getInt(8),SQLUtil.getFullDateTime(rs,9), rs.getBoolean(7),rs.getInt(8),SQLUtil.getFullDateTime(rs,9),
rs.getString(10),rs.getInt(11),rs.getString(12), rs.getString(10),rs.getInt(11),rs.getString(12),
rs.getString(13)); rs.getString(13),rs.getInt(14));
// indicates an error... // indicates an error...
throw new DataException("Message not found."); throw new DataException("Message not found.");
@ -1140,8 +1209,8 @@ class TopicMessageUserContextImpl implements TopicMessageContext
StringBuffer sql = StringBuffer sql =
new StringBuffer("SELECT p.postid, p.parent, p.num, p.linecount, p.creator_uid, p.posted, " 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, " + "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 " + "a.mimetype, a.stgmethod FROM topics t, posts p LEFT JOIN postattach a "
+ "WHERE t.topicid = p.topicid AND t.confid = "); + "ON p.postid = a.postid WHERE t.topicid = p.topicid AND t.confid = ");
sql.append(conf.realConfID()).append(" AND p.postid = ").append(postid).append(';'); sql.append(conf.realConfID()).append(" AND p.postid = ").append(postid).append(';');
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("SQL: " + sql.toString()); logger.debug("SQL: " + sql.toString());
@ -1152,7 +1221,7 @@ class TopicMessageUserContextImpl implements TopicMessageContext
rs.getInt(4),rs.getInt(5),SQLUtil.getFullDateTime(rs,6), rs.getInt(4),rs.getInt(5),SQLUtil.getFullDateTime(rs,6),
rs.getBoolean(7),rs.getInt(8),SQLUtil.getFullDateTime(rs,9), rs.getBoolean(7),rs.getInt(8),SQLUtil.getFullDateTime(rs,9),
rs.getString(10),rs.getInt(11),rs.getString(12), rs.getString(10),rs.getInt(11),rs.getString(12),
rs.getString(13)); rs.getString(13),rs.getInt(14));
// indicates an error... // indicates an error...
throw new DataException("Message not found."); throw new DataException("Message not found.");

View File

@ -7,7 +7,7 @@
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
* language governing rights and limitations under the License. * 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>, * 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 * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
@ -23,6 +23,13 @@ import com.silverwrist.util.StringUtil;
public class SQLUtil public class SQLUtil
{ {
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
private static SimpleTimeZone utc = new SimpleTimeZone(0,"UTC");
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
* Internal functions * Internal functions
*-------------------------------------------------------------------------------- *--------------------------------------------------------------------------------
@ -35,7 +42,7 @@ public class SQLUtil
try try
{ // do almost the reverse process of formatting it into a string { // do almost the reverse process of formatting it into a string
GregorianCalendar cal = new GregorianCalendar(new SimpleTimeZone(0,"UTC")); GregorianCalendar cal = new GregorianCalendar(utc);
cal.set(Calendar.YEAR,Integer.parseInt(dstr.substring(0,4))); cal.set(Calendar.YEAR,Integer.parseInt(dstr.substring(0,4)));
cal.set(Calendar.MONTH,Integer.parseInt(dstr.substring(5,7)) - 1 + Calendar.JANUARY); cal.set(Calendar.MONTH,Integer.parseInt(dstr.substring(5,7)) - 1 + Calendar.JANUARY);
cal.set(Calendar.DAY_OF_MONTH,Integer.parseInt(dstr.substring(8,10))); cal.set(Calendar.DAY_OF_MONTH,Integer.parseInt(dstr.substring(8,10)));
@ -112,7 +119,7 @@ public class SQLUtil
public static String encodeDate(java.util.Date d) public static String encodeDate(java.util.Date d)
{ {
// Break down the date as a UTC value. // Break down the date as a UTC value.
GregorianCalendar cal = new GregorianCalendar(new SimpleTimeZone(0,"UTC")); GregorianCalendar cal = new GregorianCalendar(utc);
cal.setTime(d); cal.setTime(d);
// Create the two string buffers converting the date. // Create the two string buffers converting the date.

View File

@ -111,14 +111,14 @@ public class Attachment extends VeniceServlet
return new ErrorBox(null,"Internal Error: 'thefile' should be a file param",target); return new ErrorBox(null,"Internal Error: 'thefile' should be a file param",target);
// get the SIG // get the SIG
SIGContext sig = getSIGParameter(request,user,true,"top"); SIGContext sig = getSIGParameter(mphandler,user,true,"top");
changeMenuSIG(request,sig); changeMenuSIG(request,sig);
// get the conference // get the conference
ConferenceContext conf = getConferenceParameter(request,sig,true,"top"); ConferenceContext conf = getConferenceParameter(mphandler,sig,true,"top");
// get the message we want to use // get the message we want to use
TopicMessageContext msg = getMessageParameter(request,conf,true,"top"); TopicMessageContext msg = getMessageParameter(mphandler,conf,true,"top");
try try
{ // attach the data to the message! { // attach the data to the message!

22
web/default.jsp Normal file
View File

@ -0,0 +1,22 @@
<%--
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):
--%>
<%
ServletContext ctxt = getServletConfig().getServletContext();
RequestDispatcher disp = ctxt.getNamedDispatcher("top");
disp.forward(request,response);
%>