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 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 extension. 047 */ 048 public static final String ELEMENT_NAME = "notify-queue-details"; 049 050 /** 051 * Namespace of the stanza 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(String enclosingNamespace) { 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 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 eventType = parser.next(); 158 while ((eventType == XmlPullParser.START_TAG) && "user".equals(parser.getName())) { 159 String uid; 160 int position = -1; 161 int time = -1; 162 Date joinTime = null; 163 164 uid = parser.getAttributeValue("", "jid"); 165 166 if (uid == null) { 167 // throw exception 168 } 169 170 eventType = parser.next(); 171 while ((eventType != XmlPullParser.END_TAG) 172 || (!"user".equals(parser.getName()))) { 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}