* landed code for viewing topics in a conference, and for adding a topic
(first workout of HTML Checker code) * modified the dictionary implementation to use a trie system rather than a set of HashSets, and also started using a new, much smaller dictionary * general bugfixes and cleanup on other items as needed
This commit is contained in:
@@ -109,4 +109,7 @@ public interface ConferenceContext
|
||||
|
||||
public abstract TopicContext getTopic(short number) throws DataException, AccessError;
|
||||
|
||||
public abstract TopicContext addTopic(String title, String zp_pseud, String zp_text)
|
||||
throws DataException, AccessError;
|
||||
|
||||
} // end interface ConferenceContext
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
package com.silverwrist.venice.core.impl;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.Date;
|
||||
|
||||
public interface ConferenceBackend extends SIGBackend
|
||||
{
|
||||
@@ -27,6 +28,8 @@ public interface ConferenceBackend extends SIGBackend
|
||||
|
||||
public abstract void touchRead(Connection conn) throws SQLException;
|
||||
|
||||
public abstract void touchPost(Connection conn, java.util.Date post_date) throws SQLException;
|
||||
|
||||
public abstract String realConfAlias();
|
||||
|
||||
} // end interface ConferenceBackend
|
||||
|
||||
@@ -52,7 +52,7 @@ class ConferenceCoreData implements ConferenceData
|
||||
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 int top_topic; // the highest topic number in the 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)
|
||||
@@ -142,7 +142,7 @@ class ConferenceCoreData implements ConferenceData
|
||||
nuke_level = rs.getInt("nuke_lvl");
|
||||
change_level = rs.getInt("change_lvl");
|
||||
delete_level = rs.getInt("delete_lvl");
|
||||
top_topic = rs.getInt("top_topic");
|
||||
top_topic = rs.getShort("top_topic");
|
||||
name = rs.getString("name");
|
||||
description = rs.getString("descr");
|
||||
// "icon_url" and "color" fields are skipped
|
||||
@@ -817,6 +817,121 @@ class ConferenceCoreData implements ConferenceData
|
||||
|
||||
} // end getAnAlias
|
||||
|
||||
public 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
|
||||
short new_topic_num; // sequential number of the new topic
|
||||
int new_topic_id; // ID of the new topic
|
||||
java.util.Date creation; // creation date for new topic
|
||||
|
||||
try
|
||||
{ // get a database connection
|
||||
conn = datapool.getConnection();
|
||||
Statement stmt = conn.createStatement();
|
||||
|
||||
// lock the tables we need to use so we can update them
|
||||
stmt.executeUpdate("LOCK TABLES confs WRITE, topics WRITE, posts WRITE, postdata WRITE;");
|
||||
|
||||
try
|
||||
{ // determine the data for the initial topic
|
||||
new_topic_num = (short)(top_topic + 1);
|
||||
|
||||
// add the topic row to the database
|
||||
StringBuffer sql = new StringBuffer("INSERT INTO topics (confid, num, creator_uid, createdate, "
|
||||
+ "lastupdate, name) VALUES (");
|
||||
sql.append(confid).append(", ").append(new_topic_num).append(", ").append(sig.realUID()).append(", '");
|
||||
creation = new java.util.Date();
|
||||
String now_str = SQLUtil.encodeDate(creation);
|
||||
sql.append(now_str).append("', '").append(now_str).append("', '").append(title).append("');");
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("SQL: " + sql.toString());
|
||||
stmt.executeUpdate(sql.toString());
|
||||
|
||||
// get the topic ID we just inserted
|
||||
ResultSet rs = stmt.executeQuery("SELECT LAST_INSERT_ID();");
|
||||
if (!(rs.next()))
|
||||
throw new InternalStateError("createNewTopic() could not get back inserted Topic ID");
|
||||
new_topic_id = rs.getInt(1);
|
||||
|
||||
// insert the "header" for the "zero post" in the topic
|
||||
sql.setLength(0);
|
||||
sql.append("INSERT INTO posts (topicid, num, linecount, creator_uid, posted, pseud) VALUES (");
|
||||
sql.append(new_topic_id).append(", 0, ").append(body_lines).append(", ").append(sig.realUID());
|
||||
sql.append(", '").append(now_str).append("', '").append(pseud).append("');");
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("SQL: " + sql.toString());
|
||||
stmt.executeUpdate(sql.toString());
|
||||
|
||||
// get the ID of the zero post
|
||||
rs = stmt.executeQuery("SELECT LAST_INSERT_ID();");
|
||||
if (!(rs.next()))
|
||||
throw new InternalStateError("createNewTopic() could not get back inserted zero post ID");
|
||||
long zero_post_id = rs.getLong(1);
|
||||
|
||||
// insert the post data
|
||||
sql.setLength(0);
|
||||
sql.append("INSERT INTO postdata (postid, data) VALUES (").append(zero_post_id).append(", '");
|
||||
sql.append(body).append("');");
|
||||
stmt.executeUpdate(sql.toString());
|
||||
|
||||
// touch the "conference" entry to reflect the update
|
||||
sql.setLength(0);
|
||||
sql.append("UPDATE confs SET lastupdate = '").append(now_str).append("', top_topic = ");
|
||||
sql.append(new_topic_num).append(" WHERE confid = ").append(confid).append(';');
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("SQL: " + sql.toString());
|
||||
stmt.executeUpdate(sql.toString());
|
||||
|
||||
// touch the local variables, too
|
||||
top_topic = new_topic_num;
|
||||
last_update = creation;
|
||||
|
||||
// create an audit record indicating we were successful
|
||||
ar = new AuditRecord(AuditRecord.CREATE_TOPIC,sig.realUID(),sig.userRemoteAddress(),sig.realSIGID(),
|
||||
"confid=" + String.valueOf(confid),"num=" + String.valueOf(new_topic_num),
|
||||
"title=" + title);
|
||||
|
||||
} // end try
|
||||
finally
|
||||
{ // we need to unlock the tables before we go
|
||||
Statement ulk_stmt = conn.createStatement();
|
||||
ulk_stmt.executeUpdate("UNLOCK TABLES;");
|
||||
|
||||
} // end finally
|
||||
|
||||
} // end try
|
||||
catch (SQLException e)
|
||||
{ // database error - this is a DataException
|
||||
logger.error("DB error creating topic: " + e.getMessage(),e);
|
||||
throw new DataException("unable to create topic: " + e.getMessage(),e);
|
||||
|
||||
} // end catch
|
||||
finally
|
||||
{ // make sure the connection is released 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
|
||||
|
||||
// we have three pieces of data to return, so we need a temporary object
|
||||
return new ReturnTopicInfo(new_topic_id,new_topic_num,creation);
|
||||
|
||||
} // end createNewTopic
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* External static operations (usable only from within package)
|
||||
*--------------------------------------------------------------------------------
|
||||
@@ -865,14 +980,14 @@ class ConferenceCoreData implements ConferenceData
|
||||
// insert the record into the conferences table!
|
||||
sql.setLength(0);
|
||||
sql.append("INSERT INTO confs (createdate, read_lvl, post_lvl, create_lvl, hide_lvl, nuke_lvl, "
|
||||
+ "change_lvl, delete_lvl, top_topic, name, descr) VALUES ('");
|
||||
+ "change_lvl, delete_lvl, name, descr) VALUES ('");
|
||||
created = new java.util.Date();
|
||||
sql.append(SQLUtil.encodeDate(created)).append("', ").append(DefaultLevels.newConferenceRead(pvt));
|
||||
sql.append(", ").append(DefaultLevels.newConferencePost(pvt)).append(", ");
|
||||
sql.append(DefaultLevels.newConferenceCreate(pvt)).append(", ");
|
||||
sql.append(DefaultLevels.newConferenceHide()).append(", ").append(DefaultLevels.newConferenceNuke());
|
||||
sql.append(", ").append(DefaultLevels.newConferenceChange()).append(", ");
|
||||
sql.append(DefaultLevels.newConferenceDelete()).append(", 0, '").append(SQLUtil.encodeString(name));
|
||||
sql.append(DefaultLevels.newConferenceDelete()).append(", '").append(SQLUtil.encodeString(name));
|
||||
sql.append("', '").append(SQLUtil.encodeString(description)).append("');");
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("SQL: " + sql.toString());
|
||||
|
||||
@@ -76,4 +76,7 @@ public interface ConferenceData 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;
|
||||
|
||||
} // end interface ConferenceData
|
||||
|
||||
@@ -88,4 +88,7 @@ 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;
|
||||
|
||||
} // end interface ConferenceSIGContext
|
||||
|
||||
@@ -611,4 +611,11 @@ class ConferenceSIGContextImpl implements ConferenceSIGContext
|
||||
|
||||
} // end getAnAlias
|
||||
|
||||
public ReturnTopicInfo createNewTopic(SIGBackend sig, String title, String pseud, String body,
|
||||
int body_lines) throws DataException
|
||||
{
|
||||
return getConferenceData().createNewTopic(sig,title,pseud,body,body_lines);
|
||||
|
||||
} // end createNewTopic
|
||||
|
||||
} // end class ConferenceSIGContextImpl
|
||||
|
||||
@@ -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.DefaultLevels;
|
||||
import com.silverwrist.venice.core.*;
|
||||
|
||||
@@ -810,6 +811,79 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
|
||||
|
||||
} // end getTopic
|
||||
|
||||
public TopicContext addTopic(String title, String zp_pseud, String zp_text)
|
||||
throws DataException, AccessError
|
||||
{
|
||||
if (!(getConferenceData().canCreateTopic(level)))
|
||||
{ // not allowed to create a topic - bail out
|
||||
logger.error("user not permitted to create new topic");
|
||||
throw new AccessError("You are not permitted to create a topic in this conference.");
|
||||
|
||||
} // end if
|
||||
|
||||
// preprocess the three 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
|
||||
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)
|
||||
{ // this isn't right...
|
||||
throw new InternalStateError("HTMLChecker erroneously throwing AlreadyFinishedException",e);
|
||||
|
||||
} // end catch
|
||||
|
||||
// Create the actual topic in the database.
|
||||
String real_title;
|
||||
ReturnTopicInfo new_topic_inf;
|
||||
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());
|
||||
|
||||
} // end try
|
||||
catch (NotYetFinishedException e)
|
||||
{ // this isn't right either!
|
||||
throw new InternalStateError("HTMLChecker erroneously throwing NotYetFinishedException",e);
|
||||
|
||||
} // end catch
|
||||
|
||||
// now we need to reset our last post date
|
||||
Connection conn = null;
|
||||
try
|
||||
{ // get a connection and feed it to the touchPost function
|
||||
conn = datapool.getConnection();
|
||||
touchPost(conn,new_topic_inf.getCreateDate());
|
||||
|
||||
} // end try
|
||||
catch (SQLException e)
|
||||
{ // this becomes a DataException
|
||||
logger.error("DB error updating user information: " + e.getMessage(),e);
|
||||
throw new DataException("unable to update user information: " + e.getMessage(),e);
|
||||
|
||||
} // end catch
|
||||
finally
|
||||
{ // make sure we release the connection before we go
|
||||
if (conn!=null)
|
||||
datapool.releaseConnection(conn);
|
||||
|
||||
} // end finally
|
||||
|
||||
// create the topic context to return to the user
|
||||
return new TopicUserContextImpl(engine,this,datapool,new_topic_inf,real_title);
|
||||
|
||||
} // end addTopic
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Implementations from interface UserBackend
|
||||
*--------------------------------------------------------------------------------
|
||||
@@ -929,6 +1003,34 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
|
||||
|
||||
} // end touchRead
|
||||
|
||||
public void touchPost(Connection conn, java.util.Date post_date) throws SQLException
|
||||
{
|
||||
Statement stmt = conn.createStatement();
|
||||
StringBuffer sql = new StringBuffer();
|
||||
|
||||
if (settings_loaded)
|
||||
{ // generate an update statement
|
||||
sql.append("UPDATE confsettings SET last_post = '").append(SQLUtil.encodeDate(post_date));
|
||||
sql.append("' WHERE confid = ").append(confid).append(" AND uid = ").append(sig.realUID()).append(';');
|
||||
|
||||
} // end if
|
||||
else
|
||||
{ // need to insert a confsettings row
|
||||
sql.append("INSERT INTO confsettings (confid, uid, default_pseud, last_read) VALUES (").append(confid);
|
||||
sql.append(", ").append(sig.realUID()).append(", '").append(SQLUtil.encodeString(pseud)).append("', '");
|
||||
sql.append(SQLUtil.encodeDate(post_date)).append("');");
|
||||
|
||||
} // end else
|
||||
|
||||
// execute the statement
|
||||
stmt.executeUpdate(sql.toString());
|
||||
|
||||
// save off the values to our local fields
|
||||
last_post = post_date;
|
||||
settings_loaded = true;
|
||||
|
||||
} // end touchRead
|
||||
|
||||
public String realConfAlias()
|
||||
{
|
||||
try
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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 Community 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.util.Date;
|
||||
|
||||
public class ReturnTopicInfo
|
||||
{
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Attributes
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private int topic_id;
|
||||
private short topic_num;
|
||||
private Date create_date;
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Constructor
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public ReturnTopicInfo(int topic_id, short topic_num, Date create_date)
|
||||
{
|
||||
this.topic_id = topic_id;
|
||||
this.topic_num = topic_num;
|
||||
this.create_date = create_date;
|
||||
|
||||
} // end constructor
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* External operations
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public int getTopicID()
|
||||
{
|
||||
return topic_id;
|
||||
|
||||
} // end getTopicID
|
||||
|
||||
public short getTopicNum()
|
||||
{
|
||||
return topic_num;
|
||||
|
||||
} // end getTopicNum
|
||||
|
||||
public Date getCreateDate()
|
||||
{
|
||||
return create_date;
|
||||
|
||||
} // end getCreateDate
|
||||
|
||||
} // end class ReturnTopicInfo
|
||||
@@ -79,7 +79,27 @@ class TopicUserContextImpl implements TopicContext
|
||||
this.hidden = hidden;
|
||||
this.unread = unread;
|
||||
|
||||
} // end TopicUserContextImpl
|
||||
} // end constructor
|
||||
|
||||
TopicUserContextImpl(EngineBackend engine, ConferenceBackend conf, DataPool datapool, ReturnTopicInfo inf,
|
||||
String name)
|
||||
{
|
||||
this.engine = engine;
|
||||
this.conf = conf;
|
||||
this.datapool = datapool;
|
||||
this.topicid = inf.getTopicID();
|
||||
this.topicnum = inf.getTopicNum();
|
||||
this.creator_uid = conf.realUID();
|
||||
this.top_message = 0;
|
||||
this.frozen = false;
|
||||
this.archived = false;
|
||||
this.created = inf.getCreateDate();
|
||||
this.lastupdate = inf.getCreateDate();
|
||||
this.name = name;
|
||||
this.hidden = false;
|
||||
this.unread = 1;
|
||||
|
||||
} // end constructor
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Internal functions
|
||||
@@ -553,23 +573,24 @@ class TopicUserContextImpl implements TopicContext
|
||||
break;
|
||||
|
||||
case ConferenceContext.DISPLAY_NEW:
|
||||
where_clause = "hidden = 0 AND unread > 0"; // only non-hidden topics w/unread messages
|
||||
// only non-hidden topics w/unread messages
|
||||
where_clause = "IFNULL(s.hidden,0) = 0 AND t.top_message > IFNULL(s.last_message,-1)";
|
||||
break;
|
||||
|
||||
case ConferenceContext.DISPLAY_ACTIVE:
|
||||
where_clause = "t.archived = 0 AND hidden = 0"; // only non-hidden, non-archived topics
|
||||
where_clause = "t.archived = 0 AND IFNULL(s.hidden,0) = 0"; // only non-hidden, non-archived topics
|
||||
break;
|
||||
|
||||
case ConferenceContext.DISPLAY_ALL:
|
||||
where_clause = "t.archived = 0 AND hidden = 0"; // only non-hidden, non-archived topics
|
||||
where_clause = "t.archived = 0 AND IFNULL(s.hidden,0) = 0"; // only non-hidden, non-archived topics
|
||||
break;
|
||||
|
||||
case ConferenceContext.DISPLAY_HIDDEN:
|
||||
where_clause = "hidden = 1"; // only hidden topics
|
||||
where_clause = "IFNULL(s.hidden,0) = 1"; // only hidden topics
|
||||
break;
|
||||
|
||||
case ConferenceContext.DISPLAY_ARCHIVED:
|
||||
where_clause = "t.archived = 1 AND hidden = 0"; // only non-hidden, archived topics
|
||||
where_clause = "t.archived = 1 AND IFNULL(s.hidden,0) = 0"; // only non-hidden, archived topics
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -435,7 +435,7 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
|
||||
String[] dictfiles = new String[dictionary_tmp.size()];
|
||||
for (int i=0; i<dictionary_tmp.size(); i++)
|
||||
dictfiles[i] = (String)(dictionary_tmp.get(i));
|
||||
LazyLexicon lex = new LazyLexicon(dictfiles);
|
||||
LazyTreeLexicon lex = new LazyTreeLexicon(dictfiles);
|
||||
spell_rewriter.addDictionary(lex);
|
||||
|
||||
html_configs = new HTMLCheckerConfig[4]; // create the array
|
||||
|
||||
Reference in New Issue
Block a user