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