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 }