Add support for multiple status codes to MUCUser

Fixes SMACK-604
This commit is contained in:
Florian Schmaus 2014-09-05 00:18:48 +02:00
parent 5d4aa76d19
commit afd7c67bf9
5 changed files with 145 additions and 27 deletions

View File

@ -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);

View File

@ -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<Status> 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<String> params = new ArrayList<String>();
params.add(from);
params.add(mucUser.getItem().getNick());

View File

@ -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<Status> statusCodes = new HashSet<Status>(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<Status> 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<Status> 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 <a href="http://xmpp.org/registrar/mucstatus.html">Multi-User Chat Status Codes</a>.
*
* @author Gaston Dombiak
*/
public static class Status implements Element {
public static final String ELEMENT = "status";
private String code;
private static final Map<Integer, Status> statusMap = new HashMap<Integer, Status>(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;

View File

@ -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));

View File

@ -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<Status> createStatusSet() {
Status status301 = Status.create(301);
Status status110 = Status.create(110);
Set<Status> statusSet = new HashSet<Status>();
statusSet.add(status301);
statusSet.add(status110);
return statusSet;
}
@Test
public void mucUserStatusShouldCompareWithStatus() {
Set<Status> 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")));
}
}