📄 dbforummessage.java
字号:
/**
* $RCSfile: DbForumMessage.java,v $
* $Revision: 1.1.1.1 $
* $Date: 2002/09/09 13:50:54 $
*
* New Jive from Jdon.com.
*
* This software is the proprietary information of CoolServlets, Inc.
* Use is subject to license terms.
*/
package com.jivesoftware.forum.database;
import java.sql.*;
import java.util.*;
import java.io.*;
import java.text.SimpleDateFormat;
import com.jivesoftware.forum.*;
import com.jivesoftware.util.Cacheable;
import com.jivesoftware.util.CacheSizes;
import com.jivesoftware.util.StringUtils;
/**
* Database implementation of the ForumMessage interface. It stores messages
* in the jiveMessage database table, and message properties in JiveMessageProp
* table.<p>
*
* Messages are not inserted into the database until they are added
* to a thread. Therefore, it is best to set all properties of the message
* before adding it to a thread in order to avoid extra database operations.<p>
*
* One key feature of the Jive message architecture is the ability to apply
* dynamic filters to messages (specified at the global and forum level).
* However, computing the filtered value of a message can be fairly expensive.
* Therefore,
*/
public final class DbForumMessage implements ForumMessage, Cacheable {
/** DATABASE QUERIES **/
private static final String LOAD_PROPERTIES =
"SELECT name, propValue FROM jiveMessageProp WHERE messageID=?";
private static final String INSERT_PROPERTY =
"INSERT INTO jiveMessageProp(messageID,name,propValue) VALUES(?,?,?)";
private static final String DELETE_PROPERTY =
"DELETE FROM jiveMessageProp WHERE messageID=? AND name=?";
private static final String DELETE_PROPERTIES =
"DELETE FROM jiveMessageProp WHERE messageID=?";
private static final String LOAD_MESSAGE =
"SELECT threadID, forumID, userID, subject, body, modValue, rewardPoints, "+
"creationDate, modifiedDate FROM jiveMessage WHERE messageID=?";
private static final String INSERT_MESSAGE =
"INSERT INTO jiveMessage(messageID, parentMessageID, threadID, forumID, " +
"userID, subject, body, modValue, rewardPoints, creationDate, modifiedDate) " +
"VALUES(?,?,?,?,?,?,?,?,?,?,?)";
private static final String SAVE_MESSAGE =
"UPDATE jiveMessage SET userID=?, subject=?, body=?, modValue=?, " +
"rewardPoints=?, creationDate=?, modifiedDate=? WHERE messageID=?";
private static final String INSERT_MODERATION_ENTRY =
"INSERT INTO jiveModeration(objectID, objectType, userID, modDate, " +
"modValue) VALUES(?,?,?,?,?)";
/**
* Controls whether extended properties should be lazily loaded (not loaded
* until requested). If the properties are infrequently used, this provides
* a great speedup in initial object loading time. However, if your
* application does use extended properties all the time, you may wish to
* turn lazy loading off, as it's actually faster in total db lookup time
* to load everything at once.
*
* NOTE: lazy loading turned off by default for now since new filter
* caching code always calls properties. This may be optimized in the
* future so that lazy property loading makes sense again.
*/
private static final boolean LAZY_PROP_LOADING = false;
private long id = -1;
private java.util.Date creationDate;
private java.util.Date modifiedDate;
private String subject = "";
private String body = "";
private long userID;
// Default the moderation point value to Integer.MIN_VALUE. Then, if the
// moderation value gets changed before being inserted into the db, we'll know.
private int moderationValue = Integer.MIN_VALUE;
private int rewardPoints = 0;
private Map properties = null;
// Variables to hold filtered values.
protected String filteredSubject = null;
protected String filteredBody = null;
protected Map filteredProperties = null;
private DbForumFactory factory;
protected long threadID = -1;
protected long forumID = -1;
/**
* Indicates if the object is ready to be saved or not. An object is not
* ready to be saved if it has just been created and has not yet been added
* to its container. For example, a message added to a thread, etc.
*/
private boolean isReadyToSave = false;
/**
* Creates a new DbForumMessage object. If the User object is null, we'll
* assume that the message has an anonymous author.
*/
protected DbForumMessage(User user, DbForumFactory factory) {
this.factory = factory;
if (user != null) {
this.userID = user.getID();
}
else {
this.userID = -1;
}
this.id = SequenceManager.nextID(JiveGlobals.MESSAGE);
long now = System.currentTimeMillis();
creationDate = new java.util.Date(now);
modifiedDate = new java.util.Date(now);
properties = new Hashtable();
}
/**
* Loads the specified DbForumMessage by its message id.
*/
protected DbForumMessage(long id, DbForumFactory factory)
throws ForumMessageNotFoundException
{
this.id = id;
this.factory = factory;
loadFromDb();
isReadyToSave = true;
}
//FROM THE FORUMMESSAGE INTERFACE//
public long getID() {
return id;
}
public java.util.Date getCreationDate() {
return creationDate;
}
public void setCreationDate(java.util.Date creationDate)
throws UnauthorizedException
{
this.creationDate = creationDate;
// Only save to the db if the object is read
if (!isReadyToSave) {
return;
}
saveToDb();
// Remove message from cache
factory.cacheManager.messageCache.remove(this.id);
}
public java.util.Date getModifiedDate() {
return modifiedDate;
}
public void setModifiedDate(java.util.Date modifiedDate)
throws UnauthorizedException
{
this.modifiedDate = modifiedDate;
// Only save to the db if the object is read
if (!isReadyToSave) {
return;
}
saveToDb();
// Remove message from cache
factory.cacheManager.messageCache.remove(this.id);
}
public String getSubject() {
// Return cached filter value if it exists.
if (filteredSubject != null) {
return filteredSubject;
}
// Otherwise, return normal value.
else {
return subject;
}
}
public String getUnfilteredSubject() {
return subject;
}
public void setSubject(String subject) throws UnauthorizedException {
this.subject = subject;
// Only save to the db if the object is read
if (!isReadyToSave) {
return;
}
// Update modifiedDate to the current time.
modifiedDate.setTime(System.currentTimeMillis());
saveToDb();
// Remove message from cache
factory.cacheManager.messageCache.remove(this.id);
}
public String getBody() {
// Return cached filter value if it exists.
if (filteredBody != null) {
return filteredBody;
}
// Otherwise, return normal value.
else {
return body;
}
}
public String getUnfilteredBody() {
return body;
}
public void setBody(String body) throws UnauthorizedException {
this.body = body;
// Only save to the db if the object is read
if (!isReadyToSave) {
return;
}
// Update modifiedDate to the current time.
modifiedDate.setTime(System.currentTimeMillis());
saveToDb();
// Remove message from cache
factory.cacheManager.messageCache.remove(this.id);
}
public User getUser() {
if (userID == -1) {
return null;
}
User user = null;
try {
user = factory.getUserManager().getUser(userID);
}
catch (UserNotFoundException unfe) {
unfe.printStackTrace();
}
return user;
}
public int getModerationValue() {
return moderationValue;
}
public void setModerationValue(int value, Authorization auth) {
// If the new value is the same as the old value, return.
if (moderationValue == value) {
return;
}
int oldValue = moderationValue;
moderationValue = value;
// Only save to the db if the object is ready
if (!isReadyToSave) {
return;
}
saveToDb();
long now = System.currentTimeMillis();
// We modified the moderation value of the message, so update the
// modified date.
this.modifiedDate.setTime(now);
// If the message is switching from hidden to visible, we should update
// the modified date of the thread and forum it belongs to. We'll also
// trigger a watch update and send out the message to gateways. These
// last actions have the potential for problems since it's possible that
// a message could switch from being below the moderation threshold to
// above multiple times. However, it's probably ok to let there be
// be multiple watch updates, and the gateway implementations should
// ensure that no message gets exported twice.
try {
DbForum dbForum = factory.cacheManager.forumCache.get(this.forumID);
if (oldValue < dbForum.getModerationMinMessageValue()
&& value >= dbForum.getModerationMinMessageValue())
{
ForumThread thread = dbForum.getThread(this.threadID);
thread.setModifiedDate(modifiedDate);
dbForum.setModifiedDate(modifiedDate);
// Notify the watch manager that the thread has been updated.
factory.watchManager.notifyWatches(thread);
// Notify the gateway manager that we're ready to be exported.
// dbForum.getGatewayManager().exportData(this);
}
}
catch (ForumNotFoundException fnfe) { /* ignore */ }
catch (ForumThreadNotFoundException ftnfe) { /* ignore */ }
catch (UnauthorizedException ue) { /* ignore */ }
// Remove message from cache
factory.cacheManager.messageCache.remove(this.id);
// Also remove thread from cache
factory.cacheManager.threadCache.remove(this.threadID);
// Finally, make an entry into the jiveModeration table for moderation
// auditing purposes.
Connection con = null;
PreparedStatement pstmt = null;
try {
con = ConnectionManager.getConnection();
pstmt = con.prepareStatement(INSERT_MODERATION_ENTRY);
pstmt.setLong(1, id);
pstmt.setInt(2, JiveGlobals.MESSAGE);
if (auth.isAnonymous()) {
pstmt.setNull(3, Types.NUMERIC);
}
else {
pstmt.setLong(3, auth.getUserID());
}
pstmt.setString(4, StringUtils.dateToMillis(modifiedDate));
pstmt.setInt(5, moderationValue);
pstmt.executeUpdate();
}
catch (Exception e) {
e.printStackTrace();
}
finally {
try { pstmt.close(); }
catch (Exception e) { e.printStackTrace(); }
try { con.close(); }
catch (Exception e) { e.printStackTrace(); }
}
}
public String getProperty(String name) {
if (LAZY_PROP_LOADING) {
if (properties == null && isReadyToSave) {
loadPropertiesFromDb();
}
}
// Return the cached filter value if it exists.
if (filteredProperties != null) {
return (String)filteredProperties.get(name);
}
// Otherwise, return normal value.
else {
return (String)properties.get(name);
}
}
public String getUnfilteredProperty(String name) {
if (LAZY_PROP_LOADING) {
if (properties == null && isReadyToSave) {
loadPropertiesFromDb();
}
}
return (String)properties.get(name);
}
public void setProperty(String name, String value) {
if (LAZY_PROP_LOADING) {
if (properties == null && isReadyToSave) {
loadPropertiesFromDb();
}
}
properties.put(name, value);
// Only save to the db if the object is read
if (!isReadyToSave) {
return;
}
// Open a database connection and start a transaction to save properties.
boolean abortTransaction = false;
Connection con = null;
try {
con = ConnectionManager.getTransactionConnection();
savePropertiesToDb(con, true);
}
catch( Exception e ) {
e.printStackTrace();
abortTransaction = true;
}
finally {
ConnectionManager.closeTransactionConnection(con, abortTransaction);
}
// Remove message from cache
factory.cacheManager.messageCache.remove(this.id);
}
public void deleteProperty(String name)
throws UnauthorizedException
{
if (LAZY_PROP_LOADING) {
if (properties == null && isReadyToSave) {
loadPropertiesFromDb();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -