⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 workgroup.java

📁 openfire 服务器源码下载
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/**
 * $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.xmpp.workgroup.chatbot.Chatbot;
import org.jivesoftware.xmpp.workgroup.dispatcher.BasicDispatcherInfo;
import org.jivesoftware.xmpp.workgroup.dispatcher.DispatcherInfoProvider;
import org.jivesoftware.xmpp.workgroup.event.WorkgroupEventDispatcher;
import org.jivesoftware.xmpp.workgroup.interceptor.InterceptorManager;
import org.jivesoftware.xmpp.workgroup.interceptor.PacketRejectedException;
import org.jivesoftware.xmpp.workgroup.interceptor.RoomInterceptorManager;
import org.jivesoftware.xmpp.workgroup.interceptor.WorkgroupInterceptorManager;
import org.jivesoftware.xmpp.workgroup.request.InvitationRequest;
import org.jivesoftware.xmpp.workgroup.request.Request;
import org.jivesoftware.xmpp.workgroup.request.TransferRequest;
import org.jivesoftware.xmpp.workgroup.request.UserRequest;
import org.jivesoftware.xmpp.workgroup.routing.RoutingManager;
import org.jivesoftware.xmpp.workgroup.spi.BasicRequestFilterFactory;
import org.jivesoftware.xmpp.workgroup.spi.JiveLiveProperties;
import org.jivesoftware.xmpp.workgroup.spi.dispatcher.DbDispatcherInfoProvider;
import org.jivesoftware.xmpp.workgroup.utils.DbWorkgroup;
import org.jivesoftware.xmpp.workgroup.utils.FastpathConstants;
import org.jivesoftware.xmpp.workgroup.utils.ModelUtil;
import org.dom4j.Element;
import org.jivesoftware.database.DbConnectionManager;
import org.jivesoftware.database.SequenceManager;
import org.jivesoftware.openfire.group.Group;
import org.jivesoftware.util.FastDateFormat;
import org.jivesoftware.util.NotFoundException;
import org.jivesoftware.util.StringUtils;
import org.xmpp.component.ComponentManagerFactory;
import org.xmpp.muc.*;
import org.xmpp.packet.*;

import java.net.URL;
import java.sql.*;
import java.sql.Date;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * <p>Database implementation of a workgroup agent.</p>
 * <p>The current implementation doesn't store any meta data about an agent.</p>
 *
 * @author Derek DeMoro
 */
public class Workgroup {

    private static final String LOAD_WORKGROUP =
            "SELECT jid, displayName, description, status, modes, creationDate, " +
            "modificationDate, maxchats, minchats, offerTimeout, requestTimeout, " +
            "schedule FROM fpWorkgroup WHERE workgroupID=?";
    private static final String UPDATE_WORKGRUP =
            "UPDATE fpWorkgroup SET displayName=?,description=?,status=?,modes=?," +
            "creationDate=?,modificationDate=?,maxchats=?,minchats=?,offerTimeout=?," +
            "requestTimeout=?,schedule=? WHERE workgroupID=?";
    private static final String LOAD_QUEUES =
            "SELECT queueID FROM fpQueue WHERE workgroupID=?";
    private static final String CREATE_QUEUE =
            "INSERT into fpQueue (queueID,workgroupID,name,priority,maxchats,minchats," +
            "overflow,backupQueue) VALUES (?,?,?,?,?,?,0,0)";
    private static final String DELETE_QUEUE =
            "DELETE FROM fpQueue WHERE queueID=?";
    private static final String DELETE_QUEUE_PROPS =
            "DELETE FROM fpDispatcherProp WHERE ownerID=?";

    private static final FastDateFormat UTC_FORMAT = FastDateFormat
        .getInstance("yyyyMMdd'T'HH:mm:ss", TimeZone.getTimeZone("GMT+0"));

    /**
     * Flag indicating if the workgroup should accept new requests.
     */
    private boolean open;

    /**
     * Flag indicating if the workgroup is following its schedule.
     */
    private boolean followSchedule;

    /**
     * The schedule the workgroup follows when followSchedule is true.
     */
    private Schedule schedule;

    /**
     * The description for the workgroup (used in the admin UI only - lazily loaded).
     */
    private String description = null;
    private Date creationDate;
    private Date modDate;
    private long offerTimeout = -1;
    private long requestTimeout = -1;
    private int maxChats;
    private int minChats;

    /**
     * Convenience copy of the WorkgroupManager's agent manager (similar to deliverer convenience).
     */
    private AgentManager agentManager;

    /**
     * Used when creating queues.
     */
    private DispatcherInfoProvider dispatcherInfoProvider = new DbDispatcherInfoProvider();

    /**
     * Factory to produce request filters.
     */
    private RequestFilterFactory requestFilterFactory = new BasicRequestFilterFactory();

    /**
     * Chatbot that will handle all the messages sent to this workgroup. If no chatbot was
     * defined then messages will not be answered.
     */
    private Chatbot chatbot;
    // ------------------------------------------------------------------------
    // Packet handlers
    // ------------------------------------------------------------------------
    private WorkgroupPresence workgroupPresenceHandler;
    private WorkgroupIQHandler workgroupIqHandler;
    private MessageHandler messageHandler;


    private Map<Long, RequestQueue> queues = new HashMap<Long, RequestQueue>();

    /**
     * Custom properties for the workgroup.
     */
    private JiveLiveProperties properties;

    private String workgroupName;
    private String displayName;
    private long id;

    /**
     * Keep the conversation transcript of each room that this workgroup has created. Rooms are
     * destroyed after the support session is over. Therefore, this variable keeps track of the
     * chat transcripts of the current support sessions.
     */
    private Map<String, Map<Packet, java.util.Date>> transcripts =
            new ConcurrentHashMap<String, Map<Packet, java.util.Date>>();

    /**
     * Keep a counter of occupants for each room that the workgroup created. The
     * occupants will be updated every time a presence packet is received from the
     * room. When all the occupants (except the workgroup) has left the room then the
     * workgroup will leave the room thus destroying it.
     */
    private Map<String, Set<String>> occupantsCounter = new ConcurrentHashMap<String, Set<String>>();

    /**
     * Keep a list of the requests for which a room was created and still hasn't been destroyed.
     * A new entry is added when sending room invitations and the same entry will be removed when
     * the room is destroyed.
     * Key: sessionID (ie. roomID), value: Request
     */
    private Map<String, UserRequest> requests = new ConcurrentHashMap<String, UserRequest>();

    public Workgroup(long id, AgentManager agentManager) {
        this.id = id;
        this.agentManager = agentManager;
        // Initialize standalone runtime fields

        // Initialize runtime fields that only save reference to the workgroup
        workgroupPresenceHandler = new WorkgroupPresence(this);

        workgroupIqHandler = new WorkgroupIQHandler();
        workgroupIqHandler.setWorkgroup(this);
        messageHandler = new MessageHandler(this);

        // Load settings from database
        loadWorkgroup();
        loadQueues();

        // Send presence to let everyone know you're available/unavailable
        broadcastPresence();
        broadcastQueuesStatus();
    }

    /**
     * Broadcasts the presence of the workgroup to all users and agents of the workgroup.
     */
    public void broadcastPresence() {
        // TODO Send presence from the workgroup to the server

        TaskEngine.getInstance().submit(new Runnable() {
            public void run() {
                try {
                    // Send the status of this workgroup to all the connected agents
                    Collection<AgentSession> sessions = getAgentSessions();
                    for (AgentSession session : sessions) {
                        workgroupPresenceHandler.sendPresence(session.getJID());
                    }

                    // Get all the users' JID in a Set since a user may be having a chat with
                    // many agents
                    Set<JID> jids = new HashSet<JID>();
                    for (AgentSession session : sessions) {
                        jids.addAll(session.getUsersJID(Workgroup.this));
                    }
                    // Send the status to all the users that are having a chat with agents of
                    // the workgroup
                    for (JID jid : jids) {
                        workgroupPresenceHandler.sendPresence(jid);
                    }
                }
                catch (Exception e) {
                    ComponentManagerFactory.getComponentManager().getLog().error("Error broadcasting workgroup presence", e);
                }
            }
        });
    }

    /**
     * Broadcasts the presence of all the queues in the workgroup to all agents.
     */
    public void broadcastQueuesStatus() {
        TaskEngine.getInstance().submit(new Runnable() {
            public void run() {
                try {
                    // Send status of each queue to all the connected agents
                    for (RequestQueue requestQueue : getRequestQueues()) {
                        requestQueue.getAgentSessionList().broadcastQueueStatus(requestQueue);
                    }
                }
                catch (Exception e) {
                    ComponentManagerFactory.getComponentManager().getLog().error("Error broadcasting status of queues", e);
                }
            }
        });
    }

    /**
     * Return true if the Workgroup is available to take requests.
     *
     * @return true if the workgroup is available to take requests.
     */
    public boolean isAvailable() {
        for (RequestQueue requestQueue : getRequestQueues()) {
            Presence presence = requestQueue.getDetailedStatusPresence();
            if (presence.getType() == null) {
                return true;
            }
        }
        return false;
    }


    // ###############################################################################
    // Request queue management
    // ###############################################################################
    public RequestQueue createRequestQueue(String name) throws UnauthorizedException {
        RequestQueue queue = null;
        long queueID = SequenceManager.nextID(FastpathConstants.WORKGROUP_QUEUE);
        // This should probably be moved into a queue manager class
        // First create the queue, then the dispatcher,
        // then the queue implementation object
        boolean queueCreated = createQueue(queueID, name);
        if (queueCreated) {
            BasicDispatcherInfo info = new BasicDispatcherInfo(this, queueID,
                "Round Robin Dispatcher", "None", -1, -1);
            try {
                dispatcherInfoProvider.insertDispatcherInfo(queueID, info);
                queue = new RequestQueue(this, queueID);
            }
            catch (UserAlreadyExistsException e) {
                ComponentManagerFactory.getComponentManager().getLog().error(e);
            }
        }
        else {
            throw new UnauthorizedException();
        }
        queues.put(queueID, queue);
        return queue;
    }

    public void deleteRequestQueue(RequestQueue queue) {
        queues.remove(queue.getID());
        // Delete the RequestQueue from the database
        if (deleteQueue(queue.getID())) {
            // Stop processing requests in this queue
            queue.shutdown();
            // Remove the agents from this queue
            for (Agent agent : queue.getMembers()) {
                queue.removeMember(agent);
            }
            // Remove the agent groups from this queue
            for (Group group : queue.getGroups()) {
                queue.removeGroup(group);
            }
            try {
                // Delete the dispatcher of this queue from the database
                dispatcherInfoProvider.deleteDispatcherInfo(queue.getID());
            }
            catch (UnauthorizedException e) {
                ComponentManagerFactory.getComponentManager().getLog().error(e);
            }
        }
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -