diff --git a/src/java/org/apache/commons/lang/enum/Enum.java b/src/java/org/apache/commons/lang/enum/Enum.java index 048f427e5..0f348b52d 100644 --- a/src/java/org/apache/commons/lang/enum/Enum.java +++ b/src/java/org/apache/commons/lang/enum/Enum.java @@ -63,6 +63,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import org.apache.commons.lang.ClassUtils; import org.apache.commons.lang.StringUtils; /** @@ -203,12 +204,15 @@ import org.apache.commons.lang.StringUtils; * @author Chris Webb * @author Mike Bowler * @since 1.0 - * @version $Id: Enum.java,v 1.15 2003/07/20 15:49:58 scolebourne Exp $ + * @version $Id: Enum.java,v 1.16 2003/07/30 23:13:09 scolebourne Exp $ */ public abstract class Enum implements Comparable, Serializable { + + /** Serialization id */ + static final long serialVersionUID = -487045951170455942L; + // After discussion, the default size for HashMaps is used, as the // sizing algorithm changes across the JDK versions - /** * An empty Map, as JDK1.2 didn't have an empty map. */ @@ -221,6 +225,14 @@ public abstract class Enum implements Comparable, Serializable { * The string representation of the Enum. */ private final String iName; + /** + * The hashcode representation of the Enum. + */ + private transient final int iHashCode; + /** + * The toString representation of the Enum. + */ + protected transient String iToString = null; /** *

Enable the iterator to retain the source code order.

@@ -268,6 +280,9 @@ public abstract class Enum implements Comparable, Serializable { } entry.map.put(name, this); entry.list.add(this); + + iHashCode = 7 + enumClass.hashCode() + 3 * name.hashCode(); + // cannot create toString here as subclasses may want to include other data } /** @@ -490,7 +505,7 @@ public abstract class Enum implements Comparable, Serializable { * @return a hashcode based on the name */ public final int hashCode() { - return 7 + iName.hashCode(); + return iHashCode; } /** @@ -507,25 +522,26 @@ public abstract class Enum implements Comparable, Serializable { * @throws NullPointerException if other is null */ public int compareTo(Object other) { + if (other == this) { + return 0; + } return iName.compareTo(((Enum) other).iName); } /** *

Human readable description of this Enum item.

- * - *

For use when debugging.

* * @return String in the form type[name], for example: * Color[Red]. Note that the package name is stripped from * the type name. */ public String toString() { - String shortName = Enum.getEnumClass(getClass()).getName(); - int pos = shortName.lastIndexOf('.'); - if (pos != -1) { - shortName = shortName.substring(pos + 1); + if (iToString == null) { + Class cls = Enum.getEnumClass(getClass()); + String shortName = ClassUtils.getShortClassName(cls); + iToString = shortName + "[" + getName() + "]"; } - shortName = shortName.replace('$', '.'); - return shortName + "[" + getName() + "]"; + return iToString; } + } diff --git a/src/java/org/apache/commons/lang/enum/ValuedEnum.java b/src/java/org/apache/commons/lang/enum/ValuedEnum.java index 398cc67a5..333a4b3ef 100644 --- a/src/java/org/apache/commons/lang/enum/ValuedEnum.java +++ b/src/java/org/apache/commons/lang/enum/ValuedEnum.java @@ -56,6 +56,8 @@ package org.apache.commons.lang.enum; import java.util.Iterator; import java.util.List; +import org.apache.commons.lang.ClassUtils; + /** *

Abstract superclass for type-safe enums with integer values suitable * for use in switch statements.

@@ -131,7 +133,7 @@ import java.util.List; * @author Apache Avalon project * @author Stephen Colebourne * @since 1.0 - * @version $Id: ValuedEnum.java,v 1.8 2003/07/20 15:49:58 scolebourne Exp $ + * @version $Id: ValuedEnum.java,v 1.9 2003/07/30 23:13:09 scolebourne Exp $ */ public abstract class ValuedEnum extends Enum { /** @@ -205,19 +207,16 @@ public abstract class ValuedEnum extends Enum { /** *

Human readable description of this Enum item.

* - *

For use when debugging.

- * * @return String in the form type[name=value], for example: * JavaVersion[Java 1.0=100]. Note that the package name is * stripped from the type name. */ public String toString() { - String shortName = Enum.getEnumClass(getClass()).getName(); - int pos = shortName.lastIndexOf('.'); - if (pos != -1) { - shortName = shortName.substring(pos + 1); + if (iToString == null) { + Class cls = Enum.getEnumClass(getClass()); + String shortName = ClassUtils.getShortClassName(cls); + iToString = shortName + "[" + getName() + "=" + getValue() + "]"; } - shortName = shortName.replace('$', '.'); - return shortName + "[" + getName() + "=" + getValue() + "]"; + return iToString; } } diff --git a/src/test/org/apache/commons/lang/enum/DummyEnum.java b/src/test/org/apache/commons/lang/enum/DummyEnum.java new file mode 100644 index 000000000..63c4d3c92 --- /dev/null +++ b/src/test/org/apache/commons/lang/enum/DummyEnum.java @@ -0,0 +1,68 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002-2003 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang.enum; + +/** + * Dummy enumeration - no values. + * + * @author Stephen Colebourne + * @version $Id: DummyEnum.java,v 1.1 2003/07/30 23:13:09 scolebourne Exp $ + */ +public abstract class DummyEnum extends Enum { + + private DummyEnum(String name) { + super(name); + } + +} diff --git a/src/test/org/apache/commons/lang/enum/EnumTest.java b/src/test/org/apache/commons/lang/enum/EnumTest.java index ca1b79026..e3fd458f9 100644 --- a/src/test/org/apache/commons/lang/enum/EnumTest.java +++ b/src/test/org/apache/commons/lang/enum/EnumTest.java @@ -67,7 +67,7 @@ import org.apache.commons.lang.SerializationUtils; * Test cases for the {@link Enum} class. * * @author Stephen Colebourne - * @version $Id: EnumTest.java,v 1.7 2003/05/22 22:00:06 scolebourne Exp $ + * @version $Id: EnumTest.java,v 1.8 2003/07/30 23:13:09 scolebourne Exp $ */ public final class EnumTest extends TestCase { @@ -95,11 +95,27 @@ public final class EnumTest extends TestCase { assertTrue(ColorEnum.BLUE.compareTo(ColorEnum.BLUE) == 0); assertTrue(ColorEnum.RED.compareTo(ColorEnum.BLUE) > 0); assertTrue(ColorEnum.BLUE.compareTo(ColorEnum.RED) < 0); + try { + ColorEnum.RED.compareTo(null); + fail(); + } catch (NullPointerException ex) {} + try { + ColorEnum.RED.compareTo(new Object()); + fail(); + } catch (ClassCastException ex) {} } public void testEquals() { assertSame(ColorEnum.RED, ColorEnum.RED); assertSame(ColorEnum.getEnum("Red"), ColorEnum.RED); + assertEquals(false, ColorEnum.RED.equals(null)); + assertEquals(true, ColorEnum.RED.equals(ColorEnum.RED)); + assertEquals(true, ColorEnum.RED.equals(ColorEnum.getEnum("Red"))); + } + + public void testHashCode() { + assertEquals(ColorEnum.RED.hashCode(), ColorEnum.RED.hashCode()); + assertEquals(7 + ColorEnum.class.hashCode() + 3 * "Red".hashCode(), ColorEnum.RED.hashCode()); } public void testToString() { @@ -151,7 +167,9 @@ public final class EnumTest extends TestCase { } public void testSerialization() { + int hashCode = ColorEnum.RED.hashCode(); assertSame(ColorEnum.RED, SerializationUtils.clone(ColorEnum.RED)); + assertEquals(hashCode, SerializationUtils.clone(ColorEnum.RED).hashCode()); assertSame(ColorEnum.GREEN, SerializationUtils.clone(ColorEnum.GREEN)); assertSame(ColorEnum.BLUE, SerializationUtils.clone(ColorEnum.BLUE)); } diff --git a/src/test/org/apache/commons/lang/enum/EnumUtilsTest.java b/src/test/org/apache/commons/lang/enum/EnumUtilsTest.java index eec3e2983..2744a4e7f 100644 --- a/src/test/org/apache/commons/lang/enum/EnumUtilsTest.java +++ b/src/test/org/apache/commons/lang/enum/EnumUtilsTest.java @@ -65,7 +65,7 @@ import junit.framework.TestSuite; * Test cases for the {@link Enum} class. * * @author Stephen Colebourne - * @version $Id: EnumUtilsTest.java,v 1.3 2003/05/22 22:00:06 scolebourne Exp $ + * @version $Id: EnumUtilsTest.java,v 1.4 2003/07/30 23:13:09 scolebourne Exp $ */ public final class EnumUtilsTest extends TestCase { @@ -88,15 +88,19 @@ public final class EnumUtilsTest extends TestCase { assertSame(ColorEnum.RED, it.next()); assertSame(ColorEnum.GREEN, it.next()); assertSame(ColorEnum.BLUE, it.next()); + it = EnumUtils.iterator(DummyEnum.class); + assertEquals(false, it.hasNext()); } public void testIteratorEx() { try { EnumUtils.iterator(null); - } catch (IllegalArgumentException ex) { - return; - } - fail(); + fail(); + } catch (IllegalArgumentException ex) {} + try { + EnumUtils.iterator(Object.class); + fail(); + } catch (IllegalArgumentException ex) {} } public void testList() { @@ -105,15 +109,19 @@ public final class EnumUtilsTest extends TestCase { assertSame(ColorEnum.RED, it.next()); assertSame(ColorEnum.GREEN, it.next()); assertSame(ColorEnum.BLUE, it.next()); + list = EnumUtils.getEnumList(DummyEnum.class); + assertEquals(0, list.size()); } public void testListEx() { try { EnumUtils.getEnumList(null); - } catch (IllegalArgumentException ex) { - return; - } - fail(); + fail(); + } catch (IllegalArgumentException ex) {} + try { + EnumUtils.getEnumList(Object.class); + fail(); + } catch (IllegalArgumentException ex) {} } public void testMap() { @@ -124,15 +132,19 @@ public final class EnumUtilsTest extends TestCase { assertSame(ColorEnum.RED, map.get("Red")); assertSame(ColorEnum.GREEN, map.get("Green")); assertSame(ColorEnum.BLUE, map.get("Blue")); + map = EnumUtils.getEnumMap(DummyEnum.class); + assertEquals(0, map.size()); } public void testMapEx() { try { EnumUtils.getEnumMap(null); - } catch (IllegalArgumentException ex) { - return; - } - fail(); + fail(); + } catch (IllegalArgumentException ex) {} + try { + EnumUtils.getEnumMap(Object.class); + fail(); + } catch (IllegalArgumentException ex) {} } public void testGet() { @@ -140,15 +152,18 @@ public final class EnumUtilsTest extends TestCase { assertSame(ColorEnum.GREEN, EnumUtils.getEnum(ColorEnum.class, "Green")); assertSame(ColorEnum.BLUE, EnumUtils.getEnum(ColorEnum.class, "Blue")); assertSame(null, EnumUtils.getEnum(ColorEnum.class, "Pink")); + assertSame(null, EnumUtils.getEnum(DummyEnum.class, "Pink")); } public void testGetEx() { try { EnumUtils.getEnum(null, ""); - } catch (IllegalArgumentException ex) { - return; - } - fail(); + fail(); + } catch (IllegalArgumentException ex) {} + try { + EnumUtils.getEnum(Object.class, "Red"); + fail(); + } catch (IllegalArgumentException ex) {} } public void testGetValue() { @@ -156,15 +171,18 @@ public final class EnumUtilsTest extends TestCase { assertSame(ValuedColorEnum.GREEN, EnumUtils.getEnum(ValuedColorEnum.class, 2)); assertSame(ValuedColorEnum.BLUE, EnumUtils.getEnum(ValuedColorEnum.class, 3)); assertSame(null, EnumUtils.getEnum(ValuedColorEnum.class, 4)); + assertSame(null, EnumUtils.getEnum(DummyEnum.class, 5)); } public void testGetValueEx() { try { EnumUtils.getEnum(null, 0); - } catch (IllegalArgumentException ex) { - return; - } - fail(); + fail(); + } catch (IllegalArgumentException ex) {} + try { + EnumUtils.getEnum(Object.class, 2); + fail(); + } catch (IllegalArgumentException ex) {} } }