KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jivesoftware > smack > RosterGroup


1 /**
2  * $RCSfile$
3  * $Revision: 2707 $
4  * $Date: 2005-08-22 21:01:04 -0300 (Mon, 22 Aug 2005) $
5  *
6  * Copyright 2003-2004 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.RosterPacket;
24 import org.jivesoftware.smack.packet.IQ;
25 import org.jivesoftware.smack.util.StringUtils;
26 import org.jivesoftware.smack.filter.PacketIDFilter;
27
28 import java.util.*;
29
30 /**
31  * A group of roster entries.
32  *
33  * @see Roster#getGroup(String)
34  * @author Matt Tucker
35  */

36 public class RosterGroup {
37
38     private String JavaDoc name;
39     private XMPPConnection connection;
40     private List entries;
41
42     /**
43      * Creates a new roster group instance.
44      *
45      * @param name the name of the group.
46      * @param connection the connection the group belongs to.
47      */

48     RosterGroup(String JavaDoc name, XMPPConnection connection) {
49         this.name = name;
50         this.connection = connection;
51         entries = new ArrayList();
52     }
53
54     /**
55      * Returns the name of the group.
56      *
57      * @return the name of the group.
58      */

59     public String JavaDoc getName() {
60         return name;
61     }
62
63     /**
64      * Sets the name of the group. Changing the group's name is like moving all the group entries
65      * of the group to a new group specified by the new name. Since this group won't have entries
66      * it will be removed from the roster. This means that all the references to this object will
67      * be invalid and will need to be updated to the new group specified by the new name.
68      *
69      * @param name the name of the group.
70      */

71     public void setName(String JavaDoc name) {
72         synchronized (entries) {
73             for (int i=0; i<entries.size(); i++) {
74                 RosterPacket packet = new RosterPacket();
75                 packet.setType(IQ.Type.SET);
76                 RosterEntry entry = (RosterEntry)entries.get(i);
77                 RosterPacket.Item item = RosterEntry.toRosterItem(entry);
78                 item.removeGroupName(this.name);
79                 item.addGroupName(name);
80                 packet.addRosterItem(item);
81                 connection.sendPacket(packet);
82             }
83         }
84     }
85
86     /**
87      * Returns the number of entries in the group.
88      *
89      * @return the number of entries in the group.
90      */

91     public int getEntryCount() {
92         synchronized (entries) {
93             return entries.size();
94         }
95     }
96
97     /**
98      * Returns an iterator for the entries in the group.
99      *
100      * @return an iterator for the entries in the group.
101      */

102     public Iterator getEntries() {
103         synchronized (entries) {
104             return Collections.unmodifiableList(new ArrayList(entries)).iterator();
105         }
106     }
107
108     /**
109      * Returns the roster entry associated with the given XMPP address or
110      * <tt>null</tt> if the user is not an entry in the group.
111      *
112      * @param user the XMPP address of the user (eg "jsmith@example.com").
113      * @return the roster entry or <tt>null</tt> if it does not exist in the group.
114      */

115     public RosterEntry getEntry(String JavaDoc user) {
116         if (user == null) {
117             return null;
118         }
119         // Roster entries never include a resource so remove the resource
120
// if it's a part of the XMPP address.
121
user = StringUtils.parseBareAddress(user);
122         synchronized (entries) {
123             for (Iterator i=entries.iterator(); i.hasNext(); ) {
124                 RosterEntry entry = (RosterEntry)i.next();
125                 if (entry.getUser().toLowerCase().equals(user.toLowerCase())) {
126                     return entry;
127                 }
128             }
129         }
130         return null;
131     }
132
133     /**
134      * Returns true if the specified entry is part of this group.
135      *
136      * @param entry a roster entry.
137      * @return true if the entry is part of this group.
138      */

139     public boolean contains(RosterEntry entry) {
140         synchronized (entries) {
141             return entries.contains(entry);
142         }
143     }
144
145     /**
146      * Returns true if the specified XMPP address is an entry in this group.
147      *
148      * @param user the XMPP address of the user.
149      * @return true if the XMPP address is an entry in this group.
150      */

151     public boolean contains(String JavaDoc user) {
152         if (user == null) {
153             return false;
154         }
155         // Roster entries never include a resource so remove the resource
156
// if it's a part of the XMPP address.
157
user = StringUtils.parseBareAddress(user);
158         synchronized (entries) {
159             for (Iterator i=entries.iterator(); i.hasNext(); ) {
160                 RosterEntry entry = (RosterEntry)i.next();
161                 if (entry.getUser().toLowerCase().equals(user.toLowerCase())) {
162                     return true;
163                 }
164             }
165         }
166         return false;
167     }
168
169     /**
170      * Adds a roster entry to this group. If the entry was unfiled then it will be removed from
171      * the unfiled list and will be added to this group.
172      *
173      * @param entry a roster entry.
174      * @throws XMPPException if an error occured while trying to add the entry to the group.
175      */

176     public void addEntry(RosterEntry entry) throws XMPPException {
177         PacketCollector collector = null;
178         // Only add the entry if it isn't already in the list.
179
synchronized (entries) {
180             if (!entries.contains(entry)) {
181                 RosterPacket packet = new RosterPacket();
182                 packet.setType(IQ.Type.SET);
183                 packet.addRosterItem(RosterEntry.toRosterItem(entry));
184                 // Wait up to a certain number of seconds for a reply from the server.
185
collector = connection
186                         .createPacketCollector(new PacketIDFilter(packet.getPacketID()));
187                 connection.sendPacket(packet);
188             }
189         }
190         if (collector != null) {
191             IQ response = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
192             collector.cancel();
193             if (response == null) {
194                 throw new XMPPException("No response from the server.");
195             }
196             // If the server replied with an error, throw an exception.
197
else if (response.getType() == IQ.Type.ERROR) {
198                 throw new XMPPException(response.getError());
199             }
200             // Add the new entry to the group since the server processed the request successfully
201
entries.add(entry);
202         }
203     }
204
205     /**
206      * Removes a roster entry from this group. If the entry does not belong to any other group
207      * then it will be considered as unfiled, therefore it will be added to the list of unfiled
208      * entries.
209      *
210      * @param entry a roster entry.
211      * @throws XMPPException if an error occured while trying to remove the entry from the group.
212      */

213     public void removeEntry(RosterEntry entry) throws XMPPException {
214         PacketCollector collector = null;
215         // Only remove the entry if it's in the entry list.
216
// Remove the entry locally, if we wait for RosterPacketListenerprocess>>Packet(Packet)
217
// to take place the entry will exist in the group until a packet is received from the
218
// server.
219
synchronized (entries) {
220             if (entries.contains(entry)) {
221                 RosterPacket packet = new RosterPacket();
222                 packet.setType(IQ.Type.SET);
223                 RosterPacket.Item item = RosterEntry.toRosterItem(entry);
224                 item.removeGroupName(this.getName());
225                 packet.addRosterItem(item);
226                 // Wait up to a certain number of seconds for a reply from the server.
227
collector = connection
228                         .createPacketCollector(new PacketIDFilter(packet.getPacketID()));
229                 connection.sendPacket(packet);
230             }
231         }
232         if (collector != null) {
233             IQ response = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
234             collector.cancel();
235             if (response == null) {
236                 throw new XMPPException("No response from the server.");
237             }
238             // If the server replied with an error, throw an exception.
239
else if (response.getType() == IQ.Type.ERROR) {
240                 throw new XMPPException(response.getError());
241             }
242             // Remove the entry locally since the server processed the request successfully
243
entries.remove(entry);
244         }
245     }
246
247     void addEntryLocal(RosterEntry entry) {
248         // Only add the entry if it isn't already in the list.
249
synchronized (entries) {
250             entries.remove(entry);
251             entries.add(entry);
252         }
253     }
254
255     void removeEntryLocal(RosterEntry entry) {
256          // Only remove the entry if it's in the entry list.
257
synchronized (entries) {
258             if (entries.contains(entry)) {
259                 entries.remove(entry);
260             }
261         }
262     }
263 }
Popular Tags