KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jivesoftware > messenger > roster > RosterItem


1 /**
2  * $RCSfile: RosterItem.java,v $
3  * $Revision: 1.7 $
4  * $Date: 2005/02/20 22:29:36 $
5  *
6  * Copyright (C) 2004 Jive Software. All rights reserved.
7  *
8  * This software is published under the terms of the GNU Public License (GPL),
9  * a copy of which is included in this distribution.
10  */

11
12 package org.jivesoftware.messenger.roster;
13
14 import org.jivesoftware.util.IntEnum;
15 import org.jivesoftware.util.Cacheable;
16 import org.jivesoftware.util.CacheSizes;
17 import org.jivesoftware.messenger.group.GroupManager;
18 import org.jivesoftware.messenger.group.GroupNotFoundException;
19 import org.jivesoftware.messenger.group.Group;
20 import org.jivesoftware.messenger.SharedGroupException;
21 import org.xmpp.packet.JID;
22
23 import java.util.*;
24
25 /**
26  * <p>Represents a single roster item for a User's Roster.</p>
27  * <p>The server doesn't need to know anything about roster groups so they are
28  * not stored with easy retrieval or manipulation in mind. The important data
29  * elements of a roster item (beyond the jid adddress of the roster entry) includes:</p>
30  * <p/>
31  * <ul>
32  * <li>nick - A nickname for the user when used in this roster</li>
33  * <li>sub - A subscription type: to, from, none, both</li>
34  * <li>ask - An optional subscription ask status: subscribe, unsubscribe</li>
35  * <li>groups - A list of groups to organize roster entries under (e.g. friends, co-workers, etc)</li>
36  * </ul>
37  *
38  * @author Gaston Dombiak
39  */

