📄 dbforumfactory.java
字号:
/**
* $RCSfile: DbForumFactory.java,v $
* $Revision: 1.1.1.1 $
* $Date: 2002/09/09 13:50:53 $
*
* New Jive from Jdon.com. Modified by Frank Chu
*
* This software is the proprietary information of CoolServlets, Inc.
* Use is subject to license terms.
*/
package com.airinbox.member.forum.database;
import com.airinbox.member.util.*;
import com.airinbox.member.forum.*;
import java.sql.*;
import java.io.*;
import java.util.*;
import java.lang.reflect.Constructor;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.component.ComponentException;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.context.ContextException;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.context.DefaultContext;
import org.apache.avalon.framework.configuration.*;
import com.airinbox.component.authorize.UnauthorizedException;
import com.airinbox.component.authorize.Authorization;
import com.airinbox.component.dbpool.PoolManager;
/**
* Database implementation of the ForumFactory interface.
*/
public class DbForumFactory extends ForumFactory {
/** DATABASE QUERIES **/
private static final String GET_FORUMS = "SELECT forumID FROM "+Globals.getConfig(Globals._TABLE_FORUM);
private static final String FORUM_COUNT = "SELECT count(1) FROM "+Globals.getConfig(Globals._TABLE_FORUM);
private static final String DELETE_FORUM = "DELETE FROM "+Globals.getConfig(Globals._TABLE_FORUM)+" WHERE forumID=?";
private static final String GET_FORUM_ID =
"SELECT forumID FROM "+Globals.getConfig(Globals._TABLE_FORUM)+" WHERE name=?";
private static final String DELETE_FORUM_PROPERTIES =
"DELETE FROM "+Globals.getConfig(Globals._TABLE_FORUM_PROP)+" WHERE forumID=?";
private static final String POPULAR_FORUMS =
"SELECT forumID, count(1) AS msgCount FROM "+Globals.getConfig(Globals._TABLE_MESSAGE)+" " +
"WHERE modifiedDate > ? GROUP BY forumID ORDER BY msgCount DESC";
private static final String POPULAR_THREADS =
"SELECT threadID, count(1) AS msgCount FROM "+Globals.getConfig(Globals._TABLE_MESSAGE)+" " +
"WHERE modifiedDate > ? GROUP BY threadID ORDER BY msgCount DESC";
private static final String MOVE_THREADS_TO_FORUM =
"UPDATE "+Globals.getConfig(Globals._TABLE_THREAD)+" SET forumID=? WHERE forumID=?";
private static final String MOVE_MESSAGES_TO_FORUM =
"UPDATE "+Globals.getConfig(Globals._TABLE_MESSAGE)+" SET forumID=? WHERE forumID=?";
/**
* The cache manager is the global entry point for all the various object
* caches in Jive.
*/
public DatabaseCacheManager cacheManager;
protected UserManager userManager;
protected DbGroupManager groupManager;
private DbSearchManager searchManager;
private DbFilterManager filterManager;
protected DbPermissionsManager permissionsManager;
protected DbWatchManager watchManager;
protected DbRewardManager rewardManager;
private PoolManager m_poolManager;
/**
* Store GatewayManager objects for each forum. We can't attach the objects
* to instances of DbForum since those objects go in and out of cache and
* GatewayManager objects must remain active over time. The only added
* complexity with storing the managers globally is that we must keep the
* map up to date as forums are created and deleted.
*/
protected LongHashMap gatewayManagers;
/**
* Keep a cache of user message counts. This greatly helps for skins that
* show the number of messages a user has posted next to each of their
* messages. Each userManager implementation is responsible for actually
* using this cache at its option.
*/
public LongCache userMessageCountCache = new LongCache(64*1024, 6*Globals.HOUR);
// Values for the popular forums/threads feature that can be overidden
// with Jive property settings. Defaults are specified.
private int popularForumsNumber = 4; // 10 forums
private int popularForumsWindow = 1; // 1 day
private int popularThreadsNumber = 4; // 10 threads
private int popularThreadsWindow = 1; // 1 day
protected int forumCount = -1;
protected long [] forums = null;
protected long [] popularForums = null;
protected long [] popularThreads = null;
/**
* Pass the Context to the component.
* This method is called after the Loggable.setLogger() (if present)
* method and before any other method.
*
* @param context the context
* @exception ContextException if context is invalid
*/
public void contextualize( Context context ) throws ContextException
{
if(initialized || disposed)
throw new ContextException("contextualize failed cause initialized or disposed");
m_context = new DefaultContext(context);
}
/**
* Pass the <code>ComponentManager</code> to the <code>composer</code>.
* The <code>Composable</code> implementation should use the specified
* <code>ComponentManager</code> to acquire the components it needs for
* execution.
*
* @param manager The <code>ComponentManager</code> which this
* <code>Composable</code> uses.
*/
public void compose( ComponentManager componentManager ) throws ComponentException
{
super.compose(componentManager);
m_poolManager = (PoolManager)componentManager.lookup(PoolManager.ROLE);
cacheManager = new DatabaseCacheManager(this);
groupManager = new DbGroupManager(this);
searchManager = new DbSearchManager();
filterManager = new DbFilterManager(-1, this);
permissionsManager = new DbPermissionsManager(-1, this);
watchManager = new DbWatchManager(this);
rewardManager = new DbRewardManager(this);
// Load up a UserManager implementation. If the correct Jive property
// is set, it will be a custom UserManager class.
String className = "com.airinbox.member.forum.database.DbUserManager";
try {
Class c = Class.forName(className);
// Attempt to instantiate the UserManager implementation with a
// DbForumFactory as a paramater.
Class [] params = new Class [] { this.getClass() };
Constructor constructor = c.getConstructor(params);
// Intantiate the gateway object. We assume that
userManager = (UserManager)constructor.newInstance(
new Object[] { this });
}
catch (Exception e) {
System.err.println("Exception creating UserManager!");
e.printStackTrace();
}
// Load custom popular threads/forums values if they exist.
try {
String number = Globals.getMemberProperty("popularForums.number");
if (number != null) {
popularForumsNumber = Integer.parseInt(number);
}
} catch (Exception e) { }
try {
String window = Globals.getMemberProperty("popularForums.timeWindow");
if (window != null) {
popularForumsWindow = Integer.parseInt(window);
}
} catch (Exception e) { }
try {
String number = Globals.getMemberProperty("popularThreads.number");
if (number != null) {
popularThreadsNumber = Integer.parseInt(number);
}
} catch (Exception e) { }
try {
String window = Globals.getMemberProperty("popularThreads.timeWindow");
if (window != null) {
popularThreadsWindow = Integer.parseInt(window);
}
} catch (Exception e) { }
}
/**
* Pass the <code>Configuration</code> to the <code>Configurable</code>
* class. This method must always be called after the constructor
* and before any other method.
*
* @param configuration the class configurations.
*/
public void configure(Configuration configuration) throws ConfigurationException
{
//从配置文件中获取信息
//DATABASE_CONFIG_FILE = configuration.getChild("forum-config").getValue("");
/*
File file = new File(path);
reconfigure(file);
SubFileWatchdog dog = new SubFileWatchdog();
dog.setDaemon(true);
dog.setName("Sub-File-Watchlog");
dog.addFile(file);
dog.start();
*/
}
public void reconfigure(File file) throws ConfigurationException
{
/*
DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
Configuration theconfig = null;
try
{
theconfig = builder.buildFromFile(file);
}
catch(Exception e)
{
throw new ConfigurationException("build file ["+file.getAbsolutePath()+"] failed cause:\n",e);
}
getLogger().debug("reconfigure .....");
Configuration[] cc = theconfig.getChild("global").getChildren();
for(int i=0; i<cc.length; i++)
{
forumConfig.put(cc[i].getName(),cc[i].getValue());
logger().debug("["+cc[i].getName()+"] ["+cc[i].getValue()+"]");
}
logger().debug("================================================================");
cc = theconfig.getChild("database").getChildren();
for(int i=0; i<cc.length; i++)
{
dbConfig.put(cc[i].getName(),cc[i].getValue());
logger().debug("["+cc[i].getName()+"] ["+cc[i].getValue()+"]");
}
getLogger().debug("reconfigure successfull.....");
*/
}
public class SubFileWatchdog extends com.airinbox.util.FileWatchdog
{
public void doOnChange(File file)
{
try{
reconfigure(file);
}catch(Exception e)
{
e.printStackTrace();
}
}
}
/**
* Initialialize the component. Initialization includes
* allocating any resources required throughout the
* components lifecycle.
*
* @exception Exception if an error occurs
*/
public void initialize() throws Exception
{
super.initialize();
factory = this;
}
//FROM THE FORUMFACTORY INTERFACE//
public Forum createForum(String name, String description)
throws UnauthorizedException, ForumAlreadyExistsException
{
Forum newForum = null;
try {
Forum existingForum = getForum(name);
// The forum already exists since now exception, so:
throw new ForumAlreadyExistsException();
}
catch (ForumNotFoundException fnfe) {
// The forum doesn't already exist so we can create a new one
newForum = new DbForum(name, description, this);
}
// Create a new GatewayManager for the forum.
// gatewayManagers.put(newForum.getID(), new GatewayManager(this, newForum));
// Now, delete the forum list since we created a new one.
this.forums = null;
this.forumCount = -1;
return newForum;
}
public ForumThread createThread(ForumMessage rootMessage)
throws UnauthorizedException
{
return new DbForumThread(rootMessage, this);
}
public ForumMessage createMessage() {
return new DbForumMessage(null, this);
}
public ForumMessage createMessage(User user) throws UnauthorizedException {
return new DbForumMessage(user, this);
}
public void deleteForum(Forum forum) throws UnauthorizedException {
// Delete all messages and threads in the forum. Disable the search
// component if it's on so that speed is reasonable. This means that
// the index should be rebuilt after deleting a forum, but this
// probably isn't unresonable.
boolean searchEnabled = searchManager.isSearchEnabled();
searchManager.setSearchEnabled(false);
ResultFilter ignoreModerationFilter = ResultFilter.createDefaultThreadFilter();
ignoreModerationFilter.setModerationRangeMin(Integer.MIN_VALUE);
Iterator threads = forum.threads(ignoreModerationFilter);
while (threads.hasNext()) {
ForumThread thread = (ForumThread)threads.next();
forum.deleteThread(thread);
}
// Restore searching to its previous state.
searchManager.setSearchEnabled(searchEnabled);
// Now, delete all filters associated with the forum. We delete in
// reverse order since filter indexes will change if we don't delete
// the last filter entry.
FilterManager filterManager = forum.getFilterManager();
int filterCount = filterManager.getFilterCount();
for (int i=filterCount-1; i>=0; i--) {
filterManager.removeFilter(i);
}
// Delete all gateways.
// forum.getGatewayManager().deleteContext();
//gatewayManagers.removeKey(forum.getID());
// Delete all permissions
PermissionsManager permManager = forum.getPermissionsManager();
permManager.removeAllUserPermissions();
permManager.removeAllGroupPermissions();
// Finally, delete the forum itself and all its properties.
boolean abortTransaction = false;
Connection con = null;
PreparedStatement pstmt = null;
try {
con = ConnectionManager.getTransactionConnection();
// Properties
pstmt = con.prepareStatement(DELETE_FORUM_PROPERTIES);
pstmt.setLong(1,forum.getID());
pstmt.execute();
pstmt.close();
pstmt = con.prepareStatement(DELETE_FORUM);
pstmt.setLong(1,forum.getID());
pstmt.execute();
}
catch( Exception sqle ) {
sqle.printStackTrace();
abortTransaction = true;
}
finally {
try { pstmt.close(); }
catch (Exception e) { e.printStackTrace(); }
ConnectionManager.closeTransactionConnection(con, abortTransaction);
}
// Remove from cache
cacheManager.forumCache.remove(forum.getID());
// Finally, delete the list of forums
this.forumCount = -1;
this.forums = null;
}
public void mergeForums(Forum forum1, Forum forum2)
throws UnauthorizedException
{
// First, remove all permissions to forum2 so that people no longer
// post in it or see it.
PermissionsManager permManager = forum2.getPermissionsManager();
permManager.removeAllUserPermissions();
permManager.removeAllGroupPermissions();
// Read all messageIDs of the thread into an array so that we can expire
// each of them later. This may be quite large for huge forums, but there
// isn't really a better way around this.
ResultFilter ignoreModerationFilter = ResultFilter.createDefaultMessageFilter();
ignoreModerationFilter.setModerationRangeMin(Integer.MIN_VALUE);
LongList messageIDList = new LongList();
Iterator iter = forum2.messages(ignoreModerationFilter);
while (iter.hasNext()) {
long messageID = ((ForumMessage)iter.next()).getID();
messageIDList.add(messageID);
}
// Perform db operations.
boolean abortTransaction = false;
Connection con = null;
PreparedStatement pstmt = null;
try {
con = ConnectionManager.getTransactionConnection();
// Move all threads to new forum
pstmt = con.prepareStatement(MOVE_THREADS_TO_FORUM);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -