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
039/**
040 * Queue details stanza extension, which contains details about the users
041 * currently in a queue.
042 */
043public final class QueueDetails implements ExtensionElement {
044    private static final Logger LOGGER = Logger.getLogger(QueueDetails.class.getName());
045
046    /**
047     * Element name of the stanza extension.
048     */
049    public static final String ELEMENT_NAME = "notify-queue-details";
050
051    /**
052     * Namespace of the stanza extension.
053     */
054    public static final String NAMESPACE = "http://jabber.org/protocol/workgroup";
055    public static final QName QNAME = new QName(NAMESPACE, ELEMENT_NAME);
056
057    private static final String DATE_FORMAT = "yyyyMMdd'T'HH:mm:ss";
058
059    private final SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
060    /**
061     * The list of users in the queue.
062     */
063    private final Set<QueueUser> users = new HashSet<>();
064
065    /**
066     * Returns the number of users currently in the queue that are waiting to
067     * be routed to an agent.
068     *
069     * @return the number of users in the queue.
070     */
071    public int getUserCount() {
072        return users.size();
073    }
074
075    /**
076     * Returns the set of users in the queue that are waiting to
077     * be routed to an agent (as QueueUser objects).
078     *
079     * @return a Set for the users waiting in a queue.
080     */
081    public Set<QueueUser> getUsers() {
082        synchronized (users) {
083            return users;
084        }
085    }
086
087    /**
088     * Adds a user to the packet.
089     *
090     * @param user the user.
091     */
092    private void addUser(QueueUser user) {
093        synchronized (users) {
094            users.add(user);
095        }
096    }
097
098    @Override
099    public String getElementName() {
100        return ELEMENT_NAME;
101    }
102
103    @Override
104    public String getNamespace() {
105        return NAMESPACE;
106    }
107
108    @Override
109    public String toXML(org.jivesoftware.smack.packet.XmlEnvironment enclosingNamespace) {
110        StringBuilder buf = new StringBuilder();
111        buf.append('<').append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\">");
112
113        synchronized (users) {
114            for (Iterator<QueueUser> i = users.iterator(); i.hasNext(); ) {
115                QueueUser user = i.next();
116                int position = user.getQueuePosition();
117                int timeRemaining = user.getEstimatedRemainingTime();
118                Date timestamp = user.getQueueJoinTimestamp();
119
120                buf.append("<user jid=\"").append(user.getUserID()).append("\">");
121
122                if (position != -1) {
123                    buf.append("<position>").append(position).append("</position>");
124                }
125
126                if (timeRemaining != -1) {
127                    buf.append("<time>").append(timeRemaining).append("</time>");
128                }
129
130                if (timestamp != null) {
131                    buf.append("<join-time>");
132                    buf.append(dateFormat.format(timestamp));
133                    buf.append("</join-time>");
134                }
135
136                buf.append("</user>");
137            }
138        }
139        buf.append("</").append(ELEMENT_NAME).append('>');
140        return buf.toString();
141    }
142
143    /**
144     * Provider class for QueueDetails stanza extensions.
145     */
146    public static class Provider extends ExtensionElementProvider<QueueDetails> {
147
148        @SuppressWarnings("JavaUtilDate")
149        @Override
150        public QueueDetails parse(XmlPullParser parser,
151                        int initialDepth, XmlEnvironment xmlEnvironment) throws XmlPullParserException,
152                        IOException, TextParseException, ParseException {
153
154            SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
155            QueueDetails queueDetails = new QueueDetails();
156
157            XmlPullParser.Event eventType = parser.getEventType();
158            while (eventType != XmlPullParser.Event.END_ELEMENT &&
159                    "notify-queue-details".equals(parser.getName())) {
160                eventType = parser.next();
161                while ((eventType == XmlPullParser.Event.START_ELEMENT) && "user".equals(parser.getName())) {
162                    String uid;
163                    int position = -1;
164                    int time = -1;
165                    Date joinTime = null;
166
167                    uid = parser.getAttributeValue("", "jid");
168
169                    if (uid == null) {
170                        // throw exception
171                    }
172
173                    eventType = parser.next();
174                    while (eventType != XmlPullParser.Event.END_ELEMENT
175                                || !"user".equals(parser.getName())) {
176                        if ("position".equals(parser.getName())) {
177                            position = Integer.parseInt(parser.nextText());
178                        }
179                        else if ("time".equals(parser.getName())) {
180                            time = Integer.parseInt(parser.nextText());
181                        }
182                        else if ("join-time".equals(parser.getName())) {
183                                joinTime = dateFormat.parse(parser.nextText());
184                        }
185                        else if (parser.getName().equals("waitTime")) {
186                            Date wait = dateFormat.parse(parser.nextText());
187                            LOGGER.fine(wait.toString());
188                        }
189
190                        eventType = parser.next();
191
192                        if (eventType != XmlPullParser.Event.END_ELEMENT) {
193                            // throw exception
194                        }
195                    }
196
197                    queueDetails.addUser(new QueueUser(uid, position, time, joinTime));
198
199                    eventType = parser.next();
200                }
201            }
202            return queueDetails;
203        }
204    }
205}