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 }