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