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 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 Set<QueueUser> users;
060
061    /**
062     * Creates a new QueueDetails packet
063     */
064    private QueueDetails() {
065        users = new HashSet<QueueUser>();
066    }
067
068    /**
069     * Returns the number of users currently in the queue that are waiting to
070     * be routed to an agent.
071     *
072     * @return the number of users in the queue.
073     */
074    public int getUserCount() {
075        return users.size();
076    }
077
078    /**
079     * Returns the set of users in the queue that are waiting to
080     * be routed to an agent (as QueueUser objects).
081     *
082     * @return a Set for the users waiting in a queue.
083     */
084    public Set<QueueUser> getUsers() {
085        synchronized (users) {
086            return users;
087        }
088    }
089
090    /**
091     * Adds a user to the packet.
092     *
093     * @param user the user.
094     */
095    private void addUser(QueueUser user) {
096        synchronized (users) {
097            users.add(user);
098        }
099    }
100
101    public String getElementName() {
102        return ELEMENT_NAME;
103    }
104
105    public String getNamespace() {
106        return NAMESPACE;
107    }
108
109    public String toXML() {
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 = (QueueUser)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(/packet) extensions.
145     */
146    public static class Provider extends ExtensionElementProvider<QueueDetails> {
147
148        @Override
149        public QueueDetails parse(XmlPullParser parser,
150                        int initialDepth) throws XmlPullParserException,
151                        IOException, SmackException {
152            
153            SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
154            QueueDetails queueDetails = new QueueDetails();
155
156            int eventType = parser.getEventType();
157            while (eventType != XmlPullParser.END_TAG &&
158                    "notify-queue-details".equals(parser.getName()))
159            {
160                eventType = parser.next();
161                while ((eventType == XmlPullParser.START_TAG) && "user".equals(parser.getName())) {
162                    String uid = null;
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.END_TAG)
175                                || (! "user".equals(parser.getName())))
176                    {                        
177                        if ("position".equals(parser.getName())) {
178                            position = Integer.parseInt(parser.nextText());
179                        }
180                        else if ("time".equals(parser.getName())) {
181                            time = Integer.parseInt(parser.nextText());
182                        }
183                        else if ("join-time".equals(parser.getName())) {
184                            try {
185                                joinTime = dateFormat.parse(parser.nextText());
186                            } catch (ParseException e) {
187                                throw new SmackException(e);
188                            }
189                        }
190                        else if( parser.getName().equals( "waitTime" ) ) {
191                            Date wait;
192                            try {
193                                wait = dateFormat.parse(parser.nextText());
194                            } catch (ParseException e) {
195                                throw new SmackException(e);
196                            }
197                            LOGGER.fine(wait.toString());
198                        }
199
200                        eventType = parser.next();
201
202                        if (eventType != XmlPullParser.END_TAG) {
203                            // throw exception
204                        }
205                    }
206
207                    queueDetails.addUser(new QueueUser(uid, position, time, joinTime));
208
209                    eventType = parser.next();
210                }
211            }
212            return queueDetails;
213        }
214    }
215}