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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -39,23 +39,24 @@ class ConferenceCoreData implements ConferenceData
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private int refcount = 1; // object reference count
|
||||
private EngineBackend engine; // pointer to engine back end
|
||||
private DataPool datapool; // pointer to data pool
|
||||
private int confid; // ID of this conference
|
||||
private java.util.Date create_date; // creation date of this conference
|
||||
private java.util.Date last_update; // last update date of conference
|
||||
private int read_level; // access level required to read conference contents
|
||||
private int post_level; // access level required to post messages
|
||||
private int create_level; // access level required to create new topics
|
||||
private int hide_level; // access level required to hide posts/archive topics
|
||||
private int nuke_level; // access level required to delete topics/scribble/nuke posts
|
||||
private int change_level; // access level required to modify conference profile
|
||||
private int delete_level; // access level required to delete conference
|
||||
private short top_topic; // the highest topic number in the conference
|
||||
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 int refcount = 1; // object reference count
|
||||
private EngineBackend engine; // pointer to engine back end
|
||||
private DataPool datapool; // pointer to data pool
|
||||
private int confid; // ID of this conference
|
||||
private java.util.Date create_date; // creation date of this conference
|
||||
private java.util.Date last_update; // last update date of conference
|
||||
private int read_level; // access level required to read conference contents
|
||||
private int post_level; // access level required to post messages
|
||||
private int create_level; // access level required to create new topics
|
||||
private int hide_level; // access level required to hide posts/archive topics
|
||||
private int nuke_level; // access level required to delete topics/scribble/nuke posts
|
||||
private int change_level; // access level required to modify conference profile
|
||||
private int delete_level; // access level required to delete conference
|
||||
private short top_topic; // the highest topic number in the conference
|
||||
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)
|
||||
*--------------------------------------------------------------------------------
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
*--------------------------------------------------------------------------------
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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
|
||||
*--------------------------------------------------------------------------------
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user