diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/DefaultUserStatusListener.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/DefaultUserStatusListener.java index 0ac93ccbd..e90b6993a 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/DefaultUserStatusListener.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/DefaultUserStatusListener.java @@ -82,7 +82,7 @@ public class DefaultUserStatusListener implements UserStatusListener { } @Override - public void roomDestroyed(MultiUserChat alternateMUC, String reason) { + public void roomDestroyed(MultiUserChat alternateMUC, String password, String reason) { } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java index 1628f258d..9383d9e28 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java @@ -290,7 +290,7 @@ public class MultiUserChat { } for (UserStatusListener listener : userStatusListeners) { - listener.roomDestroyed(alternateMuc, destroy.getReason()); + listener.roomDestroyed(alternateMuc, destroy.getPassword(), destroy.getReason()); } } @@ -965,12 +965,32 @@ public class MultiUserChat { * @throws InterruptedException if the calling thread was interrupted. */ public void destroy(String reason, EntityBareJid alternateJID) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { + destroy(reason, alternateJID, null); + } + + /** + * Sends a request to the server to destroy the 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 (403). + * + * @param reason an optional reason for the room destruction. + * @param alternateJID an optional JID of an alternate location. + * @param password an optional password for the alternate location + * @throws XMPPErrorException if an error occurs while trying to destroy the room. + * An error can occur which will be wrapped by an XMPPException -- + * XMPP error code 403. The error code can be used to present more + * appropriate error messages to end-users. + * @throws NoResponseException if there was no response from the server. + * @throws NotConnectedException if the XMPP connection is not connected. + * @throws InterruptedException if the calling thread was interrupted. + */ + public void destroy(String reason, EntityBareJid alternateJID, String password) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { MUCOwner iq = new MUCOwner(); iq.setTo(room); iq.setType(IQ.Type.set); // Create the reason for the room destruction - Destroy destroy = new Destroy(alternateJID, reason); + Destroy destroy = new Destroy(alternateJID, password, reason); iq.setDestroy(destroy); try { diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/UserStatusListener.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/UserStatusListener.java index 0e87cb5bd..b8d9db944 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/UserStatusListener.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/UserStatusListener.java @@ -28,7 +28,7 @@ import org.jxmpp.jid.Jid; * banned, or granted admin permissions or the room is destroyed. *

* Note that the methods {@link #kicked(Jid, String)}, {@link #banned(Jid, String)} and - * {@link #roomDestroyed(MultiUserChat, String)} will be called before the generic {@link #removed(MUCUser, Presence)} + * {@link #roomDestroyed(MultiUserChat, String, String)} will be called before the generic {@link #removed(MUCUser, Presence)} * callback will be invoked. The generic {@link #removed(MUCUser, Presence)} callback will be invoked every time the user * was removed from the MUC involuntarily. It is hence the recommended callback to listen for and act upon. *

@@ -161,10 +161,11 @@ public interface UserStatusListener { * Called when the room is destroyed. * * @param alternateMUC an alternate MultiUserChat, may be null. + * @param password a password for the alternative MultiUserChat, may be null. * @param reason the reason why the room was closed, may be null. * @see #removed(MUCUser, Presence) */ - default void roomDestroyed(MultiUserChat alternateMUC, String reason) { + default void roomDestroyed(MultiUserChat alternateMUC, String password, String reason) { } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/packet/Destroy.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/packet/Destroy.java index 1361f79fe..9da151c4c 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/packet/Destroy.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/packet/Destroy.java @@ -40,14 +40,22 @@ public class Destroy implements NamedElement, Serializable { private final String reason; private final EntityBareJid jid; + private final String password; public Destroy(Destroy other) { - this(other.jid, other.reason); + this(other.jid, other.password, other.reason); } public Destroy(EntityBareJid alternativeJid, String reason) { this.jid = alternativeJid; this.reason = reason; + this.password = null; + } + + public Destroy(EntityBareJid alternativeJid, String password, String reason) { + this.jid = alternativeJid; + this.password = password; + this.reason = reason; } /** @@ -59,6 +67,15 @@ public class Destroy implements NamedElement, Serializable { return jid; } + /** + * Returns the password of the alternate location. + * + * @return the password of the alternate location. + */ + public String getPassword() { + return password; + } + /** * Returns the reason for the room destruction. * @@ -73,6 +90,7 @@ public class Destroy implements NamedElement, Serializable { XmlStringBuilder xml = new XmlStringBuilder(this); xml.optAttribute("jid", getJid()); xml.rightAngleBracket(); + xml.optElement("password", getPassword()); xml.optElement("reason", getReason()); xml.closeElement(this); return xml; diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/provider/MUCParserUtils.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/provider/MUCParserUtils.java index 897fc131b..3cfa04423 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/provider/MUCParserUtils.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/provider/MUCParserUtils.java @@ -79,6 +79,7 @@ public class MUCParserUtils { final int initialDepth = parser.getDepth(); final EntityBareJid jid = ParserUtils.getBareJidAttribute(parser); String reason = null; + String password = null; outerloop: while (true) { XmlPullParser.Event eventType = parser.next(); switch (eventType) { @@ -88,6 +89,9 @@ public class MUCParserUtils { case "reason": reason = parser.nextText(); break; + case "password": + password = parser.nextText(); + break; } break; case END_ELEMENT: @@ -100,6 +104,6 @@ public class MUCParserUtils { break; } } - return new Destroy(jid, reason); + return new Destroy(jid, password, reason); } } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java index e97cf4ac5..b407c5f31 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java @@ -112,7 +112,7 @@ public class MultiUserChatIntegrationTest extends AbstractMultiUserChatIntegrati UserStatusListener userStatusListener = new UserStatusListener() { @Override - public void roomDestroyed(MultiUserChat alternateMUC, String reason) { + public void roomDestroyed(MultiUserChat alternateMUC, String password, String reason) { mucDestroyed.signal(); } };