You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ak...@apache.org on 2005/02/03 08:18:53 UTC

svn commit: r151131 [3/9] - in incubator/directory/asn1/branches/rewrite/ber: ./ src/java/org/apache/asn1/ber/ src/java/org/apache/asn1/ber/digester/ src/java/org/apache/asn1/ber/digester/rules/ src/java/org/apache/asn1/ber/primitives/ src/java/org/apache/asn1/tuples/ src/java/org/apache/asn1/util/ src/test/org/apache/asn1/ber/ src/test/org/apache/asn1/ber/primitives/

Added: incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/BooleanUtils.java
URL: http://svn.apache.org/viewcvs/incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/BooleanUtils.java?view=auto&rev=151131
==============================================================================
--- incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/BooleanUtils.java (added)
+++ incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/BooleanUtils.java Wed Feb  2 23:18:42 2005
@@ -0,0 +1,1051 @@
+/*
+ * Copyright 2002-2004 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.asn1.util;
+
+
+/**
+ * <p>Operations on boolean primitives and Boolean objects.</p>
+ * <p/>
+ * <p>This class tries to handle <code>null</code> input gracefully. An
+ * exception will not be thrown for a <code>null</code> input. Each method
+ * documents its behaviour in more detail.</p>
+ *
+ * @author Stephen Colebourne
+ * @author Matthew Hawthorne
+ * @author Gary Gregory
+ * @version $Id: BooleanUtils.java,v 1.18 2004/02/18 22:59:50 ggregory Exp $
+ * @since 2.0
+ */
+public class BooleanUtils
+{
+    private static final Integer INTEGER_ZERO = new Integer( 0 );
+    private static final Integer INTEGER_ONE = new Integer( 1 );
+
+
+    /**
+     * <p><code>BooleanUtils</code> instances should NOT be constructed in
+     * standard programming. Instead, the class should be used as
+     * <code>BooleanUtils.toBooleanObject(true);</code>.</p>
+     * <p/>
+     * <p>This constructor is public to permit tools that require a JavaBean
+     * instance to operate.</p>
+     */
+    public BooleanUtils()
+    {
+    }
+
+    // Boolean utilities
+    //--------------------------------------------------------------------------
+    /**
+     * <p>Negates the specified boolean.</p>
+     * <p/>
+     * <p>If <code>null</code> is passed in, <code>null</code> will be
+     * returned.</p>
+     * <p/>
+     * <pre>
+     *   BooleanUtils.negate(Boolean.TRUE)  = Boolean.FALSE;
+     *   BooleanUtils.negate(Boolean.FALSE) = Boolean.TRUE;
+     *   BooleanUtils.negate(null)          = null;
+     * </pre>
+     *
+     * @param bool the Boolean to negate, may be null
+     * @return the negated Boolean, or <code>null</code> if <code>null</code>
+     *         input
+     */
+    public static Boolean negate( Boolean bool )
+    {
+        if ( bool == null )
+        {
+            return null;
+        }
+        return ( bool.booleanValue() ? Boolean.FALSE : Boolean.TRUE );
+    }
+    
+    // boolean Boolean methods
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Boolean factory that avoids creating new Boolean objecs all the
+     * time.</p>
+     * <p/>
+     * <p>This method was added to JDK1.4 but is available here for earlier
+     * JDKs.</p>
+     * <p/>
+     * <pre>
+     *   BooleanUtils.toBooleanObject(false) = Boolean.FALSE
+     *   BooleanUtils.toBooleanObject(true)  = Boolean.TRUE
+     * </pre>
+     *
+     * @param bool the boolean to convert
+     * @return Boolean.TRUE or Boolean.FALSE as appropriate
+     */
+    public static Boolean toBooleanObject( boolean bool )
+    {
+        return ( bool ? Boolean.TRUE : Boolean.FALSE );
+    }
+
+
+    /**
+     * <p>Converts a Boolean to a boolean handling <code>null</code> by
+     * returning <code>false</code>.</p>
+     * <p/>
+     * <pre>
+     *   BooleanUtils.toBoolean(Boolean.TRUE)  = true
+     *   BooleanUtils.toBoolean(Boolean.FALSE) = false
+     *   BooleanUtils.toBoolean(null)          = false
+     * </pre>
+     *
+     * @param bool the boolean to convert
+     * @return <code>true</code> or <code>false</code>, <code>null</code>
+     *         returns <code>false</code>
+     */
+    public static boolean toBoolean( Boolean bool )
+    {
+        if ( bool == null )
+        {
+            return false;
+        }
+        return ( bool.booleanValue() ? true : false );
+    }
+
+
+    /**
+     * <p>Converts a Boolean to a boolean handling <code>null</code>.</p>
+     * <p/>
+     * <pre>
+     *   BooleanUtils.toBooleanDefaultIfNull(Boolean.TRUE, false) = true
+     *   BooleanUtils.toBooleanDefaultIfNull(Boolean.FALSE, true) = false
+     *   BooleanUtils.toBooleanDefaultIfNull(null, true)          = true
+     * </pre>
+     *
+     * @param bool        the boolean to convert
+     * @param valueIfNull the boolean value to return if <code>null</code>
+     * @return <code>true</code> or <code>false</code>
+     */
+    public static boolean toBooleanDefaultIfNull( Boolean bool, boolean valueIfNull )
+    {
+        if ( bool == null )
+        {
+            return valueIfNull;
+        }
+        return ( bool.booleanValue() ? true : false );
+    }
+    
+    // Integer to Boolean methods
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Converts an int to a boolean using the convention that
+     * <code>zero</code> is <code>false</code>.</p>
+     * <p/>
+     * <pre>
+     *   BooleanUtils.toBoolean(0) = false
+     *   BooleanUtils.toBoolean(1) = true
+     *   BooleanUtils.toBoolean(2) = true
+     * </pre>
+     *
+     * @param value the int to convert
+     * @return <code>true</code> if non-zero, <code>false</code> if zero
+     */
+    public static boolean toBoolean( int value )
+    {
+        return ( value == 0 ? false : true );
+    }
+
+
+    /**
+     * <p>Converts an int to a Boolean using the convention that
+     * <code>zero</code> is <code>false</code>.</p>
+     * <p/>
+     * <pre>
+     *   BooleanUtils.toBoolean(0) = Boolean.FALSE
+     *   BooleanUtils.toBoolean(1) = Boolean.TRUE
+     *   BooleanUtils.toBoolean(2) = Boolean.TRUE
+     * </pre>
+     *
+     * @param value the int to convert
+     * @return Boolean.TRUE if non-zero, Boolean.FALSE if zero,
+     *         <code>null</code> if <code>null</code>
+     */
+    public static Boolean toBooleanObject( int value )
+    {
+        return ( value == 0 ? Boolean.FALSE : Boolean.TRUE );
+    }
+
+
+    /**
+     * <p>Converts an Integer to a Boolean using the convention that
+     * <code>zero</code> is <code>false</code>.</p>
+     * <p/>
+     * <p><code>null</code> will be converted to <code>null</code>.</p>
+     * <p/>
+     * <pre>
+     *   BooleanUtils.toBoolean(new Integer(0))    = Boolean.FALSE
+     *   BooleanUtils.toBoolean(new Integer(1))    = Boolean.TRUE
+     *   BooleanUtils.toBoolean(new Integer(null)) = null
+     * </pre>
+     *
+     * @param value the Integer to convert
+     * @return Boolean.TRUE if non-zero, Boolean.FALSE if zero,
+     *         <code>null</code> if <code>null</code> input
+     */
+    public static Boolean toBooleanObject( Integer value )
+    {
+        if ( value == null )
+        {
+            return null;
+        }
+        return ( value.intValue() == 0 ? Boolean.FALSE : Boolean.TRUE );
+    }
+
+
+    /**
+     * <p>Converts an int to a boolean specifying the conversion values.</p>
+     * <p/>
+     * <pre>
+     *   BooleanUtils.toBoolean(0, 1, 0) = false
+     *   BooleanUtils.toBoolean(1, 1, 0) = true
+     *   BooleanUtils.toBoolean(2, 1, 2) = false
+     *   BooleanUtils.toBoolean(2, 2, 0) = true
+     * </pre>
+     *
+     * @param value      the Integer to convert
+     * @param trueValue  the value to match for <code>true</code>
+     * @param falseValue the value to match for <code>false</code>
+     * @return <code>true</code> or <code>false</code>
+     * @throws IllegalArgumentException if no match
+     */
+    public static boolean toBoolean( int value, int trueValue, int falseValue )
+    {
+        if ( value == trueValue )
+        {
+            return true;
+        }
+        else if ( value == falseValue )
+        {
+            return false;
+        }
+        // no match
+        throw new IllegalArgumentException( "The Integer did not match either specified value" );
+    }
+
+
+    /**
+     * <p>Converts an Integer to a boolean specifying the conversion
+     * values.</p>
+     * <p/>
+     * <pre>
+     *   BooleanUtils.toBoolean(new Integer(0), new Integer(1), new Integer(0))
+     * = false
+     *   BooleanUtils.toBoolean(new Integer(1), new Integer(1), new Integer(0))
+     * = true
+     *   BooleanUtils.toBoolean(new Integer(2), new Integer(1), new Integer(2))
+     * = false
+     *   BooleanUtils.toBoolean(new Integer(2), new Integer(2), new Integer(0))
+     * = true
+     *   BooleanUtils.toBoolean(null, null, new Integer(0))
+     * = true
+     * </pre>
+     *
+     * @param value      the Integer to convert
+     * @param trueValue  the value to match for <code>true</code>, may be
+     *                   <code>null</code>
+     * @param falseValue the value to match for <code>false</code>, may be
+     *                   <code>null</code>
+     * @return <code>true</code> or <code>false</code>
+     * @throws IllegalArgumentException if no match
+     */
+    public static boolean toBoolean( Integer value, Integer trueValue, Integer falseValue )
+    {
+        if ( value == null )
+        {
+            if ( trueValue == null )
+            {
+                return true;
+            }
+            else if ( falseValue == null )
+            {
+                return false;
+            }
+        }
+        else if ( value.equals( trueValue ) )
+        {
+            return true;
+        }
+        else if ( value.equals( falseValue ) )
+        {
+            return false;
+        }
+        // no match
+        throw new IllegalArgumentException( "The Integer did not match either specified value" );
+    }
+
+
+    /**
+     * <p>Converts an int to a Boolean specifying the conversion values.</p>
+     * <p/>
+     * <pre>
+     *   BooleanUtils.toBooleanObject(0, 0, 2, 3) = Boolean.TRUE
+     *   BooleanUtils.toBooleanObject(2, 1, 2, 3) = Boolean.FALSE
+     *   BooleanUtils.toBooleanObject(3, 1, 2, 3) = null
+     * </pre>
+     *
+     * @param value      the Integer to convert
+     * @param trueValue  the value to match for <code>true</code>
+     * @param falseValue the value to match for <code>false</code>
+     * @param nullValue  the value to to match for <code>null</code>
+     * @return Boolean.TRUE, Boolean.FALSE, or <code>null</code>
+     * @throws IllegalArgumentException if no match
+     */
+    public static Boolean toBooleanObject( int value, int trueValue, int falseValue, int nullValue )
+    {
+        if ( value == trueValue )
+        {
+            return Boolean.TRUE;
+        }
+        else if ( value == falseValue )
+        {
+            return Boolean.FALSE;
+        }
+        else if ( value == nullValue )
+        {
+            return null;
+        }
+        // no match
+        throw new IllegalArgumentException( "The Integer did not match any specified value" );
+    }
+
+
+    /**
+     * <p>Converts an Integer to a Boolean specifying the conversion
+     * values.</p>
+     * <p/>
+     * <pre>
+     *   BooleanUtils.toBooleanObject(new Integer(0), new Integer(0), new
+     * Integer(2), new Integer(3)) = Boolean.TRUE
+     *   BooleanUtils.toBooleanObject(new Integer(2), new Integer(1), new
+     * Integer(2), new Integer(3)) = Boolean.FALSE
+     *   BooleanUtils.toBooleanObject(new Integer(3), new Integer(1), new
+     * Integer(2), new Integer(3)) = null
+     * </pre>
+     *
+     * @param value      the Integer to convert
+     * @param trueValue  the value to match for <code>true</code>, may be
+     *                   <code>null</code>
+     * @param falseValue the value to match for <code>false</code>, may be
+     *                   <code>null</code>
+     * @param nullValue  the value to to match for <code>null</code>, may be
+     *                   <code>null</code>
+     * @return Boolean.TRUE, Boolean.FALSE, or <code>null</code>
+     * @throws IllegalArgumentException if no match
+     */
+    public static Boolean toBooleanObject( Integer value, Integer trueValue, Integer falseValue, Integer nullValue )
+    {
+        if ( value == null )
+        {
+            if ( trueValue == null )
+            {
+                return Boolean.TRUE;
+            }
+            else if ( falseValue == null )
+            {
+                return Boolean.FALSE;
+            }
+            else if ( nullValue == null )
+            {
+                return null;
+            }
+        }
+        else if ( value.equals( trueValue ) )
+        {
+            return Boolean.TRUE;
+        }
+        else if ( value.equals( falseValue ) )
+        {
+            return Boolean.FALSE;
+        }
+        else if ( value.equals( nullValue ) )
+        {
+            return null;
+        }
+        // no match
+        throw new IllegalArgumentException( "The Integer did not match any specified value" );
+    }
+    
+    // Boolean to Integer methods
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Converts a boolean to an int using the convention that
+     * <code>zero</code> is <code>false</code>.</p>
+     * <p/>
+     * <pre>
+     *   BooleanUtils.toInteger(true)  = 1
+     *   BooleanUtils.toInteger(false) = 0
+     * </pre>
+     *
+     * @param bool the boolean to convert
+     * @return one if <code>true</code>, zero if <code>false</code>
+     */
+    public static int toInteger( boolean bool )
+    {
+        return ( bool ? 1 : 0 );
+    }
+
+
+    /**
+     * <p>Converts a boolean to an Integer using the convention that
+     * <code>zero</code> is <code>false</code>.</p>
+     * <p/>
+     * <pre>
+     *   BooleanUtils.toIntegerObject(true)  = new Integer(1)
+     *   BooleanUtils.toIntegerObject(false) = new Integer(0)
+     * </pre>
+     *
+     * @param bool the boolean to convert
+     * @return one if <code>true</code>, zero if <code>false</code>
+     */
+    public static Integer toIntegerObject( boolean bool )
+    {
+        return ( bool ? INTEGER_ONE : INTEGER_ZERO );
+    }
+
+
+    /**
+     * <p>Converts a Boolean to a Integer using the convention that
+     * <code>zero</code> is <code>false</code>.</p>
+     * <p/>
+     * <p><code>null</code> will be converted to <code>null</code>.</p>
+     * <p/>
+     * <pre>
+     *   BooleanUtils.toIntegerObject(Boolean.TRUE)  = new Integer(1)
+     *   BooleanUtils.toIntegerObject(Boolean.FALSE) = new Integer(0)
+     * </pre>
+     *
+     * @param bool the Boolean to convert
+     * @return one if Boolean.TRUE, zero if Boolean.FALSE, <code>null</code> if
+     *         <code>null</code>
+     */
+    public static Integer toIntegerObject( Boolean bool )
+    {
+        if ( bool == null )
+        {
+            return null;
+        }
+        return ( bool.booleanValue() ? INTEGER_ONE : INTEGER_ZERO );
+    }
+
+
+    /**
+     * <p>Converts a boolean to an int specifying the conversion values.</p>
+     * <p/>
+     * <pre>
+     *   BooleanUtils.toInteger(true, 1, 0)  = 1
+     *   BooleanUtils.toInteger(false, 1, 0) = 0
+     * </pre>
+     *
+     * @param bool       the to convert
+     * @param trueValue  the value to return if <code>true</code>
+     * @param falseValue the value to return if <code>false</code>
+     * @return the appropriate value
+     */
+    public static int toInteger( boolean bool, int trueValue, int falseValue )
+    {
+        return ( bool ? trueValue : falseValue );
+    }
+
+
+    /**
+     * <p>Converts a Boolean to an int specifying the conversion values.</p>
+     * <p/>
+     * <pre>
+     *   BooleanUtils.toInteger(Boolean.TRUE, 1, 0, 2)  = 1
+     *   BooleanUtils.toInteger(Boolean.FALSE, 1, 0, 2) = 0
+     *   BooleanUtils.toInteger(null, 1, 0, 2)          = 2
+     * </pre>
+     *
+     * @param bool       the Boolean to convert
+     * @param trueValue  the value to return if <code>true</code>
+     * @param falseValue the value to return if <code>false</code>
+     * @param nullValue  the value to return if <code>null</code>
+     * @return the appropriate value
+     */
+    public static int toInteger( Boolean bool, int trueValue, int falseValue, int nullValue )
+    {
+        if ( bool == null )
+        {
+            return nullValue;
+        }
+        return ( bool.booleanValue() ? trueValue : falseValue );
+    }
+
+
+    /**
+     * <p>Converts a boolean to an Integer specifying the conversion
+     * values.</p>
+     * <p/>
+     * <pre>
+     *   BooleanUtils.toIntegerObject(true, new Integer(1), new Integer(0))  =
+     * new Integer(1)
+     *   BooleanUtils.toIntegerObject(false, new Integer(1), new Integer(0)) =
+     * new Integer(0)
+     * </pre>
+     *
+     * @param bool       the to convert
+     * @param trueValue  the value to return if <code>true</code>, may be
+     *                   <code>null</code>
+     * @param falseValue the value to return if <code>false</code>, may be
+     *                   <code>null</code>
+     * @return the appropriate value
+     */
+    public static Integer toIntegerObject( boolean bool, Integer trueValue, Integer falseValue )
+    {
+        return ( bool ? trueValue : falseValue );
+    }
+
+
+    /**
+     * <p>Converts a Boolean to an Integer specifying the conversion
+     * values.</p>
+     * <p/>
+     * <pre>
+     *   BooleanUtils.toIntegerObject(Boolean.TRUE, new Integer(1), new
+     * Integer(0), new Integer(2))  = new Integer(1)
+     *   BooleanUtils.toIntegerObject(Boolean.FALSE, new Integer(1), new
+     * Integer(0), new Integer(2)) = new Integer(0)
+     *   BooleanUtils.toIntegerObject(null, new Integer(1), new Integer(0), new
+     * Integer(2))          = new Integer(2)
+     * </pre>
+     *
+     * @param bool       the Boolean to convert
+     * @param trueValue  the value to return if <code>true</code>, may be
+     *                   <code>null</code>
+     * @param falseValue the value to return if <code>false</code>, may be
+     *                   <code>null</code>
+     * @param nullValue  the value to return if <code>null</code>, may be
+     *                   <code>null</code>
+     * @return the appropriate value
+     */
+    public static Integer toIntegerObject( Boolean bool, Integer trueValue, Integer falseValue, Integer nullValue )
+    {
+        if ( bool == null )
+        {
+            return nullValue;
+        }
+        return ( bool.booleanValue() ? trueValue : falseValue );
+    }
+    
+    // String to Boolean methods
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Converts a String to a Boolean.</p>
+     * <p/>
+     * <p><code>'true'</code>, <code>'on'</code> or <code>'yes'</code> (case
+     * insensitive) will return <code>true</code>. <code>'false'</code>,
+     * <code>'off'</code> or <code>'no'</code> (case insensitive) will return
+     * <code>false</code>. Otherwise, <code>null</code> is returned.</p>
+     * <p/>
+     * <pre>
+     *   BooleanUtils.toBooleanObject(null)    = null
+     *   BooleanUtils.toBooleanObject("true")  = Boolean.TRUE
+     *   BooleanUtils.toBooleanObject("false") = Boolean.FALSE
+     *   BooleanUtils.toBooleanObject("on")    = Boolean.TRUE
+     *   BooleanUtils.toBooleanObject("ON")    = Boolean.TRUE
+     *   BooleanUtils.toBooleanObject("off")   = Boolean.FALSE
+     *   BooleanUtils.toBooleanObject("oFf")   = Boolean.FALSE
+     *   BooleanUtils.toBooleanObject("blue")  = null
+     * </pre>
+     *
+     * @param str the String to check
+     * @return the Boolean value of the string, <code>null</code> if no match or
+     *         <code>null</code> input
+     */
+    public static Boolean toBooleanObject( String str )
+    {
+        if ( "true".equalsIgnoreCase( str ) )
+        {
+            return Boolean.TRUE;
+        }
+        else if ( "false".equalsIgnoreCase( str ) )
+        {
+            return Boolean.FALSE;
+        }
+        else if ( "on".equalsIgnoreCase( str ) )
+        {
+            return Boolean.TRUE;
+        }
+        else if ( "off".equalsIgnoreCase( str ) )
+        {
+            return Boolean.FALSE;
+        }
+        else if ( "yes".equalsIgnoreCase( str ) )
+        {
+            return Boolean.TRUE;
+        }
+        else if ( "no".equalsIgnoreCase( str ) )
+        {
+            return Boolean.FALSE;
+        }
+        // no match
+        return null;
+    }
+
+
+    /**
+     * <p>Converts a String to a Boolean throwing an exception if no match.</p>
+     * <p/>
+     * <pre>
+     *   BooleanUtils.toBooleanObject("true", "true", "false", "null")  =
+     * Boolean.TRUE
+     *   BooleanUtils.toBooleanObject("false", "true", "false", "null") =
+     * Boolean.FALSE
+     *   BooleanUtils.toBooleanObject("null", "true", "false", "null")  = null
+     * </pre>
+     *
+     * @param str         the String to check
+     * @param trueString  the String to match for <code>true</code> (case
+     *                    sensitive), may be <code>null</code>
+     * @param falseString the String to match for <code>false</code> (case
+     *                    sensitive), may be <code>null</code>
+     * @param nullString  the String to match for <code>null</code> (case
+     *                    sensitive), may be <code>null</code>
+     * @return the Boolean value of the string, <code>null</code> if no match or
+     *         <code>null</code> input
+     */
+    public static Boolean toBooleanObject( String str, String trueString, String falseString, String nullString )
+    {
+        if ( str == null )
+        {
+            if ( trueString == null )
+            {
+                return Boolean.TRUE;
+            }
+            else if ( falseString == null )
+            {
+                return Boolean.FALSE;
+            }
+            else if ( nullString == null )
+            {
+                return null;
+            }
+        }
+        else if ( str.equals( trueString ) )
+        {
+            return Boolean.TRUE;
+        }
+        else if ( str.equals( falseString ) )
+        {
+            return Boolean.FALSE;
+        }
+        else if ( str.equals( nullString ) )
+        {
+            return null;
+        }
+        // no match
+        throw new IllegalArgumentException( "The String did not match any specified value" );
+    }
+
+    // String to boolean methods
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Converts a String to a boolean (optimised for performance).</p>
+     * <p/>
+     * <p><code>'true'</code>, <code>'on'</code> or <code>'yes'</code> (case
+     * insensitive) will return <code>true</code>. Otherwise, <code>false</code>
+     * is returned.</p>
+     * <p/>
+     * <p>This method performs 4 times faster (JDK1.4) than
+     * <code>Boolean.valueOf(String)</code>. However, this method accepts 'on'
+     * and 'yes' as true values.
+     * <p/>
+     * <pre>
+     *   BooleanUtils.toBoolean(null)    = false
+     *   BooleanUtils.toBoolean("true")  = true
+     *   BooleanUtils.toBoolean("TRUE")  = true
+     *   BooleanUtils.toBoolean("tRUe")  = true
+     *   BooleanUtils.toBoolean("on")    = true
+     *   BooleanUtils.toBoolean("yes")   = true
+     *   BooleanUtils.toBoolean("false") = false
+     *   BooleanUtils.toBoolean("x gti") = false
+     * </pre>
+     *
+     * @param str the String to check
+     * @return the boolean value of the string, <code>false</code> if no match
+     */
+    public static boolean toBoolean( String str )
+    {
+        // Previously used equalsIgnoreCase, which was fast for interned 'true'.
+        // Non interned 'true' matched 15 times slower.
+        //
+        // Optimisation provides same performance as before for interned 'true'.
+        // Similar performance for null, 'false', and other strings not length 2/3/4.
+        // 'true'/'TRUE' match 4 times slower, 'tRUE'/'True' 7 times slower.
+        if ( str == "true" )
+        {
+            return true;
+        }
+        if ( str == null )
+        {
+            return false;
+        }
+        switch ( str.length() )
+        {
+            case 2:
+                {
+                    char ch0 = str.charAt( 0 );
+                    char ch1 = str.charAt( 1 );
+                    return
+                            ( ch0 == 'o' || ch0 == 'O' ) &&
+                            ( ch1 == 'n' || ch1 == 'N' );
+                }
+            case 3:
+                {
+                    char ch = str.charAt( 0 );
+                    if ( ch == 'y' )
+                    {
+                        return
+                                ( str.charAt( 1 ) == 'e' || str.charAt( 1 ) == 'E' ) &&
+                                ( str.charAt( 2 ) == 's' || str.charAt( 2 ) == 'S' );
+                    }
+                    if ( ch == 'Y' )
+                    {
+                        return
+                                ( str.charAt( 1 ) == 'E' || str.charAt( 1 ) == 'e' ) &&
+                                ( str.charAt( 2 ) == 'S' || str.charAt( 2 ) == 's' );
+                    }
+                }
+            case 4:
+                {
+                    char ch = str.charAt( 0 );
+                    if ( ch == 't' )
+                    {
+                        return
+                                ( str.charAt( 1 ) == 'r' || str.charAt( 1 ) == 'R' ) &&
+                                ( str.charAt( 2 ) == 'u' || str.charAt( 2 ) == 'U' ) &&
+                                ( str.charAt( 3 ) == 'e' || str.charAt( 3 ) == 'E' );
+                    }
+                    if ( ch == 'T' )
+                    {
+                        return
+                                ( str.charAt( 1 ) == 'R' || str.charAt( 1 ) == 'r' ) &&
+                                ( str.charAt( 2 ) == 'U' || str.charAt( 2 ) == 'u' ) &&
+                                ( str.charAt( 3 ) == 'E' || str.charAt( 3 ) == 'e' );
+                    }
+                }
+        }
+        return false;
+    }
+
+
+    /**
+     * <p>Converts a String to a Boolean throwing an exception if no match
+     * found.</p>
+     * <p/>
+     * <p>null is returned if there is no match.</p>
+     * <p/>
+     * <pre>
+     *   BooleanUtils.toBoolean("true", "true", "false")  = true
+     *   BooleanUtils.toBoolean("false", "true", "false") = false
+     * </pre>
+     *
+     * @param str         the String to check
+     * @param trueString  the String to match for <code>true</code> (case
+     *                    sensitive), may be <code>null</code>
+     * @param falseString the String to match for <code>false</code> (case
+     *                    sensitive), may be <code>null</code>
+     * @return the boolean value of the string
+     * @throws IllegalArgumentException if the String doesn't match
+     */
+    public static boolean toBoolean( String str, String trueString, String falseString )
+    {
+        if ( str == null )
+        {
+            if ( trueString == null )
+            {
+                return true;
+            }
+            else if ( falseString == null )
+            {
+                return false;
+            }
+        }
+        else if ( str.equals( trueString ) )
+        {
+            return true;
+        }
+        else if ( str.equals( falseString ) )
+        {
+            return false;
+        }
+        // no match
+        throw new IllegalArgumentException( "The String did not match either specified value" );
+    }
+
+    // Boolean to String methods
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Converts a Boolean to a String returning <code>'true'</code>,
+     * <code>'false'</code>, or <code>null</code>.</p>
+     * <p/>
+     * <pre>
+     *   BooleanUtils.toStringTrueFalse(Boolean.TRUE)  = "true"
+     *   BooleanUtils.toStringTrueFalse(Boolean.FALSE) = "false"
+     *   BooleanUtils.toStringTrueFalse(null)          = null;
+     * </pre>
+     *
+     * @param bool the Boolean to check
+     * @return <code>'true'</code>, <code>'false'</code>, or <code>null</code>
+     */
+    public static String toStringTrueFalse( Boolean bool )
+    {
+        return toString( bool, "true", "false", null );
+    }
+
+
+    /**
+     * <p>Converts a Boolean to a String returning <code>'on'</code>,
+     * <code>'off'</code>, or <code>null</code>.</p>
+     * <p/>
+     * <pre>
+     *   BooleanUtils.toStringOnOff(Boolean.TRUE)  = "on"
+     *   BooleanUtils.toStringOnOff(Boolean.FALSE) = "off"
+     *   BooleanUtils.toStringOnOff(null)          = null;
+     * </pre>
+     *
+     * @param bool the Boolean to check
+     * @return <code>'on'</code>, <code>'off'</code>, or <code>null</code>
+     */
+    public static String toStringOnOff( Boolean bool )
+    {
+        return toString( bool, "on", "off", null );
+    }
+
+
+    /**
+     * <p>Converts a Boolean to a String returning <code>'yes'</code>,
+     * <code>'no'</code>, or <code>null</code>.</p>
+     * <p/>
+     * <pre>
+     *   BooleanUtils.toStringYesNo(Boolean.TRUE)  = "yes"
+     *   BooleanUtils.toStringYesNo(Boolean.FALSE) = "no"
+     *   BooleanUtils.toStringYesNo(null)          = null;
+     * </pre>
+     *
+     * @param bool the Boolean to check
+     * @return <code>'yes'</code>, <code>'no'</code>, or <code>null</code>
+     */
+    public static String toStringYesNo( Boolean bool )
+    {
+        return toString( bool, "yes", "no", null );
+    }
+
+
+    /**
+     * <p>Converts a Boolean to a String returning one of the input
+     * Strings.</p>
+     * <p/>
+     * <pre>
+     *   BooleanUtils.toString(Boolean.TRUE, "true", "false", null)   = "true"
+     *   BooleanUtils.toString(Boolean.FALSE, "true", "false", null)  = "false"
+     *   BooleanUtils.toString(null, "true", "false", null)           = null;
+     * </pre>
+     *
+     * @param bool        the Boolean to check
+     * @param trueString  the String to return if <code>true</code>, may be
+     *                    <code>null</code>
+     * @param falseString the String to return if <code>false</code>, may be
+     *                    <code>null</code>
+     * @param nullString  the String to return if <code>null</code>, may be
+     *                    <code>null</code>
+     * @return one of the three input Strings
+     */
+    public static String toString( Boolean bool, String trueString, String falseString, String nullString )
+    {
+        if ( bool == null )
+        {
+            return nullString;
+        }
+        return ( bool.booleanValue() ? trueString : falseString );
+    }
+    
+    // boolean to String methods
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Converts a boolean to a String returning <code>'true'</code> or
+     * <code>'false'</code>.</p>
+     * <p/>
+     * <pre>
+     *   BooleanUtils.toStringTrueFalse(true)   = "true"
+     *   BooleanUtils.toStringTrueFalse(false)  = "false"
+     * </pre>
+     *
+     * @param bool the Boolean to check
+     * @return <code>'true'</code>, <code>'false'</code>, or <code>null</code>
+     */
+    public static String toStringTrueFalse( boolean bool )
+    {
+        return toString( bool, "true", "false" );
+    }
+
+
+    /**
+     * <p>Converts a boolean to a String returning <code>'on'</code> or
+     * <code>'off'</code>.</p>
+     * <p/>
+     * <pre>
+     *   BooleanUtils.toStringOnOff(true)   = "on"
+     *   BooleanUtils.toStringOnOff(false)  = "off"
+     * </pre>
+     *
+     * @param bool the Boolean to check
+     * @return <code>'on'</code>, <code>'off'</code>, or <code>null</code>
+     */
+    public static String toStringOnOff( boolean bool )
+    {
+        return toString( bool, "on", "off" );
+    }
+
+
+    /**
+     * <p>Converts a boolean to a String returning <code>'yes'</code> or
+     * <code>'no'</code>.</p>
+     * <p/>
+     * <pre>
+     *   BooleanUtils.toStringYesNo(true)   = "yes"
+     *   BooleanUtils.toStringYesNo(false)  = "no"
+     * </pre>
+     *
+     * @param bool the Boolean to check
+     * @return <code>'yes'</code>, <code>'no'</code>, or <code>null</code>
+     */
+    public static String toStringYesNo( boolean bool )
+    {
+        return toString( bool, "yes", "no" );
+    }
+
+
+    /**
+     * <p>Converts a boolean to a String returning one of the input
+     * Strings.</p>
+     * <p/>
+     * <pre>
+     *   BooleanUtils.toString(true, "true", "false")   = "true"
+     *   BooleanUtils.toString(false, "true", "false")  = "false"
+     * </pre>
+     *
+     * @param bool        the Boolean to check
+     * @param trueString  the String to return if <code>true</code>, may be
+     *                    <code>null</code>
+     * @param falseString the String to return if <code>false</code>, may be
+     *                    <code>null</code>
+     * @return one of the two input Strings
+     */
+    public static String toString( boolean bool, String trueString, String falseString )
+    {
+        return ( bool ? trueString : falseString );
+    }
+    
+    // xor methods
+    // ----------------------------------------------------------------------
+    /**
+     * <p>Performs an xor on a set of booleans.</p>
+     * <p/>
+     * <pre>
+     *   BooleanUtils.xor(new boolean[] { true, true })   = false
+     *   BooleanUtils.xor(new boolean[] { false, false }) = false
+     *   BooleanUtils.xor(new boolean[] { true, false })  = true
+     * </pre>
+     *
+     * @param array an array of <code>boolean<code>s
+     * @return <code>true</code> if the xor is successful.
+     * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
+     * @throws IllegalArgumentException if <code>array</code> is empty.
+     */
+    public static boolean xor( boolean[] array )
+    {
+        // Validates input
+        if ( array == null )
+        {
+            throw new IllegalArgumentException( "The Array must not be null" );
+        }
+        else if ( array.length == 0 )
+        {
+            throw new IllegalArgumentException( "Array is empty" );
+        }
+
+        // Loops through array, comparing each item
+        int trueCount = 0;
+        for ( int i = 0; i < array.length; i++ )
+        {
+            // If item is true, and trueCount is < 1, increments count
+            // Else, xor fails
+            if ( array[i] )
+            {
+                if ( trueCount < 1 )
+                {
+                    trueCount++;
+                }
+                else
+                {
+                    return false;
+                }
+            }
+        }
+
+        // Returns true if there was exactly 1 true item
+        return trueCount == 1;
+    }
+
+
+    /**
+     * <p>Performs an xor on an array of Booleans.</p>
+     * <p/>
+     * <pre>
+     *   BooleanUtils.xor(new Boolean[] { Boolean.TRUE, Boolean.TRUE })   =
+     * Boolean.FALSE
+     *   BooleanUtils.xor(new Boolean[] { Boolean.FALSE, Boolean.FALSE }) =
+     * Boolean.FALSE
+     *   BooleanUtils.xor(new Boolean[] { Boolean.TRUE, Boolean.FALSE })  =
+     * Boolean.TRUE
+     * </pre>
+     *
+     * @param array an array of <code>Boolean<code>s
+     * @return <code>true</code> if the xor is successful.
+     * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
+     * @throws IllegalArgumentException if <code>array</code> is empty.
+     * @throws IllegalArgumentException if <code>array</code> contains a
+     *                                  <code>null</code>
+     */
+    public static Boolean xor( Boolean[] array )
+    {
+        if ( array == null )
+        {
+            throw new IllegalArgumentException( "The Array must not be null" );
+        }
+        else if ( array.length == 0 )
+        {
+            throw new IllegalArgumentException( "Array is empty" );
+        }
+        boolean[] primitive = null;
+        try
+        {
+            primitive = ArrayUtils.toPrimitive( array );
+        }
+        catch ( NullPointerException ex )
+        {
+            throw new IllegalArgumentException( "The array must not contain any null elements" );
+        }
+        return ( xor( primitive ) ? Boolean.TRUE : Boolean.FALSE );
+    }
+
+}

Added: incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/Enum.java
URL: http://svn.apache.org/viewcvs/incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/Enum.java?view=auto&rev=151131
==============================================================================
--- incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/Enum.java (added)
+++ incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/Enum.java Wed Feb  2 23:18:42 2005
@@ -0,0 +1,720 @@
+/*
+ * Copyright 2002-2004 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.asn1.util;
+
+
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.*;
+
+
+/**
+ * <p>Abstract superclass for type-safe enums.</p>
+ * <p/>
+ * <p>One feature of the C programming language lacking in Java is enumerations.
+ * The C implementation based on ints was poor and open to abuse. The original
+ * Java recommendation and most of the JDK also uses int constants. It has been
+ * recognised however that a more robust type-safe class-based solution can be
+ * designed. This class follows the basic Java type-safe enumeration
+ * pattern.</p>
+ * <p/>
+ * <p><em>NOTE:</em>Due to the way in which Java ClassLoaders work, comparing
+ * Enum objects should always be done using <code>equals()</code>, not
+ * <code>==</code>. The equals() method will try == first so in most cases the
+ * effect is the same.</p>
+ * <p/>
+ * <p>Of course, if you actually want (or don't mind) Enums in different class
+ * loaders being non-equal, then you can use <code>==</code>.</p>
+ * <p/>
+ * <h4>Simple Enums</h4>
+ * <p/>
+ * <p>To use this class, it must be subclassed. For example:</p>
+ * <p/>
+ * <pre>
+ * public final class ColorEnum extends Enum {
+ *   public static final ColorEnum RED = new ColorEnum("Red");
+ *   public static final ColorEnum GREEN = new ColorEnum("Green");
+ *   public static final ColorEnum BLUE = new ColorEnum("Blue");
+ * <p/>
+ *   private ColorEnum(String color) {
+ *     super(color);
+ *   }
+ * <p/>
+ *   public static ColorEnum getEnum(String color) {
+ *     return (ColorEnum) getEnum(ColorEnum.class, color);
+ *   }
+ * <p/>
+ *   public static Map getEnumMap() {
+ *     return getEnumMap(ColorEnum.class);
+ *   }
+ * <p/>
+ *   public static List getEnumList() {
+ *     return getEnumList(ColorEnum.class);
+ *   }
+ * <p/>
+ *   public static Iterator iterator() {
+ *     return iterator(ColorEnum.class);
+ *   }
+ * }
+ * </pre>
+ * <p/>
+ * <p>As shown, each enum has a name. This can be accessed using
+ * <code>getName</code>.</p>
+ * <p/>
+ * <p>The <code>getEnum</code> and <code>iterator</code> methods are
+ * recommended. Unfortunately, Java restrictions require these to be coded as
+ * shown in each subclass. An alternative choice is to use the {@link EnumUtils}
+ * class.</p>
+ * <p/>
+ * <h4>Subclassed Enums</h4> <p>A hierarchy of Enum classes can be built. In
+ * this case, the superclass is unaffected by the addition of subclasses (as per
+ * normal Java). The subclasses may add additional Enum constants <em>of the
+ * type of the superclass</em>. The query methods on the subclass will return
+ * all of the Enum constants from the superclass and subclass.</p>
+ * <p/>
+ * <pre>
+ * public final class ExtraColorEnum extends ColorEnum {
+ *   // NOTE: Color enum declared above is final, change that to get this
+ *   // example to compile.
+ *   public static final ColorEnum YELLOW = new ExtraColorEnum("Yellow");
+ * <p/>
+ *   private ExtraColorEnum(String color) {
+ *     super(color);
+ *   }
+ * <p/>
+ *   public static ColorEnum getEnum(String color) {
+ *     return (ColorEnum) getEnum(ExtraColorEnum.class, color);
+ *   }
+ * <p/>
+ *   public static Map getEnumMap() {
+ *     return getEnumMap(ExtraColorEnum.class);
+ *   }
+ * <p/>
+ *   public static List getEnumList() {
+ *     return getEnumList(ExtraColorEnum.class);
+ *   }
+ * <p/>
+ *   public static Iterator iterator() {
+ *     return iterator(ExtraColorEnum.class);
+ *   }
+ * }
+ * </pre>
+ * <p/>
+ * <p>This example will return RED, GREEN, BLUE, YELLOW from the List and
+ * iterator methods in that order. The RED, GREEN and BLUE instances will be the
+ * same (==) as those from the superclass ColorEnum. Note that YELLOW is
+ * declared as a ColorEnum and not an ExtraColorEnum.</p>
+ * <p/>
+ * <h4>Functional Enums</h4>
+ * <p/>
+ * <p>The enums can have functionality by defining subclasses and overriding the
+ * <code>getEnumClass()</code> method:</p>
+ * <p/>
+ * <pre>
+ *   public static final OperationEnum PLUS = new PlusOperation();
+ *   private static final class PlusOperation extends OperationEnum {
+ *     private PlusOperation() {
+ *       super("Plus");
+ *     }
+ *     public int eval(int a, int b) {
+ *       return (a + b);
+ *     }
+ *   }
+ *   public static final OperationEnum MINUS = new MinusOperation();
+ *   private static final class MinusOperation extends OperationEnum {
+ *     private MinusOperation() {
+ *       super("Minus");
+ *     }
+ *     public int eval(int a, int b) {
+ *       return (a - b);
+ *     }
+ *   }
+ * <p/>
+ *   private OperationEnum(String color) {
+ *     super(color);
+ *   }
+ * <p/>
+ *   public final Class getEnumClass() {     // NOTE: new method!
+ *     return OperationEnum.class;
+ *   }
+ * <p/>
+ *   public abstract double eval(double a, double b);
+ * <p/>
+ *   public static OperationEnum getEnum(String name) {
+ *     return (OperationEnum) getEnum(OperationEnum.class, name);
+ *   }
+ * <p/>
+ *   public static Map getEnumMap() {
+ *     return getEnumMap(OperationEnum.class);
+ *   }
+ * <p/>
+ *   public static List getEnumList() {
+ *     return getEnumList(OperationEnum.class);
+ *   }
+ * <p/>
+ *   public static Iterator iterator() {
+ *     return iterator(OperationEnum.class);
+ *   }
+ * }
+ * </pre>
+ * <p>The code above will work on JDK 1.2. If JDK1.3 and later is used, the
+ * subclasses may be defined as anonymous.</p>
+ * <p/>
+ * <h4>Nested class Enums</h4>
+ * <p/>
+ * <p>Care must be taken with class loading when defining a static nested class
+ * for enums. The static nested class can be loaded without the surrounding
+ * outer class being loaded. This can result in an empty list/map/iterator being
+ * returned. One solution is to define a static block that references the outer
+ * class where the constants are defined. For example:</p>
+ * <p/>
+ * <pre>
+ * public final class Outer {
+ *   public static final BWEnum BLACK = new BWEnum("Black");
+ *   public static final BWEnum WHITE = new BWEnum("White");
+ * <p/>
+ *   // static nested enum class
+ *   public static final class BWEnum extends Enum {
+ * <p/>
+ *     static {
+ *       // explicitly reference BWEnum class to force constants to load
+ *       Object obj = Outer.BLACK;
+ *     }
+ * <p/>
+ *     // ... other methods omitted
+ *   }
+ * }
+ * </pre>
+ * <p/>
+ * <p>Although the above solves the problem, it is not recommended. The best
+ * solution is to define the constants in the enum class, and hold references in
+ * the outer class:
+ * <p/>
+ * <pre>
+ * public final class Outer {
+ *   public static final BWEnum BLACK = BWEnum.BLACK;
+ *   public static final BWEnum WHITE = BWEnum.WHITE;
+ * <p/>
+ *   // static nested enum class
+ *   public static final class BWEnum extends Enum {
+ *     // only define constants in enum classes - private if desired
+ *     private static final BWEnum BLACK = new BWEnum("Black");
+ *     private static final BWEnum WHITE = new BWEnum("White");
+ * <p/>
+ *     // ... other methods omitted
+ *   }
+ * }
+ * </pre>
+ * <p/>
+ * <p>For more details, see the 'Nested' test cases.
+ *
+ * @author Apache Avalon project
+ * @author Stephen Colebourne
+ * @author Chris Webb
+ * @author Mike Bowler
+ * @version $Id: Enum.java,v 1.28 2004/02/23 04:34:20 ggregory Exp $
+ * @since 1.0
+ */
+public abstract class Enum implements Comparable, Serializable
+{
+
+    // After discussion, the default size for HashMaps is used, as the
+    // sizing algorithm changes across the JDK versions
+    /**
+     * An empty <code>Map</code>, as JDK1.2 didn't have an empty map.
+     */
+    private static final Map EMPTY_MAP = Collections.unmodifiableMap( new HashMap( 0 ) );
+
+    /**
+     * <code>Map</code>, key of class name, value of <code>Entry</code>.
+     */
+    private static final Map cEnumClasses = new HashMap();
+
+    /**
+     * 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.
+     *
+     * @since 2.0
+     */
+    protected transient String iToString = null;
+
+    /**
+     * <p>Enable the iterator to retain the source code order.</p>
+     */
+    private static class Entry
+    {
+        /**
+         * Map of Enum name to Enum.
+         */
+        final Map map = new HashMap();
+        /**
+         * Map of Enum name to Enum.
+         */
+        final Map unmodifiableMap = Collections.unmodifiableMap( map );
+        /**
+         * List of Enums in source code order.
+         */
+        final List list = new ArrayList( 25 );
+        /**
+         * Map of Enum name to Enum.
+         */
+        final List unmodifiableList = Collections.unmodifiableList( list );
+
+
+        /**
+         * <p>Restrictive constructor.</p>
+         */
+        private Entry()
+        {
+        }
+    }
+
+
+    /**
+     * <p>Constructor to add a new named item to the enumeration.</p>
+     *
+     * @param name the name of the enum object, must not be empty or
+     *             <code>null</code>
+     * @throws IllegalArgumentException if the name is <code>null</code> or an
+     *                                  empty string
+     * @throws IllegalArgumentException if the getEnumClass() method returns a
+     *                                  null or invalid Class
+     */
+    protected Enum( String name )
+    {
+        super();
+
+        init( name );
+
+        iName = name;
+        iHashCode = 7 + getEnumClass().hashCode() + 3 * name.hashCode();
+
+        // cannot create toString here as subclasses may want to include other data
+    }
+
+
+    private static boolean isEmpty( String str )
+    {
+        return ( str == null || str.length() == 0 );
+    }
+
+
+    /**
+     * Initializes the enumeration.
+     *
+     * @param name the enum name
+     * @throws IllegalArgumentException if the name is null or empty or
+     *                                  duplicate
+     * @throws IllegalArgumentException if the enumClass is null or invalid
+     */
+    private void init( String name )
+    {
+        if ( isEmpty( name ) )
+        {
+            throw new IllegalArgumentException( "The Enum name must not be empty or null" );
+        }
+
+        Class enumClass = getEnumClass();
+
+        if ( enumClass == null )
+        {
+            throw new IllegalArgumentException( "getEnumClass() must not be null" );
+        }
+
+        Class cls = getClass();
+
+        boolean ok = false;
+
+        while ( cls != null && cls != Enum.class && cls != ValuedEnum.class )
+        {
+            if ( cls == enumClass )
+            {
+                ok = true;
+
+                break;
+            }
+
+            cls = cls.getSuperclass();
+        }
+
+        if ( ok == false )
+        {
+            throw new IllegalArgumentException( "getEnumClass() must return a superclass of this class" );
+        }
+
+        // create entry
+        Entry entry = ( Entry ) cEnumClasses.get( enumClass );
+
+        if ( entry == null )
+        {
+            entry = createEntry( enumClass );
+
+            cEnumClasses.put( enumClass, entry );
+        }
+        if ( entry.map.containsKey( name ) )
+        {
+            throw new IllegalArgumentException( "The Enum name must be unique, '" + name + "' has already been added" );
+        }
+
+        entry.map.put( name, this );
+
+        entry.list.add( this );
+    }
+
+
+    /**
+     * <p>Handle the deserialization of the class to ensure that multiple copies
+     * are not wastefully created, or illegal enum types created.</p>
+     *
+     * @return the resolved object
+     */
+    protected Object readResolve()
+    {
+        Entry entry = ( Entry ) cEnumClasses.get( getEnumClass() );
+
+        if ( entry == null )
+        {
+            return null;
+        }
+
+        return ( Enum ) entry.map.get( getName() );
+    }
+    
+    //--------------------------------------------------------------------------------
+
+    /**
+     * <p>Gets an <code>Enum</code> object by class and name.</p>
+     *
+     * @param enumClass the class of the Enum to get, must not be
+     *                  <code>null</code>
+     * @param name      the name of the <code>Enum</code> to get, may be
+     *                  <code>null</code>
+     * @return the enum object, or null if the enum does not exist
+     * @throws IllegalArgumentException if the enum class is <code>null</code>
+     */
+    protected static Enum getEnum( Class enumClass, String name )
+    {
+        Entry entry = getEntry( enumClass );
+
+        if ( entry == null )
+        {
+            return null;
+        }
+
+        return ( Enum ) entry.map.get( name );
+    }
+
+
+    /**
+     * <p>Gets the <code>Map</code> of <code>Enum</code> objects by name using
+     * the <code>Enum</code> class.</p>
+     * <p/>
+     * <p>If the requested class has no enum objects an empty <code>Map</code>
+     * is returned.</p>
+     *
+     * @param enumClass the class of the <code>Enum</code> to get, must not be
+     *                  <code>null</code>
+     * @return the enum object Map
+     * @throws IllegalArgumentException if the enum class is <code>null</code>
+     * @throws IllegalArgumentException if the enum class is not a subclass of
+     *                                  Enum
+     */
+    protected static Map getEnumMap( Class enumClass )
+    {
+        Entry entry = getEntry( enumClass );
+
+        if ( entry == null )
+        {
+            return EMPTY_MAP;
+        }
+
+        return entry.unmodifiableMap;
+    }
+
+
+    /**
+     * <p>Gets the <code>List</code> of <code>Enum</code> objects using the
+     * <code>Enum</code> class.</p>
+     * <p/>
+     * <p>The list is in the order that the objects were created (source code
+     * order). If the requested class has no enum objects an empty
+     * <code>List</code> is returned.</p>
+     *
+     * @param enumClass the class of the <code>Enum</code> to get, must not be
+     *                  <code>null</code>
+     * @return the enum object Map
+     * @throws IllegalArgumentException if the enum class is <code>null</code>
+     * @throws IllegalArgumentException if the enum class is not a subclass of
+     *                                  Enum
+     */
+    protected static List getEnumList( Class enumClass )
+    {
+        Entry entry = getEntry( enumClass );
+
+        if ( entry == null )
+        {
+            return Collections.EMPTY_LIST;
+        }
+
+        return entry.unmodifiableList;
+    }
+
+
+    /**
+     * <p>Gets an <code>Iterator</code> over the <code>Enum</code> objects in an
+     * <code>Enum</code> class.</p>
+     * <p/>
+     * <p>The <code>Iterator</code> is in the order that the objects were
+     * created (source code order). If the requested class has no enum objects
+     * an empty <code>Iterator</code> is returned.</p>
+     *
+     * @param enumClass the class of the <code>Enum</code> to get, must not be
+     *                  <code>null</code>
+     * @return an iterator of the Enum objects
+     * @throws IllegalArgumentException if the enum class is <code>null</code>
+     * @throws IllegalArgumentException if the enum class is not a subclass of
+     *                                  Enum
+     */
+    protected static Iterator iterator( Class enumClass )
+    {
+        return Enum.getEnumList( enumClass ).iterator();
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Gets an <code>Entry</code> from the map of Enums.</p>
+     *
+     * @param enumClass the class of the <code>Enum</code> 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 );
+
+        return entry;
+    }
+
+
+    /**
+     * <p>Creates an <code>Entry</code> for storing the Enums.</p>
+     * <p/>
+     * <p>This accounts for subclassed Enums.</p>
+     *
+     * @param enumClass the class of the <code>Enum</code> to get
+     * @return the enum entry
+     */
+    private static Entry createEntry( Class enumClass )
+    {
+        Entry entry = new Entry();
+
+        Class cls = enumClass.getSuperclass();
+
+        while ( cls != null && cls != Enum.class && cls != ValuedEnum.class )
+        {
+            Entry loopEntry = ( Entry ) cEnumClasses.get( cls );
+
+            if ( loopEntry != null )
+            {
+                entry.list.addAll( loopEntry.list );
+
+                entry.map.putAll( loopEntry.map );
+
+                break;  // stop here, as this will already have had superclasses added
+            }
+            cls = cls.getSuperclass();
+        }
+
+        return entry;
+    }
+
+
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Retrieve the name of this Enum item, set in the constructor.</p>
+     *
+     * @return the <code>String</code> name of this Enum item
+     */
+    public final String getName()
+    {
+        return iName;
+    }
+
+
+    /**
+     * <p>Retrieves the Class of this Enum item, set in the constructor.</p>
+     * <p/>
+     * <p>This is normally the same as <code>getClass()</code>, but for advanced
+     * Enums may be different. If overridden, it must return a constant
+     * value.</p>
+     *
+     * @return the <code>Class</code> of the enum
+     * @since 2.0
+     */
+    public Class getEnumClass()
+    {
+        return getClass();
+    }
+
+
+    /**
+     * <p>Tests for equality.</p>
+     * <p/>
+     * <p>Two Enum objects are considered equal if they have the same class
+     * names and the same names. Identity is tested for first, so this method
+     * usually runs fast.</p>
+     * <p/>
+     * <p>If the parameter is in a different class loader than this instance,
+     * reflection is used to compare the names.</p>
+     *
+     * @param other the other object to compare for equality
+     * @return <code>true</code> if the Enums are equal
+     */
+    public final boolean equals( Object other )
+    {
+        if ( other == this )
+        {
+            return true;
+        }
+        else if ( other == null )
+        {
+            return false;
+        }
+        else if ( other.getClass() == this.getClass() )
+        {
+            // Ok to do a class cast to Enum here since the test above
+            // guarantee both
+            // classes are in the same class loader.
+            return iName.equals( ( ( Enum ) other ).iName );
+        }
+        else
+        {
+            // This and other are in different class loaders, we must use reflection.
+            try
+            {
+                Method mth = other.getClass().getMethod( "getName", null );
+
+                String name = ( String ) mth.invoke( other, null );
+
+                return iName.equals( name );
+            }
+            catch ( NoSuchMethodException e )
+            {
+                // ignore - should never happen
+            }
+            catch ( IllegalAccessException e )
+            {
+                // ignore - should never happen
+            }
+            catch ( InvocationTargetException e )
+            {
+                // ignore - should never happen
+            }
+
+            return false;
+        }
+    }
+
+
+    /**
+     * <p>Returns a suitable hashCode for the enumeration.</p>
+     *
+     * @return a hashcode based on the name
+     */
+    public final int hashCode()
+    {
+        return iHashCode;
+    }
+
+
+    /**
+     * <p>Tests for order.</p>
+     * <p/>
+     * <p>The default ordering is alphabetic by name, but this can be overridden
+     * by subclasses.</p>
+     *
+     * @param other the other object to compare to
+     * @return -ve if this is less than the other object, +ve if greater than,
+     *         <code>0</code> of equal
+     * @throws ClassCastException   if other is not an Enum
+     * @throws NullPointerException if other is <code>null</code>
+     * @see java.lang.Comparable#compareTo(Object)
+     */
+    public int compareTo( Object other )
+    {
+        if ( other == this )
+        {
+            return 0;
+        }
+
+        return iName.compareTo( ( ( Enum ) other ).iName );
+    }
+
+
+    /**
+     * <p>Human readable description of this Enum item.</p>
+     *
+     * @return String in the form <code>type[name]</code>, for example:
+     *         <code>Color[Red]</code>. Note that the package name is stripped
+     *         from the type name.
+     */
+    public String toString()
+    {
+        if ( iToString == null )
+        {
+            String shortName = getShortName( getEnumClass() );
+
+            iToString = shortName + "[" + getName() + "]";
+        }
+        return iToString;
+    }
+
+
+    protected String getShortName( Class c )
+    {
+        String[] comps = c.getName().split( "." );
+
+        if ( comps.length - 1 > 0 )
+        {
+            return comps[comps.length - 1];
+        }
+
+        if ( comps.length == 1 )
+        {
+            return comps[0];
+        }
+
+        return "ENUM";
+    }
+}

Added: incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/EnumUtils.java
URL: http://svn.apache.org/viewcvs/incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/EnumUtils.java?view=auto&rev=151131
==============================================================================
--- incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/EnumUtils.java (added)
+++ incubator/directory/asn1/branches/rewrite/ber/src/java/org/apache/asn1/util/EnumUtils.java Wed Feb  2 23:18:42 2005
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2002-2004 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.asn1.util;
+
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * <p>Utility class for accessing and manipulating {@link Enum}s.</p>
+ *
+ * @author Stephen Colebourne
+ * @author Gary Gregory
+ * @version $Id: EnumUtils.java,v 1.12 2004/02/23 04:34:20 ggregory Exp $
+ * @see Enum
+ * @see ValuedEnum
+ * @since 1.0
+ */
+public class EnumUtils
+{
+
+    /**
+     * Public constructor. This class should not normally be instantiated.
+     *
+     * @since 2.0
+     */
+    public EnumUtils()
+    {
+    }
+
+
+    /**
+     * <p>Gets an <code>Enum</code> object by class and name.</p>
+     *
+     * @param enumClass the class of the <code>Enum</code> to get
+     * @param name      the name of the Enum to get, may be <code>null</code>
+     * @return the enum object
+     * @throws IllegalArgumentException if the enum class is <code>null</code>
+     */
+    public static Enum getEnum( Class enumClass, String name )
+    {
+        return Enum.getEnum( enumClass, name );
+    }
+
+
+    /**
+     * <p>Gets a <code>ValuedEnum</code> object by class and value.</p>
+     *
+     * @param enumClass the class of the <code>Enum</code> to get
+     * @param value     the value of the <code>Enum</code> to get
+     * @return the enum object, or null if the enum does not exist
+     * @throws IllegalArgumentException if the enum class is <code>null</code>
+     */
+    public static ValuedEnum getEnum( Class enumClass, int value )
+    {
+        return ( ValuedEnum ) ValuedEnum.getEnum( enumClass, value );
+    }
+
+
+    /**
+     * <p>Gets the <code>Map</code> of <code>Enum</code> objects by name using
+     * the <code>Enum</code> class.</p>
+     * <p/>
+     * <p>If the requested class has no enum objects an empty <code>Map</code>
+     * is returned. The <code>Map</code> is unmodifiable.</p>
+     *
+     * @param enumClass the class of the <code>Enum</code> to get
+     * @return the enum object Map
+     * @throws IllegalArgumentException if the enum class is <code>null</code>
+     * @throws IllegalArgumentException if the enum class is not a subclass of
+     *                                  <code>Enum</code>
+     */
+    public static Map getEnumMap( Class enumClass )
+    {
+        return Enum.getEnumMap( enumClass );
+    }
+
+
+    /**
+     * <p>Gets the <code>List</code> of <code>Enum</code> objects using the
+     * <code>Enum</code> class.</p>
+     * <p/>
+     * <p>The list is in the order that the objects were created (source code
+     * order).</p>
+     * <p/>
+     * <p>If the requested class has no enum objects an empty <code>List</code>
+     * is returned. The <code>List</code> is unmodifiable.</p>
+     *
+     * @param enumClass the class of the Enum to get
+     * @return the enum object Map
+     * @throws IllegalArgumentException if the enum class is <code>null</code>
+     * @throws IllegalArgumentException if the enum class is not a subclass of
+     *                                  <code>Enum</code>
+     */
+    public static List getEnumList( Class enumClass )
+    {
+        return Enum.getEnumList( enumClass );
+    }
+
+
+    /**
+     * <p>Gets an <code>Iterator</code> over the <code>Enum</code> objects in an
+     * <code>Enum</code> class.</p>
+     * <p/>
+     * <p>The iterator is in the order that the objects were created (source
+     * code order).</p>
+     * <p/>
+     * <p>If the requested class has no enum objects an empty
+     * <code>Iterator</code> is returned. The <code>Iterator</code> is
+     * unmodifiable.</p>
+     *
+     * @param enumClass the class of the <code>Enum</code> to get
+     * @return an <code>Iterator</code> of the <code>Enum</code> objects
+     * @throws IllegalArgumentException if the enum class is <code>null</code>
+     * @throws IllegalArgumentException if the enum class is not a subclass of
+     *                                  <code>Enum</code>
+     */
+    public static Iterator iterator( Class enumClass )
+    {
+        return Enum.getEnumList( enumClass ).iterator();
+    }
+
+}