001/*
002 *
003 * Copyright 2003-2007 Jive Software.
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018package org.jivesoftware.smackx.workgroup.packet;
019
020import java.io.IOException;
021import java.text.ParseException;
022import java.text.SimpleDateFormat;
023import java.util.Date;
024import java.util.HashSet;
025import java.util.Iterator;
026import java.util.Set;
027import java.util.logging.Logger;
028
029import javax.xml.namespace.QName;
030
031import org.jivesoftware.smack.packet.ExtensionElement;
032import org.jivesoftware.smack.packet.XmlEnvironment;
033import org.jivesoftware.smack.provider.ExtensionElementProvider;
034import org.jivesoftware.smack.xml.XmlPullParser;
035import org.jivesoftware.smack.xml.XmlPullParserException;
036
037import org.jivesoftware.smackx.workgroup.QueueUser;
038
039import org.jxmpp.JxmppContext;
040
041/**
042 * Queue details stanza extension, which contains details about the users
043 * currently in a queue.
044 */
045public final class QueueDetails implements ExtensionElement {
046    private static final Logger LOGGER = Logger.getLogger(QueueDetails.class.getName());
047
048    /**
049     * Element name of the stanza extension.
050     */
051    public static final String ELEMENT_NAME = "notify-queue-details";
052
053    /**
054     * Namespace of the stanza extension.
055     */
056    public static final String NAMESPACE = "http://jabber.org/protocol/workgroup";
057    public static final QName QNAME = new QName(NAMESPACE, ELEMENT_NAME);
058
059    private static final String DATE_FORMAT = "yyyyMMdd'T'HH:mm:ss";
060
061    private final SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
062    /**
063     * The list of users in the queue.
064     */
065    private final Set<QueueUser> users = new HashSet<>();
066
067    /**
068     * Returns the number of users currently in the queue that are waiting to
069     * be routed to an agent.
070     *
071     * @return the number of users in the queue.
072     */
073    public int getUserCount() {
074        return users.size();
075    }
076
077    /**
078     * Returns the set of users in the queue that are waiting to
079     * be routed to an agent (as QueueUser objects).
080     *
081     * @return a Set for the users waiting in a queue.
082     */
083    public Set<QueueUser> getUsers() {
084        synchronized (users) {
085            return users;
086        }
087    }
088
089    /**
090     * Adds a user to the packet.
091     *
092     * @param user the user.
093     */
094    private void addUser(QueueUser user) {
095        synchronized (users) {
096            users.add(user);
097        }
098    }
099
100    @Override
101    public String getElementName() {
102        return ELEMENT_NAME;
103    }
104
105    @Override
106    public String getNamespace() {
107        return NAMESPACE;
108    }
109
110    @Override
111    public String toXML(org.jivesoftware.smack.packet.XmlEnvironment enclosingNamespace) {
112        StringBuilder buf = new StringBuilder();
113        buf.append('<').append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\">");
114
115        synchronized (users) {
116            for (Iterator<QueueUser> i = users.iterator(); i.hasNext(); ) {
117                QueueUser user = i.next();
118                int position = user.getQueuePosition();
119                int timeRemaining = user.getEstimatedRemainingTime();
120                Date timestamp = user.getQueueJoinTimestamp();
121
122                buf.append("<user jid=\"").append(user.getUserID()).append("\">");
123
124                if (position != -1) {
125                    buf.append("<position>").append(position).append("</position>");
126                }
127
128                if (timeRemaining != -1) {
129                    buf.append("<time>").append(timeRemaining).append("</time>");
130                }
131
132                if (timestamp != null) {
133                    buf.append("<join-time>");
134                    buf.append(dateFormat.format(timestamp));
135                    buf.append("</join-time>");
136                }
137
138                buf.append("</user>");
139            }
140        }
141        buf.append("</").append(ELEMENT_NAME).append('>');
142        return buf.toString();
143    }
144
145    /**
146     * Provider class for QueueDetails stanza extensions.
147     */
148    public static class Provider extends ExtensionElementProvider<QueueDetails> {
149
150        @SuppressWarnings("JavaUtilDate")
151        @Override
152        public QueueDetails parse(XmlPullParser parser,
153                        int initialDepth, XmlEnvironment xmlEnvironment, JxmppContext jxmppContext) throws XmlPullParserException,
154                        IOException, TextParseException, ParseException {
155
156            SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
157            QueueDetails queueDetails = new QueueDetails();
158
159            XmlPullParser.Event eventType = parser.getEventType();
160            while (eventType != XmlPullParser.Event.END_ELEMENT &&
161                    "notify-queue-details".equals(parser.getName())) {
162                eventType = parser.next();
163                while ((eventType == XmlPullParser.Event.START_ELEMENT) && "user".equals(parser.getName())) {
164                    String uid;
165                    int position = -1;
166                    int time = -1;
167                    Date joinTime = null;
168
169                    uid = parser.getAttributeValue("", "jid");
170
171                    if (uid == null) {
172                        // throw exception
173                    }
174
175                    eventType = parser.next();
176                    while (eventType != XmlPullParser.Event.END_ELEMENT
177                                || !"user".equals(parser.getName())) {
178                        if ("position".equals(parser.getName())) {
179                            position = Integer.parseInt(parser.nextText());
180                        }
181                        else if ("time".equals(parser.getName())) {
182                            time = Integer.parseInt(parser.nextText());
183                        }
184                        else if ("join-time".equals(parser.getName())) {
185                                joinTime = dateFormat.parse(parser.nextText());
186                        }
187                        else if (parser.getName().equals("waitTime")) {
188                            Date wait = dateFormat.parse(parser.nextText());
189                            LOGGER.fine(wait.toString());
190                        }
191
192                        eventType = parser.next();
193
194                        if (eventType != XmlPullParser.Event.END_ELEMENT) {
195                            // throw exception
196                        }
197                    }
198
199                    queueDetails.addUser(new QueueUser(uid, position, time, joinTime));
200
201                    eventType = parser.next();
202                }
203            }
204            return queueDetails;
205        }
206    }
207}