Home | History | Annotate | Download | only in smack
      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;
     22 
     23 import org.jivesoftware.smack.packet.IQ;
     24 import org.jivesoftware.smack.packet.RosterPacket;
     25 
     26 import java.util.*;
     27 
     28 /**
     29  * Each user in your roster is represented by a roster entry, which contains the user's
     30  * JID and a name or nickname you assign.
     31  *
     32  * @author Matt Tucker
     33  */
     34 public class RosterEntry {
     35 
     36     private String user;
     37     private String name;
     38     private RosterPacket.ItemType type;
     39     private RosterPacket.ItemStatus status;
     40     final private Roster roster;
     41     final private Connection connection;
     42 
     43     /**
     44      * Creates a new roster entry.
     45      *
     46      * @param user the user.
     47      * @param name the nickname for the entry.
     48      * @param type the subscription type.
     49      * @param status the subscription status (related to subscriptions pending to be approbed).
     50      * @param connection a connection to the XMPP server.
     51      */
     52     RosterEntry(String user, String name, RosterPacket.ItemType type,
     53                 RosterPacket.ItemStatus status, Roster roster, Connection connection) {
     54         this.user = user;
     55         this.name = name;
     56         this.type = type;
     57         this.status = status;
     58         this.roster = roster;
     59         this.connection = connection;
     60     }
     61 
     62     /**
     63      * Returns the JID of the user associated with this entry.
     64      *
     65      * @return the user associated with this entry.
     66      */
     67     public String getUser() {
     68         return user;
     69     }
     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     /**
     81      * Sets the name associated with this entry.
     82      *
     83      * @param name the name.
     84      */
     85     public void setName(String name) {
     86         // Do nothing if the name hasn't changed.
     87         if (name != null && name.equals(this.name)) {
     88             return;
     89         }
     90         this.name = name;
     91         RosterPacket packet = new RosterPacket();
     92         packet.setType(IQ.Type.SET);
     93         packet.addRosterItem(toRosterItem(this));
     94         connection.sendPacket(packet);
     95     }
     96 
     97     /**
     98      * Updates the state of the entry with the new values.
     99      *
    100      * @param name the nickname for the entry.
    101      * @param type the subscription type.
    102      * @param status the subscription status (related to subscriptions pending to be approbed).
    103      */
    104     void updateState(String name, RosterPacket.ItemType type, RosterPacket.ItemStatus status) {
    105         this.name = name;
    106         this.type = type;
    107         this.status = status;
    108     }
    109 
    110     /**
    111      * Returns an unmodifiable collection of the roster groups that this entry belongs to.
    112      *
    113      * @return an iterator for the groups this entry belongs to.
    114      */
    115     public Collection<RosterGroup> getGroups() {
    116         List<RosterGroup> results = new ArrayList<RosterGroup>();
    117         // Loop through all roster groups and find the ones that contain this
    118         // entry. This algorithm should be fine
    119         for (RosterGroup group: roster.getGroups()) {
    120             if (group.contains(this)) {
    121                 results.add(group);
    122             }
    123         }
    124         return Collections.unmodifiableCollection(results);
    125     }
    126 
    127     /**
    128      * Returns the roster subscription type of the entry. When the type is
    129      * RosterPacket.ItemType.none or RosterPacket.ItemType.from,
    130      * refer to {@link RosterEntry getStatus()} to see if a subscription request
    131      * is pending.
    132      *
    133      * @return the type.
    134      */
    135     public RosterPacket.ItemType getType() {
    136         return type;
    137     }
    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 
    150     public String toString() {
    151         StringBuilder buf = new StringBuilder();
    152         if (name != null) {
    153             buf.append(name).append(": ");
    154         }
    155         buf.append(user);
    156         Collection<RosterGroup> groups = getGroups();
    157         if (!groups.isEmpty()) {
    158             buf.append(" [");
    159             Iterator<RosterGroup> iter = groups.iterator();
    160             RosterGroup group = iter.next();
    161             buf.append(group.getName());
    162             while (iter.hasNext()) {
    163             buf.append(", ");
    164                 group = iter.next();
    165                 buf.append(group.getName());
    166             }
    167             buf.append("]");
    168         }
    169         return buf.toString();
    170     }
    171 
    172     public boolean equals(Object object) {
    173         if (this == object) {
    174             return true;
    175         }
    176         if (object != null && object instanceof RosterEntry) {
    177             return user.equals(((RosterEntry)object).getUser());
    178         }
    179         else {
    180             return false;
    181         }
    182     }
    183 
    184     @Override
    185     public int hashCode() {
    186         return this.user.hashCode();
    187     }
    188 
    189     /**
    190      * Indicates whether some other object is "equal to" this by comparing all members.
    191      * <p>
    192      * The {@link #equals(Object)} method returns <code>true</code> if the user JIDs are equal.
    193      *
    194      * @param obj the reference object with which to compare.
    195      * @return <code>true</code> if this object is the same as the obj argument; <code>false</code>
    196      *         otherwise.
    197      */
    198     public boolean equalsDeep(Object obj) {
    199         if (this == obj)
    200             return true;
    201         if (obj == null)
    202             return false;
    203         if (getClass() != obj.getClass())
    204             return false;
    205         RosterEntry other = (RosterEntry) obj;
    206         if (name == null) {
    207             if (other.name != null)
    208                 return false;
    209         }
    210         else if (!name.equals(other.name))
    211             return false;
    212         if (status == null) {
    213             if (other.status != null)
    214                 return false;
    215         }
    216         else if (!status.equals(other.status))
    217             return false;
    218         if (type == null) {
    219             if (other.type != null)
    220                 return false;
    221         }
    222         else if (!type.equals(other.type))
    223             return false;
    224         if (user == null) {
    225             if (other.user != null)
    226                 return false;
    227         }
    228         else if (!user.equals(other.user))
    229             return false;
    230         return true;
    231     }
    232 
    233     static RosterPacket.Item toRosterItem(RosterEntry entry) {
    234         RosterPacket.Item item = new RosterPacket.Item(entry.getUser(), entry.getName());
    235         item.setItemType(entry.getType());
    236         item.setItemStatus(entry.getStatus());
    237         // Set the correct group names for the item.
    238         for (RosterGroup group : entry.getGroups()) {
    239             item.addGroupName(group.getName());
    240         }
    241         return item;
    242     }
    243 
    244 }