implemented the rest of the functions on the "posts" page; fixed post links

so they work now; added the HTML Reference (originally from CW); added the
post output filtering to turn the "pseudo-URIs" in the database into real
URIs
This commit is contained in:
Eric J. Bowersox 2001-02-09 09:10:46 +00:00
parent 70774ead7d
commit a51fa644b7
58 changed files with 3326 additions and 123 deletions

13
TODO
View File

@ -25,19 +25,6 @@ Lots!
statements in the case of joined queries (no need to SELECT table.column
AS name).
- 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:

View File

@ -30,6 +30,7 @@ fucking
hairstyle
hairstyles
hasn't
haven't
he'd
html
i'd

View File

@ -43,6 +43,9 @@
<!-- Base URL for all images loaded by the server code. MUST include the trailing slash. -->
<image>http://delenn:8080/venice/images/</image>
<!-- Base URL for all static pages linked to by the engine. MUST include the trailing slash. -->
<static>http://delenn:8080/venice/static/</static>
<!-- The fully-qualified URL to the site logo. The image should be 140x80 pixels. -->
<site-logo>http://delenn:8080/venice/images/powered-by-venice.gif</site-logo>
</paths>

View File

@ -11,7 +11,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
@ -21,9 +21,9 @@
-->
<web-app>
<display-name>Venice Web Community System</display-name>
<display-name>Venice Web Communities System</display-name>
<description>
The Venice Web conferencing system provides an online conferencing
The Venice Web Communities System provides an online conferencing
environment, including discussions, online services, and other
things. Written by Eric J. Bowersox (erbo@silcom.com).
</description>
@ -158,6 +158,30 @@
<servlet-class>com.silverwrist.venice.servlets.Attachment</servlet-class>
</servlet>
<servlet>
<servlet-name>topicoperations</servlet-name>
<description>
General topic operations.
</description>
<servlet-class>com.silverwrist.venice.servlets.TopicOperations</servlet-class>
</servlet>
<servlet>
<servlet-name>postoperations</servlet-name>
<description>
General post operations.
</description>
<servlet-class>com.silverwrist.venice.servlets.PostOperations</servlet-class>
</servlet>
<servlet>
<servlet-name>postshortcut</servlet-name>
<description>
Processes post links and redirects to the appropriate page.
</description>
<servlet-class>com.silverwrist.venice.servlets.PostShortcut</servlet-class>
</servlet>
<!-- the following are test servlets, they should go away -->
<servlet>
@ -226,6 +250,21 @@
<url-pattern>/attachment</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>topicoperations</servlet-name>
<url-pattern>/topicops</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>postoperations</servlet-name>
<url-pattern>/postops</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>postshortcut</servlet-name>
<url-pattern>/go/*</url-pattern>
</servlet-mapping>
<!-- the following are test servlets, they should go away -->
<servlet-mapping>
<servlet-name>testformdata</servlet-name>

View File

@ -30,6 +30,14 @@ USE venice;
# Table Creation
##############################################################################
# The global parameters table. This is used for stuff that a Venice admin would be
# likely to edit "on the fly." Stuff that can only be updated with a shutdown should go
# in the XML config file. This table has ONLY ONE ROW!
CREATE TABLE globals (
posts_per_page INT NOT NULL,
old_posts_at_top INT NOT NULL
);
# The audit records table. Most "major" events add a record to this table.
CREATE TABLE audit (
record BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT,
@ -1282,6 +1290,10 @@ INSERT INTO refsigftr (ftr_code, is_default, is_locked, is_hidden, require_read,
# Database Initialization
##############################################################################
# Initialize the system globals table.
INSERT INTO globals (posts_per_page, old_posts_at_top)
VALUES (20, 2);
# Add the 'Anonymous Honyak' user to the users table.
# (Do 'SELECT * FROM users WHERE is_anon = 1' to retrieve the AC user details.)
# (UID = 1, CONTACTID = 1)

View File

@ -19,6 +19,7 @@ package com.silverwrist.venice.core;
import java.util.Date;
import java.util.List;
import com.silverwrist.venice.htmlcheck.HTMLChecker;
public interface ConferenceContext
{
@ -114,4 +115,6 @@ public interface ConferenceContext
public abstract TopicMessageContext getMessageByPostID(long postid) throws DataException, AccessError;
public abstract HTMLChecker getNewTopicPreviewChecker();
} // end interface ConferenceContext

View File

@ -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
@ -72,4 +72,30 @@ public class IDUtils
} // end isValidConfirmationNumber
public static boolean isValidVeniceIDChar(char c)
{
if ((c>='A') && (c<='Z'))
return true; // upper-case letters are OK
if ((c>='a') && (c<='z'))
return true; // lower-case letters are OK
if ((c>='0') && (c<='9'))
return true; // digits are OK
return (EXTRA_VALID.indexOf(c)>=0);
} // end isValidVeniceIDChar
public static boolean isValidPostLinkChar(char c)
{
if ((c>='A') && (c<='Z'))
return true; // upper-case letters are OK
if ((c>='a') && (c<='z'))
return true; // lower-case letters are OK
if ((c>='0') && (c<='9'))
return true; // digits are OK
if (EXTRA_VALID.indexOf(c)>=0)
return true; // other characters from Venice IDs are OK
return ((c=='.') || (c=='!')); // also dots and bangs
} // end isValidPostLinkChar
} // end class IDUtils

View File

@ -19,6 +19,7 @@ package com.silverwrist.venice.core;
import java.util.Date;
import java.util.List;
import com.silverwrist.venice.htmlcheck.HTMLChecker;
public interface TopicContext
{
@ -71,4 +72,11 @@ public interface TopicContext
public abstract TopicMessageContext postNewMessage(long parent, String pseud, String text)
throws DataException, AccessError;
public abstract HTMLChecker getPreviewChecker();
public abstract boolean canDelete();
public abstract void delete() throws DataException, AccessError;
} // end interface TopicContext

View File

@ -61,8 +61,10 @@ public interface VeniceEngine extends SearchMode
public abstract boolean confAliasExists(String alias);
public abstract HTMLChecker getPreviewChecker();
public abstract HTMLChecker getEscapingChecker();
public abstract int getNumPostsPerPage();
public abstract int getNumOldPostsBeforeNew();
} // end interface VeniceEngine

View File

@ -0,0 +1,112 @@
/*
* 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.core.impl;
import java.sql.*;
import org.apache.log4j.*;
import com.silverwrist.venice.db.*;
class BackgroundTopicPurge implements Runnable
{
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
private static Category logger = Category.getInstance(BackgroundTopicPurge.class.getName());
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private DataPool datapool;
private int topicid;
private int num_posts;
private long max_postid;
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
BackgroundTopicPurge(DataPool datapool, int topicid, int num_posts, long max_postid)
{
this.datapool = datapool;
this.topicid = topicid;
this.num_posts = num_posts;
this.max_postid = max_postid;
} // end constructor
/*--------------------------------------------------------------------------------
* Implementations from interface Runnable
*--------------------------------------------------------------------------------
*/
public void run()
{
if (logger.isDebugEnabled())
logger.debug("BackgroundTopicPurge running on topic #" + String.valueOf(topicid));
long[] postids = new long[num_posts]; // stores the post IDs
Connection conn = null; // pooled database connection
try
{ // get a database connection from the pool
conn = datapool.getConnection();
Statement stmt = conn.createStatement();
// look up all the post IDs that are present for this topic
StringBuffer sql = new StringBuffer("SELECT postid FROM posts WHERE topicid = ");
sql.append(topicid).append(" AND postid <= ").append(max_postid).append(" ORDER BY postid;");
ResultSet rs = stmt.executeQuery(sql.toString());
int posts = 0;
while (rs.next())
postids[posts++] = rs.getLong(1);
for (int i=0; i<posts; i++)
{ // remove all references to the posts in question
stmt.executeUpdate("DELETE FROM posts WHERE postid = " + String.valueOf(postids[i]) + ";");
stmt.executeUpdate("DELETE FROM postdata WHERE postid = " + String.valueOf(postids[i]) + ";");
stmt.executeUpdate("DELETE FROM postattach WHERE postid = " + String.valueOf(postids[i]) + ";");
stmt.executeUpdate("DELETE FROM postdogear WHERE postid = " + String.valueOf(postids[i]) + ";");
} // end for
// all done, Bunky!
if (logger.isDebugEnabled())
logger.debug("BackgroundTopicPurge complete for topic #" + String.valueOf(topicid));
} // end try
catch (SQLException e)
{ // on an error, just die
logger.error("BackgroundTopicPurge FATAL EXCEPTION purging #" + String.valueOf(topicid) + ": "
+ e.getMessage(),e);
} // end catch
finally
{ // make sure we release the connection before we go
if (conn!=null)
datapool.releaseConnection(conn);
} // end finally
} // end run
} // end class BackgroundTopicPurge

View File

@ -20,6 +20,7 @@ package com.silverwrist.venice.core.impl;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Date;
import com.silverwrist.venice.db.PostLinkDecoderContext;
import com.silverwrist.venice.core.DataException;
public interface ConferenceBackend extends SIGBackend
@ -44,4 +45,6 @@ public interface ConferenceBackend extends SIGBackend
public abstract void touchUpdate(Connection conn, java.util.Date date) throws DataException;
public abstract PostLinkDecoderContext createDecoderContext(short topicid);
} // end interface ConferenceBackend

View File

@ -56,6 +56,7 @@ class ConferenceCoreData implements ConferenceData
private String name; // the name of the conference
private String description; // the conference's description
private String cached_alias = null; // the cached alias (for getAnAlias)
private boolean creating_topic = false; // is somebody creating a topic?
/*--------------------------------------------------------------------------------
* Constructors
@ -817,8 +818,8 @@ class ConferenceCoreData implements ConferenceData
} // end getAnAlias
public ReturnTopicInfo createNewTopic(SIGBackend sig, String title, String pseud, String body,
int body_lines) throws DataException
public synchronized ReturnTopicInfo createNewTopic(SIGBackend sig, String title, String pseud,
String body, int body_lines) throws DataException
{
Connection conn = null; // database connection
AuditRecord ar = null; // audit record
@ -963,6 +964,40 @@ class ConferenceCoreData implements ConferenceData
} // end touchUpdate
public synchronized short enterCreateTopic()
{
while (creating_topic)
{ // we're ready to create a topic
try
{ // wait for another thread to relinquish the topic create mechanism
wait();
} // end try
catch (InterruptedException e)
{ // do nothing
} // end catch
} // end while
creating_topic = true;
// new topic number, needed to properly parse post links in new topic's zero post
return (short)(top_topic + 1);
} // end enterCreateTopic
public synchronized void exitCreateTopic()
{
creating_topic = false;
notify(); // wake somebody up if they were going to create a topic
} // end exitCreateTopic
public short getTopTopic()
{
return top_topic;
} // end getTopTopic
/*--------------------------------------------------------------------------------
* External static operations (usable only from within package)
*--------------------------------------------------------------------------------

View File

@ -86,4 +86,10 @@ public interface ConferenceData extends ReferencedData
public abstract void touchUpdate(Connection conn, Date date) throws DataException;
public abstract short enterCreateTopic();
public abstract void exitCreateTopic();
public abstract short getTopTopic();
} // end interface ConferenceData

View File

@ -89,8 +89,8 @@ public interface ConferenceSIGContext extends ReferencedData
public abstract String getAnAlias() throws DataException;
public abstract ReturnTopicInfo createNewTopic(SIGBackend sig, String title, String pseud, String body,
int body_lines) throws DataException;
public abstract ReturnTopicInfo createNewTopic(SIGBackend sig, String title, String pseud, String body)
throws DataException;
public abstract boolean canScribblePosts(int level);
@ -98,4 +98,6 @@ public interface ConferenceSIGContext extends ReferencedData
public abstract void touchUpdate(Connection conn, Date date) throws DataException;
public abstract short getTopTopic();
} // end interface ConferenceSIGContext

View File

@ -21,6 +21,7 @@ import java.sql.*;
import java.util.*;
import org.apache.log4j.*;
import com.silverwrist.venice.db.*;
import com.silverwrist.venice.htmlcheck.*;
import com.silverwrist.venice.security.AuditRecord;
import com.silverwrist.venice.core.*;
@ -611,10 +612,48 @@ class ConferenceSIGContextImpl implements ConferenceSIGContext
} // end getAnAlias
public ReturnTopicInfo createNewTopic(SIGBackend sig, String title, String pseud, String body,
int body_lines) throws DataException
public ReturnTopicInfo createNewTopic(SIGBackend sig, String title, String pseud, String body)
throws DataException
{
return getConferenceData().createNewTopic(sig,title,pseud,body,body_lines);
ConferenceData d = getConferenceData();
String conf_alias = d.getAnAlias();
short new_topic = d.enterCreateTopic();
try
{ // preprocess the body argument through the HTML checker
HTMLChecker text_ch = engine.createCheckerObject(engine.HTMLC_POST_BODY);
text_ch.setContextValue("PostLinkDecoderContext",
new PostLinkDecoderContext(sig.realSIGAlias(),conf_alias,new_topic));
try
{ // run through the HTML checker
text_ch.append(body);
text_ch.finish();
} // end try
catch (AlreadyFinishedException e)
{ // this isn't right...
throw new InternalStateError("HTMLChecker erroneously throwing AlreadyFinishedException",e);
} // end catch
try
{ // call down to create the new topic!
return d.createNewTopic(sig,title,pseud,text_ch.getValue(),text_ch.getLines());
} // end try
catch (NotYetFinishedException e)
{ // this isn't right either!
throw new InternalStateError("HTMLChecker erroneously throwing NotYetFinishedException",e);
} // end catch
} // end try
finally
{ // make sure we relinquish the topic creation no matter what happens
d.exitCreateTopic();
} // end finally
} // end createNewTopic
@ -648,4 +687,14 @@ class ConferenceSIGContextImpl implements ConferenceSIGContext
} // end touchUpdate
public short getTopTopic()
{
ConferenceData c = getConferenceDataNE();
if (c==null)
return -1;
else
return c.getTopTopic();
} // end getTopTopic
} // end class ConferenceSIGContextImpl

View File

@ -821,19 +821,16 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
} // end if
// preprocess the three arguments through HTML checkers
// preprocess the pseud and title arguments through HTML checkers
HTMLChecker title_ch = engine.createCheckerObject(engine.HTMLC_POST_PSEUD);
HTMLChecker zp_pseud_ch = engine.createCheckerObject(engine.HTMLC_POST_PSEUD);
HTMLChecker zp_text_ch = engine.createCheckerObject(engine.HTMLC_POST_BODY);
try
{ // run all three arguments through the HTML checker
{ // run arguments through the HTML checker
title_ch.append(title);
title_ch.finish();
zp_pseud_ch.append(zp_pseud);
zp_pseud_ch.finish();
zp_text_ch.append(zp_text);
zp_text_ch.finish();
} // end try
catch (AlreadyFinishedException e)
@ -848,8 +845,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
try
{ // call down to create the new topic!
real_title = title_ch.getValue();
new_topic_inf = getConferenceData().createNewTopic(sig,real_title,zp_pseud_ch.getValue(),
zp_text_ch.getValue(),zp_text_ch.getLines());
new_topic_inf = getConferenceData().createNewTopic(sig,real_title,zp_pseud_ch.getValue(),zp_text);
} // end try
catch (NotYetFinishedException e)
@ -898,6 +894,20 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
} // end getMessageByPostID
public HTMLChecker getNewTopicPreviewChecker()
{
ConferenceSIGContext c = getConferenceDataNE();
short new_topic;
if (c==null)
new_topic = 0;
else
new_topic = (short)(c.getTopTopic() + 1);
HTMLChecker rc = engine.createCheckerObject(engine.HTMLC_PREVIEW_BODY);
rc.setContextValue("PostLinkDecoderContext",createDecoderContext(new_topic));
return rc;
} // end getNewTopicPreviewChecker
/*--------------------------------------------------------------------------------
* Implementations from interface UserBackend
*--------------------------------------------------------------------------------
@ -1097,6 +1107,12 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
} // end getConferenceData
public PostLinkDecoderContext createDecoderContext(short topicid)
{
return new PostLinkDecoderContext(sig.realSIGAlias(),realConfAlias(),topicid);
} // end createDecoderContext
/*--------------------------------------------------------------------------------
* Static functions usable only from within the package
*--------------------------------------------------------------------------------

View File

@ -30,6 +30,9 @@ public interface EngineBackend
public static final int HTMLC_PREVIEW_BODY = 2;
public static final int HTMLC_ESCAPE_BODY_PSEUD = 3;
public static final int IP_POSTSPERPAGE = 0;
public static final int IP_POSTSATTOP = 1;
public abstract SimpleEmailer createEmailer();
public abstract String getStockMessage(String key);
@ -66,4 +69,8 @@ public interface EngineBackend
public abstract HTMLChecker createCheckerObject(int type);
public abstract int getParamInt(int selector);
public abstract void forceParamReload() throws DataException;
} // end interface EngineBackend

View File

@ -134,9 +134,10 @@ class TopicMessageUserContextImpl implements TopicMessageContext
private void refresh(Connection conn) throws SQLException
{
Statement stmt = conn.createStatement();
StringBuffer sql = new StringBuffer("SELECT 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.postid = ");
StringBuffer sql = new StringBuffer("SELECT posts.hidden, posts.scribble_uid, posts.scribble_date, "
+ "posts.pseud, postattach.datalen, postattach.filename, "
+ "postattach.mimetype FROM posts LEFT JOIN postattach ON "
+ "posts.postid = postattach.postid WHERE posts.postid = ");
sql.append(postid).append(';');
ResultSet rs = stmt.executeQuery(sql.toString());
if (rs.next())

View File

@ -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
@ -617,6 +617,7 @@ class TopicUserContextImpl implements TopicContext
// preprocess the two arguments through HTML checkers
HTMLChecker pseud_ch = engine.createCheckerObject(engine.HTMLC_POST_PSEUD);
HTMLChecker text_ch = engine.createCheckerObject(engine.HTMLC_POST_BODY);
text_ch.setContextValue("PostLinkDecoderContext",conf.createDecoderContext(topicnum));
try
{ // run both arguments through the HTML checker
pseud_ch.append(pseud);
@ -773,6 +774,117 @@ class TopicUserContextImpl implements TopicContext
} // end postMessage
public HTMLChecker getPreviewChecker()
{
HTMLChecker rc = engine.createCheckerObject(engine.HTMLC_PREVIEW_BODY);
rc.setContextValue("PostLinkDecoderContext",conf.createDecoderContext(topicnum));
return rc;
} // end getPreviewChecker
public boolean canDelete()
{
return conf.userCanNuke();
} // end canDelete
public void delete() throws DataException, AccessError
{
if (!(conf.userCanNuke()))
{ // we can't delete the topic!
logger.error("trying to delete w/o permission!");
throw new AccessError("You do not have permission to delete this topic.");
} // end if
if (deleted)
return; // an exercise in futility...
Connection conn = null;
AuditRecord ar = null;
int post_count;
long post_max;
try
{ // get a database connection
conn = datapool.getConnection();
Statement stmt = conn.createStatement();
// lock some tables while we do the critical parts of the delete
stmt.executeUpdate("LOCK TABLES confs WRITE, topics WRITE, topicsettings WRITE, posts READ;");
try
{ // first delete the topic record itself
StringBuffer sql = new StringBuffer("DELETE FROM topics WHERE topicid = ");
sql.append(topicid).append(';');
stmt.executeUpdate(sql.toString());
// now delete all topicsettings records
sql.setLength(0);
sql.append("DELETE FROM topicsettings WHERE topicid = ").append(topicid).append(';');
stmt.executeUpdate(sql.toString());
// and indicate that we updated the conference
conf.touchUpdate(conn,new java.util.Date());
// determine the number of posts in this topic, and the maximum post ID
sql.setLength(0);
sql.append("SELECT COUNT(*), MAX(postid) FROM posts WHERE topicid = ").append(topicid).append(';');
ResultSet rs = stmt.executeQuery(sql.toString());
if (!(rs.next()))
throw new InternalStateError("TopicContext.delete screwup on post SELECT");
post_count = rs.getInt(1);
post_max = rs.getLong(2);
// and record that we're now deleted
makeDeleted();
} // end try
finally
{ // make sure and unlock before we're done
Statement ulk_stmt = conn.createStatement();
ulk_stmt.executeUpdate("UNLOCK TABLES;");
} // end finally
// record what we did in an audit record
ar = new AuditRecord(AuditRecord.DELETE_TOPIC,conf.realUID(),conf.userRemoteAddress(),
conf.realSIGID(),"conf=" + String.valueOf(conf.realConfID()) + ",topic="
+ String.valueOf(topicid));
} // end try
catch (SQLException e)
{ // turn SQLException into data exception
logger.error("DB error deleting topic: " + e.getMessage(),e);
throw new DataException("unable to delete topic: " + 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
// Delete the rest of the gunk in the background; spin off another thread to handle it.
BackgroundTopicPurge purger = new BackgroundTopicPurge(datapool,topicid,post_count,post_max);
Thread thrd = new Thread(purger);
thrd.setPriority(Thread.NORM_PRIORITY-1);
thrd.start();
} // end delete
/*--------------------------------------------------------------------------------
* External operations usable only from within the package
*--------------------------------------------------------------------------------

View File

@ -213,6 +213,7 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
private Hashtable feature_syms = new Hashtable(); // hashtable mapping symbols to features
private Hashtable conf_objects = new Hashtable(); // holder for ConferenceCoreData objects
private HTMLCheckerConfig[] html_configs; // holder for HTML checker configurations
private int[] gp_ints; // global integer parameters
/*--------------------------------------------------------------------------------
* Constructor
@ -239,6 +240,19 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
} // end checkInitialized
private void loadDefaults(Statement stmt) throws SQLException, DataException
{
final String query = "SELECT posts_per_page, old_posts_at_top FROM globals;";
ResultSet rs = stmt.executeQuery(query);
if (!(rs.next()))
throw new DataException("Globals table does not appear to be loaded!");
// stash the globals from the database
gp_ints[IP_POSTSPERPAGE] = rs.getInt(1);
gp_ints[IP_POSTSATTOP] = rs.getInt(2);
} // end loadDefaults
/*--------------------------------------------------------------------------------
* Implementations from interface VeniceEngine
*--------------------------------------------------------------------------------
@ -378,6 +392,9 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
} // end catch
// Allocate the global parameter arrays.
gp_ints = new int[2];
// initialize anything that requires us to pull from the database
Connection conn = null;
try
@ -404,6 +421,9 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
if (logger.isDebugEnabled())
logger.debug(String.valueOf(max_value) + " features loaded from database");
// load the global defaults
loadDefaults(stmt);
} // end try
catch (SQLException e)
{ // convert exceptions to DataException
@ -1207,18 +1227,24 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
} // end confAliasExists
public HTMLChecker getPreviewChecker()
{
return html_configs[HTMLC_PREVIEW_BODY].createHTMLChecker();
} // end getPreviewChecker
public HTMLChecker getEscapingChecker()
{
return html_configs[HTMLC_ESCAPE_BODY_PSEUD].createHTMLChecker();
} // end getEscapingChecker
public int getNumPostsPerPage()
{
return gp_ints[IP_POSTSPERPAGE];
} // end getNumPostsPerPage
public int getNumOldPostsBeforeNew()
{
return gp_ints[IP_POSTSATTOP];
} // end getNumOldPostsBeforeNew
/*--------------------------------------------------------------------------------
* Implementations from interface EngineBackend
*--------------------------------------------------------------------------------
@ -1557,4 +1583,36 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
} // end createCheckerObject
public int getParamInt(int selector)
{
return gp_ints[selector];
} // end getParamInt
public void forceParamReload() throws DataException
{
Connection conn = null; // data pooled connection
try
{ // get a connection and use it to reload
conn = datapool.getConnection();
Statement stmt = conn.createStatement();
loadDefaults(stmt);
} // end try
catch (SQLException e)
{ // just log an error if we screwed up
logger.error("DB error loading parameters: " + e.getMessage(),e);
throw new DataException("Database error reloading parameters: " + e.getMessage(),e);
} // end catch
finally
{ // make sure the connection is released before we go
if (conn!=null)
datapool.releaseConnection(conn);
} // end finally
} // end forceParamReload
} // end class VeniceEngineImpl

View File

@ -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
@ -27,6 +27,13 @@ import com.silverwrist.venice.core.IDUtils;
public class PostLinkRewriter implements Rewriter
{
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
public static final String URI_PREFIX = "x-postlink:";
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
@ -52,7 +59,7 @@ public class PostLinkRewriter implements Rewriter
private static String buildPostLink(PostLinkDecoder pl, PostLinkDecoderContext ctxt)
{
StringBuffer b = new StringBuffer("x-postlink:");
StringBuffer b = new StringBuffer(URI_PREFIX);
boolean started = false;
if (pl.getSIG()==null)
b.append(ctxt.getSIGName());

View File

@ -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
@ -26,6 +26,13 @@ import com.silverwrist.venice.core.IDUtils;
public class UserNameRewriter implements Rewriter
{
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
public static final String URI_PREFIX = "x-userlink:";
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
@ -85,8 +92,9 @@ public class UserNameRewriter implements Rewriter
} // end finally
StringBuffer open_a = new StringBuffer("<A HREF=\"x-userlink:");
open_a.append(data).append("\"");
// build the markup data and return it
StringBuffer open_a = new StringBuffer("<A HREF=\"");
open_a.append(URI_PREFIX).append(data).append("\"");
String catenate = svc.getRewriterAttrValue("ANCHORTAIL");
if (!(StringUtil.isStringEmpty(catenate)))
open_a.append(' ').append(catenate);

View File

@ -224,7 +224,7 @@ public class ConfDisplay extends VeniceServlet
} // end getViewSortDefaults
private static PostInterval getInterval(ServletRequest request, TopicContext topic)
private static PostInterval getInterval(VeniceEngine engine, ServletRequest request, TopicContext topic)
throws ValidationException
{
int first, last;
@ -274,10 +274,10 @@ public class ConfDisplay extends VeniceServlet
{ // no range specified - cook up a default one
last = topic.getTotalMessages();
int ur = topic.getUnreadMessages();
if ((ur==0) || (ur>=20)) // TODO: configurable
first = last - 20;
if ((ur==0) || (ur>=engine.getNumPostsPerPage()))
first = last - engine.getNumPostsPerPage();
else
first = last - (ur+2);
first = last - (ur + engine.getNumOldPostsBeforeNew());
last--;
} // end if
@ -324,6 +324,72 @@ public class ConfDisplay extends VeniceServlet
} // end getInterval
private static void restorePosts(ServletRequest request, ConferenceContext conf)
{
String xtopic = request.getParameter("rtop");
if (StringUtil.isStringEmpty(xtopic))
return;
String xcount = request.getParameter("rct");
if (StringUtil.isStringEmpty(xcount))
return;
TopicContext topic;
try
{ // get the topic corresponding to the first parameter
topic = conf.getTopic(Short.parseShort(xtopic));
} // end try
catch (NumberFormatException nfe)
{ // the topic number was invalid - forget it
logger.warn("restorePosts: error translating topic number");
return;
} // end catch
catch (DataException de)
{ // could not get the topic...
logger.warn("restorePosts: DataException getting topic - " + de.getMessage(),de);
return;
} // end catch
catch (AccessError ae)
{ // no access to the topic
logger.warn("restorePosts: AccessError getting topic - " + ae.getMessage(),ae);
return;
} // end catch
int nunread;
try
{ // translate the number of unread posts to set
nunread = Integer.parseInt(xcount);
if ((nunread<=0) || (nunread>topic.getTotalMessages()))
{ // must be in the range [1, #messages]...
logger.warn("restorePosts: unread post count out of range");
return;
} // end if
} // end try
catch (NumberFormatException nfe)
{ // the number of unread posts was invalid - forget it
logger.warn("restorePosts: error translating unread post count");
return;
} // end catch
try
{ // now try to set the unread messages
topic.setUnreadMessages(nunread);
} // end try
catch (DataException de)
{ // could not get the topic...
logger.warn("restorePosts: DataException setting unread messages - " + de.getMessage(),de);
} // end catch
} // end restorePosts
/*--------------------------------------------------------------------------------
* Overrides from class HttpServlet
*--------------------------------------------------------------------------------
@ -428,14 +494,18 @@ public class ConfDisplay extends VeniceServlet
if (logger.isDebugEnabled())
logger.debug("MODE: display messages in topic");
// if this request is restoring the number of unread posts in another topic, try to do so
restorePosts(request,conf);
try
{ // determine what the post interval is we want to display
PostInterval piv = getInterval(request,topic);
VeniceEngine engine = getVeniceEngine();
PostInterval piv = getInterval(engine,request,topic);
boolean read_new = !(StringUtil.isStringEmpty(request.getParameter("rnm")));
boolean show_adv = !(StringUtil.isStringEmpty(request.getParameter("shac")));
// create the post display
TopicPosts tpos = new TopicPosts(request,sig,conf,topic,piv.getFirst(),piv.getLast(),
TopicPosts tpos = new TopicPosts(request,engine,sig,conf,topic,piv.getFirst(),piv.getLast(),
read_new,show_adv);
content = tpos;
page_title = topic.getName() + ": " + String.valueOf(topic.getTotalMessages()) + " Total; "

View File

@ -414,7 +414,7 @@ public class ConfOperations extends VeniceServlet
try
{ // do a preview generation
ntf.generatePreview(getVeniceEngine(),request);
ntf.generatePreview(getVeniceEngine(),conf,request);
if (ntf.isNullRequest())
{ // no title or text specified - this is a "204 No Content" return

View File

@ -0,0 +1,393 @@
/*
* 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.venice.ValidationException;
import com.silverwrist.venice.core.*;
import com.silverwrist.venice.servlets.format.*;
public class PostOperations extends VeniceServlet
{
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
private static final String NUKE_CONFIRM_ATTR = "servlets.PostOperations.nuke.confirm";
private static final String NUKE_CONFIRM_PARAM = "confirm";
private static Category logger = Category.getInstance(TopicOperations.class.getName());
/*--------------------------------------------------------------------------------
* Internal functions
*--------------------------------------------------------------------------------
*/
private static SIGContext getSIGParameter(ServletRequest request, UserContext user)
throws ValidationException, DataException
{
String str = request.getParameter("sig");
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 ConferenceContext getConferenceParameter(ServletRequest request, SIGContext sig)
throws ValidationException, DataException, AccessError
{
String str = request.getParameter("conf");
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 TopicContext getTopicParameter(ServletRequest request, ConferenceContext conf)
throws ValidationException, DataException, AccessError
{
String str = request.getParameter("top");
if (StringUtil.isStringEmpty(str))
{ // no topic parameter - bail out now!
logger.error("Topic parameter not specified!");
throw new ValidationException("No topic specified.");
} // end if
try
{ // turn the string into a TopicID, and thence to a TopicContext
short topicid = Short.parseShort(str);
return conf.getTopic(topicid);
} // end try
catch (NumberFormatException nfe)
{ // error in Integer.parseInt
logger.error("Cannot convert topic parameter '" + str + "'!");
throw new ValidationException("Invalid topic parameter.");
} // end catch
} // end getTopicParameter
private static TopicMessageContext getMessageParameter(ServletRequest request, TopicContext topic)
throws ValidationException, DataException, AccessError
{
String str = request.getParameter("msg");
if (StringUtil.isStringEmpty(str))
{ // no topic parameter - bail out now!
logger.error("Message parameter not specified!");
throw new ValidationException("No message specified.");
} // end if
try
{ // turn the string into a TopicID, and thence to a TopicContext
int message_num = Integer.parseInt(str);
return topic.getMessage(message_num);
} // 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
/*--------------------------------------------------------------------------------
* Overrides from class HttpServlet
*--------------------------------------------------------------------------------
*/
public String getServletInfo()
{
String rc = "PostOperations servlet - General post operations (hide, scribble, etc.)\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 location = "top";
String locator = null;
String page_title = null;
Object content = null;
SIGContext sig = null; // SIG context
ConferenceContext conf = null; // conference context
TopicContext topic = null; // topic 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()));
locator = "sig=" + String.valueOf(sig.getSIGID());
location = "sigprofile?" + locator;
} // 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(),location);
} // 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()));
locator += "&conf=" + String.valueOf(conf.getConfID());
location = "confdisp?" + locator;
} // 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(),location);
} // end catch
} // end if
if (content==null)
{ // we got the conference parameter OK
try
{ // now we need a topic parameter
topic = getTopicParameter(request,conf);
if (logger.isDebugEnabled())
logger.debug("found topic #" + String.valueOf(topic.getTopicID()));
locator += "&top=" + String.valueOf(topic.getTopicID());
location = "confdisp?" + locator;
} // end try
catch (DataException de)
{ // error looking up the conference
page_title = "Database Error";
content = new ErrorBox(page_title,"Database error finding topic: " + de.getMessage(),location);
} // end catch
} // end if
if (content==null)
{ // we got the topic parameter OK
try
{ // now we need a message parameter
msg = getMessageParameter(request,topic);
if (logger.isDebugEnabled())
logger.debug("found message #" + String.valueOf(msg.getPostID()));
location = "confdisp?" + locator + "&p1=" + msg.getPostNumber() + "&shac=1";
} // 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(),location);
} // 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(),location);
} // 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(),location);
} // end catch
if (content==null)
{ // figure out what command we want to perform
String cmd = request.getParameter("cmd");
if (cmd==null)
cmd = "???";
if (cmd.equals("HY") || cmd.equals("HN"))
{ // we want to hide or show the message
try
{ // attempt to hide or show the message
msg.setHidden(cmd.equals("HY"));
// go back and display stuff
rdat.redirectTo(location);
return;
} // end try
catch (DataException de)
{ // there was a database error
page_title = "Database Error";
content = new ErrorBox(page_title,"Database error setting hidden status: " + de.getMessage(),
location);
} // end catch
catch (AccessError ae)
{ // naughty naughty = you can't do this!
page_title = "Access Error";
content = new ErrorBox(page_title,ae.getMessage(),location);
} // end catch
} // end if ("hide" or "show")
else if (cmd.equals("SCR"))
{ // we want to scribble the message
try
{ // attempt to scribble the message
msg.scribble();
// go back and display stuff
rdat.redirectTo(location);
return;
} // end try
catch (DataException de)
{ // there was a database error
page_title = "Database Error";
content = new ErrorBox(page_title,"Database error scribbling message: " + de.getMessage(),
location);
} // end catch
catch (AccessError ae)
{ // naughty naughty = you can't do this!
page_title = "Access Error";
content = new ErrorBox(page_title,ae.getMessage(),location);
} // end catch
} // end else if ("scribble")
else if (cmd.equals("NUKE"))
{ // nuking requires confirmation
try
{ // we need confirmation on this operation!
if (ConfirmBox.isConfirmed(request,NUKE_CONFIRM_ATTR,NUKE_CONFIRM_PARAM))
{ // OK, go ahead, nuke the message!
msg.nuke();
// after which, redirect to topic view
rdat.redirectTo("confdisp?" + locator);
return;
} // end if
else
{ // not a proper confirmation - better display one
List aliases = conf.getAliases();
String message = "You are about to nuke message <" + (String)(aliases.get(0)) + "."
+ String.valueOf(topic.getTopicNumber()) + "." + String.valueOf(msg.getPostNumber())
+ ">, originally composed by <" + msg.getCreatorName()
+ ">! Are you sure you want to do this?";
String confirm_url = "postops?" + locator + "&msg=" + msg.getPostNumber() + "&cmd=NUKE";
page_title = "Nuke Message";
content = new ConfirmBox(request,NUKE_CONFIRM_ATTR,NUKE_CONFIRM_PARAM,page_title,
message,confirm_url,location);
} // end else
} // end try
catch (DataException de)
{ // there was a database error
page_title = "Database Error";
content = new ErrorBox(page_title,"Database error nuking message: " + de.getMessage(),
location);
} // end catch
catch (AccessError ae)
{ // naughty naughty = you can't do this!
page_title = "Access Error";
content = new ErrorBox(page_title,ae.getMessage(),location);
} // end catch
} // end else if ("nuke")
else
{ // unrecognized command!
page_title = "Internal Error";
logger.error("invalid command to PostOperations.doGet: " + cmd);
content = new ErrorBox(page_title,"Invalid command to PostOperations.doGet",location);
} // end else
} // end if (got parameters OK)
BaseJSPData basedat = new BaseJSPData(page_title,location,content);
basedat.transfer(getServletContext(),rdat);
} // end doGet
} // end class PostOperations

View File

@ -0,0 +1,161 @@
/*
* 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 javax.servlet.*;
import javax.servlet.http.*;
import com.silverwrist.venice.ValidationException;
import com.silverwrist.venice.core.*;
import com.silverwrist.venice.db.PostLinkDecoder;
import com.silverwrist.venice.servlets.format.*;
public class PostShortcut extends VeniceServlet
{
/*--------------------------------------------------------------------------------
* Overrides from class HttpServlet
*--------------------------------------------------------------------------------
*/
public String getServletInfo()
{
String rc = "PostShortcut servlet - Decodes a post link and redirects to it\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 raw_link = request.getPathInfo().substring(1);
PostLinkDecoder decoder;
try
{ // attempt to decode the path link information
decoder = new PostLinkDecoder(raw_link);
if (decoder.getSIG()==null) // it must include the SIG
throw new ValidationException("ambiguous post link (no SIG)");
} // end try
catch (ValidationException e)
{ // display an error message for validation
String page_title = "Invalid Post Link";
ContentRender content = new ErrorBox(page_title,"Invalid post link \"" + raw_link + "\": "
+ e.getMessage(),null);
new BaseJSPData(page_title,"top",content).transfer(getServletContext(),rdat);
return;
} // end catch
SIGContext sig;
try
{ // get the SIG represented by that alias
sig = user.getSIGContext(decoder.getSIG());
} // end try
catch (DataException e)
{ // can't find the SIG - we're screwed
String page_title = "Invalid Post Link";
ContentRender content = new ErrorBox(page_title,"Invalid post link \"" + raw_link
+ "\": cannot find SIG: " + e.getMessage(),null);
new BaseJSPData(page_title,"top",content).transfer(getServletContext(),rdat);
return;
} // end catch
if (decoder.getConference()==null)
{ // it's a SIG link only - redirect to the SIG's default page
rdat.redirectTo("sig/" + decoder.getSIG());
return;
} // end if
ConferenceContext conf;
try
{ // get the conference represented by that alias
conf = sig.getConferenceContext(decoder.getConference());
} // end try
catch (DataException e)
{ // can't find the conference - we're screwed
String page_title = "Invalid Post Link";
ContentRender content = new ErrorBox(page_title,"Invalid post link \"" + raw_link
+ "\": cannot find conference: " + e.getMessage(),null);
new BaseJSPData(page_title,"top",content).transfer(getServletContext(),rdat);
return;
} // end catch
catch (AccessError ae)
{ // we can't get to the conference...
String page_title = "Access Error";
ContentRender content = new ErrorBox(page_title,ae.getMessage(),null);
new BaseJSPData(page_title,"top",content).transfer(getServletContext(),rdat);
return;
} // end catch
// compute an elementary "locator"
String locator = "sig=" + String.valueOf(sig.getSIGID()) + "&conf=" + String.valueOf(conf.getConfID());
if (decoder.getTopic()==-1)
{ // just a conference link - go to the top-level display
rdat.redirectTo("confdisp?" + locator);
return;
} // end if
TopicContext topic;
try
{ // get the topic number specified within that topic
topic = conf.getTopic(decoder.getTopic());
} // end try
catch (DataException e)
{ // we can't find the topic - we're screwed
String page_title = "Invalid Post Link";
ContentRender content = new ErrorBox(page_title,"Invalid post link \"" + raw_link
+ "\": cannot find topic: " + e.getMessage(),null);
new BaseJSPData(page_title,"top",content).transfer(getServletContext(),rdat);
return;
} // end catch
catch (AccessError ae)
{ // we can't get to the topic...
String page_title = "Access Error";
ContentRender content = new ErrorBox(page_title,ae.getMessage(),null);
new BaseJSPData(page_title,"top",content).transfer(getServletContext(),rdat);
return;
} // end catch
// add the topic to our locator
locator += "&top=" + String.valueOf(decoder.getTopic());
if (decoder.getFirstPost()==-1) // we're just referencing the topic
rdat.redirectTo("confdisp?" + locator + "&rnm=1");
else // we're referencing a post range within the topic
rdat.redirectTo("confdisp?" + locator + "&p1=" + String.valueOf(decoder.getFirstPost()) + "&p2="
+ String.valueOf(decoder.getLastPost()));
} // end doGet
} // end class PostShortcut

View File

@ -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
@ -25,10 +25,15 @@ import com.silverwrist.venice.servlets.format.*;
public class SIGFrontEnd extends VeniceServlet
{
/*--------------------------------------------------------------------------------
* Overrides from class HttpServlet
*--------------------------------------------------------------------------------
*/
public String getServletInfo()
{
String rc = "SIGFrontEnd servlet - Redirects to the \"default feature\" of a SIG\n"
+ "Part of the Venice Web conferencing system\n";
+ "Part of the Venice Web Communities System\n";
return rc;
} // end getServletInfo

View File

@ -0,0 +1,357 @@
/*
* 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 javax.servlet.*;
import javax.servlet.http.*;
import org.apache.log4j.*;
import com.silverwrist.util.StringUtil;
import com.silverwrist.venice.ValidationException;
import com.silverwrist.venice.core.*;
import com.silverwrist.venice.servlets.format.*;
public class TopicOperations extends VeniceServlet
{
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
private static final String DELETE_CONFIRM_ATTR = "servlets.TopicOperations.delete.confirm";
private static final String DELETE_CONFIRM_PARAM = "confirm";
private static Category logger = Category.getInstance(TopicOperations.class.getName());
/*--------------------------------------------------------------------------------
* Internal functions
*--------------------------------------------------------------------------------
*/
private static SIGContext getSIGParameter(ServletRequest request, UserContext user)
throws ValidationException, DataException
{
String str = request.getParameter("sig");
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 ConferenceContext getConferenceParameter(ServletRequest request, SIGContext sig)
throws ValidationException, DataException, AccessError
{
String str = request.getParameter("conf");
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 TopicContext getTopicParameter(ServletRequest request, ConferenceContext conf)
throws ValidationException, DataException, AccessError
{
String str = request.getParameter("top");
if (StringUtil.isStringEmpty(str))
{ // no topic parameter - bail out now!
logger.error("Topic parameter not specified!");
throw new ValidationException("No topic specified.");
} // end if
try
{ // turn the string into a TopicID, and thence to a TopicContext
short topicid = Short.parseShort(str);
return conf.getTopic(topicid);
} // end try
catch (NumberFormatException nfe)
{ // error in Integer.parseInt
logger.error("Cannot convert topic parameter '" + str + "'!");
throw new ValidationException("Invalid topic parameter.");
} // end catch
} // end getTopicParameter
/*--------------------------------------------------------------------------------
* Overrides from class HttpServlet
*--------------------------------------------------------------------------------
*/
public String getServletInfo()
{
String rc = "TopicOperations servlet - General topic operations (freeze, archive, etc.)\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 location = "top";
String locator = null;
String page_title = null;
Object content = null;
SIGContext sig = null; // SIG context
ConferenceContext conf = null; // conference context
TopicContext topic = null; // topic 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()));
locator = "sig=" + String.valueOf(sig.getSIGID());
location = "sigprofile?" + locator;
} // 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(),location);
} // 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()));
locator += "&conf=" + String.valueOf(conf.getConfID());
location = "confdisp?" + locator;
} // 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(),location);
} // end catch
} // end if
if (content==null)
{ // we got the conference parameter OK
try
{ // now we need a topic parameter
topic = getTopicParameter(request,conf);
if (logger.isDebugEnabled())
logger.debug("found topic #" + String.valueOf(topic.getTopicID()));
locator += "&top=" + String.valueOf(topic.getTopicNumber());
location = "confdisp?" + locator;
} // end try
catch (DataException de)
{ // error looking up the conference
page_title = "Database Error";
content = new ErrorBox(page_title,"Database error finding topic: " + de.getMessage(),location);
} // 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(),location);
} // 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(),location);
} // end catch
if (content==null)
{ // figure out what command we want to perform...
String cmd = request.getParameter("cmd");
if (cmd==null)
cmd = "???";
if (cmd.equals("HY") || cmd.equals("HN"))
{ // we want to set the hide status of the topic
try
{ // call down to set the topic!
topic.setHidden(cmd.equals("HY"));
// go back to the topic view
rdat.redirectTo(location);
return;
} // end try
catch (DataException de)
{ // there was a database error
page_title = "Database Error";
content = new ErrorBox(page_title,"Database error setting hide status: " + de.getMessage(),location);
} // end catch
} // end if ("hide" or "show")
else if (cmd.equals("FY") || cmd.equals("FN"))
{ // we want to set the frozen status of the topic
try
{ // call down to set the topic!
topic.setFrozen(cmd.equals("FY"));
// go back to the topic view
rdat.redirectTo(location);
return;
} // end try
catch (DataException de)
{ // there was a database error
page_title = "Database Error";
content = new ErrorBox(page_title,"Database error setting freeze status: " + de.getMessage(),
location);
} // end catch
catch (AccessError ae)
{ // naughty naughty = you can't do this!
page_title = "Access Error";
content = new ErrorBox(page_title,ae.getMessage(),location);
} // end catch
} // end else if ("freeze" or "unfreeze")
else if (cmd.equals("AY") || cmd.equals("AN"))
{ // we want to change the archived status of the topic
try
{ // call down to set the topic!
topic.setArchived(cmd.equals("AY"));
// go back to the topic view
rdat.redirectTo(location);
return;
} // end try
catch (DataException de)
{ // there was a database error
page_title = "Database Error";
content = new ErrorBox(page_title,"Database error setting archive status: " + de.getMessage(),
location);
} // end catch
catch (AccessError ae)
{ // naughty naughty = you can't do this!
page_title = "Access Error";
content = new ErrorBox(page_title,ae.getMessage(),location);
} // end catch
} // end else if ("archive" or "unarchive")
else if (cmd.equals("DEL"))
{ // we need confirmation on this operation!
if (ConfirmBox.isConfirmed(request,DELETE_CONFIRM_ATTR,DELETE_CONFIRM_PARAM))
{ // OK, go ahead, delete the topic!
location = "confdisp?sig=" + String.valueOf(sig.getSIGID()) + "&conf="
+ String.valueOf(conf.getConfID());
try
{ // delete the bloody topic!
topic.delete();
// after which, redirect to conference view
rdat.redirectTo(location);
return;
} // end try
catch (DataException de)
{ // there was a database error
page_title = "Database Error";
content = new ErrorBox(page_title,"Database error deleting topic: " + de.getMessage(),location);
} // end catch
catch (AccessError ae)
{ // naughty naughty = you can't do this!
page_title = "Access Error";
content = new ErrorBox(page_title,ae.getMessage(),location);
} // end catch
} // end if
else
{ // not a proper confirmation - better display one
String message = "You are about to delete topic " + String.valueOf(topic.getTopicNumber())
+ " from the \"" + conf.getName() + "\" conference! Are you sure you want to do this?";
String confirm_url = "topicops?" + locator + "&cmd=DEL";
page_title = "Delete Topic";
content = new ConfirmBox(request,DELETE_CONFIRM_ATTR,DELETE_CONFIRM_PARAM,page_title,
message,confirm_url,location);
} // end else
} // end else if ("delete")
else
{ // unrecognized command
page_title = "Internal Error";
logger.error("invalid command to TopicOperations.doGet: " + cmd);
content = new ErrorBox(page_title,"Invalid command to TopicOperations.doGet",location);
} // end else
} // end if
BaseJSPData basedat = new BaseJSPData(page_title,location,content);
basedat.transfer(getServletContext(),rdat);
} // end doGet
} // end class TopicOperations

View File

@ -101,7 +101,8 @@ public class NewTopicForm implements JSPRender
} // end setupNewRequest
public void generatePreview(VeniceEngine engine, ServletRequest request) throws ValidationException
public void generatePreview(VeniceEngine engine, ConferenceContext conf, ServletRequest request)
throws ValidationException
{
HTMLChecker check;
@ -136,7 +137,7 @@ public class NewTopicForm implements JSPRender
post_box = check.getValue();
// generate the body text preview
check = engine.getPreviewChecker();
check = conf.getNewTopicPreviewChecker();
check.append(foo);
check.finish();
preview = check.getValue();

View File

@ -79,7 +79,7 @@ public class PostPreview implements JSPRender
this.data = check.getValue();
// now generate the preview
check = engine.getPreviewChecker();
check = topic.getPreviewChecker();
check.append(data);
check.finish();
this.preview = check.getValue();

View File

@ -47,6 +47,7 @@ public class PostSlippage implements JSPRender
private String pseud;
private String text;
private boolean attach;
private String topic_stem;
/*--------------------------------------------------------------------------------
* Constructor
@ -63,6 +64,8 @@ public class PostSlippage implements JSPRender
this.messages = topic.getMessages(lastval,topic.getTotalMessages()-1);
this.next = next;
this.attach = attach;
List aliases = conf.getAliases();
topic_stem = (String)(aliases.get(0)) + "." + String.valueOf(topic.getTopicNumber()) + ".";
try
{ // run the text and pseud through an HTML checker to escape them
@ -213,4 +216,10 @@ public class PostSlippage implements JSPRender
} // end getBodyText
public String getMessageReference(TopicMessageContext msg)
{
return topic_stem + String.valueOf(msg.getPostNumber());
} // end getMessageReference
} // end class PostSlippage

View File

@ -54,6 +54,7 @@ public class RenderConfig
private String font_face;
private String base_url;
private String image_url;
private String static_url;
private String site_logo;
/*--------------------------------------------------------------------------------
@ -148,6 +149,17 @@ public class RenderConfig
if (logger.isDebugEnabled())
logger.debug("Image path: " + image_url);
static_url = paths_sect_h.getSubElementText("static");
if (static_url==null)
{ // no <static/> tag - bail out now!
logger.fatal("<paths/> section has no <static/> element");
throw new ConfigException("no <static/> found in <paths/> section",paths_sect);
} // end if
if (logger.isDebugEnabled())
logger.debug("Static files path: " + static_url);
site_logo = paths_sect_h.getSubElementText("site-logo");
if (site_logo==null)
{ // no <image/> tag - bail out now!
@ -256,6 +268,14 @@ public class RenderConfig
} // end getFullImagePath
String getStaticFilePath(String name)
{
StringBuffer buf = new StringBuffer();
buf.append(static_url).append(name);
return buf.toString();
} // end getStaticFilePath
String getTitleTag(String specific)
{
StringBuffer buf = new StringBuffer();

View File

@ -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
@ -24,6 +24,9 @@ import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.log4j.*;
import com.silverwrist.util.StringUtil;
import com.silverwrist.venice.core.IDUtils;
import com.silverwrist.venice.db.PostLinkRewriter;
import com.silverwrist.venice.db.UserNameRewriter;
public class RenderData
{
@ -128,6 +131,12 @@ public class RenderData
} // end getFullImagePath
public String getStaticFilePath(String name)
{
return rconf.getStaticFilePath(name);
} // end getStaticFilePath
public String getFormatJSPPath(String name)
{
return "/format/" + name;
@ -320,4 +329,87 @@ public class RenderData
} // end sendBinaryData
public String rewritePostData(String data)
{
if ((data.indexOf(PostLinkRewriter.URI_PREFIX)<0) && (data.indexOf(UserNameRewriter.URI_PREFIX)<0))
return data;
StringBuffer buf = new StringBuffer();
String interm;
if (data.indexOf(PostLinkRewriter.URI_PREFIX)>=0)
{ // begin replacing everything with post links
String t = data;
int p = t.indexOf(PostLinkRewriter.URI_PREFIX);
while (p>=0)
{ // break off the start of the string
if (p>0)
buf.append(t.substring(0,p));
t = t.substring(p + PostLinkRewriter.URI_PREFIX.length());
// find the end of the post link...
p = 0;
while (IDUtils.isValidPostLinkChar(t.charAt(p)))
p++;
if (p>0)
{ // append the post link to the "go" servlet path, and encode the lot
buf.append(getEncodedServletPath("go/" + t.substring(0,p)));
t = t.substring(p);
} // end if
else // false alarm
buf.append(PostLinkRewriter.URI_PREFIX);
// and now look again...
p = t.indexOf(PostLinkRewriter.URI_PREFIX);
} // end while
buf.append(t);
interm = buf.toString();
buf.setLength(0);
} // end if
else // no post link strings, this is the intermediate form
interm = data;
if (interm.indexOf(UserNameRewriter.URI_PREFIX)>=0)
{ // begin replacing everything with user links
String t = interm;
int p = t.indexOf(UserNameRewriter.URI_PREFIX);
while (p>=0)
{ // break off the start of the string
if (p>0)
buf.append(t.substring(0,p));
t = t.substring(p + UserNameRewriter.URI_PREFIX.length());
// find the end of the user link...
p = 0;
while (IDUtils.isValidVeniceIDChar(t.charAt(p)))
p++;
if (p>0)
{ // append the post link to the "user" servlet path, and encode the lot
buf.append(getEncodedServletPath("user/" + t.substring(0,p)));
t = t.substring(p);
} // end if
else // false alarm
buf.append(UserNameRewriter.URI_PREFIX);
// and now look again...
p = t.indexOf(UserNameRewriter.URI_PREFIX);
} // end while
buf.append(t);
return buf.toString();
} // end if
else // no more to find - just return this
return interm;
} // end rewritePostData
} // end class RenderData

View File

@ -38,6 +38,7 @@ public class TopicPosts implements JSPRender
*--------------------------------------------------------------------------------
*/
private VeniceEngine engine;
private SIGContext sig;
private ConferenceContext conf;
private TopicContext topic;
@ -47,6 +48,7 @@ public class TopicPosts implements JSPRender
private int unread;
private List messages;
private TopicVisitOrder visit_order;
private String topic_stem;
private String cache_locator = null;
/*--------------------------------------------------------------------------------
@ -54,10 +56,11 @@ public class TopicPosts implements JSPRender
*--------------------------------------------------------------------------------
*/
public TopicPosts(HttpServletRequest request, SIGContext sig, ConferenceContext conf, TopicContext topic,
int first, int last, boolean read_new, boolean show_advanced)
public TopicPosts(HttpServletRequest request, VeniceEngine engine, SIGContext sig, ConferenceContext conf,
TopicContext topic, int first, int last, boolean read_new, boolean show_advanced)
throws DataException, AccessError
{
this.engine = engine;
this.sig = sig;
this.conf = conf;
this.topic = topic;
@ -70,6 +73,8 @@ public class TopicPosts implements JSPRender
this.messages = topic.getMessages(first,last);
this.visit_order = TopicVisitOrder.retrieve(request.getSession(true),conf.getConfID());
visit_order.visit(topic.getTopicNumber());
List aliases = conf.getAliases();
topic_stem = (String)(aliases.get(0)) + "." + String.valueOf(topic.getTopicNumber()) + ".";
} // end constructor
@ -192,6 +197,14 @@ public class TopicPosts implements JSPRender
} // end getNextLocator
public String getRestoreLocator()
{
StringBuffer buf = new StringBuffer("rtop=");
buf.append(topic.getTopicNumber()).append("&rct=").append(unread);
return buf.toString();
} // end getRestoreLocator
public String getIdentifyingData()
{
StringBuffer buf = new StringBuffer("Posts ");
@ -262,7 +275,7 @@ public class TopicPosts implements JSPRender
public boolean canDeleteTopic()
{
return false; // TODO: fix me
return topic.canDelete();
} // end canDeleteTopic
@ -274,7 +287,7 @@ public class TopicPosts implements JSPRender
public String getScrollUpLocator()
{
int new_first = first - 20; // TODO: configurable
int new_first = first - engine.getNumPostsPerPage();
int new_last = last - 1;
if (new_first<0)
{ // normalize so we start at 0
@ -291,14 +304,14 @@ public class TopicPosts implements JSPRender
public boolean canScrollDown()
{
return ((topic.getTotalMessages() - (1 + last))>=20); // TODO: configurable
return ((topic.getTotalMessages() - (1 + last))>=engine.getNumPostsPerPage());
} // end canScrollDown
public String getScrollDownLocator()
{
StringBuffer buf = new StringBuffer("p1=");
buf.append(last+1).append("&p2=").append(last+20); // TODO: configurable
buf.append(last+1).append("&p2=").append(last+engine.getNumPostsPerPage());
return buf.toString();
} // end getScrollDownLocator
@ -313,7 +326,7 @@ public class TopicPosts implements JSPRender
{
int my_last = topic.getTotalMessages();
StringBuffer buf = new StringBuffer("p1=");
buf.append(my_last-20).append("&p2=").append(my_last-1); // TODO: configurable
buf.append(my_last-engine.getNumPostsPerPage()).append("&p2=").append(my_last-1);
return buf.toString();
} // end getScrollToEndLocator
@ -351,4 +364,16 @@ public class TopicPosts implements JSPRender
} // end getDefaultPseud
public String getMessageReference(TopicMessageContext msg)
{
return topic_stem + String.valueOf(msg.getPostNumber());
} // end getMessageReference
public int getNumPostsPerPage()
{
return engine.getNumPostsPerPage();
} // end getNumPostsPerPage
} // end class TopicPosts

View File

@ -38,7 +38,7 @@
There were <%= data.getNumSpellingErrors() %> spelling errors in your post.
<% } // end if %>
</B></FONT>
<P><PRE><%= data.getPreviewData() %></PRE><HR>
<P><PRE><%= rdat.rewritePostData(data.getPreviewData()) %></PRE><HR>
<% } // end if %>
<FORM METHOD="POST" ACTION="<%= rdat.getEncodedServletPath("confops") %>">
@ -59,7 +59,7 @@
<TR>
<TD ALIGN=LEFT><%= rdat.getStdFontTag(null,2) %>Message:</FONT></TD>
<TD ALIGN=RIGHT><%= rdat.getStdFontTag(null,2) %>
<A HREF="TODO" TARGET="_blank">HTML Guide</A>
<A HREF="<%= rdat.getStaticFilePath("html-reference.html") %>" TARGET="_blank">HTML Guide</A>
</FONT></TD>
</TR>
<TR><TD ALIGN=LEFT COLSPAN=2>

View File

@ -47,11 +47,11 @@
BORDER=0></A>
&nbsp;&nbsp;
<% if (data.isTopicHidden()) { %>
<A HREF="<%= rdat.getEncodedServletPath("TODO?" + data.getLocator()) %>"><IMG
<A HREF="<%= rdat.getEncodedServletPath("topicops?" + data.getLocator() + "&cmd=HN") %>"><IMG
SRC="<%= rdat.getFullImagePath("bn_show_topic.gif") %>" ALT="Show Topic" WIDTH=80 HEIGHT=24
BORDER=0></A>
<% } else { %>
<A HREF="<%= rdat.getEncodedServletPath("TODO?" + data.getLocator()) %>"><IMG
<A HREF="<%= rdat.getEncodedServletPath("topicops?" + data.getLocator() + "&cmd=HY") %>"><IMG
SRC="<%= rdat.getFullImagePath("bn_hide_topic.gif") %>" ALT="Hide Topic" WIDTH=80 HEIGHT=24
BORDER=0></A>
<% } // end if %>
@ -62,8 +62,8 @@
BORDER=0></A>
&nbsp;&nbsp;
<% if (data.getNewMessages()>0) { %>
<%-- TODO: this doesn't do Keep New yet --%>
<A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getNextLocator() + "&rnm=1") %>"><IMG
<A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getNextLocator() + "&"
+ data.getRestoreLocator() + "&rnm=1") %>"><IMG
SRC="<%= rdat.getFullImagePath("bn_next_keep_new.gif") %>" ALT="Next & Keep New" WIDTH=80 HEIGHT=24
BORDER=0></A>
&nbsp;&nbsp;
@ -75,11 +75,11 @@
<% if (data.canFreezeTopic()) { %>
&nbsp;&nbsp;
<% if (data.isTopicFrozen()) { %>
<A HREF="<%= rdat.getEncodedServletPath("TODO?" + data.getLocator()) %>"><IMG
<A HREF="<%= rdat.getEncodedServletPath("topicops?" + data.getLocator() + "&cmd=FN") %>"><IMG
SRC="<%= rdat.getFullImagePath("bn_unfreeze_topic.gif") %>" ALT="Unfreeze Topic" WIDTH=80 HEIGHT=24
BORDER=0></A>
<% } else { %>
<A HREF="<%= rdat.getEncodedServletPath("TODO?" + data.getLocator()) %>"><IMG
<A HREF="<%= rdat.getEncodedServletPath("topicops?" + data.getLocator() + "&cmd=FY") %>"><IMG
SRC="<%= rdat.getFullImagePath("bn_freeze_topic.gif") %>" ALT="Freeze Topic" WIDTH=80 HEIGHT=24
BORDER=0></A>
<% } // end if %>
@ -87,18 +87,18 @@
<% if (data.canArchiveTopic()) { %>
&nbsp;&nbsp;
<% if (data.isTopicArchived()) { %>
<A HREF="<%= rdat.getEncodedServletPath("TODO?" + data.getLocator()) %>"><IMG
<A HREF="<%= rdat.getEncodedServletPath("topicops?" + data.getLocator() + "&cmd=AN") %>"><IMG
SRC="<%= rdat.getFullImagePath("bn_unarchive_topic.gif") %>" ALT="Unarchive Topic" WIDTH=80
HEIGHT=24 BORDER=0></A>
<% } else { %>
<A HREF="<%= rdat.getEncodedServletPath("TODO?" + data.getLocator()) %>"><IMG
<A HREF="<%= rdat.getEncodedServletPath("topicops?" + data.getLocator() + "&cmd=AY") %>"><IMG
SRC="<%= rdat.getFullImagePath("bn_archive_topic.gif") %>" ALT="Archive Topic" WIDTH=80 HEIGHT=24
BORDER=0></A>
<% } // end if %>
<% } // end if %>
<% if (data.canDeleteTopic()) { %>
&nbsp;&nbsp;
<A HREF="<%= rdat.getEncodedServletPath("TODO?" + data.getLocator()) %>"><IMG
<A HREF="<%= rdat.getEncodedServletPath("topicops?" + data.getLocator() + "&cmd=DEL") %>"><IMG
SRC="<%= rdat.getFullImagePath("bn_delete_topic.gif") %>" ALT="Delete Topic" WIDTH=80 HEIGHT=24
BORDER=0></A>
<% } // end if %>
@ -119,18 +119,17 @@
</TD>
<TD NOWRAP ALIGN=RIGHT><%= rdat.getStdFontTag(null,2) %>
<% if (rdat.useHTMLComments()) { %><!-- Upper navigation linkset --><% } %>
<%-- TODO: the number "20" should be configurable --%>
<A NAME="top">[</A>&nbsp;
<A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getLocator() + "&p1=0&p2=-1") %>">View All</A>
<% if (data.canScrollUp()) { %>
&nbsp;|&nbsp;
<A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getLocator() + "&"
+ data.getScrollUpLocator()) %>">Scroll Up 20</A>
+ data.getScrollUpLocator()) %>">Scroll Up <%= data.getNumPostsPerPage() %></A>
<% } // end if %>
<% if (data.canScrollDown()) { %>
&nbsp;|&nbsp;
<A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getLocator() + "&"
+ data.getScrollDownLocator()) %>">Scroll Down 20</A>
+ data.getScrollDownLocator()) %>">Scroll Down <%= data.getNumPostsPerPage() %></A>
<% } // end if %>
<% if (data.canScrollDown()) { %>
&nbsp;|&nbsp;
@ -165,7 +164,11 @@
<A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getLocator() + "&shac=1&p1="
+ String.valueOf(msg.getPostNumber())) %>"><%= msg.getPostNumber() %></A> of
<A HREF="<%= last_post %>"><%= data.getTotalMessages() - 1 %></A>
<%= rdat.getStdFontTag(null,1) %>&lt;<%= "TODO" %>&gt;</FONT><BR>
<%= rdat.getStdFontTag(null,1) %>&lt;<%= data.getMessageReference(msg) %>&gt;</FONT>
<% if (data.showAdvanced() && msg.isHidden()) { %>
<B><EM>(Hidden)</EM></B>
<% } // end if %>
<BR>
<B><%= msg.getPseud() %></B>
(<EM>
<A HREF="<%= rdat.getEncodedServletPath("user/" + poster) %>" TARGET="_blank"><%= poster %></A>,
@ -183,36 +186,37 @@
<TT><EM><B>
(Scribbled by <%= data.getMessageBodyText(msg) %> on
<%= rdat.formatDateForDisplay(msg.getScribbleDate()) %>)
</B></EM></TT>
</B></EM></TT><P>
<% } else if (msg.isHidden() && !(data.showAdvanced())) { %>
<TT><EM><B>
<A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getLocator() + "&shac=1&p1="
+ String.valueOf(msg.getPostNumber())) %>">(Hidden
Message: <%= msg.getNumLines() %> <% if (msg.getNumLines()==1) { %>Line<% } else { %>Lines<% } %></A>
</B></EM></TT>
Message: <%= msg.getNumLines() %> <% if (msg.getNumLines()==1) { %>Line<% } else { %>Lines<% } %>)</A>
</B></EM></TT><P>
<% } else { %>
<PRE><%= data.getMessageBodyText(msg) %></PRE>
<PRE><%= rdat.rewritePostData(data.getMessageBodyText(msg)) %></PRE>
<% } // end if %>
<% if (data.showAdvanced()) { %>
<% String po_loc = data.getLocator() + "&msg=" + String.valueOf(msg.getPostNumber()); %>
</TD><TD NOWRAP ALIGN=RIGHT>
<% if (!(msg.isScribbled())) { %>
<% if (msg.canHide()) { %>
<% if (msg.isHidden()) { %>
<A HREF="<%= rdat.getEncodedServletPath("TODO?" + data.getLocator()) %>"><IMG
<A HREF="<%= rdat.getEncodedServletPath("postops?" + po_loc + "&cmd=HN") %>"><IMG
SRC="<%= rdat.getFullImagePath("bn_show.gif") %>" ALT="Show" WIDTH=80 HEIGHT=24 BORDER=0></A><P>
<% } else { %>
<A HREF="<%= rdat.getEncodedServletPath("TODO?" + data.getLocator()) %>"><IMG
<A HREF="<%= rdat.getEncodedServletPath("postops?" + po_loc + "&cmd=HY") %>"><IMG
SRC="<%= rdat.getFullImagePath("bn_hide.gif") %>" ALT="Hide" WIDTH=80 HEIGHT=24 BORDER=0></A><P>
<% } // end if %>
<% } // end if (can hide) %>
<% if (msg.canScribble()) { %>
<A HREF="<%= rdat.getEncodedServletPath("TODO?" + data.getLocator()) %>"><IMG
<A HREF="<%= rdat.getEncodedServletPath("postops?" + po_loc + "&cmd=SCR") %>"><IMG
SRC="<%= rdat.getFullImagePath("bn_scribble.gif") %>" ALT="Scribble" WIDTH=80 HEIGHT=24
BORDER=0></A><P>
<% } // end if (can scribble) %>
<% } // end if (not already scribbled) %>
<% if (msg.canNuke()) { %>
<A HREF="<%= rdat.getEncodedServletPath("TODO?" + data.getLocator()) %>"><IMG
<A HREF="<%= rdat.getEncodedServletPath("postops?" + po_loc + "&cmd=NUKE") %>"><IMG
SRC="<%= rdat.getFullImagePath("bn_nuke.gif") %>" ALT="Nuke" WIDTH=80 HEIGHT=24
BORDER=0></A><P>
<% } // end if (can nuke) %>
@ -227,18 +231,17 @@
<TD NOWRAP ALIGN=LEFT>&nbsp;</TD>
<TD NOWRAP ALIGN=RIGHT><%= rdat.getStdFontTag(null,2) %>
<% if (rdat.useHTMLComments()) { %><!-- Upper navigation linkset --><% } %>
<%-- TODO: the number "20" should be configurable --%>
<A NAME="bottom">[</A>&nbsp;
<A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getLocator() + "&p1=0&p2=-1") %>">View All</A>
<% if (data.canScrollUp()) { %>
&nbsp;|&nbsp;
<A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getLocator() + "&"
+ data.getScrollUpLocator()) %>">Scroll Up 20</A>
+ data.getScrollUpLocator()) %>">Scroll Up <%= data.getNumPostsPerPage() %></A>
<% } // end if %>
<% if (data.canScrollDown()) { %>
&nbsp;|&nbsp;
<A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getLocator() + "&"
+ data.getScrollDownLocator()) %>">Scroll Down 20</A>
+ data.getScrollDownLocator()) %>">Scroll Down <%= data.getNumPostsPerPage() %></A>
<% } // end if %>
<% if (data.canScrollDown()) { %>
&nbsp;|&nbsp;
@ -258,11 +261,11 @@
BORDER=0></A>
&nbsp;&nbsp;
<% if (data.isTopicHidden()) { %>
<A HREF="<%= rdat.getEncodedServletPath("TODO?" + data.getLocator()) %>"><IMG
<A HREF="<%= rdat.getEncodedServletPath("topicops?" + data.getLocator() + "&cmd=HN") %>"><IMG
SRC="<%= rdat.getFullImagePath("bn_show_topic.gif") %>" ALT="Show Topic" WIDTH=80 HEIGHT=24
BORDER=0></A>
<% } else { %>
<A HREF="<%= rdat.getEncodedServletPath("TODO?" + data.getLocator()) %>"><IMG
<A HREF="<%= rdat.getEncodedServletPath("topicops?" + data.getLocator() + "&cmd=HY") %>"><IMG
SRC="<%= rdat.getFullImagePath("bn_hide_topic.gif") %>" ALT="Hide Topic" WIDTH=80 HEIGHT=24
BORDER=0></A>
<% } // end if %>
@ -273,8 +276,8 @@
BORDER=0></A>
&nbsp;&nbsp;
<% if (data.getNewMessages()>0) { %>
<%-- TODO: this doesn't do Keep New yet --%>
<A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getNextLocator() + "&rnm=1") %>"><IMG
<A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getNextLocator() + "&"
+ data.getRestoreLocator() + "&rnm=1") %>"><IMG
SRC="<%= rdat.getFullImagePath("bn_next_keep_new.gif") %>" ALT="Next & Keep New" WIDTH=80 HEIGHT=24
BORDER=0></A>
&nbsp;&nbsp;
@ -305,7 +308,7 @@
<TR>
<TD ALIGN=LEFT><%= rdat.getStdFontTag(null,2) %>Message:</FONT></TD>
<TD ALIGN=RIGHT><%= rdat.getStdFontTag(null,2) %>
<A HREF="TODO" TARGET="_blank">HTML Guide</A>
<A HREF="<%= rdat.getStaticFilePath("html-reference.html") %>" TARGET="_blank">HTML Guide</A>
</FONT></TD>
</TR>
<TR><TD ALIGN=LEFT COLSPAN=2>

