blob: 55b394ed7a738a44a83dbe3863a8a5fd61009305 [file] [log] [blame]
Shuyi Chend7955ce2013-05-22 14:51:55 -07001/**
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
21package org.jivesoftware.smack;
22
23import org.jivesoftware.smack.packet.IQ;
24import org.jivesoftware.smack.packet.RosterPacket;
25
26import 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 */
34public 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}