* landed support for reading topics and posting followup messages to a topic -
the basis of the conferencing engine is now firmly in place * tweaks to the HTML Checker to make it better at breaking lines without leaving stranded punctuation at the beginning or end of a line * also modified dictionary to better handle possessives and hyphenates * as always, miscellaneous tweaks and bugfizes as I spot them
This commit is contained in:
@@ -64,4 +64,9 @@ public interface TopicContext
|
||||
|
||||
public abstract void fixSeen() throws DataException;
|
||||
|
||||
public abstract List getMessages(int low, int high) throws DataException, AccessError;
|
||||
|
||||
public abstract TopicMessageContext postNewMessage(long parent, String pseud, String text)
|
||||
throws DataException, AccessError;
|
||||
|
||||
} // end interface TopicContext
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public interface TopicMessageContext
|
||||
{
|
||||
public abstract long getPostID();
|
||||
|
||||
public abstract long getParentPostID();
|
||||
|
||||
public abstract int getPostNumber();
|
||||
|
||||
public abstract int getNumLines();
|
||||
|
||||
public abstract int getCreatorUID();
|
||||
|
||||
public abstract String getCreatorName() throws DataException;
|
||||
|
||||
public abstract Date getPostDate();
|
||||
|
||||
public abstract boolean isHidden();
|
||||
|
||||
public abstract boolean isScribbled();
|
||||
|
||||
public abstract boolean isNuked();
|
||||
|
||||
public abstract Date getScribbleDate();
|
||||
|
||||
public abstract String getPseud();
|
||||
|
||||
public abstract String getBodyText() throws DataException;
|
||||
|
||||
public abstract boolean hasAttachment();
|
||||
|
||||
public abstract boolean canHide();
|
||||
|
||||
public abstract boolean canScribble();
|
||||
|
||||
public abstract boolean canNuke();
|
||||
|
||||
public abstract void setHidden(boolean flag) throws DataException, AccessError;
|
||||
|
||||
public abstract void scribble() throws DataException, AccessError;
|
||||
|
||||
public abstract void nuke() throws DataException, AccessError;
|
||||
|
||||
} // end interface TopicMessageContext
|
||||
@@ -17,8 +17,10 @@
|
||||
*/
|
||||
package com.silverwrist.venice.core.impl;
|
||||
|
||||
import java.sql.*;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Date;
|
||||
import com.silverwrist.venice.core.DataException;
|
||||
|
||||
public interface ConferenceBackend extends SIGBackend
|
||||
{
|
||||
@@ -32,4 +34,14 @@ public interface ConferenceBackend extends SIGBackend
|
||||
|
||||
public abstract String realConfAlias();
|
||||
|
||||
public abstract boolean userCanScribble();
|
||||
|
||||
public abstract boolean userCanNuke();
|
||||
|
||||
public abstract boolean userCanRead();
|
||||
|
||||
public abstract boolean userCanPost();
|
||||
|
||||
public abstract void touchUpdate(Connection conn, java.util.Date date) throws DataException;
|
||||
|
||||
} // end interface ConferenceBackend
|
||||
|
||||
@@ -932,6 +932,37 @@ class ConferenceCoreData implements ConferenceData
|
||||
|
||||
} // end createNewTopic
|
||||
|
||||
public boolean canScribblePosts(int level)
|
||||
{
|
||||
return (level>=nuke_level);
|
||||
|
||||
} // end canScribblePosts
|
||||
|
||||
public boolean canNukePosts(int level)
|
||||
{
|
||||
return (level>=nuke_level);
|
||||
|
||||
} // end canNukePosts
|
||||
|
||||
public synchronized void touchUpdate(Connection conn, java.util.Date date) throws DataException
|
||||
{
|
||||
try
|
||||
{ // update the last update date
|
||||
Statement stmt = conn.createStatement();
|
||||
StringBuffer sql = new StringBuffer("UPDATE confs SET lastupdate = '");
|
||||
sql.append(SQLUtil.encodeDate(date)).append("' WHERE confid = ").append(confid).append(';');
|
||||
stmt.executeUpdate(sql.toString());
|
||||
last_update = date;
|
||||
|
||||
} // end try
|
||||
catch (SQLException e)
|
||||
{ // convert the SQLException
|
||||
throw new DataException("Database error updating conference: " + e.getMessage(),e);
|
||||
|
||||
} // end catch
|
||||
|
||||
} // end touchUpdate
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* External static operations (usable only from within package)
|
||||
*--------------------------------------------------------------------------------
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
package com.silverwrist.venice.core.impl;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import com.silverwrist.venice.core.DataException;
|
||||
@@ -79,4 +80,10 @@ public interface ConferenceData extends ReferencedData
|
||||
public abstract ReturnTopicInfo createNewTopic(SIGBackend sig, String title, String pseud, String body,
|
||||
int body_lines) throws DataException;
|
||||
|
||||
public abstract boolean canScribblePosts(int level);
|
||||
|
||||
public abstract boolean canNukePosts(int level);
|
||||
|
||||
public abstract void touchUpdate(Connection conn, Date date) throws DataException;
|
||||
|
||||
} // end interface ConferenceData
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
package com.silverwrist.venice.core.impl;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import com.silverwrist.venice.core.DataException;
|
||||
@@ -91,4 +92,10 @@ public interface ConferenceSIGContext extends ReferencedData
|
||||
public abstract ReturnTopicInfo createNewTopic(SIGBackend sig, String title, String pseud, String body,
|
||||
int body_lines) throws DataException;
|
||||
|
||||
public abstract boolean canScribblePosts(int level);
|
||||
|
||||
public abstract boolean canNukePosts(int level);
|
||||
|
||||
public abstract void touchUpdate(Connection conn, Date date) throws DataException;
|
||||
|
||||
} // end interface ConferenceSIGContext
|
||||
|
||||
@@ -618,4 +618,34 @@ class ConferenceSIGContextImpl implements ConferenceSIGContext
|
||||
|
||||
} // end createNewTopic
|
||||
|
||||
public boolean canScribblePosts(int level)
|
||||
{
|
||||
ConferenceData c = getConferenceDataNE();
|
||||
if (c==null)
|
||||
return false;
|
||||
if (level<this.level)
|
||||
return c.canScribblePosts(this.level);
|
||||
else
|
||||
return c.canScribblePosts(level);
|
||||
|
||||
} // end canScribblePosts
|
||||
|
||||
public boolean canNukePosts(int level)
|
||||
{
|
||||
ConferenceData c = getConferenceDataNE();
|
||||
if (c==null)
|
||||
return false;
|
||||
if (level<this.level)
|
||||
return c.canNukePosts(this.level);
|
||||
else
|
||||
return c.canNukePosts(level);
|
||||
|
||||
} // end canNukePosts
|
||||
|
||||
public void touchUpdate(Connection conn, java.util.Date date) throws DataException
|
||||
{
|
||||
getConferenceData().touchUpdate(conn,date);
|
||||
|
||||
} // end touchUpdate
|
||||
|
||||
} // end class ConferenceSIGContextImpl
|
||||
|
||||
@@ -1047,6 +1047,42 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
|
||||
|
||||
} // end realConfAlias
|
||||
|
||||
public boolean userCanScribble()
|
||||
{
|
||||
ConferenceSIGContext c = getConferenceDataNE();
|
||||
if (c==null)
|
||||
return false;
|
||||
return c.canScribblePosts(level);
|
||||
|
||||
} // end userCanScribble
|
||||
|
||||
public boolean userCanNuke()
|
||||
{
|
||||
ConferenceSIGContext c = getConferenceDataNE();
|
||||
if (c==null)
|
||||
return false;
|
||||
return c.canNukePosts(level);
|
||||
|
||||
} // end userCanNuke
|
||||
|
||||
public boolean userCanRead()
|
||||
{
|
||||
return canReadConference();
|
||||
|
||||
} // end userCanRead
|
||||
|
||||
public boolean userCanPost()
|
||||
{
|
||||
return canPostToConference();
|
||||
|
||||
} // end userCanPost
|
||||
|
||||
public void touchUpdate(Connection conn, java.util.Date date) throws DataException
|
||||
{
|
||||
getConferenceData().touchUpdate(conn,date);
|
||||
|
||||
} // end getConferenceData
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Static functions usable only from within the package
|
||||
*--------------------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,706 @@
|
||||
/*
|
||||
* 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.sql.*;
|
||||
import java.util.*;
|
||||
import org.apache.log4j.*;
|
||||
import com.silverwrist.venice.db.*;
|
||||
import com.silverwrist.venice.security.AuditRecord;
|
||||
import com.silverwrist.venice.core.*;
|
||||
|
||||
class TopicMessageUserContextImpl implements TopicMessageContext
|
||||
{
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Static data members
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private static Category logger = Category.getInstance(TopicMessageUserContextImpl.class.getName());
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Attributes
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private EngineBackend engine;
|
||||
private ConferenceBackend conf;
|
||||
private DataPool datapool;
|
||||
private long postid;
|
||||
private long parent;
|
||||
private int num;
|
||||
private int linecount;
|
||||
private int creator_uid;
|
||||
private java.util.Date posted;
|
||||
private boolean hidden;
|
||||
private int scribble_uid;
|
||||
private java.util.Date scribble_date;
|
||||
private String pseud;
|
||||
private int datalen;
|
||||
private String filename;
|
||||
private String mimetype;
|
||||
private boolean nuked = false;
|
||||
private String creator_cache = null;
|
||||
private String text_cache = null;
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Constructors
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
protected TopicMessageUserContextImpl(EngineBackend engine, ConferenceBackend conf, DataPool datapool,
|
||||
long postid, long parent, int num, int linecount, int creator_uid,
|
||||
java.util.Date posted, boolean hidden, int scribble_uid,
|
||||
java.util.Date scribble_date, String pseud, int datalen,
|
||||
String filename, String mimetype)
|
||||
{
|
||||
this.engine = engine;
|
||||
this.conf = conf;
|
||||
this.datapool = datapool;
|
||||
this.postid = postid;
|
||||
this.parent = parent;
|
||||
this.num = num;
|
||||
this.linecount = linecount;
|
||||
this.creator_uid = creator_uid;
|
||||
this.posted = posted;
|
||||
this.hidden = hidden;
|
||||
this.scribble_uid = scribble_uid;
|
||||
this.scribble_date = scribble_date;
|
||||
this.pseud = pseud;
|
||||
this.datalen = datalen;
|
||||
this.filename = filename;
|
||||
this.mimetype = mimetype;
|
||||
|
||||
} // end constructor
|
||||
|
||||
TopicMessageUserContextImpl(EngineBackend engine, ConferenceBackend conf, DataPool datapool,
|
||||
long postid, long parent, int num, int linecount, int creator_uid,
|
||||
java.util.Date posted, String pseud)
|
||||
{
|
||||
this.engine = engine;
|
||||
this.conf = conf;
|
||||
this.datapool = datapool;
|
||||
this.postid = postid;
|
||||
this.parent = parent;
|
||||
this.num = num;
|
||||
this.linecount = linecount;
|
||||
this.creator_uid = creator_uid;
|
||||
this.posted = posted;
|
||||
this.hidden = false;
|
||||
this.scribble_uid = 0;
|
||||
this.scribble_date = null;
|
||||
this.pseud = pseud;
|
||||
this.datalen = 0;
|
||||
this.filename = null;
|
||||
this.mimetype = null;
|
||||
|
||||
} // end constructor
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Internal functions
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private static String quickGetUserName(Connection conn, int uid) throws SQLException
|
||||
{
|
||||
Statement stmt = conn.createStatement();
|
||||
ResultSet rs = stmt.executeQuery("SELECT username FROM users WHERE uid = " + String.valueOf(uid) + ";");
|
||||
if (rs.next())
|
||||
return rs.getString(1);
|
||||
else
|
||||
return "(unknown)";
|
||||
|
||||
} // end quickGetUserName
|
||||
|
||||
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 = ");
|
||||
sql.append(postid).append(';');
|
||||
ResultSet rs = stmt.executeQuery(sql.toString());
|
||||
if (rs.next())
|
||||
{ // update a variety of fields
|
||||
hidden = rs.getBoolean(1);
|
||||
scribble_uid = rs.getInt(2);
|
||||
scribble_date = SQLUtil.getFullDateTime(rs,3);
|
||||
pseud = rs.getString(4);
|
||||
datalen = rs.getInt(5);
|
||||
filename = rs.getString(6);
|
||||
mimetype = rs.getString(7);
|
||||
|
||||
} // end if
|
||||
else
|
||||
{ // the post has been nuked - update accordingly
|
||||
linecount = 0;
|
||||
creator_uid = -1;
|
||||
posted = null;
|
||||
hidden = false;
|
||||
scribble_uid = -1;
|
||||
scribble_date = null;
|
||||
pseud = null;
|
||||
datalen = 0;
|
||||
filename = null;
|
||||
mimetype = null;
|
||||
nuked = true;
|
||||
creator_cache = null;
|
||||
text_cache = null;
|
||||
|
||||
} // end else
|
||||
|
||||
} // end refresh
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Implementations from interface TopicMessageContext
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public long getPostID()
|
||||
{
|
||||
return postid;
|
||||
|
||||
} // end getPostID
|
||||
|
||||
public long getParentPostID()
|
||||
{
|
||||
return parent;
|
||||
|
||||
} // end getParentPostID
|
||||
|
||||
public int getPostNumber()
|
||||
{
|
||||
return num;
|
||||
|
||||
} // end getPostNumber
|
||||
|
||||
public int getNumLines()
|
||||
{
|
||||
return linecount;
|
||||
|
||||
} // end getNumLines
|
||||
|
||||
public int getCreatorUID()
|
||||
{
|
||||
return creator_uid;
|
||||
|
||||
} // end getCreatorUID
|
||||
|
||||
public String getCreatorName() throws DataException
|
||||
{
|
||||
if (creator_cache==null)
|
||||
{ // we don't have the user name yet, get it out of the database
|
||||
if (nuked)
|
||||
return null; // post nuked!
|
||||
Connection conn = null;
|
||||
|
||||
try
|
||||
{ // use a database connection to get the user name
|
||||
conn = datapool.getConnection();
|
||||
refresh(conn);
|
||||
if (nuked)
|
||||
return null; // post nuked!
|
||||
creator_cache = quickGetUserName(conn,creator_uid);
|
||||
|
||||
} // end try
|
||||
catch (SQLException e)
|
||||
{ // turn this into a DataException
|
||||
logger.error("DB error reading user name: " + e.getMessage(),e);
|
||||
throw new DataException("unable to retrieve user name: " + e.getMessage(),e);
|
||||
|
||||
} // end catch
|
||||
finally
|
||||
{ // make sure we release the connection before we go
|
||||
if (conn!=null)
|
||||
datapool.releaseConnection(conn);
|
||||
|
||||
} // end finally
|
||||
|
||||
} // end if
|
||||
|
||||
return creator_cache;
|
||||
|
||||
} // end getCreatorName
|
||||
|
||||
public java.util.Date getPostDate()
|
||||
{
|
||||
return posted;
|
||||
|
||||
} // end getPostDate
|
||||
|
||||
public boolean isHidden()
|
||||
{
|
||||
return hidden;
|
||||
|
||||
} // end isHidden
|
||||
|
||||
public boolean isScribbled()
|
||||
{
|
||||
return (scribble_date!=null);
|
||||
|
||||
} // end isScribbled
|
||||
|
||||
public boolean isNuked()
|
||||
{
|
||||
return nuked;
|
||||
|
||||
} // end isNuked
|
||||
|
||||
public java.util.Date getScribbleDate()
|
||||
{
|
||||
return scribble_date;
|
||||
|
||||
} // end getScribbleDate
|
||||
|
||||
public String getPseud()
|
||||
{
|
||||
return pseud;
|
||||
|
||||
} // return pseud
|
||||
|
||||
public String getBodyText() throws DataException
|
||||
{
|
||||
if (text_cache==null)
|
||||
{ // we don't have the body text yet, go get it
|
||||
Connection conn = null;
|
||||
if (nuked)
|
||||
return null; // post nuked!
|
||||
|
||||
try
|
||||
{ // use a database connection to get the body text
|
||||
conn = datapool.getConnection();
|
||||
refresh(conn);
|
||||
|
||||
if (nuked)
|
||||
return null; // post nuked!
|
||||
|
||||
if (scribble_date==null)
|
||||
{ // let's go get the body text!
|
||||
Statement stmt = conn.createStatement();
|
||||
ResultSet rs = stmt.executeQuery("SELECT data FROM postdata WHERE postid = "
|
||||
+ String.valueOf(postid) + ";");
|
||||
if (rs.next())
|
||||
text_cache = rs.getString(1);
|
||||
else
|
||||
return "Data Missing"; // FUTURE: throw an exception?
|
||||
|
||||
} // end if
|
||||
else // for scribbled posts, we return the scribbler's name only
|
||||
text_cache = quickGetUserName(conn,scribble_uid);
|
||||
|
||||
} // end try
|
||||
catch (SQLException e)
|
||||
{ // turn this into a DataException
|
||||
logger.error("DB error reading post data: " + e.getMessage(),e);
|
||||
throw new DataException("unable to retrieve post data: " + e.getMessage(),e);
|
||||
|
||||
} // end catch
|
||||
finally
|
||||
{ // make sure we release the connection before we go
|
||||
if (conn!=null)
|
||||
datapool.releaseConnection(conn);
|
||||
|
||||
} // end finally
|
||||
|
||||
} // end if
|
||||
|
||||
return text_cache;
|
||||
|
||||
} // end getBodyText
|
||||
|
||||
public boolean hasAttachment()
|
||||
{
|
||||
return (mimetype!=null);
|
||||
|
||||
} // end hasAttachment
|
||||
|
||||
public boolean canHide()
|
||||
{
|
||||
return ((creator_uid==conf.realUID()) || conf.userCanHide());
|
||||
|
||||
} // end canHide
|
||||
|
||||
public boolean canScribble()
|
||||
{
|
||||
return ((creator_uid==conf.realUID()) || conf.userCanScribble());
|
||||
|
||||
} // end canScribble
|
||||
|
||||
public boolean canNuke()
|
||||
{
|
||||
return conf.userCanNuke();
|
||||
|
||||
} // end canNuke
|
||||
|
||||
public void setHidden(boolean flag) throws DataException, AccessError
|
||||
{
|
||||
if ((creator_uid!=conf.realUID()) && !(conf.userCanHide()))
|
||||
{ // we can't change the hidden status!
|
||||
logger.error("trying to set hidden status of post w/o permission!");
|
||||
throw new AccessError("You are not permitted to change the hidden status of this message.");
|
||||
|
||||
} // end if
|
||||
|
||||
if (nuked || (scribble_date!=null))
|
||||
return; // changing the status of a nuked or scribbled post is futile
|
||||
|
||||
Connection conn = null;
|
||||
AuditRecord ar = null;
|
||||
|
||||
try
|
||||
{ // open up a database connection
|
||||
conn = datapool.getConnection();
|
||||
Statement stmt = conn.createStatement();
|
||||
|
||||
// lock the tables we reference
|
||||
stmt.executeUpdate("LOCK TABLES posts WRITE, postattach READ;");
|
||||
try
|
||||
{ // first, make sure we have the right status for our post
|
||||
refresh(conn);
|
||||
if (nuked || (scribble_date!=null))
|
||||
return; // changing the status of a nuked or scribbled post is futile
|
||||
if (hidden==flag)
|
||||
return; // this is a no-op
|
||||
|
||||
// update the "hidden" flag in the database
|
||||
StringBuffer sql = new StringBuffer("UPDATE posts SET hidden = ");
|
||||
sql.append(flag ? '1' : '0').append(" WHERE postid = ").append(postid).append(';');
|
||||
stmt.executeUpdate(sql.toString());
|
||||
|
||||
hidden = flag; // store flag
|
||||
|
||||
} // end try
|
||||
finally
|
||||
{ // unlock the tables before we go
|
||||
Statement ulk_stmt = conn.createStatement();
|
||||
ulk_stmt.executeUpdate("UNLOCK TABLES;");
|
||||
|
||||
} // end finally
|
||||
|
||||
// record what we did in an audit record
|
||||
ar = new AuditRecord(AuditRecord.HIDE_MESSAGE,conf.realUID(),conf.userRemoteAddress(),
|
||||
conf.realSIGID(),"conf=" + String.valueOf(conf.realConfID()) + ",post="
|
||||
+ String.valueOf(postid),flag ? "hide" : "unhide");
|
||||
|
||||
} // end try
|
||||
catch (SQLException e)
|
||||
{ // turn this into a DataException
|
||||
logger.error("DB error setting hidden status: " + e.getMessage(),e);
|
||||
throw new DataException("unable to set hidden status: " + 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
|
||||
|
||||
} // end setHidden
|
||||
|
||||
public void scribble() throws DataException, AccessError
|
||||
{
|
||||
if ((creator_uid!=conf.realUID()) && !(conf.userCanScribble()))
|
||||
{ // we can't scribble this post
|
||||
logger.error("trying to scribble post w/o permission!");
|
||||
throw new AccessError("You are not permitted to scribble this message.");
|
||||
|
||||
} // end if
|
||||
|
||||
if (nuked || (scribble_date!=null))
|
||||
return; // scribbling a nuked or scribbled post is futile
|
||||
|
||||
Connection conn = null;
|
||||
AuditRecord ar = null;
|
||||
|
||||
try
|
||||
{ // open up a database connection
|
||||
conn = datapool.getConnection();
|
||||
Statement stmt = conn.createStatement();
|
||||
|
||||
// lock the tables we reference
|
||||
stmt.executeUpdate("LOCK TABLES posts WRITE, postdata WRITE, postattach WRITE;");
|
||||
try
|
||||
{ // first, make sure we have the right status for our post
|
||||
refresh(conn);
|
||||
if (nuked || (scribble_date!=null))
|
||||
return; // scribbling a nuked or scribbled post is futile
|
||||
|
||||
// First, set the appropriate "scribbled" information in the "header".
|
||||
StringBuffer sql = new StringBuffer("UPDATE posts SET linecount = 0, hidden = 0, scribble_uid = ");
|
||||
sql.append(conf.realUID()).append(", scribble_date = '");
|
||||
java.util.Date now = new java.util.Date();
|
||||
final String scribble_pseud = "<EM><B>(Scribbled)</B></EM>"; // TODO: configurable option
|
||||
sql.append(SQLUtil.encodeDate(now)).append("', pseud = '").append(scribble_pseud);
|
||||
sql.append("' WHERE postid = ").append(postid).append(';');
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("SQL: " + sql.toString());
|
||||
stmt.executeUpdate(sql.toString());
|
||||
|
||||
// Determine if we need to "rub out" the post before we delete it.
|
||||
ResultSet rs = stmt.executeQuery("SELECT LENGTH(data) FROM postdata WHERE postid = "
|
||||
+ String.valueOf(postid) + ";");
|
||||
if (rs.next())
|
||||
{ // use this data to overwrite the post with X's
|
||||
int len = rs.getInt(1);
|
||||
if (len>0)
|
||||
{ // construct the "rubout" statement and execute it
|
||||
sql.setLength(0);
|
||||
sql.append("UPDATE postdata SET data = '");
|
||||
while (len>0)
|
||||
{ // generate a string of X's the length of the post
|
||||
sql.append('X');
|
||||
len--;
|
||||
|
||||
} // end while
|
||||
|
||||
sql.append("' WHERE postid = ").append(postid).append(';');
|
||||
stmt.executeUpdate(sql.toString());
|
||||
|
||||
} // end if
|
||||
// else not much need to do a rubout
|
||||
|
||||
} // end if
|
||||
// else don't try...we're deleting the row anyway
|
||||
|
||||
// Delete the actual post data row.
|
||||
sql.setLength(0);
|
||||
sql.append("DELETE FROM postdata WHERE postid = ").append(postid).append(';');
|
||||
stmt.executeUpdate(sql.toString());
|
||||
|
||||
// Delete the attachment data row.
|
||||
// FUTURE: can we do an overwrite on the attachment the way we did on the post data?
|
||||
sql.setLength(0);
|
||||
sql.append("DELETE FROM postattach WHERE postid = ").append(postid).append(';');
|
||||
stmt.executeUpdate(sql.toString());
|
||||
|
||||
// Update our internal data fields.
|
||||
linecount = 0;
|
||||
hidden = false;
|
||||
scribble_uid = conf.realUID();
|
||||
scribble_date = now;
|
||||
pseud = scribble_pseud;
|
||||
text_cache = null;
|
||||
|
||||
} // end try
|
||||
finally
|
||||
{ // unlock the tables before we go
|
||||
Statement ulk_stmt = conn.createStatement();
|
||||
ulk_stmt.executeUpdate("UNLOCK TABLES;");
|
||||
|
||||
} // end finally
|
||||
|
||||
// record what we did in an audit record
|
||||
ar = new AuditRecord(AuditRecord.SCRIBBLE_MESSAGE,conf.realUID(),conf.userRemoteAddress(),
|
||||
conf.realSIGID(),"conf=" + String.valueOf(conf.realConfID()) + ",post="
|
||||
+ String.valueOf(postid));
|
||||
|
||||
} // end try
|
||||
catch (SQLException e)
|
||||
{ // turn this into a DataException
|
||||
logger.error("DB error scribbling post: " + e.getMessage(),e);
|
||||
throw new DataException("unable to scribble message: " + 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
|
||||
|
||||
} // end scribble
|
||||
|
||||
public void nuke() throws DataException, AccessError
|
||||
{
|
||||
if (!(conf.userCanNuke()))
|
||||
{ // we can't scribble this post
|
||||
logger.error("trying to nuke post w/o permission!");
|
||||
throw new AccessError("You are not permitted to nuke this message.");
|
||||
|
||||
} // end if
|
||||
|
||||
if (nuked)
|
||||
return; // nuking a nuked post is futile
|
||||
|
||||
Connection conn = null;
|
||||
AuditRecord ar = null;
|
||||
|
||||
try
|
||||
{ // open up a database connection
|
||||
conn = datapool.getConnection();
|
||||
Statement stmt = conn.createStatement();
|
||||
|
||||
// lock the tables we reference
|
||||
stmt.executeUpdate("LOCK TABLES posts WRITE, postdata WRITE, postattach WRITE, postdogear WRITE;");
|
||||
|
||||
try
|
||||
{ // first, make sure we have the right status for our post
|
||||
refresh(conn);
|
||||
if (nuked)
|
||||
return; // nuking a nuked post is futile
|
||||
|
||||
// Delete any and all references to this post!
|
||||
stmt.executeUpdate("DELETE FROM posts WHERE postid = " + String.valueOf(postid) + ";");
|
||||
stmt.executeUpdate("DELETE FROM postdata WHERE postid = " + String.valueOf(postid) + ";");
|
||||
stmt.executeUpdate("DELETE FROM postattach WHERE postid = " + String.valueOf(postid) + ";");
|
||||
stmt.executeUpdate("DELETE FROM postdogear WHERE postid = " + String.valueOf(postid) + ";");
|
||||
|
||||
// Update our internal variables.
|
||||
linecount = 0;
|
||||
creator_uid = -1;
|
||||
posted = null;
|
||||
hidden = false;
|
||||
scribble_uid = -1;
|
||||
scribble_date = null;
|
||||
pseud = null;
|
||||
datalen = 0;
|
||||
filename = null;
|
||||
mimetype = null;
|
||||
nuked = true;
|
||||
creator_cache = null;
|
||||
text_cache = null;
|
||||
|
||||
} // end try
|
||||
finally
|
||||
{ // unlock the tables before we go
|
||||
Statement ulk_stmt = conn.createStatement();
|
||||
ulk_stmt.executeUpdate("UNLOCK TABLES;");
|
||||
|
||||
} // end finally
|
||||
|
||||
// record what we did in an audit record
|
||||
ar = new AuditRecord(AuditRecord.NUKE_MESSAGE,conf.realUID(),conf.userRemoteAddress(),
|
||||
conf.realSIGID(),"conf=" + String.valueOf(conf.realConfID()) + ",post="
|
||||
+ String.valueOf(postid));
|
||||
|
||||
} // end try
|
||||
catch (SQLException e)
|
||||
{ // turn this into a DataException
|
||||
logger.error("DB error nuking post: " + e.getMessage(),e);
|
||||
throw new DataException("unable to nuke message: " + 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
|
||||
|
||||
} // end nuke
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* External static operations
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static List loadMessageRange(EngineBackend engine, ConferenceBackend conf, DataPool datapool, int topicid,
|
||||
int post_low, int post_high) throws DataException
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("loadMessageRange for conf # " + String.valueOf(conf.realConfID()) + ", topic #"
|
||||
+ String.valueOf(topicid) + ", range [" + String.valueOf(post_low) + ", "
|
||||
+ String.valueOf(post_high) + "]");
|
||||
|
||||
Vector rc = new Vector();
|
||||
Connection conn = null; // pooled database connection
|
||||
|
||||
try
|
||||
{ // get a database connection
|
||||
conn = datapool.getConnection();
|
||||
Statement stmt = conn.createStatement();
|
||||
|
||||
// run a query to get all the posts in a particular topic
|
||||
StringBuffer sql =
|
||||
new StringBuffer("SELECT p.postid, p.parent, p.num, p.linecount, p.creator_uid, p.posted, "
|
||||
+ "p.hidden, p.scribble_uid, p.scribble_date, p.pseud, a.datalen, a.filename, "
|
||||
+ "a.mimetype FROM posts p LEFT JOIN postattach a ON p.postid = a.postid "
|
||||
+ "WHERE p.topicid = ");
|
||||
sql.append(topicid).append(" AND p.num >= ").append(post_low).append(" AND p.num <= ");
|
||||
sql.append(post_high).append(" ORDER BY p.num ASC;");
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("SQL: " + sql.toString());
|
||||
ResultSet rs = stmt.executeQuery(sql.toString());
|
||||
|
||||
while (rs.next())
|
||||
{ // create implementation objects and shove them into the return vector
|
||||
TopicMessageContext val =
|
||||
new TopicMessageUserContextImpl(engine,conf,datapool,rs.getLong(1),rs.getLong(2),rs.getInt(3),
|
||||
rs.getInt(4),rs.getInt(5),SQLUtil.getFullDateTime(rs,6),
|
||||
rs.getBoolean(7),rs.getInt(8),SQLUtil.getFullDateTime(rs,9),
|
||||
rs.getString(10),rs.getInt(11),rs.getString(12),rs.getString(13));
|
||||
rc.add(val);
|
||||
|
||||
} // end while
|
||||
|
||||
} // end try
|
||||
catch (SQLException e)
|
||||
{ // turn SQLException into data exception
|
||||
logger.error("DB error reading message entries: " + e.getMessage(),e);
|
||||
throw new DataException("unable to retrieve messages: " + e.getMessage(),e);
|
||||
|
||||
} // end catch
|
||||
finally
|
||||
{ // make sure we release the connection before we go
|
||||
if (conn!=null)
|
||||
datapool.releaseConnection(conn);
|
||||
|
||||
} // end finally
|
||||
|
||||
return new ReadOnlyVector(rc); // wrap the return vector
|
||||
|
||||
} // end loadMessageRange
|
||||
|
||||
} // end class TopicMessageUserContextImpl
|
||||
@@ -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.*;
|
||||
|
||||
@@ -109,11 +110,13 @@ class TopicUserContextImpl implements TopicContext
|
||||
private static ResultSet queryByTopic(Statement stmt, int topicid, int uid) throws SQLException
|
||||
{
|
||||
StringBuffer sql =
|
||||
new StringBuffer("SELECT t.topicid, t.num, t.creator_uid, t.top_message, t.frozen, t.archived, "
|
||||
+ "t.createdate, t.lastupdate, t.name, IFNULL(s.hidden,0) AS hidden, "
|
||||
+ "(t.top_message - IFNULL(s.last_message,-1)) AS unread FROM topics t "
|
||||
+ "LEFT JOIN topicsettings s ON t.topicid = s.topicid AND s.uid = ");
|
||||
sql.append(uid).append(" WHERE t.topicid = ").append(topicid).append(';');
|
||||
new StringBuffer("SELECT topics.topicid, topics.num, topics.creator_uid, topics.top_message, "
|
||||
+ "topics.frozen, topics.archived, topics.createdate, topics.lastupdate, "
|
||||
+ "topics.name, IFNULL(topicsettings.hidden,0) AS hidden, "
|
||||
+ "(topics.top_message - IFNULL(topicsettings.last_message,-1)) AS unread "
|
||||
+ "FROM topics LEFT JOIN topicsettings ON topics.topicid = topicsettings.topicid "
|
||||
+ "AND topicsettings.uid = ");
|
||||
sql.append(uid).append(" WHERE topics.topicid = ").append(topicid).append(';');
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("SQL: " + sql.toString());
|
||||
return stmt.executeQuery(sql.toString());
|
||||
@@ -134,8 +137,29 @@ class TopicUserContextImpl implements TopicContext
|
||||
|
||||
} // end if
|
||||
|
||||
private void refresh(Connection conn) throws SQLException
|
||||
{
|
||||
Statement stmt = conn.createStatement();
|
||||
|
||||
// perform a requery of the database
|
||||
ResultSet rs = queryByTopic(stmt,topicid,conf.realUID());
|
||||
if (rs.next())
|
||||
{ // update the fields that are capable of changing
|
||||
top_message = rs.getInt(4);
|
||||
frozen = rs.getBoolean(5);
|
||||
archived = rs.getBoolean(6);
|
||||
lastupdate = SQLUtil.getFullDateTime(rs,8);
|
||||
hidden = rs.getBoolean(10);
|
||||
unread = rs.getInt(11);
|
||||
|
||||
} // end if
|
||||
else // this topic must have been deleted - fsck it
|
||||
makeDeleted();
|
||||
|
||||
} // end refresh
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Implementatuions from interface TopicContext
|
||||
* Implementations from interface TopicContext
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@@ -148,22 +172,7 @@ class TopicUserContextImpl implements TopicContext
|
||||
try
|
||||
{ // get a database connection
|
||||
conn = datapool.getConnection();
|
||||
Statement stmt = conn.createStatement();
|
||||
|
||||
// perform a requery of the database
|
||||
ResultSet rs = queryByTopic(stmt,topicid,conf.realUID());
|
||||
if (rs.next())
|
||||
{ // update the fields that are capable of changing
|
||||
top_message = rs.getInt(4);
|
||||
frozen = rs.getBoolean(5);
|
||||
archived = rs.getBoolean(6);
|
||||
lastupdate = SQLUtil.getFullDateTime(rs,8);
|
||||
hidden = rs.getBoolean(10);
|
||||
unread = rs.getInt(11);
|
||||
|
||||
} // end if
|
||||
else // this topic must have been deleted - fsck it
|
||||
makeDeleted();
|
||||
refresh(conn);
|
||||
|
||||
} // end try
|
||||
catch (SQLException e)
|
||||
@@ -524,8 +533,8 @@ class TopicUserContextImpl implements TopicContext
|
||||
} // end try
|
||||
catch (SQLException e)
|
||||
{ // turn SQLException into data exception
|
||||
logger.error("DB error setting topic data: " + e.getMessage(),e);
|
||||
throw new DataException("unable to set topic hidden status: " + e.getMessage(),e);
|
||||
logger.error("DB error setting topic user data: " + e.getMessage(),e);
|
||||
throw new DataException("unable to set unread messages: " + e.getMessage(),e);
|
||||
|
||||
} // end catch
|
||||
finally
|
||||
@@ -543,6 +552,213 @@ class TopicUserContextImpl implements TopicContext
|
||||
|
||||
} // end fixSeen
|
||||
|
||||
public List getMessages(int low, int high) throws DataException, AccessError
|
||||
{
|
||||
if (!(conf.userCanRead()))
|
||||
{ // they can't read messages in this topic!
|
||||
logger.error("trying to read postings w/o permission!");
|
||||
throw new AccessError("You do not have permission to read messages in this conference.");
|
||||
|
||||
} // end if
|
||||
|
||||
// reorder parameters so they come in the correct order!
|
||||
if (low<=high)
|
||||
return TopicMessageUserContextImpl.loadMessageRange(engine,conf,datapool,topicid,low,high);
|
||||
else
|
||||
return TopicMessageUserContextImpl.loadMessageRange(engine,conf,datapool,topicid,high,low);
|
||||
|
||||
} // end getMessages
|
||||
|
||||
public TopicMessageContext postNewMessage(long parent, String pseud, String text)
|
||||
throws DataException, AccessError
|
||||
{
|
||||
if (!(conf.userCanPost()))
|
||||
{ // they can't post in this topic!
|
||||
logger.error("trying to post w/o permission!");
|
||||
throw new AccessError("You do not have permission to post messages in this conference.");
|
||||
|
||||
} // end if
|
||||
|
||||
if (deleted)
|
||||
{ // the topic has been deleted
|
||||
logger.error("can't post to a deleted topic!");
|
||||
throw new AccessError("You cannot post to a topic that has been deleted.");
|
||||
|
||||
} // end if
|
||||
|
||||
if (frozen && !(conf.userCanHide()))
|
||||
{ // can't post to a frozen topic!
|
||||
logger.error("can't post to a frozen topic!");
|
||||
throw new AccessError("The topic is frozen, and you do not have permission to post to it.");
|
||||
|
||||
} // end if
|
||||
|
||||
if (archived && !(conf.userCanHide()))
|
||||
{ // can't post to a frozen topic!
|
||||
logger.error("can't post to an archived topic!");
|
||||
throw new AccessError("The topic is archived, and you do not have permission to post to it.");
|
||||
|
||||
} // end if
|
||||
|
||||
// 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);
|
||||
try
|
||||
{ // run both arguments through the HTML checker
|
||||
pseud_ch.append(pseud);
|
||||
pseud_ch.finish();
|
||||
text_ch.append(text);
|
||||
text_ch.finish();
|
||||
|
||||
} // end try
|
||||
catch (AlreadyFinishedException e)
|
||||
{ // this isn't right...
|
||||
throw new InternalStateError("HTMLChecker erroneously throwing AlreadyFinishedException",e);
|
||||
|
||||
} // end catch
|
||||
|
||||
String real_pseud, real_text;
|
||||
int text_linecount;
|
||||
try
|
||||
{ // retrieve the processed values
|
||||
real_pseud = pseud_ch.getValue();
|
||||
real_text = text_ch.getValue();
|
||||
text_linecount = text_ch.getLines();
|
||||
|
||||
} // end try
|
||||
catch (NotYetFinishedException e)
|
||||
{ // this isn't right either!
|
||||
throw new InternalStateError("HTMLChecker erroneously throwing NotYetFinishedException",e);
|
||||
|
||||
} // end catch
|
||||
|
||||
int new_post_num;
|
||||
long new_post_id;
|
||||
java.util.Date posted_date;
|
||||
Connection conn = null;
|
||||
AuditRecord ar = null;
|
||||
|
||||
try
|
||||
{ // get a database connection
|
||||
conn = datapool.getConnection();
|
||||
Statement stmt = conn.createStatement();
|
||||
|
||||
// slap a lock on all the tables we need to touch
|
||||
stmt.executeUpdate("LOCK TABLES confs WRITE, topics WRITE, posts WRITE, postdata WRITE, "
|
||||
+ "confsettings WRITE, topicsettings READ;");
|
||||
|
||||
try
|
||||
{ // refresh our current status and recheck allowed status
|
||||
refresh(conn);
|
||||
if (deleted)
|
||||
{ // the topic has been deleted
|
||||
logger.error("can't post to a deleted topic!");
|
||||
throw new AccessError("You cannot post to a topic that has been deleted.");
|
||||
|
||||
} // end if
|
||||
|
||||
if (frozen && !(conf.userCanHide()))
|
||||
{ // can't post to a frozen topic!
|
||||
logger.error("can't post to a frozen topic!");
|
||||
throw new AccessError("The topic is frozen, and you do not have permission to post to it.");
|
||||
|
||||
} // end if
|
||||
|
||||
if (archived && !(conf.userCanHide()))
|
||||
{ // can't post to a frozen topic!
|
||||
logger.error("can't post to an archived topic!");
|
||||
throw new AccessError("The topic is archived, and you do not have permission to post to it.");
|
||||
|
||||
} // end if
|
||||
|
||||
// Determine what the new post number is.
|
||||
new_post_num = top_message + 1;
|
||||
|
||||
// Add the post "header" to the posts table.
|
||||
StringBuffer sql = new StringBuffer("INSERT INTO posts (parent, topicid, num, linecount, creator_uid, "
|
||||
+ "posted, pseud) VALUES (");
|
||||
sql.append(parent).append(", ").append(topicid).append(", ").append(new_post_num).append(", ");
|
||||
sql.append(text_linecount).append(", ").append(conf.realUID()).append(", '");
|
||||
posted_date = new java.util.Date();
|
||||
sql.append(SQLUtil.encodeDate(posted_date)).append("', '").append(real_pseud).append("');");
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("SQL: " + sql.toString());
|
||||
stmt.executeUpdate(sql.toString());
|
||||
|
||||
// Retrieve the new post ID.
|
||||
ResultSet rs = stmt.executeQuery("SELECT LAST_INSERT_ID();");
|
||||
if (!(rs.next()))
|
||||
throw new InternalStateError("postMessage(): Unable to get new post ID!");
|
||||
new_post_id = rs.getLong(1);
|
||||
|
||||
// Touch the topic values to reflect the added post.
|
||||
sql.setLength(0);
|
||||
sql.append("UPDATE topics SET top_message = ").append(new_post_num).append(", lastupdate = '");
|
||||
sql.append(SQLUtil.encodeDate(posted_date)).append("' WHERE topicid = ").append(topicid).append(';');
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("SQL: " + sql.toString());
|
||||
stmt.executeUpdate(sql.toString());
|
||||
|
||||
// insert the post data
|
||||
sql.setLength(0);
|
||||
sql.append("INSERT INTO postdata (postid, data) VALUES (").append(new_post_id).append(", '");
|
||||
sql.append(real_text).append("');");
|
||||
stmt.executeUpdate(sql.toString());
|
||||
|
||||
// mark that we posted to the conference
|
||||
conf.touchUpdate(conn,posted_date);
|
||||
conf.touchPost(conn,posted_date);
|
||||
|
||||
// fill in our own local variables to reflect the update
|
||||
top_message = new_post_num;
|
||||
lastupdate = posted_date;
|
||||
|
||||
} // end try
|
||||
finally
|
||||
{ // make sure we unlock the tables when 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.POST_MESSAGE,conf.realUID(),conf.userRemoteAddress(),
|
||||
conf.realSIGID(),"conf=" + String.valueOf(conf.realConfID()) + ",topic="
|
||||
+ String.valueOf(topicid) + ",post=" + String.valueOf(new_post_id),
|
||||
"pseud=" + real_pseud);
|
||||
|
||||
} // end try
|
||||
catch (SQLException e)
|
||||
{ // turn SQLException into data exception
|
||||
logger.error("DB error posting message: " + e.getMessage(),e);
|
||||
throw new DataException("unable to post message: " + 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
|
||||
|
||||
// return the new message context
|
||||
return new TopicMessageUserContextImpl(engine,conf,datapool,new_post_id,parent,new_post_num,
|
||||
text_linecount,conf.realUID(),posted_date,real_pseud);
|
||||
|
||||
} // end postMessage
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* External operations usable only from within the package
|
||||
*--------------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user