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        @Override
149        public QueueDetails parse(XmlPullParser parser,
150                        int initialDepth, XmlEnvironment xmlEnvironment) throws XmlPullParserException,
151                        IOException, TextParseException, ParseException {
152
153            SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
154            QueueDetails queueDetails = new QueueDetails();
155
156            XmlPullParser.Event eventType = parser.getEventType();
157            while (eventType != XmlPullParser.Event.END_ELEMENT &&
158                    "notify-queue-details".equals(parser.getName())) {
159                eventType = parser.next();
160                while ((eventType == XmlPullParser.Event.START_ELEMENT) && "user".equals(parser.getName())) {
161                    String uid;
162                    int position = -1;
163                    int time = -1;
164                    Date joinTime = null;
165
166                    uid = parser.getAttributeValue("", "jid");
167
168                    if (uid == null) {
169                        // throw exception
170                    }
171
172                    eventType = parser.next();
173                    while (eventType != XmlPullParser.Event.END_ELEMENT
174                                || !"user".equals(parser.getName())) {
175                        if ("position".equals(parser.getName())) {
176                            position = Integer.parseInt(parser.nextText());
177                        }
178                        else if ("time".equals(parser.getName())) {
179                            time = Integer.parseInt(parser.nextText());
180                        }
181                        else if ("join-time".equals(parser.getName())) {
182                                joinTime = dateFormat.parse(parser.nextText());
183                        }
184                        else if (parser.getName().equals("waitTime")) {
185                            Date wait = dateFormat.parse(parser.nextText());
186                            LOGGER.fine(wait.toString());
187                        }
188
189                        eventType = parser.next();
190
191                        if (eventType != XmlPullParser.Event.END_ELEMENT) {
192                            // throw exception
193                        }
194                    }
195
196                    queueDetails.addUser(new QueueUser(uid, position, time, joinTime));
197
198                    eventType = parser.next();
199                }
200            }
201            return queueDetails;
202        }
203    }
204}