40 public class RosterItem implements Cacheable {
41
42     public static class SubType extends IntEnum {
43         protected SubType(String JavaDoc name, int value) {
44             super(name, value);
45             register(this);
46         }
47
48         public static SubType getTypeFromInt(int value) {
49             return (SubType)getEnumFromInt(SubType.class, value);
50         }
51     }
52
53     public static class AskType extends IntEnum {
54         protected AskType(String JavaDoc name, int value) {
55             super(name, value);
56             register(this);
57         }
58
59         public static AskType getTypeFromInt(int value) {
60             return (AskType)getEnumFromInt(AskType.class, value);
61         }
62     }
63
64     public static class RecvType extends IntEnum {
65         protected RecvType(String JavaDoc name, int value) {
66             super(name, value);
67             register(this);
68         }
69
70         public static RecvType getTypeFromInt(int value) {
71             return (RecvType)getEnumFromInt(RecvType.class, value);
72         }
73     }
74
75     /**
76      * <p>Indicates the roster item should be removed.</p>
77      */

78     public static final SubType SUB_REMOVE = new SubType("remove", -1);
79     /**
80      * <p>No subscription is established.</p>
81      */

82     public static final SubType SUB_NONE = new SubType("none", 0);
83     /**
84      * <p>The roster owner has a subscription to the roster item's presence.</p>
85      */

86     public static final SubType SUB_TO = new SubType("to", 1);
87     /**
88      * <p>The roster item has a subscription to the roster owner's presence.</p>
89      */

90     public static final SubType SUB_FROM = new SubType("from", 2);
91     /**
92      * <p>The roster item and owner have a mutual subscription.</p>
93      */

94     public static final SubType SUB_BOTH = new SubType("both", 3);
95
96     /**
97      * <p>The roster item has no pending subscripton requests.</p>
98      */

99     public static final AskType ASK_NONE = new AskType("", -1);
100     /**
101      * <p>The roster item has been asked for permission to subscribe to their presence
102      * but no response has been received.</p>
103      */

104     public static final AskType ASK_SUBSCRIBE = new AskType("subscribe", 0);
105     /**
106      * <p>The roster owner has asked to the roster item to unsubscribe from it's
107      * presence but has not received confirmation.</p>
108      */

109     public static final AskType ASK_UNSUBSCRIBE = new AskType("unsubscribe", 1);
110
111     /**
112      * <p>There are no subscriptions that have been received but not presented to the user.</p>
113      */

114     public static final RecvType RECV_NONE = new RecvType("", -1);
115     /**
116      * <p>The server has received a subscribe request, but has not forwarded it to the user.</p>
117      */

118     public static final RecvType RECV_SUBSCRIBE = new RecvType("sub", 1);
119     /**
120      * <p>The server has received an unsubscribe request, but has not forwarded it to the user.</p>
121      */

122     public static final RecvType RECV_UNSUBSCRIBE = new RecvType("unsub", 2);
123
124     protected RecvType recvStatus;
125     protected JID jid;
126     protected String JavaDoc nickname;
127     protected List<String JavaDoc> groups;
128     protected Set<Group> sharedGroups = new HashSet<Group>();
129     protected Set<Group> invisibleSharedGroups = new HashSet<Group>();
130     protected SubType subStatus;
131     protected AskType askStatus;
132     private long rosterID;
133
134     public RosterItem(long id,
135                                 JID jid,
136                                 SubType subStatus,
137                                 AskType askStatus,
138                                 RecvType recvStatus,
139                                 String JavaDoc nickname,
140                                 List<String JavaDoc> groups) {
141         this(jid, subStatus, askStatus, recvStatus, nickname, groups);
142         this.rosterID = id;
143     }
144
145     public RosterItem(JID jid,
146                            SubType subStatus,
147                            AskType askStatus,
148                            RecvType recvStatus,
149                            String JavaDoc nickname,
150                            List<String JavaDoc> groups) {
151         this.jid = jid;
152         this.subStatus = subStatus;
153         this.askStatus = askStatus;
154         this.recvStatus = recvStatus;
155         this.nickname = nickname;
156         this.groups = new LinkedList<String JavaDoc>();
157         if (groups != null) {
158             for (String JavaDoc group : groups) {
159                 this.groups.add(group);
160             }
161         }
162     }
163
164     /**
165      * <p>Create a roster item from the data in another one.</p>
166      *
167      * @param item
168      */

169     public RosterItem(org.xmpp.packet.Roster.Item item) {
170         this(item.getJID(),
171                 getSubType(item),
172                 getAskStatus(item),
173                 RosterItem.RECV_NONE,
174                 item.getName(),
175                 new LinkedList<String JavaDoc>(item.getGroups()));
176     }
177
178     private static RosterItem.AskType getAskStatus(org.xmpp.packet.Roster.Item item) {
179         if (item.getAsk() == org.xmpp.packet.Roster.Ask.subscribe) {
180             return RosterItem.ASK_SUBSCRIBE;
181         }
182         else if (item.getAsk() == org.xmpp.packet.Roster.Ask.unsubscribe) {
183             return RosterItem.ASK_UNSUBSCRIBE;
184         }
185         else {
186             return RosterItem.ASK_NONE;
187         }
188     }
189
190     private static RosterItem.SubType getSubType(org.xmpp.packet.Roster.Item item) {
191         if (item.getSubscription() == org.xmpp.packet.Roster.Subscription.to) {
192             return RosterItem.SUB_TO;
193         }
194         else if (item.getSubscription() == org.xmpp.packet.Roster.Subscription.from) {
195             return RosterItem.SUB_FROM;
196         }
197         else if (item.getSubscription() == org.xmpp.packet.Roster.Subscription.both) {
198             return RosterItem.SUB_BOTH;
199         }
200         else if (item.getSubscription() == org.xmpp.packet.Roster.Subscription.remove) {
201             return RosterItem.SUB_REMOVE;
202         }
203         else {
204             return RosterItem.SUB_NONE;
205         }
206     }
207
208     /**
209      * <p>Obtain the current subscription status of the item.</p>
210      *
211      * @return The subscription status of the item
212      */

213     public SubType getSubStatus() {
214         return subStatus;
215     }
216
217     /**
218      * <p>Set the current subscription status of the item.</p>
219      *
220      * @param subStatus The subscription status of the item
221      */

222     public void setSubStatus(SubType subStatus) {
223         this.subStatus = subStatus;
224     }
225
226     /**
227      * <p>Obtain the current ask status of the item.</p>
228      *
229      * @return The ask status of the item
230      */

231     public AskType getAskStatus() {
232         if (isShared()) {
233             // Redefine the ask status since the item belongs to a shared group
234
return ASK_NONE;
235         }
236         else {
237             return askStatus;
238         }
239     }
240
241     /**
242      * <p>Set the current ask status of the item.</p>
243      *
244      * @param askStatus The ask status of the item
245      */

246     public void setAskStatus(AskType askStatus) {
247         this.askStatus = askStatus;
248     }
249
250     /**
251      * <p>Obtain the current recv status of the item.</p>
252      *
253      * @return The recv status of the item
254      */

255     public RecvType getRecvStatus() {
256         return recvStatus;
257     }
258
259     /**
260      * <p>Set the current recv status of the item.</p>
261      *
262      * @param recvStatus The recv status of the item
263      */

264     public void setRecvStatus(RecvType recvStatus) {
265         this.recvStatus = recvStatus;
266     }
267
268     /**
269      * <p>Obtain the address of the item.</p>
270      *
271      * @return The address of the item
272      */

273     public JID getJid() {
274         return jid;
275     }
276
277     /**
278      * <p>Obtain the current nickname for the item.</p>
279      *
280      * @return The subscription status of the item
281      */

282     public String JavaDoc getNickname() {
283         return nickname;
284     }
285
286     /**
287      * <p>Set the current nickname for the item.</p>
288      *
289      * @param nickname The subscription status of the item
290      */

291     public void setNickname(String JavaDoc nickname) {
292         this.nickname = nickname;
293     }
294
295     /**
296      * Returns the groups for the item. Shared groups won't be included in the answer.
297      *
298      * @return The groups for the item.
299      */

300     public List<String JavaDoc> getGroups() {
301         return groups;
302     }
303
304     /**
305      * <p>Set the current groups for the item.</p>
306      *
307      * @param groups The new lists of groups the item belongs to.
308      */

309     public void setGroups(List<String JavaDoc> groups) throws SharedGroupException {
310         if (groups == null) {
311             this.groups = new LinkedList<String JavaDoc>();
312         }
313         else {
314             // Raise an error if the user is trying to remove the item from a shared group
315
for (Group group: getSharedGroups()) {
316                 // Get the display name of the group
317
String JavaDoc groupName = group.getProperties().get("sharedRoster.displayName");
318                 // Check if the group has been removed from the new groups list
319
if (!groups.contains(groupName)) {
320                     throw new SharedGroupException("Cannot remove item from shared group");
321                 }
322             }
323
324             // Remove shared groups from the param
325
for (Iterator<String JavaDoc> it=groups.iterator(); it.hasNext();) {
326                 try {
327                     String JavaDoc group = it.next();
328                     // Check if exists a shared group with this name
329
GroupManager.getInstance().getGroup(group);
330                     // Remove the shared group from the list (since it exists)
331
it.remove();
332                 }
333                 catch (GroupNotFoundException e) {
334                     // Do nothing since the group is a personal group
335
}
336             }
337             this.groups = groups;
338         }
339     }
340
341     /**
342      * Returns the shared groups for the item.
343      *
344      * @return The shared groups this item belongs to.
345      */

346     public Collection<Group> getSharedGroups() {
347         return sharedGroups;
348     }
349
350     /**
351      * Returns the invisible shared groups for the item. These groups are for internal use
352      * and help track the reason why a roster item has a presence subscription of type FROM
353      * when using shared groups.
354      *
355      * @return The shared groups this item belongs to.
356      */

357     public Collection<Group> getInvisibleSharedGroups() {
358         return invisibleSharedGroups;
359     }
360
361     /**
362      * Adds a new group to the shared groups list.
363      *
364      * @param sharedGroup The shared group to add to the list of shared groups.
365      */

366     public void addSharedGroup(Group sharedGroup) {
367         sharedGroups.add(sharedGroup);
368         invisibleSharedGroups.remove(sharedGroup);
369     }
370
371     /**
372      * Adds a new group to the list shared groups that won't be sent to the user. These groups
373      * are for internal use and help track the reason why a roster item has a presence
374      * subscription of type FROM when using shared groups.
375      *
376      * @param sharedGroup The shared group to add to the list of shared groups.
377      */

378     public void addInvisibleSharedGroup(Group sharedGroup) {
379         invisibleSharedGroups.add(sharedGroup);
380     }
381
382     /**
383      * Removes a group from the shared groups list.
384      *
385      * @param sharedGroup The shared group to remove from the list of shared groups.
386      */

387     public void removeSharedGroup(Group sharedGroup) {
388         sharedGroups.remove(sharedGroup);
389         invisibleSharedGroups.remove(sharedGroup);
390     }
391
392     /**
393      * Returns true if this item belongs to a shared group. Return true even if the item belongs
394      * to a personal group and a shared group.
395      *
396      * @return true if this item belongs to a shared group.
397      */

398     public boolean isShared() {
399         return !sharedGroups.isEmpty() || !invisibleSharedGroups.isEmpty();
400     }
401
402     /**
403      * Returns true if this item belongs ONLY to shared groups. This means that the the item is
404      * considered to be "only shared" if it doesn't belong to a personal group but only to shared
405      * groups.
406      *
407      * @return true if this item belongs ONLY to shared groups.
408      */

409     public boolean isOnlyShared() {
410         return isShared() && groups.isEmpty();
411     }
412
413     /**
414      * <p>Obtain the roster ID associated with this particular roster item.</p>
415      * <p/>
416      * <p>Databases can use the roster ID as the key in locating roster items.</p>
417      *
418      * @return The roster ID
419      */

420     public long getID() {
421         return rosterID;
422     }
423
424     public void setID(long rosterID) {
425         this.rosterID = rosterID;
426     }
427
428     /**
429      * <p>Update the cached item as a copy of the given item.</p>
430      * <p/>
431      * <p>A convenience for getting the item and setting each attribute.</p>
432      *
433      * @param item The item who's settings will be copied into the cached copy
434      */

435     public void setAsCopyOf(org.xmpp.packet.Roster.Item item) throws SharedGroupException {
436         setGroups(new LinkedList<String JavaDoc>(item.getGroups()));
437         setNickname(item.getName());
438     }
439
440     public int getCachedSize() {
441         int size = jid.toBareJID().length();
442         size += CacheSizes.sizeOfString(nickname);
443         size += CacheSizes.sizeOfCollection(groups);
444         size += CacheSizes.sizeOfInt(); // subStatus
445
size += CacheSizes.sizeOfInt(); // askStatus
446
size += CacheSizes.sizeOfLong(); // id
447
return size;
448     }
449 }
Popular Tags