1d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/**
2d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Copyright 2003-2007 Jive Software.
3d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *
4d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
5d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * you may not use this file except in compliance with the License.
6d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * You may obtain a copy of the License at
7d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *
8d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *     http://www.apache.org/licenses/LICENSE-2.0
9d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *
10d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Unless required by applicable law or agreed to in writing, software
11d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * distributed under the License is distributed on an "AS IS" BASIS,
12d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * See the License for the specific language governing permissions and
14d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * limitations under the License.
15d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */
16d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
17d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpackage org.jivesoftware.smackx.workgroup.user;
18d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
19d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smackx.workgroup.MetaData;
20d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smackx.workgroup.WorkgroupInvitation;
21d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smackx.workgroup.WorkgroupInvitationListener;
22d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smackx.workgroup.ext.forms.WorkgroupForm;
23d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smackx.workgroup.packet.DepartQueuePacket;
24d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smackx.workgroup.packet.QueueUpdate;
25d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smackx.workgroup.packet.SessionID;
26d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smackx.workgroup.packet.UserID;
27d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smackx.workgroup.settings.*;
28d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.*;
29d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.filter.*;
30d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.packet.*;
31d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.util.StringUtils;
32d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smackx.Form;
33d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smackx.FormField;
34d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smackx.ServiceDiscoveryManager;
35d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smackx.muc.MultiUserChat;
36d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smackx.packet.DataForm;
37d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smackx.packet.DiscoverInfo;
38d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smackx.packet.MUCUser;
39d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
40d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.ArrayList;
41d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.Iterator;
42d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.List;
43d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.Map;
44d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
45d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/**
46d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Provides workgroup services for users. Users can join the workgroup queue, depart the
47d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * queue, find status information about their placement in the queue, and register to
48d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * be notified when they are routed to an agent.<p>
49d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <p/>
50d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * This class only provides a users perspective into a workgroup and is not intended
51d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * for use by agents.
52d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *
53d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @author Matt Tucker
54d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @author Derek DeMoro
55d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */
56d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic class Workgroup {
57d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
58d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private String workgroupJID;
59d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private Connection connection;
60d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private boolean inQueue;
61d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private List<WorkgroupInvitationListener> invitationListeners;
62d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private List<QueueListener> queueListeners;
63d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
64d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private int queuePosition = -1;
65d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private int queueRemainingTime = -1;
66d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
67d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
68d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Creates a new workgroup instance using the specified workgroup JID
69d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * (eg support@workgroup.example.com) and XMPP connection. The connection must have
70d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * undergone a successful login before being used to construct an instance of
71d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * this class.
72d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
73d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param workgroupJID the JID of the workgroup.
74d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param connection   an XMPP connection which must have already undergone a
75d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *                     successful login.
76d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
77d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public Workgroup(String workgroupJID, Connection connection) {
78d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        // Login must have been done before passing in connection.
79d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (!connection.isAuthenticated()) {
80d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new IllegalStateException("Must login to server before creating workgroup.");
81d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
82d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
83d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        this.workgroupJID = workgroupJID;
84d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        this.connection = connection;
85d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        inQueue = false;
86d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        invitationListeners = new ArrayList<WorkgroupInvitationListener>();
87d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        queueListeners = new ArrayList<QueueListener>();
88d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
89d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        // Register as a queue listener for internal usage by this instance.
90d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        addQueueListener(new QueueListener() {
91d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            public void joinedQueue() {
92d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                inQueue = true;
93d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
94d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
95d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            public void departedQueue() {
96d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                inQueue = false;
97d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                queuePosition = -1;
98d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                queueRemainingTime = -1;
99d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
100d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
101d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            public void queuePositionUpdated(int currentPosition) {
102d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                queuePosition = currentPosition;
103d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
104d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
105d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            public void queueWaitTimeUpdated(int secondsRemaining) {
106d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                queueRemainingTime = secondsRemaining;
107d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
108d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        });
109d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
110d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        /**
111d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         * Internal handling of an invitation.Recieving an invitation removes the user from the queue.
112d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen         */
113d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        MultiUserChat.addInvitationListener(connection,
114d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                new org.jivesoftware.smackx.muc.InvitationListener() {
115d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                    public void invitationReceived(Connection conn, String room, String inviter,
116d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                                                   String reason, String password, Message message) {
117d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                        inQueue = false;
118d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                        queuePosition = -1;
119d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                        queueRemainingTime = -1;
120d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                    }
121d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                });
122d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
123d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        // Register a packet listener for all the messages sent to this client.
124d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        PacketFilter typeFilter = new PacketTypeFilter(Message.class);
125d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
126d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        connection.addPacketListener(new PacketListener() {
127d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            public void processPacket(Packet packet) {
128d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                handlePacket(packet);
129d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
130d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }, typeFilter);
131d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
132d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
133d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
134d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Returns the name of this workgroup (eg support@example.com).
135d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
136d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @return the name of the workgroup.
137d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
138d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public String getWorkgroupJID() {
139d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return workgroupJID;
140d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
141d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
142d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
143d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Returns true if the user is currently waiting in the workgroup queue.
144d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
145d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @return true if currently waiting in the queue.
146d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
147d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public boolean isInQueue() {
148d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return inQueue;
149d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
150d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
151d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
152d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Returns true if the workgroup is available for receiving new requests. The workgroup will be
153d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * available only when agents are available for this workgroup.
154d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
155d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @return true if the workgroup is available for receiving new requests.
156d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
157d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public boolean isAvailable() {
158d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        Presence directedPresence = new Presence(Presence.Type.available);
159d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        directedPresence.setTo(workgroupJID);
160d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        PacketFilter typeFilter = new PacketTypeFilter(Presence.class);
161d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        PacketFilter fromFilter = new FromContainsFilter(workgroupJID);
162d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        PacketCollector collector = connection.createPacketCollector(new AndFilter(fromFilter,
163d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                typeFilter));
164d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
165d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        connection.sendPacket(directedPresence);
166d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
167d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        Presence response = (Presence)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
168d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
169d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        // Cancel the collector.
170d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        collector.cancel();
171d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (response == null) {
172d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            return false;
173d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
174d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        else if (response.getError() != null) {
175d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            return false;
176d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
177d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        else {
178d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            return Presence.Type.available == response.getType();
179d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
180d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
181d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
182d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
183d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Returns the users current position in the workgroup queue. A value of 0 means
184d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * the user is next in line to be routed; therefore, if the queue position
185d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * is being displayed to the end user it is usually a good idea to add 1 to
186d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * the value this method returns before display. If the user is not currently
187d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * waiting in the workgroup, or no queue position information is available, -1
188d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * will be returned.
189d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
190d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @return the user's current position in the workgroup queue, or -1 if the
191d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *         position isn't available or if the user isn't in the queue.
192d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
193d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public int getQueuePosition() {
194d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return queuePosition;
195d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
196d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
197d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
198d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Returns the estimated time (in seconds) that the user has to left wait in
199d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * the workgroup queue before being routed. If the user is not currently waiting
200d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * int he workgroup, or no queue time information is available, -1 will be
201d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * returned.
202d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
203d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @return the estimated time remaining (in seconds) that the user has to
204d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *         wait inthe workgroupu queue, or -1 if time information isn't available
205d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *         or if the user isn't int the queue.
206d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
207d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public int getQueueRemainingTime() {
208d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return queueRemainingTime;
209d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
210d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
211d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
212d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Joins the workgroup queue to wait to be routed to an agent. After joining
213d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * the queue, queue status events will be sent to indicate the user's position and
214d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * estimated time left in the queue. Once joining the queue, there are three ways
215d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * the user can leave the queue: <ul>
216d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * <p/>
217d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * <li>The user is routed to an agent, which triggers a GroupChat invitation.
218d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * <li>The user asks to leave the queue by calling the {@link #departQueue} method.
219d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * <li>A server error occurs, or an administrator explicitly removes the user
220d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * from the queue.
221d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * </ul>
222d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * <p/>
223d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * A user cannot request to join the queue again if already in the queue. Therefore,
224d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * this method will throw an IllegalStateException if the user is already in the queue.<p>
225d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * <p/>
226d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Some servers may be configured to require certain meta-data in order to
227d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * join the queue. In that case, the {@link #joinQueue(Form)} method should be
228d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * used instead of this method so that meta-data may be passed in.<p>
229d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * <p/>
230d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * The server tracks the conversations that a user has with agents over time. By
231d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * default, that tracking is done using the user's JID. However, this is not always
232d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * possible. For example, when the user is logged in anonymously using a web client.
233d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * In that case the user ID might be a randomly generated value put into a persistent
234d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * cookie or a username obtained via the session. A userID can be explicitly
235d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * passed in by using the {@link #joinQueue(Form, String)} method. When specified,
236d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * that userID will be used instead of the user's JID to track conversations. The
237d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * server will ignore a manually specified userID if the user's connection to the server
238d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * is not anonymous.
239d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
240d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @throws XMPPException if an error occured joining the queue. An error may indicate
241d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *                       that a connection failure occured or that the server explicitly rejected the
242d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *                       request to join the queue.
243d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
244d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public void joinQueue() throws XMPPException {
245d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        joinQueue(null);
246d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
247d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
248d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
249d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Joins the workgroup queue to wait to be routed to an agent. After joining
250d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * the queue, queue status events will be sent to indicate the user's position and
251d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * estimated time left in the queue. Once joining the queue, there are three ways
252d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * the user can leave the queue: <ul>
253d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * <p/>
254d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * <li>The user is routed to an agent, which triggers a GroupChat invitation.
255d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * <li>The user asks to leave the queue by calling the {@link #departQueue} method.
256d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * <li>A server error occurs, or an administrator explicitly removes the user
257d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * from the queue.
258d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * </ul>
259d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * <p/>
260d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * A user cannot request to join the queue again if already in the queue. Therefore,
261d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * this method will throw an IllegalStateException if the user is already in the queue.<p>
262d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * <p/>
263d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Some servers may be configured to require certain meta-data in order to
264d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * join the queue.<p>
265d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * <p/>
266d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * The server tracks the conversations that a user has with agents over time. By
267d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * default, that tracking is done using the user's JID. However, this is not always
268d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * possible. For example, when the user is logged in anonymously using a web client.
269d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * In that case the user ID might be a randomly generated value put into a persistent
270d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * cookie or a username obtained via the session. A userID can be explicitly
271d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * passed in by using the {@link #joinQueue(Form, String)} method. When specified,
272d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * that userID will be used instead of the user's JID to track conversations. The
273d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * server will ignore a manually specified userID if the user's connection to the server
274d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * is not anonymous.
275d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
276d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param answerForm the completed form the send for the join request.
277d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @throws XMPPException if an error occured joining the queue. An error may indicate
278d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *                       that a connection failure occured or that the server explicitly rejected the
279d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *                       request to join the queue.
280d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
281d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public void joinQueue(Form answerForm) throws XMPPException {
282d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        joinQueue(answerForm, null);
283d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
284d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
285d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
286d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * <p>Joins the workgroup queue to wait to be routed to an agent. After joining
287d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * the queue, queue status events will be sent to indicate the user's position and
288d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * estimated time left in the queue. Once joining the queue, there are three ways
289d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * the user can leave the queue: <ul>
290d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * <p/>
291d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * <li>The user is routed to an agent, which triggers a GroupChat invitation.
292d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * <li>The user asks to leave the queue by calling the {@link #departQueue} method.
293d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * <li>A server error occurs, or an administrator explicitly removes the user
294d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * from the queue.
295d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * </ul>
296d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * <p/>
297d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * A user cannot request to join the queue again if already in the queue. Therefore,
298d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * this method will throw an IllegalStateException if the user is already in the queue.<p>
299d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * <p/>
300d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Some servers may be configured to require certain meta-data in order to
301d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * join the queue.<p>
302d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * <p/>
303d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * The server tracks the conversations that a user has with agents over time. By
304d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * default, that tracking is done using the user's JID. However, this is not always
305d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * possible. For example, when the user is logged in anonymously using a web client.
306d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * In that case the user ID might be a randomly generated value put into a persistent
307d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * cookie or a username obtained via the session. When specified, that userID will
308d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * be used instead of the user's JID to track conversations. The server will ignore a
309d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * manually specified userID if the user's connection to the server is not anonymous.
310d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
311d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param answerForm the completed form associated with the join reqest.
312d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param userID     String that represents the ID of the user when using anonymous sessions
313d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *                   or <tt>null</tt> if a userID should not be used.
314d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @throws XMPPException if an error occured joining the queue. An error may indicate
315d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *                       that a connection failure occured or that the server explicitly rejected the
316d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *                       request to join the queue.
317d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
318d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public void joinQueue(Form answerForm, String userID) throws XMPPException {
319d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        // If already in the queue ignore the join request.
320d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (inQueue) {
321d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new IllegalStateException("Already in queue " + workgroupJID);
322d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
323d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
324d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        JoinQueuePacket joinPacket = new JoinQueuePacket(workgroupJID, answerForm, userID);
325d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
326d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
327d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(joinPacket.getPacketID()));
328d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
329d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        this.connection.sendPacket(joinPacket);
330d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
331d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        IQ response = (IQ)collector.nextResult(10000);
332d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
333d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        // Cancel the collector.
334d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        collector.cancel();
335d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (response == null) {
336d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new XMPPException("No response from the server.");
337d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
338d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (response.getError() != null) {
339d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new XMPPException(response.getError());
340d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
341d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
342d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        // Notify listeners that we've joined the queue.
343d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        fireQueueJoinedEvent();
344d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
345d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
346d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
347d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * <p>Joins the workgroup queue to wait to be routed to an agent. After joining
348d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * the queue, queue status events will be sent to indicate the user's position and
349d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * estimated time left in the queue. Once joining the queue, there are three ways
350d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * the user can leave the queue: <ul>
351d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * <p/>
352d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * <li>The user is routed to an agent, which triggers a GroupChat invitation.
353d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * <li>The user asks to leave the queue by calling the {@link #departQueue} method.
354d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * <li>A server error occurs, or an administrator explicitly removes the user
355d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * from the queue.
356d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * </ul>
357d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * <p/>
358d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * A user cannot request to join the queue again if already in the queue. Therefore,
359d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * this method will throw an IllegalStateException if the user is already in the queue.<p>
360d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * <p/>
361d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Some servers may be configured to require certain meta-data in order to
362d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * join the queue.<p>
363d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * <p/>
364d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * The server tracks the conversations that a user has with agents over time. By
365d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * default, that tracking is done using the user's JID. However, this is not always
366d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * possible. For example, when the user is logged in anonymously using a web client.
367d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * In that case the user ID might be a randomly generated value put into a persistent
368d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * cookie or a username obtained via the session. When specified, that userID will
369d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * be used instead of the user's JID to track conversations. The server will ignore a
370d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * manually specified userID if the user's connection to the server is not anonymous.
371d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
372d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param metadata metadata to create a dataform from.
373d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param userID   String that represents the ID of the user when using anonymous sessions
374d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *                 or <tt>null</tt> if a userID should not be used.
375d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @throws XMPPException if an error occured joining the queue. An error may indicate
376d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *                       that a connection failure occured or that the server explicitly rejected the
377d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *                       request to join the queue.
378d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
379d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public void joinQueue(Map<String,Object> metadata, String userID) throws XMPPException {
380d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        // If already in the queue ignore the join request.
381d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (inQueue) {
382d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new IllegalStateException("Already in queue " + workgroupJID);
383d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
384d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
385d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        // Build dataform from metadata
386d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        Form form = new Form(Form.TYPE_SUBMIT);
387d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        Iterator<String> iter = metadata.keySet().iterator();
388d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        while (iter.hasNext()) {
389d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            String name = iter.next();
390d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            String value = metadata.get(name).toString();
391d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
392d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            String escapedName = StringUtils.escapeForXML(name);
393d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            String escapedValue = StringUtils.escapeForXML(value);
394d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
395d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            FormField field = new FormField(escapedName);
396d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            field.setType(FormField.TYPE_TEXT_SINGLE);
397d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            form.addField(field);
398d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            form.setAnswer(escapedName, escapedValue);
399d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
400d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        joinQueue(form, userID);
401d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
402d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
403d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
404d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Departs the workgroup queue. If the user is not currently in the queue, this
405d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * method will do nothing.<p>
406d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * <p/>
407d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Normally, the user would not manually leave the queue. However, they may wish to
408d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * under certain circumstances -- for example, if they no longer wish to be routed
409d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * to an agent because they've been waiting too long.
410d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
411d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @throws XMPPException if an error occured trying to send the depart queue
412d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *                       request to the server.
413d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
414d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public void departQueue() throws XMPPException {
415d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        // If not in the queue ignore the depart request.
416d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (!inQueue) {
417d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            return;
418d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
419d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
420d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        DepartQueuePacket departPacket = new DepartQueuePacket(this.workgroupJID);
421d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        PacketCollector collector = this.connection.createPacketCollector(new PacketIDFilter(departPacket.getPacketID()));
422d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
423d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        connection.sendPacket(departPacket);
424d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
425d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        IQ response = (IQ)collector.nextResult(5000);
426d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        collector.cancel();
427d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (response == null) {
428d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new XMPPException("No response from the server.");
429d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
430d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (response.getError() != null) {
431d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new XMPPException(response.getError());
432d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
433d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
434d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        // Notify listeners that we're no longer in the queue.
435d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        fireQueueDepartedEvent();
436d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
437d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
438d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
439d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Adds a queue listener that will be notified of queue events for the user
440d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * that created this Workgroup instance.
441d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
442d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param queueListener the queue listener.
443d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
444d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public void addQueueListener(QueueListener queueListener) {
445d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        synchronized (queueListeners) {
446d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            if (!queueListeners.contains(queueListener)) {
447d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                queueListeners.add(queueListener);
448d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
449d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
450d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
451d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
452d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
453d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Removes a queue listener.
454d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
455d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param queueListener the queue listener.
456d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
457d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public void removeQueueListener(QueueListener queueListener) {
458d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        synchronized (queueListeners) {
459d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            queueListeners.remove(queueListener);
460d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
461d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
462d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
463d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
464d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Adds an invitation listener that will be notified of groupchat invitations
465d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * from the workgroup for the the user that created this Workgroup instance.
466d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
467d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param invitationListener the invitation listener.
468d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
469d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public void addInvitationListener(WorkgroupInvitationListener invitationListener) {
470d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        synchronized (invitationListeners) {
471d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            if (!invitationListeners.contains(invitationListener)) {
472d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                invitationListeners.add(invitationListener);
473d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
474d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
475d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
476d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
477d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
478d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Removes an invitation listener.
479d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
480d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param invitationListener the invitation listener.
481d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
482d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public void removeQueueListener(WorkgroupInvitationListener invitationListener) {
483d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        synchronized (invitationListeners) {
484d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            invitationListeners.remove(invitationListener);
485d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
486d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
487d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
488d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private void fireInvitationEvent(WorkgroupInvitation invitation) {
489d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        synchronized (invitationListeners) {
490d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            for (Iterator<WorkgroupInvitationListener> i = invitationListeners.iterator(); i.hasNext();) {
491d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                WorkgroupInvitationListener listener = i.next();
492d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                listener.invitationReceived(invitation);
493d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
494d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
495d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
496d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
497d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private void fireQueueJoinedEvent() {
498d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        synchronized (queueListeners) {
499d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            for (Iterator<QueueListener> i = queueListeners.iterator(); i.hasNext();) {
500d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                QueueListener listener = i.next();
501d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                listener.joinedQueue();
502d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
503d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
504d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
505d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
506d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private void fireQueueDepartedEvent() {
507d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        synchronized (queueListeners) {
508d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            for (Iterator<QueueListener> i = queueListeners.iterator(); i.hasNext();) {
509d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                QueueListener listener = i.next();
510d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                listener.departedQueue();
511d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
512d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
513d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
514d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
515d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private void fireQueuePositionEvent(int currentPosition) {
516d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        synchronized (queueListeners) {
517d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            for (Iterator<QueueListener> i = queueListeners.iterator(); i.hasNext();) {
518d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                QueueListener listener = i.next();
519d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                listener.queuePositionUpdated(currentPosition);
520d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
521d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
522d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
523d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
524d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private void fireQueueTimeEvent(int secondsRemaining) {
525d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        synchronized (queueListeners) {
526d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            for (Iterator<QueueListener> i = queueListeners.iterator(); i.hasNext();) {
527d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                QueueListener listener = i.next();
528d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                listener.queueWaitTimeUpdated(secondsRemaining);
529d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
530d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
531d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
532d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
533d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    // PacketListener Implementation.
534d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
535d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private void handlePacket(Packet packet) {
536d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (packet instanceof Message) {
537d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            Message msg = (Message)packet;
538d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            // Check to see if the user left the queue.
539d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            PacketExtension pe = msg.getExtension("depart-queue", "http://jabber.org/protocol/workgroup");
540d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            PacketExtension queueStatus = msg.getExtension("queue-status", "http://jabber.org/protocol/workgroup");
541d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
542d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            if (pe != null) {
543d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                fireQueueDepartedEvent();
544d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
545d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            else if (queueStatus != null) {
546d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                QueueUpdate queueUpdate = (QueueUpdate)queueStatus;
547d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                if (queueUpdate.getPosition() != -1) {
548d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                    fireQueuePositionEvent(queueUpdate.getPosition());
549d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                }
550d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                if (queueUpdate.getRemaingTime() != -1) {
551d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                    fireQueueTimeEvent(queueUpdate.getRemaingTime());
552d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                }
553d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
554d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
555d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            else {
556d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                // Check if a room invitation was sent and if the sender is the workgroup
557d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                MUCUser mucUser = (MUCUser)msg.getExtension("x", "http://jabber.org/protocol/muc#user");
558d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                MUCUser.Invite invite = mucUser != null ? mucUser.getInvite() : null;
559d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                if (invite != null && workgroupJID.equals(invite.getFrom())) {
560d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                    String sessionID = null;
561d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                    Map<String, List<String>> metaData = null;
562d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
563d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                    pe = msg.getExtension(SessionID.ELEMENT_NAME,
564d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                            SessionID.NAMESPACE);
565d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                    if (pe != null) {
566d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                        sessionID = ((SessionID)pe).getSessionID();
567d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                    }
568d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
569d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                    pe = msg.getExtension(MetaData.ELEMENT_NAME,
570d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                            MetaData.NAMESPACE);
571d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                    if (pe != null) {
572d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                        metaData = ((MetaData)pe).getMetaData();
573d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                    }
574d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
575d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                    WorkgroupInvitation inv = new WorkgroupInvitation(connection.getUser(), msg.getFrom(),
576d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                            workgroupJID, sessionID, msg.getBody(),
577d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                            msg.getFrom(), metaData);
578d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
579d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                    fireInvitationEvent(inv);
580d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                }
581d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
582d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
583d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
584d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
585d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
586d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * IQ packet to request joining the workgroup queue.
587d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
588d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private class JoinQueuePacket extends IQ {
589d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
590d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        private String userID = null;
591d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        private DataForm form;
592d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
593d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        public JoinQueuePacket(String workgroup, Form answerForm, String userID) {
594d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            this.userID = userID;
595d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
596d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            setTo(workgroup);
597d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            setType(IQ.Type.SET);
598d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
599d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            form = answerForm.getDataFormToSend();
600d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            addExtension(form);
601d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
602d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
603d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        public String getChildElementXML() {
604d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            StringBuilder buf = new StringBuilder();
605d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
606d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            buf.append("<join-queue xmlns=\"http://jabber.org/protocol/workgroup\">");
607d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            buf.append("<queue-notifications/>");
608d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            // Add the user unique identification if the session is anonymous
609d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            if (connection.isAnonymous()) {
610d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                buf.append(new UserID(userID).toXML());
611d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
612d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
613d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            // Append data form text
614d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            buf.append(form.toXML());
615d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
616d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            buf.append("</join-queue>");
617d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
618d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            return buf.toString();
619d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
620d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
621d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
622d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
623d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Returns a single chat setting based on it's identified key.
624d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
625d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param key the key to find.
626d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @return the ChatSetting if found, otherwise false.
627d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @throws XMPPException if an error occurs while getting information from the server.
628d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
629d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public ChatSetting getChatSetting(String key) throws XMPPException {
630d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        ChatSettings chatSettings = getChatSettings(key, -1);
631d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return chatSettings.getFirstEntry();
632d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
633d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
634d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
635d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Returns ChatSettings based on type.
636d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
637d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param type the type of ChatSettings to return.
638d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @return the ChatSettings of given type, otherwise null.
639d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @throws XMPPException if an error occurs while getting information from the server.
640d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
641d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public ChatSettings getChatSettings(int type) throws XMPPException {
642d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return getChatSettings(null, type);
643d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
644d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
645d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
646d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Returns all ChatSettings.
647d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
648d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @return all ChatSettings of a given workgroup.
649d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @throws XMPPException if an error occurs while getting information from the server.
650d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
651d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public ChatSettings getChatSettings() throws XMPPException {
652d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return getChatSettings(null, -1);
653d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
654d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
655d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
656d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
657d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Asks the workgroup for it's Chat Settings.
658d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
659d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @return key specify a key to retrieve only that settings. Otherwise for all settings, key should be null.
660d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @throws XMPPException if an error occurs while getting information from the server.
661d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
662d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    private ChatSettings getChatSettings(String key, int type) throws XMPPException {
663d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        ChatSettings request = new ChatSettings();
664d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (key != null) {
665d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            request.setKey(key);
666d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
667d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (type != -1) {
668d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            request.setType(type);
669d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
670d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        request.setType(IQ.Type.GET);
671d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        request.setTo(workgroupJID);
672d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
673d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
674d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        connection.sendPacket(request);
675d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
676d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
677d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        ChatSettings response = (ChatSettings)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
678d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
679d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        // Cancel the collector.
680d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        collector.cancel();
681d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (response == null) {
682d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new XMPPException("No response from server.");
683d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
684d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (response.getError() != null) {
685d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new XMPPException(response.getError());
686d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
687d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return response;
688d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
689d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
690d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
691d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * The workgroup service may be configured to send email. This queries the Workgroup Service
692d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * to see if the email service has been configured and is available.
693d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
694d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @return true if the email service is available, otherwise return false.
695d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
696d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public boolean isEmailAvailable() {
697d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(connection);
698d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
699d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        try {
700d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            String workgroupService = StringUtils.parseServer(workgroupJID);
701d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            DiscoverInfo infoResult = discoManager.discoverInfo(workgroupService);
702d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            return infoResult.containsFeature("jive:email:provider");
703d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
704d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        catch (XMPPException e) {
705d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            return false;
706d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
707d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
708d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
709d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
710d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Asks the workgroup for it's Offline Settings.
711d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
712d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @return offlineSettings the offline settings for this workgroup.
713d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @throws XMPPException if an error occurs while getting information from the server.
714d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
715d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public OfflineSettings getOfflineSettings() throws XMPPException {
716d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        OfflineSettings request = new OfflineSettings();
717d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        request.setType(IQ.Type.GET);
718d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        request.setTo(workgroupJID);
719d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
720d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
721d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        connection.sendPacket(request);
722d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
723d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
724d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        OfflineSettings response = (OfflineSettings)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
725d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
726d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        // Cancel the collector.
727d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        collector.cancel();
728d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (response == null) {
729d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new XMPPException("No response from server.");
730d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
731d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (response.getError() != null) {
732d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new XMPPException(response.getError());
733d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
734d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return response;
735d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
736d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
737d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
738d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Asks the workgroup for it's Sound Settings.
739d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
740d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @return soundSettings the sound settings for the specified workgroup.
741d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @throws XMPPException if an error occurs while getting information from the server.
742d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
743d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public SoundSettings getSoundSettings() throws XMPPException {
744d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        SoundSettings request = new SoundSettings();
745d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        request.setType(IQ.Type.GET);
746d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        request.setTo(workgroupJID);
747d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
748d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
749d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        connection.sendPacket(request);
750d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
751d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
752d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        SoundSettings response = (SoundSettings)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
753d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
754d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        // Cancel the collector.
755d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        collector.cancel();
756d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (response == null) {
757d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new XMPPException("No response from server.");
758d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
759d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (response.getError() != null) {
760d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new XMPPException(response.getError());
761d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
762d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return response;
763d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
764d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
765d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
766d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Asks the workgroup for it's Properties
767d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
768d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @return the WorkgroupProperties for the specified workgroup.
769d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @throws XMPPException if an error occurs while getting information from the server.
770d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
771d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public WorkgroupProperties getWorkgroupProperties() throws XMPPException {
772d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        WorkgroupProperties request = new WorkgroupProperties();
773d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        request.setType(IQ.Type.GET);
774d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        request.setTo(workgroupJID);
775d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
776d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
777d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        connection.sendPacket(request);
778d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
779d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
780d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        WorkgroupProperties response = (WorkgroupProperties)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
781d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
782d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        // Cancel the collector.
783d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        collector.cancel();
784d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (response == null) {
785d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new XMPPException("No response from server.");
786d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
787d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (response.getError() != null) {
788d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new XMPPException(response.getError());
789d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
790d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return response;
791d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
792d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
793d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
794d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Asks the workgroup for it's Properties
795d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
796d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param jid the jid of the user who's information you would like the workgroup to retreive.
797d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @return the WorkgroupProperties for the specified workgroup.
798d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @throws XMPPException if an error occurs while getting information from the server.
799d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
800d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public WorkgroupProperties getWorkgroupProperties(String jid) throws XMPPException {
801d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        WorkgroupProperties request = new WorkgroupProperties();
802d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        request.setJid(jid);
803d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        request.setType(IQ.Type.GET);
804d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        request.setTo(workgroupJID);
805d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
806d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(request.getPacketID()));
807d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        connection.sendPacket(request);
808d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
809d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
810d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        WorkgroupProperties response = (WorkgroupProperties)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
811d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
812d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        // Cancel the collector.
813d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        collector.cancel();
814d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (response == null) {
815d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new XMPPException("No response from server.");
816d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
817d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (response.getError() != null) {
818d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new XMPPException(response.getError());
819d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
820d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return response;
821d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
822d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
823d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
824d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
825d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Returns the Form to use for all clients of a workgroup. It is unlikely that the server
826d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * will change the form (without a restart) so it is safe to keep the returned form
827d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * for future submissions.
828d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
829d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @return the Form to use for searching transcripts.
830d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @throws XMPPException if an error occurs while sending the request to the server.
831d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
832d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public Form getWorkgroupForm() throws XMPPException {
833d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        WorkgroupForm workgroupForm = new WorkgroupForm();
834d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        workgroupForm.setType(IQ.Type.GET);
835d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        workgroupForm.setTo(workgroupJID);
836d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
837d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(workgroupForm.getPacketID()));
838d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        connection.sendPacket(workgroupForm);
839d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
840d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        WorkgroupForm response = (WorkgroupForm)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
841d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
842d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        // Cancel the collector.
843d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        collector.cancel();
844d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (response == null) {
845d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new XMPPException("No response from server on status set.");
846d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
847d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (response.getError() != null) {
848d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            throw new XMPPException(response.getError());
849d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
850d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return Form.getFormFrom(response);
851d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
852d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
853d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /*
854d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public static void main(String args[]) throws Exception {
855d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        Connection con = new XMPPConnection("anteros");
856d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        con.connect();
857d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        con.loginAnonymously();
858d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
859d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        Workgroup workgroup = new Workgroup("demo@workgroup.anteros", con);
860d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        WorkgroupProperties props = workgroup.getWorkgroupProperties("derek@anteros.com");
861d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
862d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        System.out.print(props);
863d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        con.disconnect();
864d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
865d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    */
866d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
867d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
868d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen}