Return-Path: Delivered-To: apmail-jakarta-commons-dev-archive@apache.org Received: (qmail 73845 invoked from network); 31 Dec 2002 22:39:46 -0000 Received: from exchange.sun.com (192.18.33.10) by daedalus.apache.org with SMTP; 31 Dec 2002 22:39:46 -0000 Received: (qmail 21900 invoked by uid 97); 31 Dec 2002 22:41:04 -0000 Delivered-To: qmlist-jakarta-archive-commons-dev@jakarta.apache.org Received: (qmail 21844 invoked by uid 97); 31 Dec 2002 22:41:03 -0000 Mailing-List: contact commons-dev-help@jakarta.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Subscribe: List-Help: List-Post: List-Id: "Jakarta Commons Developers List" Reply-To: "Jakarta Commons Developers List" Delivered-To: mailing list commons-dev@jakarta.apache.org Received: (qmail 21833 invoked by uid 97); 31 Dec 2002 22:41:03 -0000 X-Antivirus: nagoya (v4218 created Aug 14 2002) Date: 31 Dec 2002 22:39:39 -0000 Message-ID: <20021231223939.78674.qmail@icarus.apache.org> From: scolebourne@apache.org To: jakarta-commons-cvs@apache.org Subject: cvs commit: jakarta-commons/lang/src/test/org/apache/commons/lang/enum OperationEnum.java EnumTest.java X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N scolebourne 2002/12/31 14:39:39 Modified: lang/src/java/org/apache/commons/lang/enum Enum.java ValuedEnum.java lang/src/test/org/apache/commons/lang/enum EnumTest.java Added: lang/src/test/org/apache/commons/lang/enum OperationEnum.java Log: Fix to enable anonymous inner classes as Enums for functionality Revision Changes Path 1.6 +100 -27 jakarta-commons/lang/src/java/org/apache/commons/lang/enum/Enum.java Index: Enum.java =================================================================== RCS file: /home/cvs/jakarta-commons/lang/src/java/org/apache/commons/lang/enum/Enum.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- Enum.java 23 Dec 2002 00:17:06 -0000 1.5 +++ Enum.java 31 Dec 2002 22:39:39 -0000 1.6 @@ -111,10 +111,50 @@ * Unfortunately, Java restrictions require these to be coded as shown in each subclass. * An alternative choice is to use the {@link EnumUtils} class. *

+ * The enums can have functionality by using anonymous inner classes + * [Effective Java, Bloch01]: + *

  + * public abstract class OperationEnum extends Enum {
  + *   public static final OperationEnum PLUS = new OperationEnum("Plus") {
  + *     public double eval(double a, double b) {
  + *       return (a + b);
  + *     }
  + *   };
  + *   public static final OperationEnum MINUS = new OperationEnum("Minus") {
  + *     public double eval(double a, double b) {
  + *       return (a - b);
  + *     }
  + *   };
  + *
  + *   private OperationEnum(String color) {
  + *     super(color);
  + *   }
  + * 
  + *   public abstract double eval(double a, double b);
  + * 
  + *   public static OperationEnum getEnum(String name) {
  + *     return (OperationEnum) getEnum(OperationEnum.class, name);
  + *   }
  + * 
  + *   public static Map getEnumMap() {
  + *     return getEnumMap(OperationEnum.class);
  + *   }
  + * 
  + *   public static List getEnumList() {
  + *     return getEnumList(OperationEnum.class);
  + *   }
  + * 
  + *   public static Iterator iterator() {
  + *     return iterator(OperationEnum.class);
  + *   }
  + * }
  + * 
+ *

* NOTE: This class originated in the Jakarta Avalon project. *

* * @author Stephen Colebourne + * @author Chris Webb * @since 1.0 * @version $Id$ */ @@ -160,10 +200,11 @@ throw new IllegalArgumentException("The Enum name must not be empty"); } iName = name; - Entry entry = (Entry) cEnumClasses.get(getClass().getName()); + String className = Enum.getEnumClassName(getClass()); + Entry entry = (Entry) cEnumClasses.get(className); if (entry == null) { entry = new Entry(); - cEnumClasses.put(getClass().getName(), entry); + cEnumClasses.put(className, entry); } if (entry.map.containsKey(name)) { throw new IllegalArgumentException("The Enum name must be unique, '" + name + "' has already been added"); @@ -178,22 +219,25 @@ * @return the resolved object */ protected Object readResolve() { - return Enum.getEnum(getClass(), getName()); + Entry entry = (Entry) cEnumClasses.get(Enum.getEnumClassName(getClass())); + if (entry == null) { + return null; + } + return (Enum) entry.map.get(getName()); } + + //-------------------------------------------------------------------------------- /** * Gets an Enum object by class and name. * - * @param enumClass the class of the Enum to get + * @param enumClass the class of the Enum to get, must not be null * @param name the name of the Enum to get, may be null * @return the enum object, or null if the enum does not exist * @throws IllegalArgumentException if the enum class is null */ protected static Enum getEnum(Class enumClass, String name) { - if (enumClass == null) { - throw new IllegalArgumentException("The Enum Class must not be null"); - } - Entry entry = (Entry) cEnumClasses.get(enumClass.getName()); + Entry entry = getEntry(enumClass); if (entry == null) { return null; } @@ -204,19 +248,13 @@ * Gets the Map of Enum objects by name using the Enum class. * If the requested class has no enum objects an empty Map is returned. * - * @param enumClass the class of the Enum to get + * @param enumClass the class of the Enum to get, must not be null * @return the enum object Map * @throws IllegalArgumentException if the enum class is null * @throws IllegalArgumentException if the enum class is not a subclass of Enum */ protected static Map getEnumMap(Class enumClass) { - if (enumClass == null) { - throw new IllegalArgumentException("The Enum Class must not be null"); - } - if (Enum.class.isAssignableFrom(enumClass) == false) { - throw new IllegalArgumentException("The Class must be a subclass of Enum"); - } - Entry entry = (Entry) cEnumClasses.get(enumClass.getName()); + Entry entry = getEntry(enumClass); if (entry == null) { return EMPTY_MAP; } @@ -228,19 +266,13 @@ * The list is in the order that the objects were created (source code order). * If the requested class has no enum objects an empty List is returned. * - * @param enumClass the class of the Enum to get + * @param enumClass the class of the Enum to get, must not be null * @return the enum object Map * @throws IllegalArgumentException if the enum class is null * @throws IllegalArgumentException if the enum class is not a subclass of Enum */ protected static List getEnumList(Class enumClass) { - if (enumClass == null) { - throw new IllegalArgumentException("The Enum Class must not be null"); - } - if (Enum.class.isAssignableFrom(enumClass) == false) { - throw new IllegalArgumentException("The Class must be a subclass of Enum"); - } - Entry entry = (Entry) cEnumClasses.get(enumClass.getName()); + Entry entry = getEntry(enumClass); if (entry == null) { return Collections.EMPTY_LIST; } @@ -252,7 +284,7 @@ * The iterator is in the order that the objects were created (source code order). * If the requested class has no enum objects an empty Iterator is returned. * - * @param enumClass the class of the Enum to get + * @param enumClass the class of the Enum to get, must not be null * @return an iterator of the Enum objects * @throws IllegalArgumentException if the enum class is null * @throws IllegalArgumentException if the enum class is not a subclass of Enum @@ -262,6 +294,47 @@ } /** + * Gets an entry from the map of Enums. + * + * @param enumClass the class of the Enum to get + * @return the enum entry + */ + private static Entry getEntry(Class enumClass) { + if (enumClass == null) { + throw new IllegalArgumentException("The Enum Class must not be null"); + } + if (Enum.class.isAssignableFrom(enumClass) == false) { + throw new IllegalArgumentException("The Class must be a subclass of Enum"); + } + Entry entry = (Entry) cEnumClasses.get(enumClass.getName()); + return entry; + } + + /** + * Convert a class to a class name accounting for inner classes. + * + * @param cls the class to get the name for + * @return the class name + */ + protected static String getEnumClassName(Class cls) { + String className = cls.getName(); + int index = className.lastIndexOf('$'); + if (index > -1) { + // is it an anonymous inner class? + String inner = className.substring(index + 1); + if (inner.length() > 0 && + inner.charAt(0) >= '0' && + inner.charAt(0) < '9') { + // Strip off anonymous inner class reference. + className = className.substring(0, index); + } + } + return className; + } + + //-------------------------------------------------------------------------------- + + /** * Retrieve the name of this Enum item, set in the constructor. * * @return the String name of this Enum item @@ -343,7 +416,7 @@ * the type name. */ public String toString() { - String shortName = getClass().getName(); + String shortName = Enum.getEnumClassName(getClass()); int pos = shortName.lastIndexOf('.'); if (pos != -1) { shortName = shortName.substring(pos + 1); 1.4 +2 -2 jakarta-commons/lang/src/java/org/apache/commons/lang/enum/ValuedEnum.java Index: ValuedEnum.java =================================================================== RCS file: /home/cvs/jakarta-commons/lang/src/java/org/apache/commons/lang/enum/ValuedEnum.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- ValuedEnum.java 23 Dec 2002 00:17:06 -0000 1.3 +++ ValuedEnum.java 31 Dec 2002 22:39:39 -0000 1.4 @@ -204,7 +204,7 @@ * stripped from the type name. */ public String toString() { - String shortName = getClass().getName(); + String shortName = Enum.getEnumClassName(getClass()); int pos = shortName.lastIndexOf('.'); if (pos != -1) { shortName = shortName.substring(pos + 1); 1.5 +44 -2 jakarta-commons/lang/src/test/org/apache/commons/lang/enum/EnumTest.java Index: EnumTest.java =================================================================== RCS file: /home/cvs/jakarta-commons/lang/src/test/org/apache/commons/lang/enum/EnumTest.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- EnumTest.java 6 Nov 2002 19:14:43 -0000 1.4 +++ EnumTest.java 31 Dec 2002 22:39:39 -0000 1.5 @@ -65,7 +65,7 @@ /** * Test cases for the {@link Enum} class. * - * @author Stephen Colebourne + * @author Stephen Colebourne * @version $Id$ */ @@ -180,6 +180,48 @@ } catch (ExceptionInInitializerError ex) { assertTrue(ex.getException() instanceof IllegalArgumentException); } + } + + public void testOperationGet() { + assertSame(OperationEnum.PLUS, OperationEnum.getEnum("Plus")); + assertSame(OperationEnum.MINUS, OperationEnum.getEnum("Minus")); + assertSame(null, OperationEnum.getEnum("Pink")); + } + + public void testOperationSerialization() { + assertSame(OperationEnum.PLUS, SerializationUtils.clone(OperationEnum.PLUS)); + assertSame(OperationEnum.MINUS, SerializationUtils.clone(OperationEnum.MINUS)); + } + + public void testOperationToString() { + assertEquals("OperationEnum[Plus]", OperationEnum.PLUS.toString()); + } + + public void testOperationList() { + List list = OperationEnum.getEnumList(); + assertNotNull(list); + assertEquals(2, list.size()); + assertEquals(list.size(), OperationEnum.getEnumMap().keySet().size()); + + Iterator it = list.iterator(); + assertSame(OperationEnum.PLUS, it.next()); + assertSame(OperationEnum.MINUS, it.next()); + } + + public void testOperationMap() { + Map map = OperationEnum.getEnumMap(); + assertNotNull(map); + assertEquals(map.keySet().size(), OperationEnum.getEnumList().size()); + + assertTrue(map.containsValue(OperationEnum.PLUS)); + assertTrue(map.containsValue(OperationEnum.MINUS)); + assertSame(OperationEnum.PLUS, map.get("Plus")); + assertSame(OperationEnum.MINUS, map.get("Minus")); + } + + public void testOperationCalculation() { + assertEquals(3, OperationEnum.PLUS.eval(1, 2)); + assertEquals(-1, OperationEnum.MINUS.eval(1, 2)); } } 1.1 jakarta-commons/lang/src/test/org/apache/commons/lang/enum/OperationEnum.java Index: OperationEnum.java =================================================================== /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2002 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; import java.util.Iterator; import java.util.List; import java.util.Map; /** * Operator enumeration. * * @author Stephen Colebourne * @version $Id: OperationEnum.java,v 1.1 2002/12/31 22:39:39 scolebourne Exp $ */ public abstract class OperationEnum extends Enum { public static final OperationEnum PLUS = new OperationEnum("Plus") { public int eval(int a, int b) { return (a + b); } }; public static final OperationEnum MINUS = new OperationEnum("Minus") { public int eval(int a, int b) { return (a - b); } }; private OperationEnum(String name) { super(name); } public abstract int eval(int a, int b); public static OperationEnum getEnum(String name) { return (OperationEnum) getEnum(OperationEnum.class, name); } public static Map getEnumMap() { return getEnumMap(OperationEnum.class); } public static List getEnumList() { return getEnumList(OperationEnum.class); } public static Iterator iterator() { return iterator(OperationEnum.class); } } -- To unsubscribe, e-mail: For additional commands, e-mail: