From afd7c67bf9bcfc114b0eb9423769ea095cf1d46f Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Fri, 5 Sep 2014 00:18:48 +0200 Subject: [PATCH] Add support for multiple status codes to MUCUser Fixes SMACK-604 --- .../smack/util/XmlStringBuilder.java | 10 +++ .../smackx/muc/MultiUserChat.java | 24 +++--- .../smackx/muc/packet/MUCUser.java | 85 ++++++++++++++++--- .../smackx/muc/provider/MUCUserProvider.java | 3 +- .../smackx/muc/packet/MUCUserTest.java | 50 +++++++++++ 5 files changed, 145 insertions(+), 27 deletions(-) create mode 100644 smack-extensions/src/test/java/org/jivesoftware/smackx/muc/packet/MUCUserTest.java diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java b/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java index c86eaa777..780e2ecc4 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java @@ -59,6 +59,11 @@ public class XmlStringBuilder implements Appendable, CharSequence { return this; } + public XmlStringBuilder element(Element element) { + assert element != null; + return append(element.toXML()); + } + public XmlStringBuilder optElement(String name, String content) { if (content != null) { element(name, content); @@ -147,6 +152,11 @@ public class XmlStringBuilder implements Appendable, CharSequence { return this; } + public XmlStringBuilder attribute(String name, int value) { + assert name != null; + return attribute(name, String.valueOf(value)); + } + public XmlStringBuilder optAttribute(String name, String value) { if (value != null) { attribute(name, value); 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 3267b74fe..417240d6b 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 @@ -27,6 +27,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Set; import java.util.WeakHashMap; import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; @@ -70,6 +71,7 @@ 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.MUCUser; +import org.jivesoftware.smackx.muc.packet.MUCUser.Status; import org.jivesoftware.smackx.xdata.Form; /** @@ -414,11 +416,9 @@ public class MultiUserChat { // Look for confirmation of room creation from the server MUCUser mucUser = MUCUser.getFrom(presence); - if (mucUser != null && mucUser.getStatus() != null) { - if ("201".equals(mucUser.getStatus().getCode())) { - // Room was created and the user has joined the room - return true; - } + if (mucUser != null && mucUser.getStatus().contains(Status.ROOM_CREATED_201)) { + // Room was created and the user has joined the room + return true; } return false; } @@ -1969,7 +1969,7 @@ public class MultiUserChat { if (mucUser != null && mucUser.getStatus() != null) { // Fire events according to the received presence code checkPresenceCode( - mucUser.getStatus().getCode(), + mucUser.getStatus(), presence.getFrom().equals(myRoomJID), mucUser, from); @@ -2241,18 +2241,18 @@ public class MultiUserChat { /** * Fires events according to the received presence code. * - * @param code + * @param statusCodes * @param isUserModification * @param mucUser * @param from */ private void checkPresenceCode( - String code, + Set statusCodes, boolean isUserModification, MUCUser mucUser, String from) { // Check if an occupant was kicked from the room - if ("307".equals(code)) { + if (statusCodes.contains(Status.KICKED_307)) { // Check if this occupant was kicked if (isUserModification) { joined = false; @@ -2275,7 +2275,7 @@ public class MultiUserChat { } } // A user was banned from the room - else if ("301".equals(code)) { + if (statusCodes.contains(Status.BANNED_301)) { // Check if this occupant was banned if (isUserModification) { joined = false; @@ -2298,7 +2298,7 @@ public class MultiUserChat { } } // A user's membership was revoked from the room - else if ("321".equals(code)) { + if (statusCodes.contains(Status.REMOVED_AFFIL_CHANGE_321)) { // Check if this occupant's membership was revoked if (isUserModification) { joined = false; @@ -2312,7 +2312,7 @@ public class MultiUserChat { } } // A occupant has changed his nickname in the room - else if ("303".equals(code)) { + if (statusCodes.contains(Status.NEW_NICKNAME_303)) { List params = new ArrayList(); params.add(from); params.add(mucUser.getItem().getNick()); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/packet/MUCUser.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/packet/MUCUser.java index 764737e26..febe48b89 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/packet/MUCUser.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/packet/MUCUser.java @@ -19,6 +19,12 @@ package org.jivesoftware.smackx.muc.packet; import org.jivesoftware.smack.packet.Element; import org.jivesoftware.smack.packet.Packet; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + import org.jivesoftware.smack.packet.PacketExtension; import org.jivesoftware.smack.util.XmlStringBuilder; @@ -33,11 +39,12 @@ public class MUCUser implements PacketExtension { public static final String ELEMENT = "x"; public static final String NAMESPACE = MUCInitialPresence.NAMESPACE + "#user"; + private final Set statusCodes = new HashSet(4); + private Invite invite; private Decline decline; private MUCItem item; private String password; - private Status status; private Destroy destroy; public String getElementName() { @@ -56,7 +63,9 @@ public class MUCUser implements PacketExtension { xml.optElement(getDecline()); xml.optElement(getItem()); xml.optElement("password", getPassword()); - xml.optElement(getStatus()); + for (Status status : statusCodes) { + xml.element(status); + } xml.optElement(getDestroy()); xml.closeElement(this); return xml; @@ -103,12 +112,12 @@ public class MUCUser implements PacketExtension { } /** - * Returns the status which holds a code that assists in presenting notification messages. + * Returns a set of status which holds the status code that assist in presenting notification messages. * - * @return the status which holds a code that assists in presenting notification messages. + * @return the set of status which holds the status code that assist in presenting notification messages. */ - public Status getStatus() { - return status; + public Set getStatus() { + return statusCodes; } /** @@ -163,13 +172,22 @@ public class MUCUser implements PacketExtension { } /** - * Sets the status which holds a code that assists in presenting notification messages. + * Add the status codes which holds the codes that assists in presenting notification messages. * - * @param status the status which holds a code that assists in presenting notification + * @param statusCodes the status codes which hold the codes that assists in presenting notification * messages. */ - public void setStatus(Status status) { - this.status = status; + public void addStatusCodes(Set statusCodes) { + this.statusCodes.addAll(statusCodes); + } + + /** + * Add a status code which hold a code that assists in presenting notification messages. + * + * @param status the status code which olds a code that assists in presenting notification messages. + */ + public void addStatusCode(Status status) { + this.statusCodes.add(status); } /** @@ -368,21 +386,43 @@ public class MUCUser implements PacketExtension { /** * Status code assists in presenting notification messages. The following link provides the - * list of existing error codes (@link http://www.xmpp.org/extensions/jep-0045.html#errorstatus). + * list of existing error codes Multi-User Chat Status Codes. * * @author Gaston Dombiak */ public static class Status implements Element { public static final String ELEMENT = "status"; - private String code; + private static final Map statusMap = new HashMap(8); + + public static final Status ROOM_CREATED_201 = Status.create(201); + public static final Status BANNED_301 = Status.create(301); + public static final Status NEW_NICKNAME_303 = Status.create(303); + public static final Status KICKED_307 = Status.create(307); + public static final Status REMOVED_AFFIL_CHANGE_321 = Status.create(321); + + private final Integer code; + + public static Status create(String string) { + Integer integer = Integer.valueOf(string); + return create(integer); + } + + public static Status create(Integer i) { + Status status = statusMap.get(i); + if (status == null) { + status = new Status(i); + statusMap.put(i, status); + } + return status; + } /** * Creates a new instance of Status with the specified code. * * @param code the code that uniquely identifies the reason of the error. */ - public Status(String code) { + private Status(int code) { this.code = code; } @@ -392,7 +432,7 @@ public class MUCUser implements PacketExtension { * * @return the code that uniquely identifies the reason of the error. */ - public String getCode() { + public int getCode() { return code; } @@ -404,6 +444,23 @@ public class MUCUser implements PacketExtension { return xml; } + @Override + public boolean equals(Object other) { + if (other == null) { + return false; + } + if (other instanceof Status) { + Status otherStatus = (Status) other; + return code.equals(otherStatus.getCode()); + } + return false; + } + + @Override + public int hashCode() { + return code; + } + @Override public String getElementName() { return ELEMENT; diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/provider/MUCUserProvider.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/provider/MUCUserProvider.java index 516c1f790..1506859b6 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/provider/MUCUserProvider.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/provider/MUCUserProvider.java @@ -54,7 +54,8 @@ public class MUCUserProvider implements PacketExtensionProvider { mucUser.setPassword(parser.nextText()); } if (parser.getName().equals("status")) { - mucUser.setStatus(new MUCUser.Status(parser.getAttributeValue("", "code"))); + String statusString = parser.getAttributeValue("", "code"); + mucUser.addStatusCode(MUCUser.Status.create(statusString)); } if (parser.getName().equals("decline")) { mucUser.setDecline(parseDecline(parser)); diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/muc/packet/MUCUserTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/muc/packet/MUCUserTest.java new file mode 100644 index 000000000..58a8054fb --- /dev/null +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/muc/packet/MUCUserTest.java @@ -0,0 +1,50 @@ +/** + * + * Copyright © 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 static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.HashSet; +import java.util.Set; + +import org.jivesoftware.smackx.muc.packet.MUCUser.Status; +import org.junit.Test; + +public class MUCUserTest { + + private static final Set createStatusSet() { + Status status301 = Status.create(301); + Status status110 = Status.create(110); + Set statusSet = new HashSet(); + statusSet.add(status301); + statusSet.add(status110); + + return statusSet; + } + + @Test + public void mucUserStatusShouldCompareWithStatus() { + Set statusSet = createStatusSet(); + + assertTrue(statusSet.contains(Status.create(110))); + assertTrue(statusSet.contains(Status.create(301))); + assertFalse(statusSet.contains(Status.create(332))); + + assertTrue(statusSet.contains(Status.create("110"))); + } +}