View File

@ -35,7 +35,7 @@
There were <%= data.getNumSpellingErrors() %> spelling errors in your post.
<% } // end if %>
</B></FONT>
<P><PRE><%= data.getPreviewData() %></PRE><HR>
<P><PRE><%= rdat.rewritePostData(data.getPreviewData()) %></PRE><HR>
<FORM METHOD="POST" ACTION="<%= rdat.getEncodedServletPath("post") %>">
<INPUT TYPE="HIDDEN" NAME="sig" VALUE="<%= data.getSIGID() %>">
@ -55,7 +55,7 @@
<TR>
<TD ALIGN=LEFT><%= rdat.getStdFontTag(null,2) %>Message:</FONT></TD>
<TD ALIGN=RIGHT><%= rdat.getStdFontTag(null,2) %>
<A HREF="TODO" TARGET="_blank">HTML Guide</A>
<A HREF="<%= rdat.getStaticFilePath("html-reference.html") %>" TARGET="_blank">HTML Guide</A>
</FONT></TD>
</TR>
<TR><TD ALIGN=LEFT COLSPAN=2>

View File

@ -41,7 +41,7 @@
%>
<%= rdat.getStdFontTag(null,2) %>
<B><%= msg.getPostNumber() %></B> of <B><%= data.getTotalMessages() - 1 %></B>
<%= rdat.getStdFontTag(null,1) %>&lt;<%= "TODO" %>&gt;</FONT><BR>
<%= rdat.getStdFontTag(null,1) %>&lt;<%= data.getMessageReference(msg) %>&gt;</FONT><BR>
<B><%= msg.getPseud() %></B>
(<EM>
<A HREF="<%= rdat.getEncodedServletPath("user/" + poster) %>" TARGET="_blank"><%= poster %></A>,
@ -54,7 +54,7 @@
<%= rdat.formatDateForDisplay(msg.getScribbleDate()) %>)
</B></EM></TT>
<% } else { %>
<PRE><%= data.getMessageBodyText(msg) %></PRE>
<PRE><%= rdat.rewritePostData(data.getMessageBodyText(msg)) %></PRE>
<% } // end if %>
<% } // end while %>
<% if (rdat.useHTMLComments()) { %><!-- End Slipped Messages --><% } %>
@ -79,7 +79,7 @@
<TR>
<TD ALIGN=LEFT><%= rdat.getStdFontTag(null,2) %>Message:</FONT></TD>
<TD ALIGN=RIGHT><%= rdat.getStdFontTag(null,2) %>
<A HREF="TODO" TARGET="_blank">HTML Guide</A>
<A HREF="<%= rdat.getStaticFilePath("html-reference.html") %>" TARGET="_blank">HTML Guide</A>
</FONT></TD>
</TR>
<TR><TD ALIGN=LEFT COLSPAN=2>

View File

@ -28,7 +28,7 @@
String tmp;
%>
<% if (rdat.useHTMLComments()) { %><!-- Topic list for conf #<%= data.getConfID() %> --><% } %>
<% rdat.writeContentHeader(out,data.getConfName() + " Topics",null); %>
<% rdat.writeContentHeader(out,"Topics in " + data.getConfName(),null); %>
<%= rdat.getStdFontTag(null,2) %>
<DIV ALIGN="LEFT">
<A HREF="<%= rdat.getEncodedServletPath("confops?sig=" + String.valueOf(data.getSIGID())) %>"><IMG
@ -40,7 +40,7 @@
WIDTH=80 HEIGHT=24 BORDER=0></A>&nbsp;&nbsp;
<% } // end if %>
<% if (data.canDoReadNew()) { %>
<A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getNextLocator()) %>"><IMG
<A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getNextLocator() + "&rnm=1") %>"><IMG
SRC="<%= rdat.getFullImagePath("bn_read_new.gif") %>" ALT="Read New" WIDTH=80 HEIGHT=24
BORDER=0></A>&nbsp;&nbsp;
<% } // end if %>

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 943 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB