📄 workgroupmanager.java
字号:
}
if (e instanceof UserAlreadyExistsException) {
throw (UserAlreadyExistsException)e;
}
else {
throw new UnauthorizedException();
}
}
return workgroup;
}
/**
* Remove a workgroup from the system.
*
* @param workgroup the workgroup to remove.
* @throws UnauthorizedException if not allowed to delete the workgroup.
*/
public void deleteWorkgroup(Workgroup workgroup) throws UnauthorizedException {
if (!loaded) {
throw new IllegalStateException("Workgroup Manager not loaded yet");
}
// Trigger the event that a workgroup is being deleted
WorkgroupEventDispatcher.workgroupDeleting(workgroup);
deleteWorkgroup(workgroup.getID());
// Notify the workgroup that it is being destroyed
workgroup.destroy();
workgroupLock.writeLock().lock();
try {
workgroups.remove(workgroup.getJID().toBareJID());
workgroupOpenStatus.remove(workgroup.getID());
}
finally {
workgroupLock.writeLock().unlock();
}
// Delete the queues of the workgroup
for (RequestQueue requestQueue : workgroup.getRequestQueues()) {
workgroup.deleteRequestQueue(requestQueue);
}
// Trigger the event that a workgroup has been deleted
WorkgroupEventDispatcher.workgroupDeleted(workgroup);
}
/**
* Returns the number of workgroups in the system.
*
* @return the number of workgroups in the system.
*/
public int getWorkgroupCount() {
return workgroups.size();
}
/**
* Returns the workgroup mapped to a specific JID.
*
* @param jid the JID mapped to the workgroup.
* @return the workgroup with the specified JID.
* @throws UserNotFoundException if the workgroup could not be loaded.
*/
public Workgroup getWorkgroup(JID jid) throws UserNotFoundException {
Workgroup wg = workgroups.get(jid.toBareJID());
if (wg == null) {
throw new UserNotFoundException(jid.toBareJID());
}
return wg;
}
/**
* Return a workgroup based on it's node.
*
* @param workgroupName the name of the workgroup.
* @return the workgroup or null if no workgroup is found.
*/
public Workgroup getWorkgroup(String workgroupName) {
for (Workgroup workgroup : getWorkgroups()) {
if (workgroup.getJID().getNode().equalsIgnoreCase(workgroupName)) {
return workgroup;
}
}
return null;
}
/**
* Returns all workgroups within the system sorted by ID.
*
* @return the collection of workgroups.
*/
public Collection<Workgroup> getWorkgroups() {
if (workgroups.isEmpty()) {
return Collections.emptyList();
}
final List<Workgroup> copy = new ArrayList<Workgroup>(workgroups.values());
Collections.sort(copy, workgroupComparator);
return Collections.unmodifiableCollection(copy);
}
public Iterator getWorkgroups(WorkgroupResultFilter filter) {
final List<Workgroup> wgroups = new ArrayList<Workgroup>(workgroups.values());
Collections.sort(wgroups, workgroupComparator);
Iterator groups = filter.filter(wgroups.iterator());
if (groups == null) {
groups = Collections.EMPTY_LIST.iterator();
}
return groups;
}
/**
* Returns the handler for disco#info packets sent to the workgroup service. The returned
* handler may be used for configuring its features providers.
*
* @return the handler for disco#info packets sent to the workgroup service.
*/
public IQDiscoInfoHandler getIqDiscoInfoHandler() {
return iqDiscoInfoHandler;
}
/**
* <p>Trigger an open check every 25 seconds after an initial 45 second delay.</p>
* <p/>
* <p>The workgroup knows when it is open according to it's own settings including
* schedule information. However, the schedule is only checked on demand when new
* users requests are submitted, or agents query the status of the workgroup.
* So we must force a check of the workgroup open status periodically to see
* if it has changed, and if so, to have the workgroup broadcast its presence.
* This is potentially more bandwidth intensive than having each workgroup watch
* it's own schedule but uses less threads.</p>
* TODO: trace down all events that cause a state change so we don't have to poll
*/
private void startTimer() {
TaskEngine taskEngine = TaskEngine.getInstance();
taskEngine.schedule(new TimerTask() {
public void run() {
workgroupLock.readLock().lock();
try {
for (Workgroup group : workgroups.values()) {
Workgroup.Status currentOpen = group.getStatus();
Workgroup.Status oldOpen = workgroupOpenStatus.get(group.getID());
if (oldOpen != currentOpen) {
group.broadcastQueuesStatus();
workgroupOpenStatus.put(group.getID(), currentOpen);
if (Workgroup.Status.OPEN != oldOpen && Workgroup.Status.OPEN == currentOpen) {
// Trigger the event that the workgroup has been opened
group.notifyOpened();
}
else if (Workgroup.Status.OPEN == oldOpen) {
// Trigger the event that the workgroup has been closed
group.notifyClosed();
}
}
}
}
finally {
workgroupLock.readLock().unlock();
}
}
}, 45000, 9000);
// Every 5 minutes let the workgroups clean up dead requests or dead rooms. This may occur
// if the connections were lost or the invitations were lost or whatever
taskEngine.schedule(new TimerTask() {
public void run() {
workgroupLock.readLock().lock();
try {
for (Workgroup group : workgroups.values()) {
group.cleanup();
}
}
finally {
workgroupLock.readLock().unlock();
}
}
}, 60000, 300000);
// Every 15 seconds check for not answered room invitations
taskEngine.schedule(new TimerTask() {
public void run() {
workgroupLock.readLock().lock();
try {
for (Workgroup group : workgroups.values()) {
group.checkRequests();
}
}
finally {
workgroupLock.readLock().unlock();
}
}
}, 10000, 15000);
// Every 30 seconds check if the search index of the workgroups should be updated
taskEngine.schedule(new TimerTask() {
public void run() {
workgroupLock.readLock().lock();
try {
for (Workgroup group : workgroups.values()) {
try {
ChatSearchManager.getInstanceFor(group).updateIndex(false);
}
catch (IOException e) {
ComponentManagerFactory.getComponentManager().getLog().error(e);
}
}
}
finally {
workgroupLock.readLock().unlock();
}
}
}, 10000, 30000);
}
void updateWorkgroupStatus(Workgroup workgroup) {
Workgroup.Status newStatus = workgroup.getStatus();
Workgroup.Status oldStatus = workgroupOpenStatus.put(workgroup.getID(), newStatus);
if (Workgroup.Status.OPEN != oldStatus && Workgroup.Status.OPEN == newStatus) {
// Trigger the event that the workgroup has been opened
workgroup.notifyOpened();
}
else if (Workgroup.Status.OPEN == oldStatus && Workgroup.Status.OPEN != newStatus) {
// Trigger the event that the workgroup has been closed
workgroup.notifyClosed();
}
}
public String getDefaultChatServer() {
return getMUCServiceName();
}
private boolean addWorkgroup(long workgroupID, String workgroupName) {
Connection con = null;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(ADD_WORKGROUP);
Date now = new Date();
pstmt.setLong(1, workgroupID);
pstmt.setString(2, workgroupName);
pstmt.setString(3, workgroupName);
pstmt.setString(4, "None");
pstmt.setInt(5, 0); // start workgroups closed
pstmt.setString(6, StringUtils.dateToMillis(now));
pstmt.setString(7, StringUtils.dateToMillis(now));
pstmt.setInt(8, -1);
pstmt.setInt(9, -1);
pstmt.setLong(10, -1);
pstmt.setLong(11, -1);
pstmt.setInt(12, 0); // start schedule mode to manual
pstmt.executeUpdate();
return true;
}
catch (SQLException ex) {
ComponentManagerFactory.getComponentManager().getLog().error(ex);
}
finally {
DbConnectionManager.closeConnection(pstmt, con);
}
return false;
}
private void deleteWorkgroup(long workgroupID) {
Connection con = null;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(DELETE_WORKGROUP);
pstmt.setLong(1, workgroupID);
pstmt.executeUpdate();
}
catch (SQLException ex) {
ComponentManagerFactory.getComponentManager().getLog().error(ex);
}
finally {
DbConnectionManager.closeConnection(pstmt, con);
}
}
private void loadWorkgroups() {
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(LOAD_WORKGROUPS);
rs = pstmt.executeQuery();
workgroupLock.writeLock().lock();
while (rs.next()) {
Workgroup workgroup = new Workgroup(rs.getLong(1),
agentManager);
workgroups.put(workgroup.getJID().toBareJID(), workgroup);
workgroupOpenStatus.put(workgroup.getID(), workgroup.getStatus());
}
}
catch (SQLException ex) {
ComponentManagerFactory.getComponentManager().getLog().error(ex);
}
finally {
workgroupLock.writeLock().unlock();
DbConnectionManager.closeConnection(rs, pstmt, con);
}
// Initialize routing manager
RoutingManager.getInstance();
}
public void processPacket(Packet packet) {
try {
// Check if the packet is a disco request
if (packet instanceof IQ) {
if (process((IQ)packet)) {
return;
}
}
// Check if the packet was sent to an existent workgroup. If a workgroup
// was found then let the workgroup process the packet
try {
Workgroup workgroup = getWorkgroup(packet.getTo());
workgroup.process(packet);
}
catch (UserNotFoundException e) {
// Answer a not_authorized error since the workgroup was not found. A
// not_acceptable error was chosen since we are returning that same error when
// sending presences to a workgroup from a JID that is not an agent or when the
// agent does not belong to the workgroup. Answering the same error code ensures
// some kind of security since the sender cannot distinguish between any of the
// above situations
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -