RosterEntry.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;

  18. import java.util.ArrayList;
  19. import java.util.Collection;
  20. import java.util.Iterator;
  21. import java.util.List;

  22. import org.jivesoftware.smack.SmackException.NoResponseException;
  23. import org.jivesoftware.smack.XMPPConnection;
  24. import org.jivesoftware.smack.SmackException.NotConnectedException;
  25. import org.jivesoftware.smack.XMPPException.XMPPErrorException;
  26. import org.jivesoftware.smack.packet.IQ;
  27. import org.jivesoftware.smack.roster.packet.RosterPacket;
  28. import org.jxmpp.jid.Jid;


  29. /**
  30.  * Each user in your roster is represented by a roster entry, which contains the user's
  31.  * JID and a name or nickname you assign.
  32.  *
  33.  * @author Matt Tucker
  34.  */
  35. public class RosterEntry {

  36.     /**
  37.      * The JID of the entity/user.
  38.      */
  39.     private final Jid user;

  40.     private String name;
  41.     private RosterPacket.ItemType type;
  42.     private RosterPacket.ItemStatus status;
  43.     final private Roster roster;
  44.     final private XMPPConnection connection;

  45.     /**
  46.      * Creates a new roster entry.
  47.      *
  48.      * @param user the user.
  49.      * @param name the nickname for the entry.
  50.      * @param type the subscription type.
  51.      * @param status the subscription status (related to subscriptions pending to be approbed).
  52.      * @param connection a connection to the XMPP server.
  53.      */
  54.     RosterEntry(Jid user, String name, RosterPacket.ItemType type,
  55.                 RosterPacket.ItemStatus status, Roster roster, XMPPConnection connection) {
  56.         this.user = user;
  57.         this.name = name;
  58.         this.type = type;
  59.         this.status = status;
  60.         this.roster = roster;
  61.         this.connection = connection;
  62.     }

  63.     /**
  64.      * Returns the JID of the user associated with this entry.
  65.      *
  66.      * @return the user associated with this entry.
  67.      */
  68.     public Jid getUser() {
  69.         return user;
  70.     }

  71.     /**
  72.      * Returns the name associated with this entry.
  73.      *
  74.      * @return the name.
  75.      */
  76.     public String getName() {
  77.         return name;
  78.     }

  79.     /**
  80.      * Sets the name associated with this entry.
  81.      *
  82.      * @param name the name.
  83.      * @throws NotConnectedException
  84.      * @throws XMPPErrorException
  85.      * @throws NoResponseException
  86.      * @throws InterruptedException
  87.      */
  88.     public void setName(String name) throws NotConnectedException, NoResponseException, XMPPErrorException, InterruptedException {
  89.         // Do nothing if the name hasn't changed.
  90.         if (name != null && name.equals(this.name)) {
  91.             return;
  92.         }

  93.         RosterPacket packet = new RosterPacket();
  94.         packet.setType(IQ.Type.set);
  95.         packet.addRosterItem(toRosterItem(this));
  96.         connection.createPacketCollectorAndSend(packet).nextResultOrThrow();

  97.         // We have received a result response to the IQ set, the name was successfully changed
  98.         this.name = name;
  99.     }

  100.     /**
  101.      * Updates the state of the entry with the new values.
  102.      *
  103.      * @param name the nickname for the entry.
  104.      * @param type the subscription type.
  105.      * @param status the subscription status (related to subscriptions pending to be approbed).
  106.      */
  107.     void updateState(String name, RosterPacket.ItemType type, RosterPacket.ItemStatus status) {
  108.         this.name = name;
  109.         this.type = type;
  110.         this.status = status;
  111.     }

  112.     /**
  113.      * Returns an copied list of the roster groups that this entry belongs to.
  114.      *
  115.      * @return an iterator for the groups this entry belongs to.
  116.      */
  117.     public List<RosterGroup> getGroups() {
  118.         List<RosterGroup> results = new ArrayList<RosterGroup>();
  119.         // Loop through all roster groups and find the ones that contain this
  120.         // entry. This algorithm should be fine
  121.         for (RosterGroup group: roster.getGroups()) {
  122.             if (group.contains(this)) {
  123.                 results.add(group);
  124.             }
  125.         }
  126.         return results;
  127.     }

  128.     /**
  129.      * Returns the roster subscription type of the entry. When the type is
  130.      * RosterPacket.ItemType.none or RosterPacket.ItemType.from,
  131.      * refer to {@link RosterEntry getStatus()} to see if a subscription request
  132.      * is pending.
  133.      *
  134.      * @return the type.
  135.      */
  136.     public RosterPacket.ItemType getType() {
  137.         return type;
  138.     }

  139.     /**
  140.      * Returns the roster subscription status of the entry. When the status is
  141.      * RosterPacket.ItemStatus.SUBSCRIPTION_PENDING, the contact has to answer the
  142.      * subscription request.
  143.      *
  144.      * @return the status.
  145.      */
  146.     public RosterPacket.ItemStatus getStatus() {
  147.         return status;
  148.     }

  149.     public String toString() {
  150.         StringBuilder buf = new StringBuilder();
  151.         if (name != null) {
  152.             buf.append(name).append(": ");
  153.         }
  154.         buf.append(user);
  155.         Collection<RosterGroup> groups = getGroups();
  156.         if (!groups.isEmpty()) {
  157.             buf.append(" [");
  158.             Iterator<RosterGroup> iter = groups.iterator();
  159.             RosterGroup group = iter.next();
  160.             buf.append(group.getName());
  161.             while (iter.hasNext()) {
  162.             buf.append(", ");
  163.                 group = iter.next();
  164.                 buf.append(group.getName());
  165.             }
  166.             buf.append("]");
  167.         }
  168.         return buf.toString();
  169.     }

  170.     @Override
  171.     public int hashCode() {
  172.         return (user == null ? 0 : user.hashCode());
  173.     }

  174.     public boolean equals(Object object) {
  175.         if (this == object) {
  176.             return true;
  177.         }
  178.         if (object != null && object instanceof RosterEntry) {
  179.             return user.equals(((RosterEntry)object).getUser());
  180.         }
  181.         else {
  182.             return false;
  183.         }
  184.     }

  185.     /**
  186.      * Indicates whether some other object is "equal to" this by comparing all members.
  187.      * <p>
  188.      * The {@link #equals(Object)} method returns <code>true</code> if the user JIDs are equal.
  189.      *
  190.      * @param obj the reference object with which to compare.
  191.      * @return <code>true</code> if this object is the same as the obj argument; <code>false</code>
  192.      *         otherwise.
  193.      */
  194.     public boolean equalsDeep(Object obj) {
  195.         if (this == obj)
  196.             return true;
  197.         if (obj == null)
  198.             return false;
  199.         if (getClass() != obj.getClass())
  200.             return false;
  201.         RosterEntry other = (RosterEntry) obj;
  202.         if (name == null) {
  203.             if (other.name != null)
  204.                 return false;
  205.         }
  206.         else if (!name.equals(other.name))
  207.             return false;
  208.         if (status == null) {
  209.             if (other.status != null)
  210.                 return false;
  211.         }
  212.         else if (!status.equals(other.status))
  213.             return false;
  214.         if (type == null) {
  215.             if (other.type != null)
  216.                 return false;
  217.         }
  218.         else if (!type.equals(other.type))
  219.             return false;
  220.         if (user == null) {
  221.             if (other.user != null)
  222.                 return false;
  223.         }
  224.         else if (!user.equals(other.user))
  225.             return false;
  226.         return true;
  227.     }
  228.    
  229.     static RosterPacket.Item toRosterItem(RosterEntry entry) {
  230.         RosterPacket.Item item = new RosterPacket.Item(entry.getUser(), entry.getName());
  231.         item.setItemType(entry.getType());
  232.         item.setItemStatus(entry.getStatus());
  233.         // Set the correct group names for the item.
  234.         for (RosterGroup group : entry.getGroups()) {
  235.             item.addGroupName(group.getName());
  236.         }
  237.         return item;
  238.     }

  239. }