LANG-259 - Fix compareTo to check the type is the same
git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/lang/trunk@432748 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
d9c6932a6e
commit
07b7795b33
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2005 The Apache Software Foundation.
|
||||
* Copyright 2002-2006 The Apache Software Foundation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package org.apache.commons.lang.enums;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -165,7 +167,11 @@ public abstract class ValuedEnum extends Enum {
|
|||
*
|
||||
* <p>The default ordering is numeric by value, but this
|
||||
* can be overridden by subclasses.</p>
|
||||
*
|
||||
*
|
||||
* <p>NOTE: From v2.2 the enums must be of the same type.
|
||||
* If the parameter is in a different class loader than this instance,
|
||||
* reflection is used to compare the values.</p>
|
||||
*
|
||||
* @see java.lang.Comparable#compareTo(Object)
|
||||
* @param other the other object to compare to
|
||||
* @return -ve if this is less than the other object, +ve if greater than,
|
||||
|
@ -174,9 +180,40 @@ public abstract class ValuedEnum extends Enum {
|
|||
* @throws NullPointerException if other is <code>null</code>
|
||||
*/
|
||||
public int compareTo(Object other) {
|
||||
if (other == this) {
|
||||
return 0;
|
||||
}
|
||||
if (other.getClass() != this.getClass()) {
|
||||
if (other.getClass().getName().equals(this.getClass().getName())) {
|
||||
return iValue - getValueInOtherClassLoader(other);
|
||||
}
|
||||
throw new ClassCastException(
|
||||
"Different enum class '" + ClassUtils.getShortClassName(other.getClass()) + "'");
|
||||
}
|
||||
return iValue - ((ValuedEnum) other).iValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Use reflection to return an objects value.</p>
|
||||
*
|
||||
* @param other the object to determine the value for
|
||||
* @return the value
|
||||
*/
|
||||
private int getValueInOtherClassLoader(Object other) {
|
||||
try {
|
||||
Method mth = other.getClass().getMethod("getValue", null);
|
||||
Integer value = (Integer) mth.invoke(other, null);
|
||||
return value.intValue();
|
||||
} catch (NoSuchMethodException e) {
|
||||
// ignore - should never happen
|
||||
} catch (IllegalAccessException e) {
|
||||
// ignore - should never happen
|
||||
} catch (InvocationTargetException e) {
|
||||
// ignore - should never happen
|
||||
}
|
||||
throw new IllegalStateException("This should not happen");
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Human readable description of this <code>Enum</code> item.</p>
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2004-2005 The Apache Software Foundation.
|
||||
* Copyright 2004-2006 The Apache Software Foundation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package org.apache.commons.lang.enums;
|
||||
|
||||
import java.net.URLClassLoader;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestCase;
|
||||
import junit.framework.TestSuite;
|
||||
|
@ -88,6 +90,34 @@ public final class EnumEqualsTest extends TestCase {
|
|||
assertEquals(false, CarColorEnum.RED.equals(new TotallyUnrelatedClass("some")));
|
||||
}
|
||||
|
||||
public void testEquals_classloader_equal() throws Exception {
|
||||
ClassLoader cl = ColorEnum.class.getClassLoader();
|
||||
if (cl instanceof URLClassLoader) {
|
||||
URLClassLoader urlCL = (URLClassLoader) cl;
|
||||
URLClassLoader urlCL1 = new URLClassLoader(urlCL.getURLs(), null);
|
||||
URLClassLoader urlCL2 = new URLClassLoader(urlCL.getURLs(), null);
|
||||
Class otherEnumClass1 = urlCL1.loadClass("org.apache.commons.lang.enums.ColorEnum");
|
||||
Class otherEnumClass2 = urlCL2.loadClass("org.apache.commons.lang.enums.ColorEnum");
|
||||
Object blue1 = otherEnumClass1.getDeclaredField("BLUE").get(null);
|
||||
Object blue2 = otherEnumClass2.getDeclaredField("BLUE").get(null);
|
||||
assertEquals(true, blue1.equals(blue2));
|
||||
}
|
||||
}
|
||||
|
||||
public void testEquals_classloader_different() throws Exception {
|
||||
ClassLoader cl = ColorEnum.class.getClassLoader();
|
||||
if (cl instanceof URLClassLoader) {
|
||||
URLClassLoader urlCL = (URLClassLoader) cl;
|
||||
URLClassLoader urlCL1 = new URLClassLoader(urlCL.getURLs(), null);
|
||||
URLClassLoader urlCL2 = new URLClassLoader(urlCL.getURLs(), null);
|
||||
Class otherEnumClass1 = urlCL1.loadClass("org.apache.commons.lang.enums.ColorEnum");
|
||||
Class otherEnumClass2 = urlCL2.loadClass("org.apache.commons.lang.enums.ColorEnum");
|
||||
Object blue1 = otherEnumClass1.getDeclaredField("BLUE").get(null);
|
||||
Object blue2 = otherEnumClass2.getDeclaredField("RED").get(null);
|
||||
assertEquals(false, blue1.equals(blue2));
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
public void testCompareTo() {
|
||||
try {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2005 The Apache Software Foundation.
|
||||
* Copyright 2002-2006 The Apache Software Foundation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
package org.apache.commons.lang.enums;
|
||||
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -64,11 +65,103 @@ public final class ValuedEnumTest extends TestCase {
|
|||
assertTrue(ValuedColorEnum.BLUE.compareTo(ValuedColorEnum.RED) > 0);
|
||||
}
|
||||
|
||||
public void testCompareTo_classloader_equal() throws Exception {
|
||||
ClassLoader cl = ValuedColorEnum.class.getClassLoader();
|
||||
if (cl instanceof URLClassLoader) {
|
||||
URLClassLoader urlCL = (URLClassLoader) cl;
|
||||
URLClassLoader urlCL1 = new URLClassLoader(urlCL.getURLs(), null);
|
||||
URLClassLoader urlCL2 = new URLClassLoader(urlCL.getURLs(), null);
|
||||
Class otherEnumClass1 = urlCL1.loadClass("org.apache.commons.lang.enums.ValuedColorEnum");
|
||||
Class otherEnumClass2 = urlCL2.loadClass("org.apache.commons.lang.enums.ValuedColorEnum");
|
||||
Object blue1 = otherEnumClass1.getDeclaredField("BLUE").get(null);
|
||||
Object blue2 = otherEnumClass2.getDeclaredField("BLUE").get(null);
|
||||
assertTrue(((Comparable) blue1).compareTo(blue2) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
public void testCompareTo_classloader_different() throws Exception {
|
||||
ClassLoader cl = ValuedColorEnum.class.getClassLoader();
|
||||
if (cl instanceof URLClassLoader) {
|
||||
URLClassLoader urlCL = (URLClassLoader) cl;
|
||||
URLClassLoader urlCL1 = new URLClassLoader(urlCL.getURLs(), null);
|
||||
URLClassLoader urlCL2 = new URLClassLoader(urlCL.getURLs(), null);
|
||||
Class otherEnumClass1 = urlCL1.loadClass("org.apache.commons.lang.enums.ValuedColorEnum");
|
||||
Class otherEnumClass2 = urlCL2.loadClass("org.apache.commons.lang.enums.ValuedColorEnum");
|
||||
Object blue1 = otherEnumClass1.getDeclaredField("BLUE").get(null);
|
||||
Object blue2 = otherEnumClass2.getDeclaredField("RED").get(null);
|
||||
assertTrue(((Comparable) blue1).compareTo(blue2) != 0);
|
||||
}
|
||||
}
|
||||
|
||||
public void testCompareTo_nonEnumType() {
|
||||
try {
|
||||
ValuedColorEnum.BLUE.compareTo(new TotallyUnrelatedClass(ValuedColorEnum.BLUE.getValue()));
|
||||
fail();
|
||||
} catch (ClassCastException ex) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
public void testCompareTo_otherEnumType() {
|
||||
try {
|
||||
ValuedColorEnum.BLUE.compareTo(ValuedLanguageEnum.ENGLISH);
|
||||
fail();
|
||||
} catch (ClassCastException ex) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
public void testCompareTo_otherType() {
|
||||
try {
|
||||
ValuedColorEnum.BLUE.compareTo("Blue");
|
||||
fail();
|
||||
} catch (ClassCastException ex) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
public void testCompareTo_null() {
|
||||
try {
|
||||
ValuedColorEnum.BLUE.compareTo(null);
|
||||
fail();
|
||||
} catch (NullPointerException ex) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
public void testEquals() {
|
||||
assertSame(ValuedColorEnum.RED, ValuedColorEnum.RED);
|
||||
assertSame(ValuedColorEnum.getEnum("Red"), ValuedColorEnum.RED);
|
||||
}
|
||||
|
||||
public void testEquals_classloader_equal() throws Exception {
|
||||
ClassLoader cl = ValuedColorEnum.class.getClassLoader();
|
||||
if (cl instanceof URLClassLoader) {
|
||||
URLClassLoader urlCL = (URLClassLoader) cl;
|
||||
URLClassLoader urlCL1 = new URLClassLoader(urlCL.getURLs(), null);
|
||||
URLClassLoader urlCL2 = new URLClassLoader(urlCL.getURLs(), null);
|
||||
Class otherEnumClass1 = urlCL1.loadClass("org.apache.commons.lang.enums.ValuedColorEnum");
|
||||
Class otherEnumClass2 = urlCL2.loadClass("org.apache.commons.lang.enums.ValuedColorEnum");
|
||||
Object blue1 = otherEnumClass1.getDeclaredField("BLUE").get(null);
|
||||
Object blue2 = otherEnumClass2.getDeclaredField("BLUE").get(null);
|
||||
assertEquals(true, blue1.equals(blue2));
|
||||
}
|
||||
}
|
||||
|
||||
public void testEquals_classloader_different() throws Exception {
|
||||
ClassLoader cl = ValuedColorEnum.class.getClassLoader();
|
||||
if (cl instanceof URLClassLoader) {
|
||||
URLClassLoader urlCL = (URLClassLoader) cl;
|
||||
URLClassLoader urlCL1 = new URLClassLoader(urlCL.getURLs(), null);
|
||||
URLClassLoader urlCL2 = new URLClassLoader(urlCL.getURLs(), null);
|
||||
Class otherEnumClass1 = urlCL1.loadClass("org.apache.commons.lang.enums.ValuedColorEnum");
|
||||
Class otherEnumClass2 = urlCL2.loadClass("org.apache.commons.lang.enums.ValuedColorEnum");
|
||||
Object blue1 = otherEnumClass1.getDeclaredField("BLUE").get(null);
|
||||
Object blue2 = otherEnumClass2.getDeclaredField("RED").get(null);
|
||||
assertEquals(false, blue1.equals(blue2));
|
||||
}
|
||||
}
|
||||
|
||||
public void testToString() {
|
||||
String toString = ValuedColorEnum.RED.toString();
|
||||
assertEquals("ValuedColorEnum[Red=1]", toString);
|
||||
|
@ -132,4 +225,17 @@ public final class ValuedEnumTest extends TestCase {
|
|||
assertSame(ValuedColorEnum.BLUE, SerializationUtils.clone(ValuedColorEnum.BLUE));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------s
|
||||
static class TotallyUnrelatedClass {
|
||||
private final int value;
|
||||
|
||||
public TotallyUnrelatedClass(final int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright 2006 The Apache Software Foundation.
|
||||
*
|
||||
* 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.apache.commons.lang.enums;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Language enumeration.
|
||||
*
|
||||
* @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
|
||||
* @version $Id: ValuedColorEnum.java 161244 2005-04-14 06:16:36Z ggregory $
|
||||
*/
|
||||
public final class ValuedLanguageEnum extends ValuedEnum {
|
||||
public static final ValuedLanguageEnum ENGLISH = new ValuedLanguageEnum("English", 1);
|
||||
public static final ValuedLanguageEnum FRENCH = new ValuedLanguageEnum("French", 2);
|
||||
public static final ValuedLanguageEnum GERMAN = new ValuedLanguageEnum("German", 3);
|
||||
|
||||
private ValuedLanguageEnum(String color, int value) {
|
||||
super(color, value);
|
||||
}
|
||||
|
||||
public static ValuedLanguageEnum getEnum(String color) {
|
||||
return (ValuedLanguageEnum) getEnum(ValuedLanguageEnum.class, color);
|
||||
}
|
||||
|
||||
public static ValuedLanguageEnum getEnum(int value) {
|
||||
return (ValuedLanguageEnum) getEnum(ValuedLanguageEnum.class, value);
|
||||
}
|
||||
|
||||
public static Map getEnumMap() {
|
||||
return getEnumMap(ValuedLanguageEnum.class);
|
||||
}
|
||||
|
||||
public static List getEnumList() {
|
||||
return getEnumList(ValuedLanguageEnum.class);
|
||||
}
|
||||
|
||||
public static Iterator iterator() {
|
||||
return iterator(ValuedLanguageEnum.class);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue