KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jivesoftware > messenger > muc > spi > IQAdminHandler


1 /**
2  * $RCSfile: IQAdminHandler.java,v $
3  * $Revision: 1.15 $
4  * $Date: 2005/03/14 18:59:37 $
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.muc.spi;
13
14 import java.util.ArrayList JavaDoc;
15 import java.util.Iterator JavaDoc;
16 import java.util.List JavaDoc;
17 import org.dom4j.Element;
18 import org.jivesoftware.messenger.PacketRouter;
19 import org.jivesoftware.messenger.muc.ConflictException;
20 import org.jivesoftware.messenger.muc.ForbiddenException;
21 import org.jivesoftware.messenger.muc.MUCRole;
22 import org.jivesoftware.messenger.muc.NotAllowedException;
23 import org.jivesoftware.messenger.user.UserNotFoundException;
24 import org.xmpp.packet.IQ;
25 import org.xmpp.packet.JID;
26 import org.xmpp.packet.PacketError;
27 import org.xmpp.packet.Presence;
28
29 /**
30  * A handler for the IQ packet with namespace http://jabber.org/protocol/muc#admin. This kind of
31  * packets are usually sent by room admins. So this handler provides the necessary functionality
32  * to support administrator requirements such as: managing room members/outcasts/etc., kicking
33  * occupants and banning users.
34  *
35  * @author Gaston Dombiak
36  */

37 public class IQAdminHandler {
38     private MUCRoomImpl room;
39
40     private PacketRouter router;
41
42     public IQAdminHandler(MUCRoomImpl chatroom, PacketRouter packetRouter) {
43         this.room = chatroom;
44         this.router = packetRouter;
45     }
46
47     /**
48      * Handles the IQ packet sent by an owner or admin of the room. Possible actions are:
49      * <ul>
50      * <li>Return the list of participants</li>
51      * <li>Return the list of moderators</li>
52      * <li>Return the list of members</li>
53      * <li>Return the list of outcasts</li>
54      * <li>Change user's affiliation to member</li>
55      * <li>Change user's affiliation to outcast</li>
56      * <li>Change user's affiliation to none</li>
57      * <li>Change occupant's affiliation to moderator</li>
58      * <li>Change occupant's affiliation to participant</li>
59      * <li>Change occupant's affiliation to visitor</li>
60      * <li>Kick occupants from the room</li>
61      * </ul>
62      *
63      * @param packet the IQ packet sent by an owner or admin of the room.
64      * @param role the role of the user that sent the request packet.
65      * @throws ForbiddenException If the user is not allowed to perform his request.
66      * @throws ConflictException If the desired room nickname is already reserved for the room or
67      * if the room was going to lose all of its owners.
68      * @throws NotAllowedException Thrown if trying to ban an owner or an administrator.
69      */

70     public void handleIQ(IQ packet, MUCRole role) throws ForbiddenException, ConflictException,
71             NotAllowedException {
72         IQ reply = IQ.createResultIQ(packet);
73         Element element = packet.getChildElement();
74
75         // Analyze the action to perform based on the included element
76
List JavaDoc itemsList = element.elements("item");
77         if (!itemsList.isEmpty()) {
78             handleItemsElement(role, itemsList, reply);
79         }
80         else {
81             // An unknown and possibly incorrect element was included in the query
82
// element so answer a BAD_REQUEST error
83
reply.setChildElement(packet.getChildElement().createCopy());
84             reply.setError(PacketError.Condition.bad_request);
85         }
86         if (reply.getTo() != null) {
87             // Send a reply only if the sender of the original packet was from a real JID. (i.e. not
88
// a packet generated locally)
89
router.route(reply);
90         }
91     }
92
93     /**
94      * Handles packets that includes item elements. Depending on the item's attributes the
95      * interpretation of the request may differ. For example, an item that only contains the
96      * "affiliation" attribute is requesting the list of participants or members. Whilst if the item
97      * contains the affiliation together with a jid means that the client is changing the
98      * affiliation of the requested jid.
99      *
100      * @param senderRole the role of the user that sent the request packet.
101      * @param itemsList the list of items sent by the client.
102      * @param reply the iq packet that will be sent back as a reply to the client's request.
103      * @throws ForbiddenException If the user is not allowed to perform his request.
104      * @throws ConflictException If the desired room nickname is already reserved for the room or
105      * if the room was going to lose all of its owners.
106      * @throws NotAllowedException Thrown if trying to ban an owner or an administrator.
107      */

108     private void handleItemsElement(MUCRole senderRole, List JavaDoc itemsList, IQ reply)
109             throws ForbiddenException, ConflictException, NotAllowedException {
110         Element item;
111         String JavaDoc affiliation = null;
112         String JavaDoc roleAttribute = null;
113         boolean hasJID = ((Element)itemsList.get(0)).attributeValue("jid") != null;
114         boolean hasNick = ((Element)itemsList.get(0)).attributeValue("nick") != null;
115         // Check if the client is requesting or changing the list of moderators/members/etc.
116
if (!hasJID && !hasNick) {
117             // The client is requesting the list of moderators/members/participants/outcasts
118
for (Iterator JavaDoc items = itemsList.iterator(); items.hasNext();) {
119                 item = (Element)items.next();
120                 affiliation = item.attributeValue("affiliation");
121                 roleAttribute = item.attributeValue("role");
122                 // Create the result that will hold an item for each
123
// moderator/member/participant/outcast
124
Element result = reply.setChildElement("query", "http://jabber.org/protocol/muc#admin");
125
126                 Element metaData;
127                 if ("outcast".equals(affiliation)) {
128                     // The client is requesting the list of outcasts
129
if (MUCRole.Affiliation.admin != senderRole.getAffiliation()
130                             && MUCRole.Affiliation.owner != senderRole.getAffiliation()) {
131                         throw new ForbiddenException();
132                     }
133                     for (String JavaDoc jid : room.getOutcasts()) {
134                         metaData = result.addElement("item", "http://jabber.org/protocol/muc#admin");
135                         metaData.addAttribute("affiliation", "outcast");
136                         metaData.addAttribute("jid", jid);
137                     }
138
139                 }
140                 else if ("member".equals(affiliation)) {
141                     // The client is requesting the list of members
142
// In a members-only room members can get the list of members
143
if (!room.isMembersOnly()
144                             && MUCRole.Affiliation.admin != senderRole.getAffiliation()
145                             && MUCRole.Affiliation.owner != senderRole.getAffiliation()) {
146                         throw new ForbiddenException();
147                     }
148                     for (String JavaDoc jid : room.getMembers()) {
149                         metaData = result.addElement("item", "http://jabber.org/protocol/muc#admin");
150                         metaData.addAttribute("affiliation", "member");
151                         metaData.addAttribute("jid", jid);
152                         try {
153                             List JavaDoc<MUCRole> roles = room.getOccupantsByBareJID(jid);
154                             MUCRole role = roles.get(0);
155                             metaData.addAttribute("role", role.getRole().toString());
156                             metaData.addAttribute("nick", role.getNickname());
157                         }
158                         catch (UserNotFoundException e) {
159                             // Do nothing
160
}
161                     }
162                 }
163                 else if ("moderator".equals(roleAttribute)) {
164                     // The client is requesting the list of moderators
165
if (MUCRole.Affiliation.admin != senderRole.getAffiliation()
166                             && MUCRole.Affiliation.owner != senderRole.getAffiliation()) {
167                         throw new ForbiddenException();
168                     }
169                     for (MUCRole role : room.getModerators()) {
170                         metaData = result.addElement("item", "http://jabber.org/protocol/muc#admin");
171                         metaData.addAttribute("role", "moderator");
172                         metaData.addAttribute("jid", role.getChatUser().getAddress().toString());
173                         metaData.addAttribute("nick", role.getNickname());
174                         metaData.addAttribute("affiliation", role.getAffiliation().toString());
175                     }
176                 }
177                 else if ("participant".equals(roleAttribute)) {
178                     // The client is requesting the list of participants
179
if (MUCRole.Role.moderator != senderRole.getRole()) {
180                         throw new ForbiddenException();
181                     }
182                     for (MUCRole role : room.getParticipants()) {
183                         metaData = result.addElement("item", "http://jabber.org/protocol/muc#admin");
184                         metaData.addAttribute("role", "participant");
185                         metaData.addAttribute("jid", role.getChatUser().getAddress().toString());
186                         metaData.addAttribute("nick", role.getNickname());
187                         metaData.addAttribute("affiliation", role.getAffiliation().toString());
188                     }
189                 }
190                 else {
191                     reply.setError(PacketError.Condition.bad_request);
192                 }
193             }
194         }
195         else {
196             // The client is modifying the list of moderators/members/participants/outcasts
197
JID jid = null;
198             String JavaDoc nick;
199             String JavaDoc target = null;
200             boolean hasAffiliation = ((Element) itemsList.get(0)).attributeValue("affiliation") !=
201                     null;
202
203             // Keep a registry of the updated presences
204
List JavaDoc<Presence> presences = new ArrayList JavaDoc<Presence>(itemsList.size());
205
206             // Collect the new affiliations or roles for the specified jids
207
for (Iterator JavaDoc items = itemsList.iterator(); items.hasNext();) {
208                 try {
209                     item = (Element)items.next();
210                     target = (hasAffiliation ? item.attributeValue("affiliation") : item
211                             .attributeValue("role"));
212                     // jid could be of the form "full JID" or "bare JID" depending if we are
213
// going to change a role or an affiliation
214
if (hasJID) {
215                         jid = new JID(item.attributeValue("jid"));
216                         nick = null;
217                     }
218                     else {
219                         // Get the JID based on the requested nick
220
nick = item.attributeValue("nick");
221                         jid = room.getOccupant(nick).getChatUser().getAddress();
222                     }
223
224                     room.lock.writeLock().lock();
225                     try {
226                         if ("moderator".equals(target)) {
227                             // Add the user as a moderator of the room based on the full JID
228
presences.add(room.addModerator(jid, senderRole));
229                         }
230                         else if ("participant".equals(target)) {
231                             // Add the user as a participant of the room based on the full JID
232
presences.add(room.addParticipant(jid,
233                                     item.elementTextTrim("reason"),
234                                     senderRole));
235                         }
236                         else if ("visitor".equals(target)) {
237                             // Add the user as a visitor of the room based on the full JID
238
presences.add(room.addVisitor(jid, senderRole));
239                         }
240                         else if ("member".equals(target)) {
241                             // Add the user as a member of the room based on the bare JID
242
boolean hadAffiliation = room.getAffiliation(jid.toBareJID()) != MUCRole.Affiliation.none;
243                             presences.addAll(room.addMember(jid.toBareJID(), nick, senderRole));
244                             // If the user had an affiliation don't send an invitation. Otherwise
245
// send an invitation if the room is members-only
246
if (!hadAffiliation && room.isMembersOnly()) {
247                                 room.sendInvitation(jid, null, senderRole, null);
248                             }
249                         }
250                         else if ("outcast".equals(target)) {
251                             // Add the user as an outcast of the room based on the bare JID
252
presences.addAll(room.addOutcast(jid.toBareJID(), item.elementTextTrim("reason"), senderRole));
253                         }
254                         else if ("none".equals(target)) {
255                             if (hasAffiliation) {
256                                 // Set that this jid has a NONE affiliation based on the bare JID
257
presences.addAll(room.addNone(jid.toBareJID(), senderRole));
258                             }
259                             else {
260                                 // Kick the user from the room
261
if (MUCRole.Role.moderator != senderRole.getRole()) {
262                                     throw new ForbiddenException();
263                                 }
264                                 presences.add(room.kickOccupant(jid,
265                                         senderRole.getChatUser().getAddress(),
266                                         item.elementTextTrim("reason")));
267                             }
268                         }
269                         else {
270                             reply.setError(PacketError.Condition.bad_request);
271                         }
272                     }
273                     finally {
274                         room.lock.writeLock().unlock();
275                     }
276                 }
277                 catch (UserNotFoundException e) {
278                     // Do nothing
279
}
280             }
281
282             // Send the updated presences to the room occupants
283
for (Presence presence : presences) {
284                 room.send(presence);
285             }
286         }
287     }
288 }
Popular Tags