• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * $RCSfile$
3  * $Revision$
4  * $Date$
5  *
6  * Copyright 2003-2007 Jive Software.
7  *
8  * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 package org.jivesoftware.smack.packet;
22 
23 import org.jivesoftware.smack.util.StringUtils;
24 
25 /**
26  * Represents XMPP presence packets. Every presence packet has a type, which is one of
27  * the following values:
28  * <ul>
29  *      <li>{@link Presence.Type#available available} -- (Default) indicates the user is available to
30  *          receive messages.
31  *      <li>{@link Presence.Type#unavailable unavailable} -- the user is unavailable to receive messages.
32  *      <li>{@link Presence.Type#subscribe subscribe} -- request subscription to recipient's presence.
33  *      <li>{@link Presence.Type#subscribed subscribed} -- grant subscription to sender's presence.
34  *      <li>{@link Presence.Type#unsubscribe unsubscribe} -- request removal of subscription to
35  *          sender's presence.
36  *      <li>{@link Presence.Type#unsubscribed unsubscribed} -- grant removal of subscription to
37  *          sender's presence.
38  *      <li>{@link Presence.Type#error error} -- the presence packet contains an error message.
39  * </ul><p>
40  *
41  * A number of attributes are optional:
42  * <ul>
43  *      <li>Status -- free-form text describing a user's presence (i.e., gone to lunch).
44  *      <li>Priority -- non-negative numerical priority of a sender's resource. The
45  *          highest resource priority is the default recipient of packets not addressed
46  *          to a particular resource.
47  *      <li>Mode -- one of five presence modes: {@link Mode#available available} (the default),
48  *          {@link Mode#chat chat}, {@link Mode#away away}, {@link Mode#xa xa} (extended away), and
49  *          {@link Mode#dnd dnd} (do not disturb).
50  * </ul><p>
51  *
52  * Presence packets are used for two purposes. First, to notify the server of our
53  * the clients current presence status. Second, they are used to subscribe and
54  * unsubscribe users from the roster.
55  *
56  * @see RosterPacket
57  * @author Matt Tucker
58  */
59 public class Presence extends Packet {
60 
61     private Type type = Type.available;
62     private String status = null;
63     private int priority = Integer.MIN_VALUE;
64     private Mode mode = null;
65     private String language;
66 
67     /**
68      * Creates a new presence update. Status, priority, and mode are left un-set.
69      *
70      * @param type the type.
71      */
Presence(Type type)72     public Presence(Type type) {
73         setType(type);
74     }
75 
76     /**
77      * Creates a new presence update with a specified status, priority, and mode.
78      *
79      * @param type the type.
80      * @param status a text message describing the presence update.
81      * @param priority the priority of this presence update.
82      * @param mode the mode type for this presence update.
83      */
Presence(Type type, String status, int priority, Mode mode)84     public Presence(Type type, String status, int priority, Mode mode) {
85         setType(type);
86         setStatus(status);
87         setPriority(priority);
88         setMode(mode);
89     }
90 
91     /**
92      * Returns true if the {@link Type presence type} is available (online) and
93      * false if the user is unavailable (offline), or if this is a presence packet
94      * involved in a subscription operation. This is a convenience method
95      * equivalent to <tt>getType() == Presence.Type.available</tt>. Note that even
96      * when the user is available, their presence mode may be {@link Mode#away away},
97      * {@link Mode#xa extended away} or {@link Mode#dnd do not disturb}. Use
98      * {@link #isAway()} to determine if the user is away.
99      *
100      * @return true if the presence type is available.
101      */
isAvailable()102     public boolean isAvailable() {
103         return type == Type.available;
104     }
105 
106     /**
107      * Returns true if the presence type is {@link Type#available available} and the presence
108      * mode is {@link Mode#away away}, {@link Mode#xa extended away}, or
109      * {@link Mode#dnd do not disturb}. False will be returned when the type or mode
110      * is any other value, including when the presence type is unavailable (offline).
111      * This is a convenience method equivalent to
112      * <tt>type == Type.available && (mode == Mode.away || mode == Mode.xa || mode == Mode.dnd)</tt>.
113      *
114      * @return true if the presence type is available and the presence mode is away, xa, or dnd.
115      */
isAway()116     public boolean isAway() {
117         return type == Type.available && (mode == Mode.away || mode == Mode.xa || mode == Mode.dnd);
118     }
119 
120     /**
121      * Returns the type of this presence packet.
122      *
123      * @return the type of the presence packet.
124      */
getType()125     public Type getType() {
126         return type;
127     }
128 
129     /**
130      * Sets the type of the presence packet.
131      *
132      * @param type the type of the presence packet.
133      */
setType(Type type)134     public void setType(Type type) {
135         if(type == null) {
136             throw new NullPointerException("Type cannot be null");
137         }
138         this.type = type;
139     }
140 
141     /**
142      * Returns the status message of the presence update, or <tt>null</tt> if there
143      * is not a status. The status is free-form text describing a user's presence
144      * (i.e., "gone to lunch").
145      *
146      * @return the status message.
147      */
getStatus()148     public String getStatus() {
149         return status;
150     }
151 
152     /**
153      * Sets the status message of the presence update. The status is free-form text
154      * describing a user's presence (i.e., "gone to lunch").
155      *
156      * @param status the status message.
157      */
setStatus(String status)158     public void setStatus(String status) {
159         this.status = status;
160     }
161 
162     /**
163      * Returns the priority of the presence, or Integer.MIN_VALUE if no priority has been set.
164      *
165      * @return the priority.
166      */
getPriority()167     public int getPriority() {
168         return priority;
169     }
170 
171     /**
172      * Sets the priority of the presence. The valid range is -128 through 128.
173      *
174      * @param priority the priority of the presence.
175      * @throws IllegalArgumentException if the priority is outside the valid range.
176      */
setPriority(int priority)177     public void setPriority(int priority) {
178         if (priority < -128 || priority > 128) {
179             throw new IllegalArgumentException("Priority value " + priority +
180                     " is not valid. Valid range is -128 through 128.");
181         }
182         this.priority = priority;
183     }
184 
185     /**
186      * Returns the mode of the presence update, or <tt>null</tt> if the mode is not set.
187      * A null presence mode value is interpreted to be the same thing as
188      * {@link Presence.Mode#available}.
189      *
190      * @return the mode.
191      */
getMode()192     public Mode getMode() {
193         return mode;
194     }
195 
196     /**
197      * Sets the mode of the presence update. A null presence mode value is interpreted
198      * to be the same thing as {@link Presence.Mode#available}.
199      *
200      * @param mode the mode.
201      */
setMode(Mode mode)202     public void setMode(Mode mode) {
203         this.mode = mode;
204     }
205 
206     /**
207      * Returns the xml:lang of this Presence, or null if one has not been set.
208      *
209      * @return the xml:lang of this Presence, or null if one has not been set.
210      * @since 3.0.2
211      */
getLanguage()212     public String getLanguage() {
213         return language;
214     }
215 
216     /**
217      * Sets the xml:lang of this Presence.
218      *
219      * @param language the xml:lang of this Presence.
220      * @since 3.0.2
221      */
setLanguage(String language)222     public void setLanguage(String language) {
223         this.language = language;
224     }
225 
toXML()226     public String toXML() {
227         StringBuilder buf = new StringBuilder();
228         buf.append("<presence");
229         if(getXmlns() != null) {
230             buf.append(" xmlns=\"").append(getXmlns()).append("\"");
231         }
232         if (language != null) {
233             buf.append(" xml:lang=\"").append(getLanguage()).append("\"");
234         }
235         if (getPacketID() != null) {
236             buf.append(" id=\"").append(getPacketID()).append("\"");
237         }
238         if (getTo() != null) {
239             buf.append(" to=\"").append(StringUtils.escapeForXML(getTo())).append("\"");
240         }
241         if (getFrom() != null) {
242             buf.append(" from=\"").append(StringUtils.escapeForXML(getFrom())).append("\"");
243         }
244         if (type != Type.available) {
245             buf.append(" type=\"").append(type).append("\"");
246         }
247         buf.append(">");
248         if (status != null) {
249             buf.append("<status>").append(StringUtils.escapeForXML(status)).append("</status>");
250         }
251         if (priority != Integer.MIN_VALUE) {
252             buf.append("<priority>").append(priority).append("</priority>");
253         }
254         if (mode != null && mode != Mode.available) {
255             buf.append("<show>").append(mode).append("</show>");
256         }
257 
258         buf.append(this.getExtensionsXML());
259 
260         // Add the error sub-packet, if there is one.
261         XMPPError error = getError();
262         if (error != null) {
263             buf.append(error.toXML());
264         }
265 
266         buf.append("</presence>");
267 
268         return buf.toString();
269     }
270 
toString()271     public String toString() {
272         StringBuilder buf = new StringBuilder();
273         buf.append(type);
274         if (mode != null) {
275             buf.append(": ").append(mode);
276         }
277         if (getStatus() != null) {
278             buf.append(" (").append(getStatus()).append(")");
279         }
280         return buf.toString();
281     }
282 
283     /**
284      * A enum to represent the presecence type. Not that presence type is often confused
285      * with presence mode. Generally, if a user is signed into a server, they have a presence
286      * type of {@link #available available}, even if the mode is {@link Mode#away away},
287      * {@link Mode#dnd dnd}, etc. The presence type is only {@link #unavailable unavailable} when
288      * the user is signing out of the server.
289      */
290     public enum Type {
291 
292        /**
293         * The user is available to receive messages (default).
294         */
295         available,
296 
297         /**
298          * The user is unavailable to receive messages.
299          */
300         unavailable,
301 
302         /**
303          * Request subscription to recipient's presence.
304          */
305         subscribe,
306 
307         /**
308          * Grant subscription to sender's presence.
309          */
310         subscribed,
311 
312         /**
313          * Request removal of subscription to sender's presence.
314          */
315         unsubscribe,
316 
317         /**
318          * Grant removal of subscription to sender's presence.
319          */
320         unsubscribed,
321 
322         /**
323          * The presence packet contains an error message.
324          */
325         error
326     }
327 
328     /**
329      * An enum to represent the presence mode.
330      */
331     public enum Mode {
332 
333         /**
334          * Free to chat.
335          */
336         chat,
337 
338         /**
339          * Available (the default).
340          */
341         available,
342 
343         /**
344          * Away.
345          */
346         away,
347 
348         /**
349          * Away for an extended period of time.
350          */
351         xa,
352 
353         /**
354          * Do not disturb.
355          */
356         dnd
357     }
358 }