📄 iqownerhandler.java
字号:
/**
* $RCSfile$
* $Revision: 1623 $
* $Date: 2005-07-12 18:40:57 -0300 (Tue, 12 Jul 2005) $
*
* Copyright (C) 2008 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution, or a commercial license
* agreement with Jive.
*/
package org.jivesoftware.openfire.muc.spi;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.QName;
import org.jivesoftware.openfire.PacketRouter;
import org.jivesoftware.openfire.forms.DataForm;
import org.jivesoftware.openfire.forms.FormField;
import org.jivesoftware.openfire.forms.spi.XDataFormImpl;
import org.jivesoftware.openfire.forms.spi.XFormFieldImpl;
import org.jivesoftware.openfire.muc.ConflictException;
import org.jivesoftware.openfire.muc.ForbiddenException;
import org.jivesoftware.openfire.muc.MUCRole;
import org.jivesoftware.openfire.muc.cluster.RoomUpdatedEvent;
import org.jivesoftware.openfire.user.UserNotFoundException;
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.cache.CacheFactory;
import org.xmpp.packet.IQ;
import org.xmpp.packet.JID;
import org.xmpp.packet.PacketError;
import org.xmpp.packet.Presence;
import java.util.*;
/**
* A handler for the IQ packet with namespace http://jabber.org/protocol/muc#owner. This kind of
* packets are usually sent by room owners. So this handler provides the necessary functionality
* to support owner requirements such as: room configuration and room destruction.
*
* @author Gaston Dombiak
*/
public class IQOwnerHandler {
private LocalMUCRoom room;
private PacketRouter router;
private XDataFormImpl configurationForm;
private Element probeResult;
public IQOwnerHandler(LocalMUCRoom chatroom, PacketRouter packetRouter) {
this.room = chatroom;
this.router = packetRouter;
init();
}
/**
* Handles the IQ packet sent by an owner of the room. Possible actions are:
* <ul>
* <li>Return the list of owners</li>
* <li>Return the list of admins</li>
* <li>Change user's affiliation to owner</li>
* <li>Change user's affiliation to admin</li>
* <li>Change user's affiliation to member</li>
* <li>Change user's affiliation to none</li>
* <li>Destroy the room</li>
* <li>Return the room configuration within a dataform</li>
* <li>Update the room configuration based on the sent dataform</li>
* </ul>
*
* @param packet the IQ packet sent by an owner of the room.
* @param role the role of the user that sent the packet.
* @throws ForbiddenException if the user does not have enough permissions (ie. is not an owner).
* @throws ConflictException If the room was going to lose all of its owners.
*/
public void handleIQ(IQ packet, MUCRole role) throws ForbiddenException, ConflictException {
// Only owners can send packets with the namespace "http://jabber.org/protocol/muc#owner"
if (MUCRole.Affiliation.owner != role.getAffiliation()) {
throw new ForbiddenException();
}
IQ reply = IQ.createResultIQ(packet);
Element element = packet.getChildElement();
// Analyze the action to perform based on the included element
Element formElement = element.element(QName.get("x", "jabber:x:data"));
if (formElement != null) {
handleDataFormElement(role, formElement);
}
else {
Element destroyElement = element.element("destroy");
if (destroyElement != null) {
room.destroyRoom(destroyElement.attributeValue("jid"), destroyElement
.elementTextTrim("reason"));
}
else {
List itemsList = element.elements("item");
if (!itemsList.isEmpty()) {
handleItemsElement(itemsList, role, reply);
}
else {
// If no element was included in the query element then answer the
// configuration form
if (!element.elementIterator().hasNext()) {
refreshConfigurationFormValues();
reply.setChildElement(probeResult.createCopy());
}
// An unknown and possibly incorrect element was included in the query
// element so answer a BAD_REQUEST error
else {
reply.setChildElement(packet.getChildElement().createCopy());
reply.setError(PacketError.Condition.bad_request);
}
}
}
}
if (reply.getTo() != null) {
// Send a reply only if the sender of the original packet was from a real JID. (i.e. not
// a packet generated locally)
router.route(reply);
}
}
/**
* Handles packets that includes item elements. Depending on the item's attributes the
* interpretation of the request may differ. For example, an item that only contains the
* "affiliation" attribute is requesting the list of owners or admins. Whilst if the item
* contains the affiliation together with a jid means that the client is changing the
* affiliation of the requested jid.
*
* @param itemsList the list of items sent by the client.
* @param senderRole the role of the user that sent the items.
* @param reply the iq packet that will be sent back as a reply to the client's request.
* @throws ForbiddenException if the user does not have enough permissions.
* @throws ConflictException If the room was going to lose all of its owners.
*/
private void handleItemsElement(List itemsList, MUCRole senderRole, IQ reply)
throws ForbiddenException, ConflictException {
Element item;
String affiliation = null;
boolean hasJID = ((Element)itemsList.get(0)).attributeValue("jid") != null;
boolean hasNick = ((Element)itemsList.get(0)).attributeValue("nick") != null;
// Check if the client is requesting or changing the list of owners/admin
if (!hasJID && !hasNick) {
// The client is requesting the list of owners or admins
for (Iterator items = itemsList.iterator(); items.hasNext();) {
item = (Element)items.next();
affiliation = item.attributeValue("affiliation");
// Create the result that will hold an item for each owner or admin
Element result = reply.setChildElement("query", "http://jabber.org/protocol/muc#owner");
if ("owner".equals(affiliation)) {
// The client is requesting the list of owners
Element ownerMetaData;
MUCRole role;
for (String jid : room.getOwners()) {
ownerMetaData = result.addElement("item", "http://jabber.org/protocol/muc#owner");
ownerMetaData.addAttribute("affiliation", "owner");
ownerMetaData.addAttribute("jid", jid);
// Add role and nick to the metadata if the user is in the room
try {
List<MUCRole> roles = room.getOccupantsByBareJID(jid);
role = roles.get(0);
ownerMetaData.addAttribute("role", role.getRole().toString());
ownerMetaData.addAttribute("nick", role.getNickname());
}
catch (UserNotFoundException e) {
// Do nothing
}
}
}
else if ("admin".equals(affiliation)) {
// The client is requesting the list of admins
Element adminMetaData;
MUCRole role;
for (String jid : room.getAdmins()) {
adminMetaData = result.addElement("item", "http://jabber.org/protocol/muc#owner");
adminMetaData.addAttribute("affiliation", "admin");
adminMetaData.addAttribute("jid", jid);
// Add role and nick to the metadata if the user is in the room
try {
List<MUCRole> roles = room.getOccupantsByBareJID(jid);
role = roles.get(0);
adminMetaData.addAttribute("role", role.getRole().toString());
adminMetaData.addAttribute("nick", role.getNickname());
}
catch (UserNotFoundException e) {
// Do nothing
}
}
}
else {
reply.setError(PacketError.Condition.bad_request);
}
}
}
else {
// The client is modifying the list of owners or admins
Map<String,String> jids = new HashMap<String,String>();
String bareJID = null;
String nick;
// Collect the new affiliations for the specified jids
for (Iterator items = itemsList.iterator(); items.hasNext();) {
try {
item = (Element)items.next();
affiliation = item.attributeValue("affiliation");
if (hasJID) {
bareJID = new JID(item.attributeValue("jid")).toBareJID();
}
else {
// Get the bare JID based on the requested nick
nick = item.attributeValue("nick");
bareJID = room.getOccupant(nick).getUserAddress().toBareJID();
}
jids.put(bareJID, affiliation);
}
catch (UserNotFoundException e) {
// Do nothing
}
}
// Keep a registry of the updated presences
List<Presence> presences = new ArrayList<Presence>(jids.size());
room.lock.readLock().lock();
try {
// Check if all the existing owners are being removed
if (jids.keySet().containsAll(room.owners)) {
// Answer a conflict error if we are only removing ALL the owners
if (!jids.containsValue("owner")) {
throw new ConflictException();
}
}
room.lock.readLock().unlock();
room.lock.writeLock().lock();
try {
String targetAffiliation = null;
for (Iterator<String> it = jids.keySet().iterator(); it.hasNext();) {
bareJID = it.next();
targetAffiliation = jids.get(bareJID);
if ("owner".equals(targetAffiliation)) {
// Add the new user as an owner of the room
presences.addAll(room.addOwner(bareJID, senderRole));
}
else if ("admin".equals(targetAffiliation)) {
// Add the new user as an admin of the room
presences.addAll(room.addAdmin(bareJID, senderRole));
}
else if ("member".equals(targetAffiliation)) {
// Add the new user as a member of the room
boolean hadAffiliation = room.getAffiliation(bareJID) != MUCRole.Affiliation.none;
presences.addAll(room.addMember(bareJID, null, senderRole));
// If the user had an affiliation don't send an invitation. Otherwise
// send an invitation if the room is members-only
if (!hadAffiliation && room.isMembersOnly()) {
room.sendInvitation(new JID(bareJID), null, senderRole, null);
}
}
else if ("none".equals(targetAffiliation)) {
// Set that this jid has a NONE affiliation
presences.addAll(room.addNone(bareJID, senderRole));
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -