Commit 8744e981 authored by Christian Schudt's avatar Christian Schudt

Use real Java enums for presence subscription states.

The homemade IntEnum and Enum classes feel totally weird and confusing, when having java.lang.Enum around.

This commit removes these classes.

The static constants in the RosterItem class now feel superfluous, but are kept in there, because they are referenced by a lot of other classes and JSP pages.
parent f40088a0
......@@ -563,10 +563,10 @@ public class Roster implements Cacheable, Externalizable {
}
private org.xmpp.packet.Roster.Ask getAskStatus(RosterItem.AskType askType) {
if (askType == null || "".equals(askType.getName())) {
if (askType == null || askType == RosterItem.AskType.NONE) {
return null;
}
return org.xmpp.packet.Roster.Ask.valueOf(askType.getName());
return org.xmpp.packet.Roster.Ask.valueOf(askType.name().toLowerCase());
}
/**
......
......@@ -26,7 +26,6 @@ import org.jivesoftware.openfire.group.GroupManager;
import org.jivesoftware.openfire.group.GroupNotFoundException;
import org.jivesoftware.openfire.user.UserNameManager;
import org.jivesoftware.openfire.user.UserNotFoundException;
import org.jivesoftware.util.IntEnum;
import org.jivesoftware.util.cache.CacheSizes;
import org.jivesoftware.util.cache.Cacheable;
import org.jivesoftware.util.cache.CannotCalculateSizeException;
......@@ -55,87 +54,174 @@ import java.util.*;
*/
public class RosterItem implements Cacheable, Externalizable {
public static class SubType extends IntEnum {
protected SubType(String name, int value) {
super(name, value);
register(this);
public enum SubType {
/**
* Indicates the roster item should be removed.
*/
REMOVE(-1),
/**
* No subscription is established.
*/
NONE(0),
/**
* The roster owner has a subscription to the roster item's presence.
*/
TO(1),
/**
* The roster item has a subscription to the roster owner's presence.
*/
FROM(2),
/**
* The roster item and owner have a mutual subscription.
*/
BOTH(3);
private final int value;
SubType(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public String getName() {
return name().toLowerCase();
}
public static SubType getTypeFromInt(int value) {
return (SubType)getEnumFromInt(SubType.class, value);
for (SubType subType : values()) {
if (subType.value == value) {
return subType;
}
}
return null;
}
}
public static class AskType extends IntEnum {
protected AskType(String name, int value) {
super(name, value);
register(this);
public enum AskType {
/**
* The roster item has no pending subscription requests.
*/
NONE(-1),
/**
* The roster item has been asked for permission to subscribe to their presence
* but no response has been received.
*/
SUBSCRIBE(0),
/**
* The roster owner has asked to the roster item to unsubscribe from it's
* presence but has not received confirmation.
*/
UNSUBSCRIBE(1);
private final int value;
AskType(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public static AskType getTypeFromInt(int value) {
return (AskType)getEnumFromInt(AskType.class, value);
for (AskType askType : values()) {
if (askType.value == value) {
return askType;
}
}
return null;
}
}
public static class RecvType extends IntEnum {
protected RecvType(String name, int value) {
super(name, value);
register(this);
public enum RecvType {
/**
* There are no subscriptions that have been received but not presented to the user.
*/
NONE(-1),
/**
* The server has received a subscribe request, but has not forwarded it to the user.
*/
SUBSCRIBE(1),
/**
* The server has received an unsubscribe request, but has not forwarded it to the user.
*/
UNSUBSCRIBE(2);
private final int value;
RecvType(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public static RecvType getTypeFromInt(int value) {
return (RecvType)getEnumFromInt(RecvType.class, value);
for (RecvType recvType : values()) {
if (recvType.value == value) {
return recvType;
}
}
return null;
}
}
/**
* <p>Indicates the roster item should be removed.</p>
*/
public static final SubType SUB_REMOVE = new SubType("remove", -1);
public static final SubType SUB_REMOVE = SubType.REMOVE;
/**
* <p>No subscription is established.</p>
*/
public static final SubType SUB_NONE = new SubType("none", 0);
public static final SubType SUB_NONE = SubType.NONE;
/**
* <p>The roster owner has a subscription to the roster item's presence.</p>
*/
public static final SubType SUB_TO = new SubType("to", 1);
public static final SubType SUB_TO = SubType.TO;
/**
* <p>The roster item has a subscription to the roster owner's presence.</p>
*/
public static final SubType SUB_FROM = new SubType("from", 2);
public static final SubType SUB_FROM = SubType.FROM;
/**
* <p>The roster item and owner have a mutual subscription.</p>
*/
public static final SubType SUB_BOTH = new SubType("both", 3);
public static final SubType SUB_BOTH = SubType.BOTH;
/**
* <p>The roster item has no pending subscription requests.</p>
*/
public static final AskType ASK_NONE = new AskType("", -1);
public static final AskType ASK_NONE = AskType.NONE;
/**
* <p>The roster item has been asked for permission to subscribe to their presence
* but no response has been received.</p>
*/
public static final AskType ASK_SUBSCRIBE = new AskType("subscribe", 0);
public static final AskType ASK_SUBSCRIBE = AskType.SUBSCRIBE;
/**
* <p>The roster owner has asked to the roster item to unsubscribe from it's
* presence but has not received confirmation.</p>
*/
public static final AskType ASK_UNSUBSCRIBE = new AskType("unsubscribe", 1);
public static final AskType ASK_UNSUBSCRIBE = AskType.UNSUBSCRIBE;
/**
* <p>There are no subscriptions that have been received but not presented to the user.</p>
*/
public static final RecvType RECV_NONE = new RecvType("", -1);
public static final RecvType RECV_NONE = RecvType.NONE;
/**
* <p>The server has received a subscribe request, but has not forwarded it to the user.</p>
*/
public static final RecvType RECV_SUBSCRIBE = new RecvType("sub", 1);
public static final RecvType RECV_SUBSCRIBE = RecvType.SUBSCRIBE;
/**
* <p>The server has received an unsubscribe request, but has not forwarded it to the user.</p>
*/
public static final RecvType RECV_UNSUBSCRIBE = new RecvType("unsub", 2);
public static final RecvType RECV_UNSUBSCRIBE = RecvType.UNSUBSCRIBE;
protected RecvType recvStatus;
protected JID jid;
......
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2004-2008 Jive Software. All rights reserved.
*
* 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.util;
/**
* A type safe enumeration object. Used for indicating distinct states
* in a generic manner. Most child classes should extend Enum and
* create static instances.
*
* @author Iain Shigeoka
*/
public class Enum {
private String name;
protected Enum(String name) {
this.name = name;
}
/**
* Returns the name of the enum.
*
* @return the name of the enum.
*/
public String getName() {
return name;
}
@Override
public boolean equals(Object object) {
if (this == object) {
return true;
}
else if ((this.getClass().isInstance(object)) && name.equals(((Enum)object).name)) {
return true;
}
else {
return false;
}
}
@Override
public int hashCode() {
return name.hashCode();
}
@Override
public String toString() {
return name;
}
}
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2004-2008 Jive Software. All rights reserved.
*
* 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.util;
import java.util.*;
/**
* <p>A type safe enumeration object that is keyed by an Int
* value for switch statements and storage in DBs.</p>
* <p>
* Used for indicating distinct states in a generic manner
* where each enum should have an associated int value. The
* given int should be unique for each enum value as hashCode
* and equals depends solely on the int value given. Most
* child classes should extend IntEnum and create static instances.</p>
*
* @author Iain Shigeoka
*/
public class IntEnum extends Enum {
private int value;
protected static Hashtable<Class<?>, Map<Integer, IntEnum>> enumTypes = new Hashtable<>();
protected IntEnum(String name, int val) {
super(name);
this.value = val;
}
/**
* Returns the int value associated with the enum.
*
* @return the int value of the enum.
*/
public int getValue() {
return value;
}
@Override
public boolean equals(Object object) {
if (this == object) {
return true;
}
else if ((this.getClass().isInstance(object)) && value == (((IntEnum)object).value)) {
return true;
}
else {
return false;
}
}
/**
* <p>Checks in an enum for use in the getEnumFromInt() method.</p>
*
* @param enumeration The enum to be registered
*/
protected static void register(IntEnum enumeration) {
Map<Integer, IntEnum> enums = enumTypes.get(enumeration.getClass());
if (enums == null) {
enums = new HashMap<>();
enumTypes.put(enumeration.getClass(), enums);
}
enums.put(enumeration.getValue(), enumeration);
}
/**
* <p>Obtain the enum associated with the given value.</p>
* <p>Values must be registered earlier using the register() method.</p>
*
* @param value the value to lookup the enum for
* @return The associated enum or null if no matching enum exists
*/
protected static IntEnum getEnumFromInt(Class enumClass, int value) {
Map enums = (Map)enumTypes.get(enumClass);
if (enums != null) {
return (IntEnum)enums.get(value);
}
return null;
}
@Override
public int hashCode() {
return value;
}
@Override
public String toString() {
return Integer.toString(value) + " " + super.toString();
}
}
\ No newline at end of file
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2004-2008 Jive Software. All rights reserved.
*
* 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.util;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
/**
* Simple test of the int enum class.
*
* @author Iain Shigeoka
*/
public class IntEnumTest {
/**
* Tests the IntEnum's enforcement of unique int values for each enum type
*/
@Test
public void testStaticEnumUniqueEnforcement(){
IntEnum e = new IntEnum("plain",1);
IntEnum.register(e);
new TestIntEnum("test",1); // auto registers the same value - does it clash with super class?
assertEquals("plain",IntEnum.getEnumFromInt(IntEnum.class,1).getName());
assertEquals("test",TestIntEnum.getTypeFromInt(1).getName());
}
static public class TestIntEnum extends IntEnum{
public TestIntEnum(String name, int value){
super(name,value);
register(this);
}
public static TestIntEnum getTypeFromInt(int value){
return (TestIntEnum) getEnumFromInt(TestIntEnum.class,value);
}
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment