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 import java.util.*; 26 import java.util.concurrent.CopyOnWriteArraySet; 27 28 /** 29 * Represents XMPP roster packets. 30 * 31 * @author Matt Tucker 32 */ 33 public class RosterPacket extends IQ { 34 35 private final List<Item> rosterItems = new ArrayList<Item>(); 36 /* 37 * The ver attribute following XEP-0237 38 */ 39 private String version; 40 41 /** 42 * Adds a roster item to the packet. 43 * 44 * @param item a roster item. 45 */ 46 public void addRosterItem(Item item) { 47 synchronized (rosterItems) { 48 rosterItems.add(item); 49 } 50 } 51 52 public String getVersion(){ 53 return version; 54 } 55 56 public void setVersion(String version){ 57 this.version = version; 58 } 59 60 /** 61 * Returns the number of roster items in this roster packet. 62 * 63 * @return the number of roster items. 64 */ 65 public int getRosterItemCount() { 66 synchronized (rosterItems) { 67 return rosterItems.size(); 68 } 69 } 70 71 /** 72 * Returns an unmodifiable collection for the roster items in the packet. 73 * 74 * @return an unmodifiable collection for the roster items in the packet. 75 */ 76 public Collection<Item> getRosterItems() { 77 synchronized (rosterItems) { 78 return Collections.unmodifiableList(new ArrayList<Item>(rosterItems)); 79 } 80 } 81 82 public String getChildElementXML() { 83 StringBuilder buf = new StringBuilder(); 84 buf.append("<query xmlns=\"jabber:iq:roster\" "); 85 if(version!=null){ 86 buf.append(" ver=\""+version+"\" "); 87 } 88 buf.append(">"); 89 synchronized (rosterItems) { 90 for (Item entry : rosterItems) { 91 buf.append(entry.toXML()); 92 } 93 } 94 buf.append("</query>"); 95 return buf.toString(); 96 } 97 98 /** 99 * A roster item, which consists of a JID, their name, the type of subscription, and 100 * the groups the roster item belongs to. 101 */ 102 public static class Item { 103 104 private String user; 105 private String name; 106 private ItemType itemType; 107 private ItemStatus itemStatus; 108 private final Set<String> groupNames; 109 110 /** 111 * Creates a new roster item. 112 * 113 * @param user the user. 114 * @param name the user's name. 115 */ 116 public Item(String user, String name) { 117 this.user = user.toLowerCase(); 118 this.name = name; 119 itemType = null; 120 itemStatus = null; 121 groupNames = new CopyOnWriteArraySet<String>(); 122 } 123 124 /** 125 * Returns the user. 126 * 127 * @return the user. 128 */ 129 public String getUser() { 130 return user; 131 } 132 133 /** 134 * Returns the user's name. 135 * 136 * @return the user's name. 137 */ 138 public String getName() { 139 return name; 140 } 141 142 /** 143 * Sets the user's name. 144 * 145 * @param name the user's name. 146 */ 147 public void setName(String name) { 148 this.name = name; 149 } 150 151 /** 152 * Returns the roster item type. 153 * 154 * @return the roster item type. 155 */ 156 public ItemType getItemType() { 157 return itemType; 158 } 159 160 /** 161 * Sets the roster item type. 162 * 163 * @param itemType the roster item type. 164 */ 165 public void setItemType(ItemType itemType) { 166 this.itemType = itemType; 167 } 168 169 /** 170 * Returns the roster item status. 171 * 172 * @return the roster item status. 173 */ 174 public ItemStatus getItemStatus() { 175 return itemStatus; 176 } 177 178 /** 179 * Sets the roster item status. 180 * 181 * @param itemStatus the roster item status. 182 */ 183 public void setItemStatus(ItemStatus itemStatus) { 184 this.itemStatus = itemStatus; 185 } 186 187 /** 188 * Returns an unmodifiable set of the group names that the roster item 189 * belongs to. 190 * 191 * @return an unmodifiable set of the group names. 192 */ 193 public Set<String> getGroupNames() { 194 return Collections.unmodifiableSet(groupNames); 195 } 196 197 /** 198 * Adds a group name. 199 * 200 * @param groupName the group name. 201 */ 202 public void addGroupName(String groupName) { 203 groupNames.add(groupName); 204 } 205 206 /** 207 * Removes a group name. 208 * 209 * @param groupName the group name. 210 */ 211 public void removeGroupName(String groupName) { 212 groupNames.remove(groupName); 213 } 214 215 public String toXML() { 216 StringBuilder buf = new StringBuilder(); 217 buf.append("<item jid=\"").append(user).append("\""); 218 if (name != null) { 219 buf.append(" name=\"").append(StringUtils.escapeForXML(name)).append("\""); 220 } 221 if (itemType != null) { 222 buf.append(" subscription=\"").append(itemType).append("\""); 223 } 224 if (itemStatus != null) { 225 buf.append(" ask=\"").append(itemStatus).append("\""); 226 } 227 buf.append(">"); 228 for (String groupName : groupNames) { 229 buf.append("<group>").append(StringUtils.escapeForXML(groupName)).append("</group>"); 230 } 231 buf.append("</item>"); 232 return buf.toString(); 233 } 234 } 235 236 /** 237 * The subscription status of a roster item. An optional element that indicates 238 * the subscription status if a change request is pending. 239 */ 240 public static class ItemStatus { 241 242 /** 243 * Request to subcribe. 244 */ 245 public static final ItemStatus SUBSCRIPTION_PENDING = new ItemStatus("subscribe"); 246 247 /** 248 * Request to unsubscribe. 249 */ 250 public static final ItemStatus UNSUBSCRIPTION_PENDING = new ItemStatus("unsubscribe"); 251 252 public static ItemStatus fromString(String value) { 253 if (value == null) { 254 return null; 255 } 256 value = value.toLowerCase(); 257 if ("unsubscribe".equals(value)) { 258 return UNSUBSCRIPTION_PENDING; 259 } 260 else if ("subscribe".equals(value)) { 261 return SUBSCRIPTION_PENDING; 262 } 263 else { 264 return null; 265 } 266 } 267 268 private String value; 269 270 /** 271 * Returns the item status associated with the specified string. 272 * 273 * @param value the item status. 274 */ 275 private ItemStatus(String value) { 276 this.value = value; 277 } 278 279 public String toString() { 280 return value; 281 } 282 } 283 284 public static enum ItemType { 285 286 /** 287 * The user and subscriber have no interest in each other's presence. 288 */ 289 none, 290 291 /** 292 * The user is interested in receiving presence updates from the subscriber. 293 */ 294 to, 295 296 /** 297 * The subscriber is interested in receiving presence updates from the user. 298 */ 299 from, 300 301 /** 302 * The user and subscriber have a mutual interest in each other's presence. 303 */ 304 both, 305 306 /** 307 * The user wishes to stop receiving presence updates from the subscriber. 308 */ 309 remove 310 } 311 } 312