📄 workgroupmanager.java
字号:
/**
* $RCSfile$
* $Revision$
* $Date: 2006-08-07 21:12:21 -0700 (Mon, 07 Aug 2006) $
*
* Copyright (C) 2004-2008 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution, or a commercial license
* agreement with Jive.
*/
package org.jivesoftware.xmpp.workgroup;
import org.jivesoftware.openfire.fastpath.util.TaskEngine;
import org.jivesoftware.openfire.fastpath.commands.CreateWorkgroup;
import org.jivesoftware.openfire.fastpath.commands.DeleteWorkgroup;
import org.jivesoftware.openfire.fastpath.events.EmailTranscriptEvent;
import org.jivesoftware.openfire.fastpath.settings.chat.ChatSettingsManager;
import org.jivesoftware.openfire.fastpath.util.WorkgroupUtils;
import org.jivesoftware.xmpp.workgroup.disco.IQDiscoInfoHandler;
import org.jivesoftware.xmpp.workgroup.disco.IQDiscoItemsHandler;
import org.jivesoftware.xmpp.workgroup.event.WorkgroupEventDispatcher;
import org.jivesoftware.xmpp.workgroup.routing.RoutingManager;
import org.jivesoftware.xmpp.workgroup.search.ChatSearchManager;
import org.jivesoftware.xmpp.workgroup.search.IQChatSearchHandler;
import org.jivesoftware.xmpp.workgroup.utils.FastpathConstants;
import org.dom4j.Element;
import org.jivesoftware.database.DbConnectionManager;
import org.jivesoftware.database.SequenceManager;
import org.jivesoftware.openfire.PresenceManager;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.commands.AdHocCommandManager;
import org.jivesoftware.openfire.event.GroupEventDispatcher;
import org.jivesoftware.openfire.event.GroupEventListener;
import org.jivesoftware.openfire.group.Group;
import org.jivesoftware.openfire.net.SASLAuthentication;
import org.jivesoftware.openfire.user.UserManager;
import org.jivesoftware.openfire.user.UserNotFoundException;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.StringUtils;
import org.xmpp.component.Component;
import org.xmpp.component.ComponentException;
import org.xmpp.component.ComponentManager;
import org.xmpp.component.ComponentManagerFactory;
import org.xmpp.packet.*;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* Manages workgroups in the system. This manager primarily defers to the workgroups
* to manage themselves and serves as a 'factory' for creating, obtaining and deleting them.
*
* @author Derek DeMoro
*/
public class WorkgroupManager implements Component {
private static final String LOAD_WORKGROUPS =
"SELECT workgroupID FROM fpWorkgroup";
private static final String ADD_WORKGROUP =
"INSERT INTO fpWorkgroup (workgroupID, jid, displayName, description, status, " +
"creationDate, modificationDate, maxchats, minchats, offerTimeout, requestTimeout, " +
"modes) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)";
private static final String DELETE_WORKGROUP =
"DELETE FROM fpWorkgroup WHERE workgroupID=?";
private static WorkgroupManager instance = new WorkgroupManager();
private EmailTranscriptEvent emailTranscriptEvent;
/**
* Returns a workgroup manager instance (singleton).
*
* @return a workgroup manager instance.
*/
public synchronized static WorkgroupManager getInstance() {
if (instance == null) {
instance = new WorkgroupManager();
}
return instance;
}
/**
* Track all Workgroups
*/
private Map<String, Workgroup> workgroups = new ConcurrentHashMap<String, Workgroup>();
/**
* Tracks the last known workgroup open status
*/
private Map<Long, Workgroup.Status> workgroupOpenStatus = new HashMap<Long, Workgroup.Status>();
private AgentManager agentManager;
public List iqHandlers = new LinkedList();
private int defaultMaxChats = 4; // default value, usually overridden by config file
private int defaultMinChats = 1;
private long defaultOfferTimeout = 20 * 1000; // 20 seconds
private long defaultRequestTimeout = 4 * 60 * 1000; // 4 minutes
/**
* <p>Simple flag to track whether the workgroups have been loaded or not.</p>
*/
private boolean loaded = false;
private ReentrantReadWriteLock workgroupLock = new ReentrantReadWriteLock();
private JID serviceAddress = null;
private String mucServiceName;
/**
* Holds the object responsible for handling disco#info packets to this manager.
*/
private IQDiscoInfoHandler iqDiscoInfoHandler;
/**
* Holds the object responsible for handling disco#items packets to this manager.
*/
private IQDiscoItemsHandler iqDiscoItemsHandler;
/**
* Holds the object responsible for handling transcript searches for this manager.
*/
private IQChatSearchHandler iqChatSearchHandler = new IQChatSearchHandler(this);
/**
* Manager that keeps the list of ad-hoc commands and processing command requests.
*/
private AdHocCommandManager commandManager;
private GroupEventListener groupEventListener;
private TimerTask presenceCheckTask;
/**
* Creates a workgroup manager implementation.
*/
public WorkgroupManager() {
// Load Chat Properties
String minChats = JiveGlobals.getProperty("xmpp.live.defaults.minchats");
String maxChats = JiveGlobals.getProperty("xmpp.live.defaults.maxchats");
if (minChats != null && minChats.trim().length() > 0) {
defaultMinChats = Integer.parseInt(minChats);
}
if (maxChats != null && maxChats.trim().length() > 0) {
defaultMaxChats = Integer.parseInt(maxChats);
}
String offerTimeout = JiveGlobals.getProperty("xmpp.live.defaults.offerTimeout");
String requestTimeout = JiveGlobals.getProperty("xmpp.live.defaults.requestTimeout");
if (offerTimeout != null && offerTimeout.trim().length() > 0) {
defaultOfferTimeout = Integer.parseInt(offerTimeout);
}
if (requestTimeout != null && requestTimeout.trim().length() > 0) {
defaultRequestTimeout = Integer.parseInt(requestTimeout);
}
// Initialize chat settings manager. TODO This will be moved over to an extension file.
ChatSettingsManager.getInstance();
// Initialize EmailTranscript Event. TODO This will be moved over to an extension file.
emailTranscriptEvent = new EmailTranscriptEvent();
addGroupManagerListener();
// Create responsible for handling ad-hoc commands in this service
commandManager = new AdHocCommandManager();
iqDiscoInfoHandler = new IQDiscoInfoHandler(this, commandManager);
iqDiscoItemsHandler = new IQDiscoItemsHandler(this, commandManager);
presenceCheckTask = new TimerTask() {
public void run() {
handleOutdatePresence();
}
};
TaskEngine.getInstance().scheduleAtFixedRate(presenceCheckTask, 5000, 5000);
}
public void start() {
// Enable the shared secret SASL mechanism, which the Fastpath web client will use.
// We use a custom SASL mechanism so that web-based customer chats can login without
// a username or password. However, a shared secret key is still required so that
// anonymous login doesn't have to be enabled for the whole server.
if (!SASLAuthentication.isSharedSecretAllowed()) {
SASLAuthentication.setSharedSecretAllowed(true);
}
// If the database was just created then create the "demo" user and "demo" workgroup
// Workgroup creation requires MUC service address so we need to run this code after the
// disco stuff
if (!JiveGlobals.getBooleanProperty("fastpath.database.setup")) {
boolean createUser = createDemoUser();
if (createUser) {
createDemoWorkgroup();
}
JiveGlobals.setProperty("fastpath.database.setup", "true");
}
// Register ad-hoc commands
commandManager.addCommand(new CreateWorkgroup());
commandManager.addCommand(new DeleteWorkgroup());
}
public void shutdown() {
workgroups.clear();
GroupEventDispatcher.removeListener(groupEventListener);
instance = null;
ChatSearchManager.shutdown();
ChatSettingsManager.shutdown();
RoutingManager.shutdown();
WorkgroupProviderManager.shutdown();
emailTranscriptEvent.shutdown();
workgroupComparator = null;
TaskEngine.getInstance().cancelScheduledTask(presenceCheckTask);
}
public void stop() {
for (Workgroup workgroup : getWorkgroups()) {
workgroup.shutdown();
}
workgroups.clear();
workgroupOpenStatus.clear();
}
public AgentManager getAgentManager() {
return agentManager;
}
public int getDefaultMinChats() {
return defaultMinChats;
}
public void setDefaultMinChats(int minChats) {
if (minChats >= 0) {
defaultMinChats = minChats;
JiveGlobals.setProperty("xmpp.live.defaults.minchats", Integer.toString(minChats));
}
}
public int getDefaultMaxChats() {
return defaultMaxChats;
}
public void setDefaultMaxChats(int maxChats) {
if (maxChats >= 0) {
defaultMaxChats = maxChats;
JiveGlobals.setProperty("xmpp.live.defaults.maxchats", Integer.toString(maxChats));
}
}
public long getDefaultOfferTimeout() {
return defaultOfferTimeout;
}
public void setDefaultOfferTimeout(long defaultOfferTimeout) {
if (defaultOfferTimeout >= 0) {
this.defaultOfferTimeout = defaultOfferTimeout;
JiveGlobals.setProperty("xmpp.live.defaults.offerTimeout",
Long.toString(defaultOfferTimeout));
}
}
public long getDefaultRequestTimeout() {
return defaultRequestTimeout;
}
public void setDefaultRequestTimeout(long defaultRequestTimeout) {
if (defaultRequestTimeout >= 0) {
this.defaultRequestTimeout = defaultRequestTimeout;
JiveGlobals.setProperty("xmpp.live.defaults.requestTimeout",
Long.toString(defaultRequestTimeout));
}
}
/**
* Creates a workgroup with default settings.
*
* @param name the name of the workgroup.
* @return the created workgroup
* @throws UnauthorizedException if not allowed to create the workgroup.
* @throws UserAlreadyExistsException If the address is already in use
*/
public Workgroup createWorkgroup(String name) throws UserAlreadyExistsException, UnauthorizedException {
if (workgroups.containsKey(name + "@" + serviceAddress.toBareJID())) {
throw new UserAlreadyExistsException(name);
}
// Reserve the username - user ID from the jiveUserID table
long id = -1;
Workgroup workgroup = null;
try {
id = SequenceManager.nextID(FastpathConstants.WORKGROUP);
boolean workgroupAdded = addWorkgroup(id, name);
if (workgroupAdded) {
workgroupLock.writeLock().lock();
try {
workgroup = new Workgroup(id, agentManager);
workgroups.put(workgroup.getJID().toBareJID(), workgroup);
workgroupOpenStatus.put(workgroup.getID(), workgroup.getStatus());
}
finally {
workgroupLock.writeLock().unlock();
}
// Create a chat room for this workgroup
workgroup.createGroupChatRoom();
// Trigger the event that a workgroup has been created
WorkgroupEventDispatcher.workgroupCreated(workgroup);
}
else {
throw new UnauthorizedException("Could not insert workgroup in database");
}
}
catch (Exception e) {
ComponentManagerFactory.getComponentManager().getLog().error(e);
if (id != -1) {
try {
if (workgroup != null) {
workgroups.remove(workgroup.getJID().toBareJID());
workgroupOpenStatus.remove(workgroup.getID());
deleteWorkgroup(id);
}
}
catch (Exception e1) {
ComponentManagerFactory.getComponentManager().getLog().error(e1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -