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