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