blob: 84fcfef50349d975cc781b21393f1ea6653f71e8 [file] [log] [blame]
Shuyi Chend7955ce2013-05-22 14:51:55 -07001/**
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
21package org.jivesoftware.smack.packet;
22
23import 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 */
59public 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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
222 public void setLanguage(String language) {
223 this.language = language;
224 }
225
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
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}