Author: scolebourne Date: Fri Aug 18 15:21:47 2006 New Revision: 432748 URL: http://svn.apache.org/viewvc?rev=432748&view=rev Log: LANG-259 - Fix compareTo to check the type is the same
Added: jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/enums/ValuedLanguageEnum.java (with props) Modified: jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/enums/ValuedEnum.java jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/enums/EnumEqualsTest.java jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/enums/ValuedEnumTest.java Modified: jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/enums/ValuedEnum.java URL: http://svn.apache.org/viewvc/jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/enums/ValuedEnum.java?rev=432748&r1=432747&r2=432748&view=diff ============================================================================== --- jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/enums/ValuedEnum.java (original) +++ jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/enums/ValuedEnum.java Fri Aug 18 15:21:47 2006 @@ -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 @@ * * <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,7 +180,38 @@ * @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"); } /** Modified: jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/enums/EnumEqualsTest.java URL: http://svn.apache.org/viewvc/jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/enums/EnumEqualsTest.java?rev=432748&r1=432747&r2=432748&view=diff ============================================================================== --- jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/enums/EnumEqualsTest.java (original) +++ jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/enums/EnumEqualsTest.java Fri Aug 18 15:21:47 2006 @@ -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; @@ -86,6 +88,34 @@ assertEquals(false, TrafficlightColorEnum.RED.equals(new TotallyUnrelatedClass("some"))); 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)); + } } //----------------------------------------------------------------------- Modified: jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/enums/ValuedEnumTest.java URL: http://svn.apache.org/viewvc/jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/enums/ValuedEnumTest.java?rev=432748&r1=432747&r2=432748&view=diff ============================================================================== --- jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/enums/ValuedEnumTest.java (original) +++ jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/enums/ValuedEnumTest.java Fri Aug 18 15:21:47 2006 @@ -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 @@ 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); @@ -130,6 +223,19 @@ assertSame(ValuedColorEnum.RED, SerializationUtils.clone(ValuedColorEnum.RED)); assertSame(ValuedColorEnum.GREEN, SerializationUtils.clone(ValuedColorEnum.GREEN)); 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; + } } } Added: jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/enums/ValuedLanguageEnum.java URL: http://svn.apache.org/viewvc/jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/enums/ValuedLanguageEnum.java?rev=432748&view=auto ============================================================================== --- jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/enums/ValuedLanguageEnum.java (added) +++ jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/enums/ValuedLanguageEnum.java Fri Aug 18 15:21:47 2006 @@ -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:[EMAIL PROTECTED]">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); + } +} Propchange: jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/enums/ValuedLanguageEnum.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/enums/ValuedLanguageEnum.java ------------------------------------------------------------------------------ svn:keywords = author date id revision --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]