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