Home | History | Annotate | Download | only in packet
      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