RosterPacket.java

  1. /**
  2.  *
  3.  * Copyright 2003-2007 Jive Software.
  4.  *
  5.  * Licensed under the Apache License, Version 2.0 (the "License");
  6.  * you may not use this file except in compliance with the License.
  7.  * You may obtain a copy of the License at
  8.  *
  9.  *     http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */

  17. package org.jivesoftware.smack.roster.packet;

  18. import org.jivesoftware.smack.packet.IQ;
  19. import org.jivesoftware.smack.packet.Stanza;
  20. import org.jivesoftware.smack.util.XmlStringBuilder;
  21. import org.jxmpp.jid.Jid;

  22. import java.util.ArrayList;
  23. import java.util.Collections;
  24. import java.util.List;
  25. import java.util.Set;
  26. import java.util.concurrent.CopyOnWriteArraySet;

  27. /**
  28.  * Represents XMPP roster packets.
  29.  *
  30.  * @author Matt Tucker
  31.  */
  32. public class RosterPacket extends IQ {

  33.     public static final String ELEMENT = QUERY_ELEMENT;
  34.     public static final String NAMESPACE = "jabber:iq:roster";

  35.     private final List<Item> rosterItems = new ArrayList<Item>();
  36.     private String rosterVersion;

  37.     public RosterPacket() {
  38.         super(ELEMENT, NAMESPACE);
  39.     }

  40.     /**
  41.      * Adds a roster item to the packet.
  42.      *
  43.      * @param item a roster item.
  44.      */
  45.     public void addRosterItem(Item item) {
  46.         synchronized (rosterItems) {
  47.             rosterItems.add(item);
  48.         }
  49.     }

  50.     /**
  51.      * Returns the number of roster items in this roster packet.
  52.      *
  53.      * @return the number of roster items.
  54.      */
  55.     public int getRosterItemCount() {
  56.         synchronized (rosterItems) {
  57.             return rosterItems.size();
  58.         }
  59.     }

  60.     /**
  61.      * Returns a copied list of the roster items in the packet.
  62.      *
  63.      * @return a copied list of the roster items in the packet.
  64.      */
  65.     public List<Item> getRosterItems() {
  66.         synchronized (rosterItems) {
  67.             return new ArrayList<Item>(rosterItems);
  68.         }
  69.     }

  70.     @Override
  71.     protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder buf) {
  72.         buf.optAttribute("ver", rosterVersion);
  73.         buf.rightAngleBracket();

  74.         synchronized (rosterItems) {
  75.             for (Item entry : rosterItems) {
  76.                 buf.append(entry.toXML());
  77.             }
  78.         }
  79.         return buf;
  80.     }

  81.     public String getVersion() {
  82.         return rosterVersion;
  83.     }

  84.     public void setVersion(String version) {
  85.         rosterVersion = version;
  86.     }

  87.     /**
  88.      * A roster item, which consists of a JID, their name, the type of subscription, and
  89.      * the groups the roster item belongs to.
  90.      */
  91.     public static class Item {

  92.         public static final String GROUP = "group";

  93.         private final Jid user;
  94.         private String name;
  95.         private ItemType itemType;
  96.         private ItemStatus itemStatus;
  97.         private final Set<String> groupNames;

  98.         /**
  99.          * Creates a new roster item.
  100.          *
  101.          * @param user the user.
  102.          * @param name the user's name.
  103.          */
  104.         public Item(Jid user, String name) {
  105.             this.user = user;
  106.             this.name = name;
  107.             itemType = null;
  108.             itemStatus = null;
  109.             groupNames = new CopyOnWriteArraySet<String>();
  110.         }

  111.         /**
  112.          * Returns the user.
  113.          *
  114.          * @return the user.
  115.          */
  116.         public Jid getUser() {
  117.             return user;
  118.         }

  119.         /**
  120.          * Returns the user's name.
  121.          *
  122.          * @return the user's name.
  123.          */
  124.         public String getName() {
  125.             return name;
  126.         }

  127.         /**
  128.          * Sets the user's name.
  129.          *
  130.          * @param name the user's name.
  131.          */
  132.         public void setName(String name) {
  133.             this.name = name;
  134.         }

  135.         /**
  136.          * Returns the roster item type.
  137.          *
  138.          * @return the roster item type.
  139.          */
  140.         public ItemType getItemType() {
  141.             return itemType;
  142.         }

  143.         /**
  144.          * Sets the roster item type.
  145.          *
  146.          * @param itemType the roster item type.
  147.          */
  148.         public void setItemType(ItemType itemType) {
  149.             this.itemType = itemType;
  150.         }

  151.         /**
  152.          * Returns the roster item status.
  153.          *
  154.          * @return the roster item status.
  155.          */
  156.         public ItemStatus getItemStatus() {
  157.             return itemStatus;
  158.         }

  159.         /**
  160.          * Sets the roster item status.
  161.          *
  162.          * @param itemStatus the roster item status.
  163.          */
  164.         public void setItemStatus(ItemStatus itemStatus) {
  165.             this.itemStatus = itemStatus;
  166.         }

  167.         /**
  168.          * Returns an unmodifiable set of the group names that the roster item
  169.          * belongs to.
  170.          *
  171.          * @return an unmodifiable set of the group names.
  172.          */
  173.         public Set<String> getGroupNames() {
  174.             return Collections.unmodifiableSet(groupNames);
  175.         }

  176.         /**
  177.          * Adds a group name.
  178.          *
  179.          * @param groupName the group name.
  180.          */
  181.         public void addGroupName(String groupName) {
  182.             groupNames.add(groupName);
  183.         }

  184.         /**
  185.          * Removes a group name.
  186.          *
  187.          * @param groupName the group name.
  188.          */
  189.         public void removeGroupName(String groupName) {
  190.             groupNames.remove(groupName);
  191.         }

  192.         public XmlStringBuilder toXML() {
  193.             XmlStringBuilder xml = new XmlStringBuilder();
  194.             xml.halfOpenElement(Stanza.ITEM).attribute("jid", user);
  195.             xml.optAttribute("name", name);
  196.             xml.optAttribute("subscription", itemType);
  197.             xml.optAttribute("ask", itemStatus);
  198.             xml.rightAngleBracket();

  199.             for (String groupName : groupNames) {
  200.                 xml.openElement(GROUP).escape(groupName).closeElement(GROUP);
  201.             }
  202.             xml.closeElement(Stanza.ITEM);
  203.             return xml;
  204.         }

  205.         @Override
  206.         public int hashCode() {
  207.             final int prime = 31;
  208.             int result = 1;
  209.             result = prime * result + ((groupNames == null) ? 0 : groupNames.hashCode());
  210.             result = prime * result + ((itemStatus == null) ? 0 : itemStatus.hashCode());
  211.             result = prime * result + ((itemType == null) ? 0 : itemType.hashCode());
  212.             result = prime * result + ((name == null) ? 0 : name.hashCode());
  213.             result = prime * result + ((user == null) ? 0 : user.hashCode());
  214.             return result;
  215.         }

  216.         @Override
  217.         public boolean equals(Object obj) {
  218.             if (this == obj)
  219.                 return true;
  220.             if (obj == null)
  221.                 return false;
  222.             if (getClass() != obj.getClass())
  223.                 return false;
  224.             Item other = (Item) obj;
  225.             if (groupNames == null) {
  226.                 if (other.groupNames != null)
  227.                     return false;
  228.             }
  229.             else if (!groupNames.equals(other.groupNames))
  230.                 return false;
  231.             if (itemStatus != other.itemStatus)
  232.                 return false;
  233.             if (itemType != other.itemType)
  234.                 return false;
  235.             if (name == null) {
  236.                 if (other.name != null)
  237.                     return false;
  238.             }
  239.             else if (!name.equals(other.name))
  240.                 return false;
  241.             if (user == null) {
  242.                 if (other.user != null)
  243.                     return false;
  244.             }
  245.             else if (!user.equals(other.user))
  246.                 return false;
  247.             return true;
  248.         }

  249.     }

  250.     /**
  251.      * The subscription status of a roster item. An optional element that indicates
  252.      * the subscription status if a change request is pending.
  253.      */
  254.     public static enum ItemStatus {
  255.         /**
  256.          * Request to subscribe
  257.          */
  258.         subscribe,

  259.         /**
  260.          * Request to unsubscribe
  261.          */
  262.         unsubscribe;

  263.         public static final ItemStatus SUBSCRIPTION_PENDING = subscribe;
  264.         public static final ItemStatus UNSUBSCRIPTION_PENDING = unsubscribe;

  265.         public static ItemStatus fromString(String s) {
  266.             if (s == null) {
  267.                 return null;
  268.             }
  269.             try {
  270.                 return ItemStatus.valueOf(s);
  271.             }
  272.             catch (IllegalArgumentException e) {
  273.                 return null;
  274.             }
  275.         }
  276.     }

  277.     public static enum ItemType {

  278.         /**
  279.          * The user does not have a subscription to the contact's presence, and the contact does not
  280.          * have a subscription to the user's presence; this is the default value, so if the
  281.          * subscription attribute is not included then the state is to be understood as "none".
  282.          */
  283.         none,

  284.         /**
  285.          * The user has a subscription to the contact's presence, but the contact does not have a
  286.          * subscription to the user's presence.
  287.          */
  288.         to,

  289.         /**
  290.          * The contact has a subscription to the user's presence, but the user does not have a
  291.          * subscription to the contact's presence.
  292.          */
  293.         from,

  294.         /**
  295.          * The user and the contact have subscriptions to each other's presence (also called a
  296.          * "mutual subscription").
  297.          */
  298.         both,

  299.         /**
  300.          * The user wishes to stop receiving presence updates from the subscriber.
  301.          */
  302.         remove
  303.     }
  304. }