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 */
017package org.jivesoftware.smackx.workgroup.packet;
018
019import org.jivesoftware.smack.packet.PacketExtension;
020import org.jivesoftware.smack.provider.PacketExtensionProvider;
021import org.xmlpull.v1.XmlPullParser;
022
023import java.text.ParseException;
024import java.text.SimpleDateFormat;
025import java.util.*;
026
027/**
028 * Agent status packet.
029 *
030 * @author Matt Tucker
031 */
032public class AgentStatus implements PacketExtension {
033
034    private static final SimpleDateFormat UTC_FORMAT = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss");
035
036    static {
037        UTC_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT+0"));
038    }
039
040    /**
041     * Element name of the packet extension.
042     */
043    public static final String ELEMENT_NAME = "agent-status";
044
045    /**
046     * Namespace of the packet extension.
047     */
048    public static final String NAMESPACE = "http://jabber.org/protocol/workgroup";
049
050    private String workgroupJID;
051    private List<ChatInfo> currentChats = new ArrayList<ChatInfo>();
052    private int maxChats = -1;
053
054    AgentStatus() {
055    }
056
057    public String getWorkgroupJID() {
058        return workgroupJID;
059    }
060
061    /**
062     * Returns a collection of ChatInfo where each ChatInfo represents a Chat where this agent
063     * is participating.
064     *
065     * @return a collection of ChatInfo where each ChatInfo represents a Chat where this agent
066     *         is participating.
067     */
068    public List<ChatInfo> getCurrentChats() {
069        return Collections.unmodifiableList(currentChats);
070    }
071
072    public int getMaxChats() {
073        return maxChats;
074    }
075
076    public String getElementName() {
077        return ELEMENT_NAME;
078    }
079
080    public String getNamespace() {
081        return NAMESPACE;
082    }
083
084    public String toXML() {
085        StringBuilder buf = new StringBuilder();
086
087        buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\"");
088        if (workgroupJID != null) {
089            buf.append(" jid=\"").append(workgroupJID).append("\"");
090        }
091        buf.append(">");
092        if (maxChats != -1) {
093            buf.append("<max-chats>").append(maxChats).append("</max-chats>");
094        }
095        if (!currentChats.isEmpty()) {
096            buf.append("<current-chats xmlns= \"http://jivesoftware.com/protocol/workgroup\">");
097            for (Iterator<ChatInfo> it = currentChats.iterator(); it.hasNext();) {
098                buf.append(((ChatInfo)it.next()).toXML());
099            }
100            buf.append("</current-chats>");
101        }
102        buf.append("</").append(this.getElementName()).append("> ");
103
104        return buf.toString();
105    }
106
107    /**
108     * Represents information about a Chat where this Agent is participating.
109     *
110     * @author Gaston Dombiak
111     */
112    public static class ChatInfo {
113
114        private String sessionID;
115        private String userID;
116        private Date date;
117        private String email;
118        private String username;
119        private String question;
120
121        public ChatInfo(String sessionID, String userID, Date date, String email, String username, String question) {
122            this.sessionID = sessionID;
123            this.userID = userID;
124            this.date = date;
125            this.email = email;
126            this.username = username;
127            this.question = question;
128        }
129
130        /**
131         * Returns the sessionID associated to this chat. Each chat will have a unique sessionID
132         * that could be used for retrieving the whole transcript of the conversation.
133         *
134         * @return the sessionID associated to this chat.
135         */
136        public String getSessionID() {
137            return sessionID;
138        }
139
140        /**
141         * Returns the user unique identification of the user that made the initial request and
142         * for which this chat was generated. If the user joined using an anonymous connection
143         * then the userID will be the value of the ID attribute of the USER element. Otherwise,
144         * the userID will be the bare JID of the user that made the request.
145         *
146         * @return the user unique identification of the user that made the initial request.
147         */
148        public String getUserID() {
149            return userID;
150        }
151
152        /**
153         * Returns the date when this agent joined the chat.
154         *
155         * @return the date when this agent joined the chat.
156         */
157        public Date getDate() {
158            return date;
159        }
160
161        /**
162         * Returns the email address associated with the user.
163         *
164         * @return the email address associated with the user.
165         */
166        public String getEmail() {
167            return email;
168        }
169
170        /**
171         * Returns the username(nickname) associated with the user.
172         *
173         * @return the username associated with the user.
174         */
175        public String getUsername() {
176            return username;
177        }
178
179        /**
180         * Returns the question the user asked.
181         *
182         * @return the question the user asked, if any.
183         */
184        public String getQuestion() {
185            return question;
186        }
187
188        public String toXML() {
189            StringBuilder buf = new StringBuilder();
190
191            buf.append("<chat ");
192            if (sessionID != null) {
193                buf.append(" sessionID=\"").append(sessionID).append("\"");
194            }
195            if (userID != null) {
196                buf.append(" userID=\"").append(userID).append("\"");
197            }
198            if (date != null) {
199                buf.append(" startTime=\"").append(UTC_FORMAT.format(date)).append("\"");
200            }
201            if (email != null) {
202                buf.append(" email=\"").append(email).append("\"");
203            }
204            if (username != null) {
205                buf.append(" username=\"").append(username).append("\"");
206            }
207            if (question != null) {
208                buf.append(" question=\"").append(question).append("\"");
209            }
210            buf.append("/>");
211
212            return buf.toString();
213        }
214    }
215
216    /**
217     * Packet extension provider for AgentStatus packets.
218     */
219    public static class Provider implements PacketExtensionProvider {
220
221        public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
222            AgentStatus agentStatus = new AgentStatus();
223
224            agentStatus.workgroupJID = parser.getAttributeValue("", "jid");
225
226            boolean done = false;
227            while (!done) {
228                int eventType = parser.next();
229
230                if (eventType == XmlPullParser.START_TAG) {
231                    if ("chat".equals(parser.getName())) {
232                        agentStatus.currentChats.add(parseChatInfo(parser));
233                    }
234                    else if ("max-chats".equals(parser.getName())) {
235                        agentStatus.maxChats = Integer.parseInt(parser.nextText());
236                    }
237                }
238                else if (eventType == XmlPullParser.END_TAG &&
239                    ELEMENT_NAME.equals(parser.getName())) {
240                    done = true;
241                }
242            }
243            return agentStatus;
244        }
245
246        private ChatInfo parseChatInfo(XmlPullParser parser) {
247
248            String sessionID = parser.getAttributeValue("", "sessionID");
249            String userID = parser.getAttributeValue("", "userID");
250            Date date = null;
251            try {
252                date = UTC_FORMAT.parse(parser.getAttributeValue("", "startTime"));
253            }
254            catch (ParseException e) {
255            }
256
257            String email = parser.getAttributeValue("", "email");
258            String username = parser.getAttributeValue("", "username");
259            String question = parser.getAttributeValue("", "question");
260
261            return new ChatInfo(sessionID, userID, date, email, username, question);
262        }
263    }
264}