1
0
Fork 0
mirror of https://codeberg.org/Mercury-IM/Smack synced 2024-11-29 17:52:06 +01:00

Improve MUC code

Removes a ton of duplicate code, mostly related to MUCItem being
duplicated in MUCOwner and MUCAdmin, but also some other duplicate code.

Make MUC code use XmlStringBuilder.

Add ELEMENT and NAMESPACE constants to the appropriate places. Also add
"static <MUCPacketExtension> getFrom(Packet)" methods.

Make some MUC classes implement Element.
This commit is contained in:
Florian Schmaus 2014-07-14 19:22:02 +02:00
parent 7735a5224c
commit e6aa2416e4
16 changed files with 578 additions and 948 deletions

View file

@ -66,6 +66,13 @@ public class XmlStringBuilder implements Appendable, CharSequence {
return this; return this;
} }
public XmlStringBuilder optElement(Element element) {
if (element != null) {
append(element.toXML());
}
return this;
}
public XmlStringBuilder optElement(String name, Enum<?> content) { public XmlStringBuilder optElement(String name, Enum<?> content) {
if (content != null) { if (content != null) {
element(name, content); element(name, content);
@ -139,6 +146,20 @@ public class XmlStringBuilder implements Appendable, CharSequence {
return this; return this;
} }
/**
* Add the given attribute if value => 0
*
* @param name
* @param value
* @return a reference to this object
*/
public XmlStringBuilder optIntAttribute(String name, int value) {
if (value >= 0) {
attribute(name, Integer.toString(value));
}
return this;
}
public XmlStringBuilder xmlnsAttribute(String value) { public XmlStringBuilder xmlnsAttribute(String value) {
optAttribute("xmlns", value); optAttribute("xmlns", value);
return this; return this;

View file

@ -17,8 +17,7 @@
package org.jivesoftware.smackx.muc; package org.jivesoftware.smackx.muc;
import org.jivesoftware.smackx.muc.packet.MUCAdmin; import org.jivesoftware.smackx.muc.packet.MUCItem;
import org.jivesoftware.smackx.muc.packet.MUCOwner;
/** /**
* Represents an affiliation of a user to a given room. The affiliate's information will always have * Represents an affiliation of a user to a given room. The affiliate's information will always have
@ -36,15 +35,7 @@ public class Affiliate {
private String role; private String role;
private String nick; private String nick;
Affiliate(MUCOwner.Item item) { Affiliate(MUCItem item) {
super();
this.jid = item.getJid();
this.affiliation = item.getAffiliation();
this.role = item.getRole();
this.nick = item.getNick();
}
Affiliate(MUCAdmin.Item item) {
super(); super();
this.jid = item.getJid(); this.jid = item.getJid();
this.affiliation = item.getAffiliation(); this.affiliation = item.getAffiliation();

View file

@ -64,8 +64,10 @@ import org.jivesoftware.smackx.disco.NodeInformationProvider;
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
import org.jivesoftware.smackx.disco.packet.DiscoverInfo; import org.jivesoftware.smackx.disco.packet.DiscoverInfo;
import org.jivesoftware.smackx.disco.packet.DiscoverItems; import org.jivesoftware.smackx.disco.packet.DiscoverItems;
import org.jivesoftware.smackx.muc.packet.Destroy;
import org.jivesoftware.smackx.muc.packet.MUCAdmin; import org.jivesoftware.smackx.muc.packet.MUCAdmin;
import org.jivesoftware.smackx.muc.packet.MUCInitialPresence; import org.jivesoftware.smackx.muc.packet.MUCInitialPresence;
import org.jivesoftware.smackx.muc.packet.MUCItem;
import org.jivesoftware.smackx.muc.packet.MUCOwner; import org.jivesoftware.smackx.muc.packet.MUCOwner;
import org.jivesoftware.smackx.muc.packet.MUCUser; import org.jivesoftware.smackx.muc.packet.MUCUser;
import org.jivesoftware.smackx.xdata.Form; import org.jivesoftware.smackx.xdata.Form;
@ -73,7 +75,7 @@ import org.jivesoftware.smackx.xdata.Form;
/** /**
* A MultiUserChat is a conversation that takes place among many users in a virtual * A MultiUserChat is a conversation that takes place among many users in a virtual
* room. A room could have many occupants with different affiliation and roles. * room. A room could have many occupants with different affiliation and roles.
* Possible affiliatons are "owner", "admin", "member", and "outcast". Possible roles * Possible affiliations are "owner", "admin", "member", and "outcast". Possible roles
* are "moderator", "participant", and "visitor". Each role and affiliation guarantees * are "moderator", "participant", and "visitor". Each role and affiliation guarantees
* different privileges (e.g. Send messages to all occupants, Kick participants and visitors, * different privileges (e.g. Send messages to all occupants, Kick participants and visitors,
* Grant voice, Edit member list, etc.). * Grant voice, Edit member list, etc.).
@ -83,8 +85,7 @@ import org.jivesoftware.smackx.xdata.Form;
public class MultiUserChat { public class MultiUserChat {
private static final Logger LOGGER = Logger.getLogger(MultiUserChat.class.getName()); private static final Logger LOGGER = Logger.getLogger(MultiUserChat.class.getName());
private final static String discoNamespace = "http://jabber.org/protocol/muc"; private final static String DISCO_NODE = MUCInitialPresence.NAMESPACE + "#rooms";
private final static String discoNode = "http://jabber.org/protocol/muc#rooms";
private static Map<XMPPConnection, List<String>> joinedRooms = private static Map<XMPPConnection, List<String>> joinedRooms =
new WeakHashMap<XMPPConnection, List<String>>(); new WeakHashMap<XMPPConnection, List<String>>();
@ -118,13 +119,13 @@ public class MultiUserChat {
// Set on every established connection that this client supports the Multi-User // Set on every established connection that this client supports the Multi-User
// Chat protocol. This information will be used when another client tries to // Chat protocol. This information will be used when another client tries to
// discover whether this client supports MUC or not. // discover whether this client supports MUC or not.
ServiceDiscoveryManager.getInstanceFor(connection).addFeature(discoNamespace); ServiceDiscoveryManager.getInstanceFor(connection).addFeature(MUCInitialPresence.NAMESPACE);
// Set the NodeInformationProvider that will provide information about the // Set the NodeInformationProvider that will provide information about the
// joined rooms whenever a disco request is received // joined rooms whenever a disco request is received
final WeakReference<XMPPConnection> weakRefConnection = new WeakReference<XMPPConnection>(connection); final WeakReference<XMPPConnection> weakRefConnection = new WeakReference<XMPPConnection>(connection);
ServiceDiscoveryManager.getInstanceFor(connection).setNodeInformationProvider( ServiceDiscoveryManager.getInstanceFor(connection).setNodeInformationProvider(
discoNode, DISCO_NODE,
new NodeInformationProvider() { new NodeInformationProvider() {
public List<DiscoverItems.Item> getNodeItems() { public List<DiscoverItems.Item> getNodeItems() {
XMPPConnection connection = weakRefConnection.get(); XMPPConnection connection = weakRefConnection.get();
@ -187,7 +188,7 @@ public class MultiUserChat {
public static boolean isServiceEnabled(XMPPConnection connection, String user) public static boolean isServiceEnabled(XMPPConnection connection, String user)
throws NoResponseException, XMPPErrorException, NotConnectedException { throws NoResponseException, XMPPErrorException, NotConnectedException {
return ServiceDiscoveryManager.getInstanceFor(connection).supportsFeature(user, return ServiceDiscoveryManager.getInstanceFor(connection).supportsFeature(user,
discoNamespace); MUCInitialPresence.NAMESPACE);
} }
/** /**
@ -223,7 +224,7 @@ public class MultiUserChat {
ArrayList<String> answer = new ArrayList<String>(); ArrayList<String> answer = new ArrayList<String>();
// Send the disco packet to the user // Send the disco packet to the user
DiscoverItems result = ServiceDiscoveryManager.getInstanceFor(connection).discoverItems( DiscoverItems result = ServiceDiscoveryManager.getInstanceFor(connection).discoverItems(
user, discoNode); user, DISCO_NODE);
// Collect the entityID for each returned item // Collect the entityID for each returned item
for (DiscoverItems.Item item : result.getItems()) { for (DiscoverItems.Item item : result.getItems()) {
answer.add(item.getEntityID()); answer.add(item.getEntityID());
@ -264,7 +265,7 @@ public class MultiUserChat {
DiscoverItems items = discoManager.discoverItems(connection.getServiceName()); DiscoverItems items = discoManager.discoverItems(connection.getServiceName());
for (DiscoverItems.Item item : items.getItems()) { for (DiscoverItems.Item item : items.getItems()) {
DiscoverInfo info = discoManager.discoverInfo(item.getEntityID()); DiscoverInfo info = discoManager.discoverInfo(item.getEntityID());
if (info.containsFeature(discoNamespace)) { if (info.containsFeature(MUCInitialPresence.NAMESPACE)) {
answer.add(item.getEntityID()); answer.add(item.getEntityID());
} }
} }
@ -420,7 +421,7 @@ public class MultiUserChat {
Presence presence = enter(nickname, null, null, connection.getPacketReplyTimeout()); Presence presence = enter(nickname, null, null, connection.getPacketReplyTimeout());
// Look for confirmation of room creation from the server // Look for confirmation of room creation from the server
MUCUser mucUser = getMUCUserExtension(presence); MUCUser mucUser = MUCUser.getFrom(presence);
if (mucUser != null && mucUser.getStatus() != null) { if (mucUser != null && mucUser.getStatus() != null) {
if ("201".equals(mucUser.getStatus().getCode())) { if ("201".equals(mucUser.getStatus().getCode())) {
// Room was created and the user has joined the room // Room was created and the user has joined the room
@ -661,7 +662,7 @@ public class MultiUserChat {
iq.setType(IQ.Type.set); iq.setType(IQ.Type.set);
// Create the reason for the room destruction // Create the reason for the room destruction
MUCOwner.Destroy destroy = new MUCOwner.Destroy(); Destroy destroy = new Destroy();
destroy.setReason(reason); destroy.setReason(reason);
destroy.setJid(alternateJID); destroy.setJid(alternateJID);
iq.setDestroy(destroy); iq.setDestroy(destroy);
@ -1371,7 +1372,7 @@ public class MultiUserChat {
iq.setTo(room); iq.setTo(room);
iq.setType(IQ.Type.set); iq.setType(IQ.Type.set);
// Set the new affiliation. // Set the new affiliation.
MUCOwner.Item item = new MUCOwner.Item(affiliation); MUCItem item = new MUCItem(affiliation);
item.setJid(jid); item.setJid(jid);
iq.addItem(item); iq.addItem(item);
@ -1385,7 +1386,7 @@ public class MultiUserChat {
iq.setType(IQ.Type.set); iq.setType(IQ.Type.set);
for (String jid : jids) { for (String jid : jids) {
// Set the new affiliation. // Set the new affiliation.
MUCOwner.Item item = new MUCOwner.Item(affiliation); MUCItem item = new MUCItem(affiliation);
item.setJid(jid); item.setJid(jid);
iq.addItem(item); iq.addItem(item);
} }
@ -1409,7 +1410,7 @@ public class MultiUserChat {
iq.setTo(room); iq.setTo(room);
iq.setType(IQ.Type.set); iq.setType(IQ.Type.set);
// Set the new affiliation. // Set the new affiliation.
MUCAdmin.Item item = new MUCAdmin.Item(affiliation, null); MUCItem item = new MUCItem(affiliation, null);
item.setJid(jid); item.setJid(jid);
item.setReason(reason); item.setReason(reason);
iq.addItem(item); iq.addItem(item);
@ -1424,7 +1425,7 @@ public class MultiUserChat {
iq.setType(IQ.Type.set); iq.setType(IQ.Type.set);
for (String jid : jids) { for (String jid : jids) {
// Set the new affiliation. // Set the new affiliation.
MUCAdmin.Item item = new MUCAdmin.Item(affiliation, null); MUCItem item = new MUCItem(affiliation, null);
item.setJid(jid); item.setJid(jid);
iq.addItem(item); iq.addItem(item);
} }
@ -1437,7 +1438,7 @@ public class MultiUserChat {
iq.setTo(room); iq.setTo(room);
iq.setType(IQ.Type.set); iq.setType(IQ.Type.set);
// Set the new role. // Set the new role.
MUCAdmin.Item item = new MUCAdmin.Item(null, role); MUCItem item = new MUCItem(null, role);
item.setNick(nickname); item.setNick(nickname);
item.setReason(reason); item.setReason(reason);
iq.addItem(item); iq.addItem(item);
@ -1451,7 +1452,7 @@ public class MultiUserChat {
iq.setType(IQ.Type.set); iq.setType(IQ.Type.set);
for (String nickname : nicknames) { for (String nickname : nicknames) {
// Set the new role. // Set the new role.
MUCAdmin.Item item = new MUCAdmin.Item(null, role); MUCItem item = new MUCItem(null, role);
item.setNick(nickname); item.setNick(nickname);
iq.addItem(item); iq.addItem(item);
} }
@ -1478,7 +1479,7 @@ public class MultiUserChat {
* in the group chat. For example, "conference@chat.jivesoftware.com/SomeUser". * in the group chat. For example, "conference@chat.jivesoftware.com/SomeUser".
* Typically, a client would only display the nickname of the occupant. To * Typically, a client would only display the nickname of the occupant. To
* get the nickname from the fully qualified name, use the * get the nickname from the fully qualified name, use the
* {@link org.jivesoftware.smack.util.StringUtils#parseResource(String)} method. * {@link org.jxmpp.util.XmppStringUtils#parseResource(String)} method.
* Note: this value will only be accurate after joining the group chat, and may * Note: this value will only be accurate after joining the group chat, and may
* fluctuate over time. * fluctuate over time.
* *
@ -1606,14 +1607,14 @@ public class MultiUserChat {
iq.setTo(room); iq.setTo(room);
iq.setType(IQ.Type.get); iq.setType(IQ.Type.get);
// Set the specified affiliation. This may request the list of owners/admins/members/outcasts. // Set the specified affiliation. This may request the list of owners/admins/members/outcasts.
MUCAdmin.Item item = new MUCAdmin.Item(affiliation, null); MUCItem item = new MUCItem(affiliation, null);
iq.addItem(item); iq.addItem(item);
MUCAdmin answer = (MUCAdmin) connection.createPacketCollectorAndSend(iq).nextResultOrThrow(); MUCAdmin answer = (MUCAdmin) connection.createPacketCollectorAndSend(iq).nextResultOrThrow();
// Get the list of affiliates from the server's answer // Get the list of affiliates from the server's answer
List<Affiliate> affiliates = new ArrayList<Affiliate>(); List<Affiliate> affiliates = new ArrayList<Affiliate>();
for (MUCAdmin.Item mucadminItem : answer.getItems()) { for (MUCItem mucadminItem : answer.getItems()) {
affiliates.add(new Affiliate(mucadminItem)); affiliates.add(new Affiliate(mucadminItem));
} }
return affiliates; return affiliates;
@ -1658,13 +1659,13 @@ public class MultiUserChat {
iq.setTo(room); iq.setTo(room);
iq.setType(IQ.Type.get); iq.setType(IQ.Type.get);
// Set the specified role. This may request the list of moderators/participants. // Set the specified role. This may request the list of moderators/participants.
MUCAdmin.Item item = new MUCAdmin.Item(null, role); MUCItem item = new MUCItem(null, role);
iq.addItem(item); iq.addItem(item);
MUCAdmin answer = (MUCAdmin) connection.createPacketCollectorAndSend(iq).nextResultOrThrow(); MUCAdmin answer = (MUCAdmin) connection.createPacketCollectorAndSend(iq).nextResultOrThrow();
// Get the list of participants from the server's answer // Get the list of participants from the server's answer
List<Occupant> participants = new ArrayList<Occupant>(); List<Occupant> participants = new ArrayList<Occupant>();
for (MUCAdmin.Item mucadminItem : answer.getItems()) { for (MUCItem mucadminItem : answer.getItems()) {
participants.add(new Occupant(mucadminItem)); participants.add(new Occupant(mucadminItem));
} }
return participants; return participants;
@ -1828,20 +1829,6 @@ public class MultiUserChat {
cleanup(); cleanup();
} }
/**
* Returns the MUCUser packet extension included in the packet or <tt>null</tt> if none.
*
* @param packet the packet that may include the MUCUser extension.
* @return the MUCUser found in the packet.
*/
private MUCUser getMUCUserExtension(Packet packet) {
if (packet != null) {
// Get the MUC User extension
return (MUCUser) packet.getExtension("x", "http://jabber.org/protocol/muc#user");
}
return null;
}
/** /**
* Adds a listener that will be notified of changes in your status in the room * Adds a listener that will be notified of changes in your status in the room
* such as the user being kicked, banned, or granted admin permissions. * such as the user being kicked, banned, or granted admin permissions.
@ -1978,11 +1965,11 @@ public class MultiUserChat {
Presence oldPresence = occupantsMap.put(from, presence); Presence oldPresence = occupantsMap.put(from, presence);
if (oldPresence != null) { if (oldPresence != null) {
// Get the previous occupant's affiliation & role // Get the previous occupant's affiliation & role
MUCUser mucExtension = getMUCUserExtension(oldPresence); MUCUser mucExtension = MUCUser.getFrom(packet);
String oldAffiliation = mucExtension.getItem().getAffiliation(); String oldAffiliation = mucExtension.getItem().getAffiliation();
String oldRole = mucExtension.getItem().getRole(); String oldRole = mucExtension.getItem().getRole();
// Get the new occupant's affiliation & role // Get the new occupant's affiliation & role
mucExtension = getMUCUserExtension(presence); mucExtension = MUCUser.getFrom(packet);
String newAffiliation = mucExtension.getItem().getAffiliation(); String newAffiliation = mucExtension.getItem().getAffiliation();
String newRole = mucExtension.getItem().getRole(); String newRole = mucExtension.getItem().getRole();
// Fire role modification events // Fire role modification events
@ -2005,7 +1992,7 @@ public class MultiUserChat {
} }
else if (presence.getType() == Presence.Type.unavailable) { else if (presence.getType() == Presence.Type.unavailable) {
occupantsMap.remove(from); occupantsMap.remove(from);
MUCUser mucUser = getMUCUserExtension(presence); MUCUser mucUser = MUCUser.getFrom(packet);
if (mucUser != null && mucUser.getStatus() != null) { if (mucUser != null && mucUser.getStatus() != null) {
// Fire events according to the received presence code // Fire events according to the received presence code
checkPresenceCode( checkPresenceCode(
@ -2030,7 +2017,7 @@ public class MultiUserChat {
PacketListener declinesListener = new PacketListener() { PacketListener declinesListener = new PacketListener() {
public void processPacket(Packet packet) { public void processPacket(Packet packet) {
// Get the MUC User extension // Get the MUC User extension
MUCUser mucUser = getMUCUserExtension(packet); MUCUser mucUser = MUCUser.getFrom(packet);
// Check if the MUCUser informs that the invitee has declined the invitation // Check if the MUCUser informs that the invitee has declined the invitation
if (mucUser.getDecline() != null && if (mucUser.getDecline() != null &&
((Message) packet).getType() != Message.Type.error) { ((Message) packet).getType() != Message.Type.error) {
@ -2513,8 +2500,7 @@ public class MultiUserChat {
invitationPacketListener = new PacketListener() { invitationPacketListener = new PacketListener() {
public void processPacket(Packet packet) { public void processPacket(Packet packet) {
// Get the MUCUser extension // Get the MUCUser extension
MUCUser mucUser = MUCUser mucUser = MUCUser.getFrom(packet);
(MUCUser) packet.getExtension("x", "http://jabber.org/protocol/muc#user");
// Check if the MUCUser extension includes an invitation // Check if the MUCUser extension includes an invitation
if (mucUser.getInvite() != null && if (mucUser.getInvite() != null &&
((Message) packet).getType() != Message.Type.error) { ((Message) packet).getType() != Message.Type.error) {

View file

@ -17,7 +17,7 @@
package org.jivesoftware.smackx.muc; package org.jivesoftware.smackx.muc;
import org.jivesoftware.smackx.muc.packet.MUCAdmin; import org.jivesoftware.smackx.muc.packet.MUCItem;
import org.jivesoftware.smackx.muc.packet.MUCUser; import org.jivesoftware.smackx.muc.packet.MUCUser;
import org.jivesoftware.smack.packet.Presence; import org.jivesoftware.smack.packet.Presence;
import org.jxmpp.util.XmppStringUtils; import org.jxmpp.util.XmppStringUtils;
@ -36,8 +36,7 @@ public class Occupant {
private String jid; private String jid;
private String nick; private String nick;
Occupant(MUCAdmin.Item item) { Occupant(MUCItem item) {
super();
this.jid = item.getJid(); this.jid = item.getJid();
this.affiliation = item.getAffiliation(); this.affiliation = item.getAffiliation();
this.role = item.getRole(); this.role = item.getRole();
@ -45,10 +44,9 @@ public class Occupant {
} }
Occupant(Presence presence) { Occupant(Presence presence) {
super();
MUCUser mucUser = (MUCUser) presence.getExtension("x", MUCUser mucUser = (MUCUser) presence.getExtension("x",
"http://jabber.org/protocol/muc#user"); "http://jabber.org/protocol/muc#user");
MUCUser.Item item = mucUser.getItem(); MUCItem item = mucUser.getItem();
this.jid = item.getJid(); this.jid = item.getJid();
this.affiliation = item.getAffiliation(); this.affiliation = item.getAffiliation();
this.role = item.getRole(); this.role = item.getRole();

View file

@ -26,6 +26,7 @@ import org.jivesoftware.smack.filter.PacketTypeFilter;
import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.Presence; import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smackx.muc.packet.MUCUser;
/** /**
* The single <code>PacketListener</code> used by each {@link MultiUserChat} * The single <code>PacketListener</code> used by each {@link MultiUserChat}
@ -42,9 +43,8 @@ class PacketMultiplexListener implements PacketListener {
return msg.getSubject() != null; return msg.getSubject() != null;
} }
}; };
private static final PacketFilter DECLINES_FILTER = private static final PacketFilter DECLINES_FILTER = new PacketExtensionFilter(MUCUser.ELEMENT,
new PacketExtensionFilter("x", MUCUser.NAMESPACE);
"http://jabber.org/protocol/muc#user");
private ConnectionDetachedPacketCollector messageCollector; private ConnectionDetachedPacketCollector messageCollector;
private PacketListener presenceListener; private PacketListener presenceListener;

View file

@ -0,0 +1,86 @@
/**
*
* Copyright 2003-2007 Jive Software, 2014 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.muc.packet;
import org.jivesoftware.smack.packet.Element;
import org.jivesoftware.smack.util.XmlStringBuilder;
/**
* Represents a request to the server to destroy a room. The sender of the request should be the
* room's owner. If the sender of the destroy request is not the room's owner then the server will
* answer a "Forbidden" error.
*
* @author Gaston Dombiak
*/
public class Destroy implements Element {
public static final String ELEMENT = "destroy";
private String reason;
private String jid;
/**
* Returns the JID of an alternate location since the current room is being destroyed.
*
* @return the JID of an alternate location.
*/
public String getJid() {
return jid;
}
/**
* Returns the reason for the room destruction.
*
* @return the reason for the room destruction.
*/
public String getReason() {
return reason;
}
/**
* Sets the JID of an alternate location since the current room is being destroyed.
*
* @param jid the JID of an alternate location.
*/
public void setJid(String jid) {
this.jid = jid;
}
/**
* Sets the reason for the room destruction.
*
* @param reason the reason for the room destruction.
*/
public void setReason(String reason) {
this.reason = reason;
}
@Override
public XmlStringBuilder toXML() {
XmlStringBuilder xml = new XmlStringBuilder(this);
xml.optAttribute("jid", getJid());
xml.rightAngelBracket();
xml.optElement("reason", getReason());
xml.closeElement(this);
return xml;
}
@Override
public String getElementName() {
return ELEMENT;
}
}

View file

@ -17,8 +17,10 @@
package org.jivesoftware.smackx.muc.packet; package org.jivesoftware.smackx.muc.packet;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.PacketExtension; import org.jivesoftware.smack.packet.PacketExtension;
import org.jivesoftware.smack.provider.PacketExtensionProvider; import org.jivesoftware.smack.provider.PacketExtensionProvider;
import org.jivesoftware.smack.util.XmlStringBuilder;
import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParser;
/** /**
@ -55,14 +57,14 @@ public class GroupChatInvitation implements PacketExtension {
/** /**
* Element name of the packet extension. * Element name of the packet extension.
*/ */
public static final String ELEMENT_NAME = "x"; public static final String ELEMENT = "x";
/** /**
* Namespace of the packet extension. * Namespace of the packet extension.
*/ */
public static final String NAMESPACE = "jabber:x:conference"; public static final String NAMESPACE = "jabber:x:conference";
private String roomAddress; private final String roomAddress;
/** /**
* Creates a new group chat invitation to the specified room address. * Creates a new group chat invitation to the specified room address.
@ -88,17 +90,23 @@ public class GroupChatInvitation implements PacketExtension {
} }
public String getElementName() { public String getElementName() {
return ELEMENT_NAME; return ELEMENT;
} }
public String getNamespace() { public String getNamespace() {
return NAMESPACE; return NAMESPACE;
} }
public String toXML() { @Override
StringBuilder buf = new StringBuilder(); public XmlStringBuilder toXML() {
buf.append("<x xmlns=\"jabber:x:conference\" jid=\"").append(roomAddress).append("\"/>"); XmlStringBuilder xml = new XmlStringBuilder(this);
return buf.toString(); xml.attribute("jid", getRoomAddress());
xml.closeEmptyElement();
return xml;
}
public static GroupChatInvitation getFrom(Packet packet) {
return packet.getExtension(ELEMENT, NAMESPACE);
} }
public static class Provider implements PacketExtensionProvider { public static class Provider implements PacketExtensionProvider {

View file

@ -21,6 +21,7 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.util.XmlStringBuilder;
/** /**
* IQ packet that serves for kicking users, granting and revoking voice, banning users, * IQ packet that serves for kicking users, granting and revoking voice, banning users,
@ -32,7 +33,9 @@ import org.jivesoftware.smack.packet.IQ;
*/ */
public class MUCAdmin extends IQ { public class MUCAdmin extends IQ {
private List<Item> items = new ArrayList<Item>(); public static final String NAMESPACE = MUCInitialPresence.NAMESPACE + "#admin";
private final List<MUCItem> items = new ArrayList<MUCItem>();
/** /**
* Returns a List of item childs that holds information about roles, affiliation, * Returns a List of item childs that holds information about roles, affiliation,
@ -41,9 +44,9 @@ public class MUCAdmin extends IQ {
* @return a List of item childs that holds information about roles, affiliation, * @return a List of item childs that holds information about roles, affiliation,
* jids and nicks. * jids and nicks.
*/ */
public List<Item> getItems() { public List<MUCItem> getItems() {
synchronized (items) { synchronized (items) {
return Collections.unmodifiableList(new ArrayList<Item>(items)); return Collections.unmodifiableList(new ArrayList<MUCItem>(items));
} }
} }
@ -52,182 +55,26 @@ public class MUCAdmin extends IQ {
* *
* @param item the item child that holds information about roles, affiliation, jids and nicks. * @param item the item child that holds information about roles, affiliation, jids and nicks.
*/ */
public void addItem(Item item) { public void addItem(MUCItem item) {
synchronized (items) { synchronized (items) {
items.add(item); items.add(item);
} }
} }
public String getChildElementXML() { @Override
StringBuilder buf = new StringBuilder(); public XmlStringBuilder getChildElementXML() {
buf.append("<query xmlns=\"http://jabber.org/protocol/muc#admin\">"); XmlStringBuilder xml = new XmlStringBuilder();
xml.halfOpenElement(IQ.QUERY_ELEMENT);
xml.xmlnsAttribute(NAMESPACE);
xml.rightAngelBracket();
synchronized (items) { synchronized (items) {
for (int i = 0; i < items.size(); i++) { for (MUCItem item : items) {
Item item = items.get(i); xml.append(item.toXML());
buf.append(item.toXML());
} }
} }
// Add packet extensions, if any are defined. // Add packet extensions, if any are defined.
buf.append(getExtensionsXML()); xml.append(getExtensionsXML());
buf.append("</query>"); xml.closeElement(IQ.QUERY_ELEMENT);
return buf.toString(); return xml;
} }
/**
* Item child that holds information about roles, affiliation, jids and nicks.
*
* @author Gaston Dombiak
*/
public static class Item {
private String actor;
private String reason;
private String affiliation;
private String jid;
private String nick;
private String role;
/**
* Creates a new item child.
*
* @param affiliation the actor's affiliation to the room
* @param role the privilege level of an occupant within a room.
*/
public Item(String affiliation, String role) {
this.affiliation = affiliation;
this.role = role;
}
/**
* Returns the actor (JID of an occupant in the room) that was kicked or banned.
*
* @return the JID of an occupant in the room that was kicked or banned.
*/
public String getActor() {
return actor;
}
/**
* Returns the reason for the item child. The reason is optional and could be used to
* explain the reason why a user (occupant) was kicked or banned.
*
* @return the reason for the item child.
*/
public String getReason() {
return reason;
}
/**
* Returns the occupant's affiliation to the room. The affiliation is a semi-permanent
* association or connection with a room. The possible affiliations are "owner", "admin",
* "member", and "outcast" (naturally it is also possible to have no affiliation). An
* affiliation lasts across a user's visits to a room.
*
* @return the actor's affiliation to the room
*/
public String getAffiliation() {
return affiliation;
}
/**
* Returns the <room@service/nick> by which an occupant is identified within the context
* of a room. If the room is non-anonymous, the JID will be included in the item.
*
* @return the room JID by which an occupant is identified within the room.
*/
public String getJid() {
return jid;
}
/**
* Returns the new nickname of an occupant that is changing his/her nickname. The new
* nickname is sent as part of the unavailable presence.
*
* @return the new nickname of an occupant that is changing his/her nickname.
*/
public String getNick() {
return nick;
}
/**
* Returns the temporary position or privilege level of an occupant within a room. The
* possible roles are "moderator", "participant", and "visitor" (it is also possible to
* have no defined role). A role lasts only for the duration of an occupant's visit to
* a room.
*
* @return the privilege level of an occupant within a room.
*/
public String getRole() {
return role;
}
/**
* Sets the actor (JID of an occupant in the room) that was kicked or banned.
*
* @param actor the actor (JID of an occupant in the room) that was kicked or banned.
*/
public void setActor(String actor) {
this.actor = actor;
}
/**
* Sets the reason for the item child. The reason is optional and could be used to
* explain the reason why a user (occupant) was kicked or banned.
*
* @param reason the reason why a user (occupant) was kicked or banned.
*/
public void setReason(String reason) {
this.reason = reason;
}
/**
* Sets the <room@service/nick> by which an occupant is identified within the context
* of a room. If the room is non-anonymous, the JID will be included in the item.
*
* @param jid the JID by which an occupant is identified within a room.
*/
public void setJid(String jid) {
this.jid = jid;
}
/**
* Sets the new nickname of an occupant that is changing his/her nickname. The new
* nickname is sent as part of the unavailable presence.
*
* @param nick the new nickname of an occupant that is changing his/her nickname.
*/
public void setNick(String nick) {
this.nick = nick;
}
public String toXML() {
StringBuilder buf = new StringBuilder();
buf.append("<item");
if (getAffiliation() != null) {
buf.append(" affiliation=\"").append(getAffiliation()).append("\"");
}
if (getJid() != null) {
buf.append(" jid=\"").append(getJid()).append("\"");
}
if (getNick() != null) {
buf.append(" nick=\"").append(getNick()).append("\"");
}
if (getRole() != null) {
buf.append(" role=\"").append(getRole()).append("\"");
}
if (getReason() == null && getActor() == null) {
buf.append("/>");
}
else {
buf.append(">");
if (getReason() != null) {
buf.append("<reason>").append(getReason()).append("</reason>");
}
if (getActor() != null) {
buf.append("<actor jid=\"").append(getActor()).append("\"/>");
}
buf.append("</item>");
}
return buf.toString();
}
};
} }

View file

@ -17,11 +17,13 @@
package org.jivesoftware.smackx.muc.packet; package org.jivesoftware.smackx.muc.packet;
import org.jivesoftware.smack.packet.Element;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.PacketExtension; import org.jivesoftware.smack.packet.PacketExtension;
import org.jivesoftware.smack.util.XmlStringBuilder;
import org.jxmpp.util.XmppDateTime;
import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.TimeZone;
/** /**
* Represents extended presence information whose sole purpose is to signal the ability of * Represents extended presence information whose sole purpose is to signal the ability of
@ -37,29 +39,28 @@ import java.util.TimeZone;
*/ */
public class MUCInitialPresence implements PacketExtension { public class MUCInitialPresence implements PacketExtension {
public static final String ELEMENT = "x";
public static final String NAMESPACE = "http://jabber.org/protocol/muc";
private String password; private String password;
private History history; private History history;
public String getElementName() { public String getElementName() {
return "x"; return ELEMENT;
} }
public String getNamespace() { public String getNamespace() {
return "http://jabber.org/protocol/muc"; return NAMESPACE;
} }
public String toXML() { @Override
StringBuilder buf = new StringBuilder(); public XmlStringBuilder toXML() {
buf.append("<").append(getElementName()).append(" xmlns=\"").append(getNamespace()).append( XmlStringBuilder xml = new XmlStringBuilder(this);
"\">"); xml.rightAngelBracket();
if (getPassword() != null) { xml.optElement("password", getPassword());
buf.append("<password>").append(getPassword()).append("</password>"); xml.optElement(getHistory());
} xml.closeElement(this);
if (getHistory() != null) { return xml;
buf.append(getHistory().toXML());
}
buf.append("</").append(getElementName()).append(">");
return buf.toString();
} }
/** /**
@ -102,13 +103,25 @@ public class MUCInitialPresence implements PacketExtension {
this.password = password; this.password = password;
} }
/**
* Retrieve the MUCInitialPresence PacketExtension from packet, if any.
*
* @param packet
* @return the MUCInitialPresence PacketExtension or {@code null}
*/
public static MUCInitialPresence getFrom(Packet packet) {
return packet.getExtension(ELEMENT, NAMESPACE);
}
/** /**
* The History class controls the number of characters or messages to receive * The History class controls the number of characters or messages to receive
* when entering a room. * when entering a room.
* *
* @author Gaston Dombiak * @author Gaston Dombiak
*/ */
public static class History { public static class History implements Element {
public static final String ELEMENT = "history";
private int maxChars = -1; private int maxChars = -1;
private int maxStanzas = -1; private int maxStanzas = -1;
@ -196,25 +209,21 @@ public class MUCInitialPresence implements PacketExtension {
this.since = since; this.since = since;
} }
public String toXML() { public XmlStringBuilder toXML() {
StringBuilder buf = new StringBuilder(); XmlStringBuilder xml = new XmlStringBuilder(this);
buf.append("<history"); xml.optIntAttribute("maxchars", getMaxChars());
if (getMaxChars() != -1) { xml.optIntAttribute("maxstanzas", getMaxStanzas());
buf.append(" maxchars=\"").append(getMaxChars()).append("\""); xml.optIntAttribute("seconds", getSeconds());
}
if (getMaxStanzas() != -1) {
buf.append(" maxstanzas=\"").append(getMaxStanzas()).append("\"");
}
if (getSeconds() != -1) {
buf.append(" seconds=\"").append(getSeconds()).append("\"");
}
if (getSince() != null) { if (getSince() != null) {
SimpleDateFormat utcFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); xml.attribute("since", XmppDateTime.formatXEP0082Date(getSince()));
utcFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
buf.append(" since=\"").append(utcFormat.format(getSince())).append("\"");
} }
buf.append("/>"); xml.closeEmptyElement();
return buf.toString(); return xml;
}
@Override
public String getElementName() {
return ELEMENT;
} }
} }
} }

View file

@ -0,0 +1,189 @@
/**
*
* Copyright 2003-2007 Jive Software, 2014 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.muc.packet;
import org.jivesoftware.smack.packet.Element;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.util.XmlStringBuilder;
/**
* Item child that holds information about roles, affiliation, jids and nicks.
*
* @author Gaston Dombiak
*/
public class MUCItem implements Element {
public static final String ELEMENT = IQ.ITEM;
private final String affiliation;
private String role;
private String actor;
private String reason;
private String jid;
private String nick;
/**
* Creates a new item child.
*
* @param affiliation the actor's affiliation to the room
*/
public MUCItem(String affiliation) {
this.affiliation = affiliation;
}
/**
* Creates a new item child.
*
* @param affiliation the actor's affiliation to the room
* @param role the privilege level of an occupant within a room.
*/
public MUCItem(String affiliation, String role) {
this(affiliation);
this.role = role;
}
/**
* Returns the actor (JID of an occupant in the room) that was kicked or banned.
*
* @return the JID of an occupant in the room that was kicked or banned.
*/
public String getActor() {
return actor;
}
/**
* Returns the reason for the item child. The reason is optional and could be used to explain
* the reason why a user (occupant) was kicked or banned.
*
* @return the reason for the item child.
*/
public String getReason() {
return reason;
}
/**
* Returns the occupant's affiliation to the room. The affiliation is a semi-permanent
* association or connection with a room. The possible affiliations are "owner", "admin",
* "member", and "outcast" (naturally it is also possible to have no affiliation). An
* affiliation lasts across a user's visits to a room.
*
* @return the actor's affiliation to the room
*/
public String getAffiliation() {
return affiliation;
}
/**
* Returns the <room@service/nick> by which an occupant is identified within the context of a
* room. If the room is non-anonymous, the JID will be included in the item.
*
* @return the room JID by which an occupant is identified within the room.
*/
public String getJid() {
return jid;
}
/**
* Returns the new nickname of an occupant that is changing his/her nickname. The new nickname
* is sent as part of the unavailable presence.
*
* @return the new nickname of an occupant that is changing his/her nickname.
*/
public String getNick() {
return nick;
}
/**
* Returns the temporary position or privilege level of an occupant within a room. The possible
* roles are "moderator", "participant", and "visitor" (it is also possible to have no defined
* role). A role lasts only for the duration of an occupant's visit to a room.
*
* @return the privilege level of an occupant within a room.
*/
public String getRole() {
return role;
}
/**
* Sets the actor (JID of an occupant in the room) that was kicked or banned.
*
* @param actor the actor (JID of an occupant in the room) that was kicked or banned.
*/
public void setActor(String actor) {
this.actor = actor;
}
/**
* Sets the reason for the item child. The reason is optional and could be used to explain the
* reason why a user (occupant) was kicked or banned.
*
* @param reason the reason why a user (occupant) was kicked or banned.
*/
public void setReason(String reason) {
this.reason = reason;
}
/**
* Sets the <room@service/nick> by which an occupant is identified within the context of a room.
* If the room is non-anonymous, the JID will be included in the item.
*
* @param jid the JID by which an occupant is identified within a room.
*/
public void setJid(String jid) {
this.jid = jid;
}
/**
* Sets the new nickname of an occupant that is changing his/her nickname. The new nickname is
* sent as part of the unavailable presence.
*
* @param nick the new nickname of an occupant that is changing his/her nickname.
*/
public void setNick(String nick) {
this.nick = nick;
}
/**
* Sets the temporary position or privilege level of an occupant within a room. The possible
* roles are "moderator", "participant", and "visitor" (it is also possible to have no defined
* role). A role lasts only for the duration of an occupant's visit to a room.
*
* @param role the new privilege level of an occupant within a room.
*/
public void setRole(String role) {
this.role = role;
}
public XmlStringBuilder toXML() {
XmlStringBuilder xml = new XmlStringBuilder(this);
xml.optAttribute("affiliation", getAffiliation());
xml.optAttribute("jid", getJid());
xml.optAttribute("nick", getNick());
xml.optAttribute("role", getRole());
xml.rightAngelBracket();
xml.optElement("reason", getReason());
if (getActor() != null) {
xml.halfOpenElement("actor").attribute("jid", getActor()).closeEmptyElement();
}
xml.closeElement(IQ.ITEM);
return xml;
}
@Override
public String getElementName() {
return ELEMENT;
}
}

View file

@ -17,6 +17,7 @@
package org.jivesoftware.smackx.muc.packet; package org.jivesoftware.smackx.muc.packet;
import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.util.XmlStringBuilder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -31,7 +32,9 @@ import java.util.List;
*/ */
public class MUCOwner extends IQ { public class MUCOwner extends IQ {
private List<Item> items = new ArrayList<Item>(); public static final String NAMESPACE = MUCInitialPresence.NAMESPACE + "#owner";
private final List<MUCItem> items = new ArrayList<MUCItem>();
private Destroy destroy; private Destroy destroy;
/** /**
@ -41,9 +44,9 @@ public class MUCOwner extends IQ {
* @return a List of item childs that holds information about affiliation, * @return a List of item childs that holds information about affiliation,
* jids and nicks. * jids and nicks.
*/ */
public List<Item> getItems() { public List<MUCItem> getItems() {
synchronized (items) { synchronized (items) {
return Collections.unmodifiableList(new ArrayList<Item>(items)); return Collections.unmodifiableList(new ArrayList<MUCItem>(items));
} }
} }
@ -74,265 +77,28 @@ public class MUCOwner extends IQ {
* *
* @param item the item child that holds information about affiliation, jids and nicks. * @param item the item child that holds information about affiliation, jids and nicks.
*/ */
public void addItem(Item item) { public void addItem(MUCItem item) {
synchronized (items) { synchronized (items) {
items.add(item); items.add(item);
} }
} }
public String getChildElementXML() { @Override
StringBuilder buf = new StringBuilder(); public XmlStringBuilder getChildElementXML() {
buf.append("<query xmlns=\"http://jabber.org/protocol/muc#owner\">"); XmlStringBuilder xml = new XmlStringBuilder();
xml.halfOpenElement(IQ.QUERY_ELEMENT);
xml.xmlnsAttribute(NAMESPACE);
xml.rightAngelBracket();
synchronized (items) { synchronized (items) {
for (int i = 0; i < items.size(); i++) { for (MUCItem item : items) {
Item item = (Item) items.get(i); xml.append(item.toXML());
buf.append(item.toXML());
} }
} }
if (getDestroy() != null) { xml.optElement(getDestroy());
buf.append(getDestroy().toXML());
}
// Add packet extensions, if any are defined. // Add packet extensions, if any are defined.
buf.append(getExtensionsXML()); xml.append(getExtensionsXML());
buf.append("</query>"); xml.closeElement(IQ.QUERY_ELEMENT);
return buf.toString(); return xml;
} }
/**
* Item child that holds information about affiliation, jids and nicks.
*
* @author Gaston Dombiak
*/
public static class Item {
private String actor;
private String reason;
private String affiliation;
private String jid;
private String nick;
private String role;
/**
* Creates a new item child.
*
* @param affiliation the actor's affiliation to the room
*/
public Item(String affiliation) {
this.affiliation = affiliation;
}
/**
* Returns the actor (JID of an occupant in the room) that was kicked or banned.
*
* @return the JID of an occupant in the room that was kicked or banned.
*/
public String getActor() {
return actor;
}
/**
* Returns the reason for the item child. The reason is optional and could be used to
* explain the reason why a user (occupant) was kicked or banned.
*
* @return the reason for the item child.
*/
public String getReason() {
return reason;
}
/**
* Returns the occupant's affiliation to the room. The affiliation is a semi-permanent
* association or connection with a room. The possible affiliations are "owner", "admin",
* "member", and "outcast" (naturally it is also possible to have no affiliation). An
* affiliation lasts across a user's visits to a room.
*
* @return the actor's affiliation to the room
*/
public String getAffiliation() {
return affiliation;
}
/**
* Returns the <room@service/nick> by which an occupant is identified within the context
* of a room. If the room is non-anonymous, the JID will be included in the item.
*
* @return the room JID by which an occupant is identified within the room.
*/
public String getJid() {
return jid;
}
/**
* Returns the new nickname of an occupant that is changing his/her nickname. The new
* nickname is sent as part of the unavailable presence.
*
* @return the new nickname of an occupant that is changing his/her nickname.
*/
public String getNick() {
return nick;
}
/**
* Returns the temporary position or privilege level of an occupant within a room. The
* possible roles are "moderator", "participant", and "visitor" (it is also possible to
* have no defined role). A role lasts only for the duration of an occupant's visit to
* a room.
*
* @return the privilege level of an occupant within a room.
*/
public String getRole() {
return role;
}
/**
* Sets the actor (JID of an occupant in the room) that was kicked or banned.
*
* @param actor the actor (JID of an occupant in the room) that was kicked or banned.
*/
public void setActor(String actor) {
this.actor = actor;
}
/**
* Sets the reason for the item child. The reason is optional and could be used to
* explain the reason why a user (occupant) was kicked or banned.
*
* @param reason the reason why a user (occupant) was kicked or banned.
*/
public void setReason(String reason) {
this.reason = reason;
}
/**
* Sets the <room@service/nick> by which an occupant is identified within the context
* of a room. If the room is non-anonymous, the JID will be included in the item.
*
* @param jid the JID by which an occupant is identified within a room.
*/
public void setJid(String jid) {
this.jid = jid;
}
/**
* Sets the new nickname of an occupant that is changing his/her nickname. The new
* nickname is sent as part of the unavailable presence.
*
* @param nick the new nickname of an occupant that is changing his/her nickname.
*/
public void setNick(String nick) {
this.nick = nick;
}
/**
* Sets the temporary position or privilege level of an occupant within a room. The
* possible roles are "moderator", "participant", and "visitor" (it is also possible to
* have no defined role). A role lasts only for the duration of an occupant's visit to
* a room.
*
* @param role the new privilege level of an occupant within a room.
*/
public void setRole(String role) {
this.role = role;
}
public String toXML() {
StringBuilder buf = new StringBuilder();
buf.append("<item");
if (getAffiliation() != null) {
buf.append(" affiliation=\"").append(getAffiliation()).append("\"");
}
if (getJid() != null) {
buf.append(" jid=\"").append(getJid()).append("\"");
}
if (getNick() != null) {
buf.append(" nick=\"").append(getNick()).append("\"");
}
if (getRole() != null) {
buf.append(" role=\"").append(getRole()).append("\"");
}
if (getReason() == null && getActor() == null) {
buf.append("/>");
}
else {
buf.append(">");
if (getReason() != null) {
buf.append("<reason>").append(getReason()).append("</reason>");
}
if (getActor() != null) {
buf.append("<actor jid=\"").append(getActor()).append("\"/>");
}
buf.append("</item>");
}
return buf.toString();
}
};
/**
* Represents a request to the server to destroy a room. The sender of the request
* should be the room's owner. If the sender of the destroy request is not the room's owner
* then the server will answer a "Forbidden" error.
*
* @author Gaston Dombiak
*/
public static class Destroy {
private String reason;
private String jid;
/**
* Returns the JID of an alternate location since the current room is being destroyed.
*
* @return the JID of an alternate location.
*/
public String getJid() {
return jid;
}
/**
* Returns the reason for the room destruction.
*
* @return the reason for the room destruction.
*/
public String getReason() {
return reason;
}
/**
* Sets the JID of an alternate location since the current room is being destroyed.
*
* @param jid the JID of an alternate location.
*/
public void setJid(String jid) {
this.jid = jid;
}
/**
* Sets the reason for the room destruction.
*
* @param reason the reason for the room destruction.
*/
public void setReason(String reason) {
this.reason = reason;
}
public String toXML() {
StringBuilder buf = new StringBuilder();
buf.append("<destroy");
if (getJid() != null) {
buf.append(" jid=\"").append(getJid()).append("\"");
}
if (getReason() == null) {
buf.append("/>");
}
else {
buf.append(">");
if (getReason() != null) {
buf.append("<reason>").append(getReason()).append("</reason>");
}
buf.append("</destroy>");
}
return buf.toString();
}
}
} }

View file

@ -17,7 +17,10 @@
package org.jivesoftware.smackx.muc.packet; package org.jivesoftware.smackx.muc.packet;
import org.jivesoftware.smack.packet.Element;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.PacketExtension; import org.jivesoftware.smack.packet.PacketExtension;
import org.jivesoftware.smack.util.XmlStringBuilder;
/** /**
* Represents extended presence information about roles, affiliations, full JIDs, * Represents extended presence information about roles, affiliations, full JIDs,
@ -27,45 +30,36 @@ import org.jivesoftware.smack.packet.PacketExtension;
*/ */
public class MUCUser implements PacketExtension { public class MUCUser implements PacketExtension {
public static final String ELEMENT = "x";
public static final String NAMESPACE = MUCInitialPresence.NAMESPACE + "#user";
private Invite invite; private Invite invite;
private Decline decline; private Decline decline;
private Item item; private MUCItem item;
private String password; private String password;
private Status status; private Status status;
private Destroy destroy; private Destroy destroy;
public String getElementName() { public String getElementName() {
return "x"; return ELEMENT;
} }
public String getNamespace() { public String getNamespace() {
return "http://jabber.org/protocol/muc#user"; return NAMESPACE;
} }
public String toXML() { @Override
StringBuilder buf = new StringBuilder(); public XmlStringBuilder toXML() {
buf.append("<").append(getElementName()).append(" xmlns=\"").append(getNamespace()).append( XmlStringBuilder xml = new XmlStringBuilder(this);
"\">"); xml.rightAngelBracket();
if (getInvite() != null) { xml.optElement(getInvite());
buf.append(getInvite().toXML()); xml.optElement(getDecline());
} xml.optElement(getItem());
if (getDecline() != null) { xml.optElement("password", getPassword());
buf.append(getDecline().toXML()); xml.optElement(getStatus());
} xml.optElement(getDestroy());
if (getItem() != null) { xml.closeElement(this);
buf.append(getItem().toXML()); return xml;
}
if (getPassword() != null) {
buf.append("<password>").append(getPassword()).append("</password>");
}
if (getStatus() != null) {
buf.append(getStatus().toXML());
}
if (getDestroy() != null) {
buf.append(getDestroy().toXML());
}
buf.append("</").append(getElementName()).append(">");
return buf.toString();
} }
/** /**
@ -94,7 +88,7 @@ public class MUCUser implements PacketExtension {
* *
* @return an item child that holds information about roles, affiliation, jids and nicks. * @return an item child that holds information about roles, affiliation, jids and nicks.
*/ */
public Item getItem() { public MUCItem getItem() {
return item; return item;
} }
@ -154,7 +148,7 @@ public class MUCUser implements PacketExtension {
* *
* @param item the item child that holds information about roles, affiliation, jids and nicks. * @param item the item child that holds information about roles, affiliation, jids and nicks.
*/ */
public void setItem(Item item) { public void setItem(MUCItem item) {
this.item = item; this.item = item;
} }
@ -189,6 +183,16 @@ public class MUCUser implements PacketExtension {
this.destroy = destroy; this.destroy = destroy;
} }
/**
* Retrieve the MUCUser PacketExtension from packet, if any.
*
* @param packet
* @return the MUCUser PacketExtension or {@code null}
*/
public static MUCUser getFrom(Packet packet) {
return packet.getExtension(ELEMENT, NAMESPACE);
}
/** /**
* Represents an invitation for another user to a room. The sender of the invitation * Represents an invitation for another user to a room. The sender of the invitation
* must be an occupant of the room. The invitation will be sent to the room which in turn * must be an occupant of the room. The invitation will be sent to the room which in turn
@ -196,7 +200,9 @@ public class MUCUser implements PacketExtension {
* *
* @author Gaston Dombiak * @author Gaston Dombiak
*/ */
public static class Invite { public static class Invite implements Element {
public static final String ELEMENT ="invite";
private String reason; private String reason;
private String from; private String from;
private String to; private String to;
@ -257,21 +263,20 @@ public class MUCUser implements PacketExtension {
this.to = to; this.to = to;
} }
public String toXML() { @Override
StringBuilder buf = new StringBuilder(); public XmlStringBuilder toXML() {
buf.append("<invite "); XmlStringBuilder xml = new XmlStringBuilder(this);
if (getTo() != null) { xml.optAttribute("to", getTo());
buf.append(" to=\"").append(getTo()).append("\""); xml.optAttribute("from", getFrom());
xml.rightAngelBracket();
xml.optElement("reason", getReason());
xml.closeElement(this);
return xml;
} }
if (getFrom() != null) {
buf.append(" from=\"").append(getFrom()).append("\""); @Override
} public String getElementName() {
buf.append(">"); return ELEMENT;
if (getReason() != null) {
buf.append("<reason>").append(getReason()).append("</reason>");
}
buf.append("</invite>");
return buf.toString();
} }
} }
@ -281,7 +286,9 @@ public class MUCUser implements PacketExtension {
* *
* @author Gaston Dombiak * @author Gaston Dombiak
*/ */
public static class Decline { public static class Decline implements Element {
public static final String ELEMENT = "decline";
private String reason; private String reason;
private String from; private String from;
private String to; private String to;
@ -342,179 +349,20 @@ public class MUCUser implements PacketExtension {
this.to = to; this.to = to;
} }
public String toXML() { @Override
StringBuilder buf = new StringBuilder(); public XmlStringBuilder toXML() {
buf.append("<decline "); XmlStringBuilder xml = new XmlStringBuilder(this);
if (getTo() != null) { xml.optAttribute("to", getTo());
buf.append(" to=\"").append(getTo()).append("\""); xml.optAttribute("from", getFrom());
} xml.rightAngelBracket();
if (getFrom() != null) { xml.optElement("reason", getReason());
buf.append(" from=\"").append(getFrom()).append("\""); xml.closeElement(this);
} return xml;
buf.append(">");
if (getReason() != null) {
buf.append("<reason>").append(getReason()).append("</reason>");
}
buf.append("</decline>");
return buf.toString();
}
} }
/** @Override
* Item child that holds information about roles, affiliation, jids and nicks. public String getElementName() {
* return ELEMENT;
* @author Gaston Dombiak
*/
public static class Item {
private String actor;
private String reason;
private String affiliation;
private String jid;
private String nick;
private String role;
/**
* Creates a new item child.
*
* @param affiliation the actor's affiliation to the room
* @param role the privilege level of an occupant within a room.
*/
public Item(String affiliation, String role) {
this.affiliation = affiliation;
this.role = role;
}
/**
* Returns the actor (JID of an occupant in the room) that was kicked or banned.
*
* @return the JID of an occupant in the room that was kicked or banned.
*/
public String getActor() {
return actor == null ? "" : actor;
}
/**
* Returns the reason for the item child. The reason is optional and could be used to
* explain the reason why a user (occupant) was kicked or banned.
*
* @return the reason for the item child.
*/
public String getReason() {
return reason == null ? "" : reason;
}
/**
* Returns the occupant's affiliation to the room. The affiliation is a semi-permanent
* association or connection with a room. The possible affiliations are "owner", "admin",
* "member", and "outcast" (naturally it is also possible to have no affiliation). An
* affiliation lasts across a user's visits to a room.
*
* @return the actor's affiliation to the room
*/
public String getAffiliation() {
return affiliation;
}
/**
* Returns the <room@service/nick> by which an occupant is identified within the context
* of a room. If the room is non-anonymous, the JID will be included in the item.
*
* @return the room JID by which an occupant is identified within the room.
*/
public String getJid() {
return jid;
}
/**
* Returns the new nickname of an occupant that is changing his/her nickname. The new
* nickname is sent as part of the unavailable presence.
*
* @return the new nickname of an occupant that is changing his/her nickname.
*/
public String getNick() {
return nick;
}
/**
* Returns the temporary position or privilege level of an occupant within a room. The
* possible roles are "moderator", "participant", and "visitor" (it is also possible to
* have no defined role). A role lasts only for the duration of an occupant's visit to
* a room.
*
* @return the privilege level of an occupant within a room.
*/
public String getRole() {
return role;
}
/**
* Sets the actor (JID of an occupant in the room) that was kicked or banned.
*
* @param actor the actor (JID of an occupant in the room) that was kicked or banned.
*/
public void setActor(String actor) {
this.actor = actor;
}
/**
* Sets the reason for the item child. The reason is optional and could be used to
* explain the reason why a user (occupant) was kicked or banned.
*
* @param reason the reason why a user (occupant) was kicked or banned.
*/
public void setReason(String reason) {
this.reason = reason;
}
/**
* Sets the <room@service/nick> by which an occupant is identified within the context
* of a room. If the room is non-anonymous, the JID will be included in the item.
*
* @param jid the JID by which an occupant is identified within a room.
*/
public void setJid(String jid) {
this.jid = jid;
}
/**
* Sets the new nickname of an occupant that is changing his/her nickname. The new
* nickname is sent as part of the unavailable presence.
*
* @param nick the new nickname of an occupant that is changing his/her nickname.
*/
public void setNick(String nick) {
this.nick = nick;
}
public String toXML() {
StringBuilder buf = new StringBuilder();
buf.append("<item");
if (getAffiliation() != null) {
buf.append(" affiliation=\"").append(getAffiliation()).append("\"");
}
if (getJid() != null) {
buf.append(" jid=\"").append(getJid()).append("\"");
}
if (getNick() != null) {
buf.append(" nick=\"").append(getNick()).append("\"");
}
if (getRole() != null) {
buf.append(" role=\"").append(getRole()).append("\"");
}
if (getReason() == null && getActor() == null) {
buf.append("/>");
}
else {
buf.append(">");
if (getReason() != null) {
buf.append("<reason>").append(getReason()).append("</reason>");
}
if (getActor() != null) {
buf.append("<actor jid=\"").append(getActor()).append("\"/>");
}
buf.append("</item>");
}
return buf.toString();
} }
} }
@ -524,7 +372,9 @@ public class MUCUser implements PacketExtension {
* *
* @author Gaston Dombiak * @author Gaston Dombiak
*/ */
public static class Status { public static class Status implements Element {
public static final String ELEMENT = "status";
private String code; private String code;
/** /**
@ -546,79 +396,17 @@ public class MUCUser implements PacketExtension {
return code; return code;
} }
public String toXML() { @Override
StringBuilder buf = new StringBuilder(); public XmlStringBuilder toXML() {
buf.append("<status code=\"").append(getCode()).append("\"/>"); XmlStringBuilder xml = new XmlStringBuilder(this);
return buf.toString(); xml.attribute("code", getCode());
} xml.closeEmptyElement();
return xml;
} }
/** @Override
* Represents a notification that the room has been destroyed. After a room has been destroyed, public String getElementName() {
* the room occupants will receive a Presence packet of type 'unavailable' with the reason for return ELEMENT;
* the room destruction if provided by the room owner.
*
* @author Gaston Dombiak
*/
public static class Destroy {
private String reason;
private String jid;
/**
* Returns the JID of an alternate location since the current room is being destroyed.
*
* @return the JID of an alternate location.
*/
public String getJid() {
return jid;
} }
/**
* Returns the reason for the room destruction.
*
* @return the reason for the room destruction.
*/
public String getReason() {
return reason;
}
/**
* Sets the JID of an alternate location since the current room is being destroyed.
*
* @param jid the JID of an alternate location.
*/
public void setJid(String jid) {
this.jid = jid;
}
/**
* Sets the reason for the room destruction.
*
* @param reason the reason for the room destruction.
*/
public void setReason(String reason) {
this.reason = reason;
}
public String toXML() {
StringBuilder buf = new StringBuilder();
buf.append("<destroy");
if (getJid() != null) {
buf.append(" jid=\"").append(getJid()).append("\"");
}
if (getReason() == null) {
buf.append("/>");
}
else {
buf.append(">");
if (getReason() != null) {
buf.append("<reason>").append(getReason()).append("</reason>");
}
buf.append("</destroy>");
}
return buf.toString();
}
} }
} }

View file

@ -36,7 +36,7 @@ public class MUCAdminProvider implements IQProvider {
int eventType = parser.next(); int eventType = parser.next();
if (eventType == XmlPullParser.START_TAG) { if (eventType == XmlPullParser.START_TAG) {
if (parser.getName().equals("item")) { if (parser.getName().equals("item")) {
mucAdmin.addItem(parseItem(parser)); mucAdmin.addItem(MUCParserUtils.parseItem(parser));
} }
} }
else if (eventType == XmlPullParser.END_TAG) { else if (eventType == XmlPullParser.END_TAG) {
@ -48,31 +48,4 @@ public class MUCAdminProvider implements IQProvider {
return mucAdmin; return mucAdmin;
} }
private MUCAdmin.Item parseItem(XmlPullParser parser) throws Exception {
boolean done = false;
MUCAdmin.Item item =
new MUCAdmin.Item(
parser.getAttributeValue("", "affiliation"),
parser.getAttributeValue("", "role"));
item.setNick(parser.getAttributeValue("", "nick"));
item.setJid(parser.getAttributeValue("", "jid"));
while (!done) {
int eventType = parser.next();
if (eventType == XmlPullParser.START_TAG) {
if (parser.getName().equals("actor")) {
item.setActor(parser.getAttributeValue("", "jid"));
}
if (parser.getName().equals("reason")) {
item.setReason(parser.nextText());
}
}
else if (eventType == XmlPullParser.END_TAG) {
if (parser.getName().equals("item")) {
done = true;
}
}
}
return item;
}
} }

View file

@ -37,10 +37,10 @@ public class MUCOwnerProvider implements IQProvider {
int eventType = parser.next(); int eventType = parser.next();
if (eventType == XmlPullParser.START_TAG) { if (eventType == XmlPullParser.START_TAG) {
if (parser.getName().equals("item")) { if (parser.getName().equals("item")) {
mucOwner.addItem(parseItem(parser)); mucOwner.addItem(MUCParserUtils.parseItem(parser));
} }
else if (parser.getName().equals("destroy")) { else if (parser.getName().equals("destroy")) {
mucOwner.setDestroy(parseDestroy(parser)); mucOwner.setDestroy(MUCParserUtils.parseDestroy(parser));
} }
// Otherwise, it must be a packet extension. // Otherwise, it must be a packet extension.
else { else {
@ -57,49 +57,4 @@ public class MUCOwnerProvider implements IQProvider {
return mucOwner; return mucOwner;
} }
private MUCOwner.Item parseItem(XmlPullParser parser) throws Exception {
boolean done = false;
MUCOwner.Item item = new MUCOwner.Item(parser.getAttributeValue("", "affiliation"));
item.setNick(parser.getAttributeValue("", "nick"));
item.setRole(parser.getAttributeValue("", "role"));
item.setJid(parser.getAttributeValue("", "jid"));
while (!done) {
int eventType = parser.next();
if (eventType == XmlPullParser.START_TAG) {
if (parser.getName().equals("actor")) {
item.setActor(parser.getAttributeValue("", "jid"));
}
if (parser.getName().equals("reason")) {
item.setReason(parser.nextText());
}
}
else if (eventType == XmlPullParser.END_TAG) {
if (parser.getName().equals("item")) {
done = true;
}
}
}
return item;
}
private MUCOwner.Destroy parseDestroy(XmlPullParser parser) throws Exception {
boolean done = false;
MUCOwner.Destroy destroy = new MUCOwner.Destroy();
destroy.setJid(parser.getAttributeValue("", "jid"));
while (!done) {
int eventType = parser.next();
if (eventType == XmlPullParser.START_TAG) {
if (parser.getName().equals("reason")) {
destroy.setReason(parser.nextText());
}
}
else if (eventType == XmlPullParser.END_TAG) {
if (parser.getName().equals("destroy")) {
done = true;
}
}
}
return destroy;
}
} }

View file

@ -0,0 +1,68 @@
/**
*
* Copyright 2003-2007 Jive Software.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.muc.provider;
import org.jivesoftware.smackx.muc.packet.Destroy;
import org.jivesoftware.smackx.muc.packet.MUCItem;
import org.xmlpull.v1.XmlPullParser;
public class MUCParserUtils {
public static MUCItem parseItem(XmlPullParser parser) throws Exception {
boolean done = false;
MUCItem item = new MUCItem(parser.getAttributeValue("", "affiliation"));
item.setNick(parser.getAttributeValue("", "nick"));
item.setRole(parser.getAttributeValue("", "role"));
item.setJid(parser.getAttributeValue("", "jid"));
while (!done) {
int eventType = parser.next();
if (eventType == XmlPullParser.START_TAG) {
if (parser.getName().equals("actor")) {
item.setActor(parser.getAttributeValue("", "jid"));
}
if (parser.getName().equals("reason")) {
item.setReason(parser.nextText());
}
}
else if (eventType == XmlPullParser.END_TAG) {
if (parser.getName().equals("item")) {
done = true;
}
}
}
return item;
}
public static Destroy parseDestroy(XmlPullParser parser) throws Exception {
boolean done = false;
Destroy destroy = new Destroy();
destroy.setJid(parser.getAttributeValue("", "jid"));
while (!done) {
int eventType = parser.next();
if (eventType == XmlPullParser.START_TAG) {
if (parser.getName().equals("reason")) {
destroy.setReason(parser.nextText());
}
}
else if (eventType == XmlPullParser.END_TAG) {
if (parser.getName().equals("destroy")) {
done = true;
}
}
}
return destroy;
}
}

View file

@ -31,14 +31,6 @@ import org.xmlpull.v1.XmlPullParser;
*/ */
public class MUCUserProvider implements PacketExtensionProvider { public class MUCUserProvider implements PacketExtensionProvider {
/**
* Creates a new MUCUserProvider.
* ProviderManager requires that every PacketExtensionProvider has a public, no-argument
* constructor
*/
public MUCUserProvider() {
}
/** /**
* Parses a MUCUser packet (extension sub-packet). * Parses a MUCUser packet (extension sub-packet).
* *
@ -56,7 +48,7 @@ public class MUCUserProvider implements PacketExtensionProvider {
mucUser.setInvite(parseInvite(parser)); mucUser.setInvite(parseInvite(parser));
} }
if (parser.getName().equals("item")) { if (parser.getName().equals("item")) {
mucUser.setItem(parseItem(parser)); mucUser.setItem(MUCParserUtils.parseItem(parser));
} }
if (parser.getName().equals("password")) { if (parser.getName().equals("password")) {
mucUser.setPassword(parser.nextText()); mucUser.setPassword(parser.nextText());
@ -68,7 +60,7 @@ public class MUCUserProvider implements PacketExtensionProvider {
mucUser.setDecline(parseDecline(parser)); mucUser.setDecline(parseDecline(parser));
} }
if (parser.getName().equals("destroy")) { if (parser.getName().equals("destroy")) {
mucUser.setDestroy(parseDestroy(parser)); mucUser.setDestroy(MUCParserUtils.parseDestroy(parser));
} }
} }
else if (eventType == XmlPullParser.END_TAG) { else if (eventType == XmlPullParser.END_TAG) {
@ -81,34 +73,7 @@ public class MUCUserProvider implements PacketExtensionProvider {
return mucUser; return mucUser;
} }
private MUCUser.Item parseItem(XmlPullParser parser) throws Exception { private static MUCUser.Invite parseInvite(XmlPullParser parser) throws Exception {
boolean done = false;
MUCUser.Item item =
new MUCUser.Item(
parser.getAttributeValue("", "affiliation"),
parser.getAttributeValue("", "role"));
item.setNick(parser.getAttributeValue("", "nick"));
item.setJid(parser.getAttributeValue("", "jid"));
while (!done) {
int eventType = parser.next();
if (eventType == XmlPullParser.START_TAG) {
if (parser.getName().equals("actor")) {
item.setActor(parser.getAttributeValue("", "jid"));
}
if (parser.getName().equals("reason")) {
item.setReason(parser.nextText());
}
}
else if (eventType == XmlPullParser.END_TAG) {
if (parser.getName().equals("item")) {
done = true;
}
}
}
return item;
}
private MUCUser.Invite parseInvite(XmlPullParser parser) throws Exception {
boolean done = false; boolean done = false;
MUCUser.Invite invite = new MUCUser.Invite(); MUCUser.Invite invite = new MUCUser.Invite();
invite.setFrom(parser.getAttributeValue("", "from")); invite.setFrom(parser.getAttributeValue("", "from"));
@ -129,7 +94,7 @@ public class MUCUserProvider implements PacketExtensionProvider {
return invite; return invite;
} }
private MUCUser.Decline parseDecline(XmlPullParser parser) throws Exception { private static MUCUser.Decline parseDecline(XmlPullParser parser) throws Exception {
boolean done = false; boolean done = false;
MUCUser.Decline decline = new MUCUser.Decline(); MUCUser.Decline decline = new MUCUser.Decline();
decline.setFrom(parser.getAttributeValue("", "from")); decline.setFrom(parser.getAttributeValue("", "from"));
@ -149,24 +114,4 @@ public class MUCUserProvider implements PacketExtensionProvider {
} }
return decline; return decline;
} }
private MUCUser.Destroy parseDestroy(XmlPullParser parser) throws Exception {
boolean done = false;
MUCUser.Destroy destroy = new MUCUser.Destroy();
destroy.setJid(parser.getAttributeValue("", "jid"));
while (!done) {
int eventType = parser.next();
if (eventType == XmlPullParser.START_TAG) {
if (parser.getName().equals("reason")) {
destroy.setReason(parser.nextText());
}
}
else if (eventType == XmlPullParser.END_TAG) {
if (parser.getName().equals("destroy")) {
done = true;
}
}
}
return destroy;
}
} }