ggregory    2004/02/14 16:51:38

  Modified:    lang/src/test/org/apache/commons/lang ClassUtilsTest.java
               lang/src/test/org/apache/commons/lang/enum EnumTest.java
               lang/src/java/org/apache/commons/lang ClassUtils.java
  Log:
  

  PR: Bugzilla Bug 26943 [patch] Class and Package Comparators for ClassUtils

  Submitted by: alban.peignier

  Reviewed by:  Gary Gregory

  
  Revision  Changes    Path
  1.8       +101 -1    
jakarta-commons/lang/src/test/org/apache/commons/lang/ClassUtilsTest.java
  
  Index: ClassUtilsTest.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons/lang/src/test/org/apache/commons/lang/ClassUtilsTest.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- ClassUtilsTest.java       23 Oct 2003 21:03:44 -0000      1.7
  +++ ClassUtilsTest.java       15 Feb 2004 00:51:37 -0000      1.8
  @@ -54,8 +54,12 @@
   package org.apache.commons.lang;
   
   import java.lang.reflect.Constructor;
  +import java.lang.reflect.InvocationTargetException;
  +import java.lang.reflect.Method;
   import java.lang.reflect.Modifier;
  +import java.net.URLClassLoader;
   import java.util.ArrayList;
  +import java.util.Comparator;
   import java.util.List;
   import java.util.Map;
   
  @@ -63,11 +67,13 @@
   import junit.framework.TestCase;
   import junit.framework.TestSuite;
   import junit.textui.TestRunner;
  +import org.apache.commons.lang.enum.ColorEnum;
   
   /**
    * Unit tests [EMAIL PROTECTED] org.apache.commons.lang.ClassUtils}.
    *
    * @author Stephen Colebourne
  + * @author Gary D. Gregory
    * @version $Id$
    */
   public class ClassUtilsTest extends TestCase {
  @@ -409,6 +415,100 @@
           // test null     
           assertNull("null -> null",
               ClassUtils.primitiveToWrapper(null));
  +    }
  +    
  +    public void testClassComparator() {
  +     Comparator comparator = ClassUtils.CLASS_NAME_COMPARATOR;
  +     Class smallClass = java.lang.Boolean.class;
  +     Class bigClass =  java.util.Set.class;
  +     
  +             assertTrue(comparator.compare(smallClass, smallClass) == 0);
  +             assertTrue(comparator.compare(bigClass, smallClass) > 0);
  +             assertTrue(comparator.compare(smallClass, bigClass) < 0);
  +             
  +             assertTrue(comparator.compare(smallClass, null) > 0);
  +             assertTrue(comparator.compare(null, smallClass) < 0);
  +
  +        assertComparatorContract(comparator, smallClass, smallClass);
  +        assertComparatorContract(comparator, bigClass, bigClass);
  +        assertComparatorContract(comparator, smallClass, bigClass);
  +    }
  +
  +    public void testPackageComparator() {
  +        Comparator comparator = ClassUtils.PACKAGE_NAME_COMPARATOR;
  +        Package smallPackage = java.lang.Boolean.class.getPackage();
  +        Package bigPackage =  java.util.Set.class.getPackage();
  +        
  +        assertTrue(comparator.compare(smallPackage, smallPackage) == 0);
  +        assertTrue(comparator.compare(bigPackage, smallPackage) > 0);
  +        assertTrue(comparator.compare(smallPackage, bigPackage) < 0);
  +        
  +        assertTrue(comparator.compare(smallPackage, null) > 0);
  +        assertTrue(comparator.compare(null, smallPackage) < 0);
  +
  +        assertComparatorContract(comparator, smallPackage, smallPackage);
  +        assertComparatorContract(comparator, bigPackage, bigPackage);
  +        assertComparatorContract(comparator, smallPackage, bigPackage);
  +    }
  +
  +    public void testPackageNameComparatorWithDifferentClassLoaders() throws 
SecurityException, IllegalArgumentException, ClassNotFoundException {
  +        Comparator comparator = ClassUtils.PACKAGE_NAME_COMPARATOR;
  +        Package p1 = java.lang.Boolean.class.getPackage();
  +        Package p2 = java.util.Set.class.getPackage();
  +        ClassLoader classLoader = newSystemClassLoader();
  +        Object p1Other = this.getPackage(classLoader, "java.lang.Boolean");
  +        Object p2Other = this.getPackage(classLoader, "java.util.Set");
  +        // all here
  +        assertComparatorContract(comparator, p1, p1);
  +        assertComparatorContract(comparator, p2, p2);
  +        assertComparatorContract(comparator, p1, p2);
  +        // all other
  +        assertComparatorContract(comparator, p1Other, p1Other);
  +        assertComparatorContract(comparator, p2Other, p2Other);
  +        assertComparatorContract(comparator, p1Other, p2Other);
  +        // p1 and p1Other
  +        assertComparatorContract(comparator, p1, p1Other);
  +        assertComparatorContract(comparator, p2, p2);
  +        assertComparatorContract(comparator, p1Other, p2);
  +        // p2 and p2Other
  +        assertComparatorContract(comparator, p1, p1);
  +        assertComparatorContract(comparator, p2, p2Other);
  +        assertComparatorContract(comparator, p1, p2Other);
  +    }
  +    
  +    Object getPackage(ClassLoader classLoader, String className) throws 
ClassNotFoundException, SecurityException,
  +            IllegalArgumentException {
  +        // Sanity check:
  +        assertNotNull(Package.getPackage("java.lang"));
  +        Package.getPackage("java.lang").equals(Package.getPackage("java.lang"));
  +        // set up:
  +        assertNotNull(classLoader);
  +        Class otherClass = classLoader.loadClass(className);
  +        assertNotNull(otherClass);
  +        Object otherPackage = otherClass.getPackage();
  +        assertNotNull(otherPackage);
  +        return otherPackage;
  +    }
  +
  +    /**
  +     * The ordering imposed by a Comparator c on a set of elements S is said to
  +     * be consistent with equals if and only if (compare((Object)e1,
  +     * (Object)e2)==0) has the same boolean value as e1.equals((Object)e2) for
  +     * every e1 and e2 in S.
  +     * 
  +     * http://java.sun.com/j2se/1.3/docs/api/java/util/Comparator.html
  +     */
  +    public void assertComparatorContract(Comparator comparator, Object e1, Object 
e2) {
  +        assertEquals(comparator.compare(e1, e2) == 0, e1.equals(e2));
  +    }
  +
  +    public static ClassLoader newSystemClassLoader() throws  SecurityException, 
IllegalArgumentException {
  +        ClassLoader scl = ClassLoader.getSystemClassLoader();
  +        if (!(scl instanceof URLClassLoader)) {
  +            fail("Need a better test set up.");
  +        }
  +        URLClassLoader urlScl = (URLClassLoader)scl;
  +        return URLClassLoader.newInstance(urlScl.getURLs(), null);
       }
       
   //    public static List getAssignableFrom(List classes, Class superclass) {
  
  
  
  1.16      +65 -26    
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.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- EnumTest.java     13 Feb 2004 23:17:45 -0000      1.15
  +++ EnumTest.java     15 Feb 2004 00:51:38 -0000      1.16
  @@ -55,7 +55,6 @@
   
   import java.lang.reflect.InvocationTargetException;
   import java.lang.reflect.Method;
  -import java.net.URLClassLoader;
   import java.util.ArrayList;
   import java.util.HashMap;
   import java.util.Iterator;
  @@ -66,13 +65,14 @@
   import junit.framework.Test;
   import junit.framework.TestCase;
   import junit.framework.TestSuite;
  -
  +import org.apache.commons.lang.ClassUtilsTest;
   import org.apache.commons.lang.SerializationUtils;
   
   /**
    * Test cases for the [EMAIL PROTECTED] Enum} class.
    *
    * @author Stephen Colebourne
  + * @author Gary D. Gregory
    * @version $Id$
    */
   
  @@ -473,18 +473,50 @@
           // the SAME class as the getEnumList(). The references in the outer class
           // are just extra references.
       }
  +    
  +    public void testColorEnumEqualsWithDifferentClassLoaders() throws 
SecurityException, IllegalArgumentException,
  +            ClassNotFoundException, NoSuchMethodException, IllegalAccessException, 
InvocationTargetException {
  +        this.testEqualsTrueWithDifferentClassLoaders(ColorEnum.BLUE);
  +        this.testEqualsTrueWithDifferentClassLoaders(ColorEnum.GREEN);
  +        this.testEqualsTrueWithDifferentClassLoaders(ColorEnum.RED);
  +    }
  +
  +    void testEqualsTrueWithDifferentClassLoaders(ColorEnum colorEnum) throws 
ClassNotFoundException, SecurityException,
  +            NoSuchMethodException, IllegalArgumentException, 
IllegalAccessException, InvocationTargetException {
  +        // Sanity checks:
  +        assertTrue(colorEnum.equals(colorEnum));
  +        assertNotNull(ColorEnum.class.getClassLoader());
  +        // set up:
  +        ClassLoader classLoader = ClassUtilsTest.newSystemClassLoader();
  +        Object enumObjectFromOtherClassLoader = this.getColorEnum(classLoader, 
colorEnum.getName());
  +        // the real test, part 1.
  +        try {
  +            ColorEnum testCase = (ColorEnum) enumObjectFromOtherClassLoader;
  +            fail("Should have thrown a ClassCastException for " + testCase);
  +        } catch (ClassCastException e) {
  +            // normal.
  +        }
  +        // the real test, part 2.
  +        assertEquals("The two objects should match even though they are from 
different class loaders", colorEnum,
  +                enumObjectFromOtherClassLoader);
  +        // the real test, part 3.
  +        int falseCount = 0;
  +        for (Iterator iter = ColorEnum.iterator(); iter.hasNext();) {
  +            ColorEnum element = (ColorEnum) iter.next();
  +            if (!colorEnum.equals(element)) {
  +                falseCount++;
  +                assertFalse(enumObjectFromOtherClassLoader.equals(element));
  +            }
  +        }
  +        assertEquals(ColorEnum.getEnumList().size() - 1, falseCount);
  +    }
   
  -    public void testEqualsWithDifferentClassLoaders() throws 
ClassNotFoundException, SecurityException, NoSuchMethodException, 
IllegalArgumentException, IllegalAccessException, InvocationTargetException {
  +    Object getColorEnum(ClassLoader classLoader, String color) throws 
ClassNotFoundException, SecurityException,
  +            NoSuchMethodException, IllegalArgumentException, 
IllegalAccessException, InvocationTargetException {
           // Sanity check:
           ColorEnum.RED.equals(ColorEnum.RED);
           assertNotNull(ColorEnum.class.getClassLoader());
           // set up:
  -        ClassLoader scl = ClassLoader.getSystemClassLoader();
  -        if (!(scl instanceof URLClassLoader)) {
  -            fail("Need a better test set up.");
  -        }
  -        URLClassLoader urlScl = (URLClassLoader)scl;
  -        ClassLoader classLoader = URLClassLoader.newInstance(urlScl.getURLs(), 
null);
           assertNotNull(classLoader);
           assertFalse(classLoader.equals(ColorEnum.class.getClassLoader()));
           Class otherColorEnumClass = 
classLoader.loadClass("org.apache.commons.lang.enum.ColorEnum");
  @@ -492,24 +524,31 @@
           assertNotNull(otherColorEnumClass.getClassLoader());
           assertTrue(classLoader.equals(otherColorEnumClass.getClassLoader()));
           
assertFalse(otherColorEnumClass.getClassLoader().equals(ColorEnum.class.getClassLoader()));
  -        Method method = otherColorEnumClass.getMethod("getEnum", new 
Class[]{String.class});        
  -        Object enumObject = method.invoke(otherColorEnumClass, new Object[]{"Red"});
  +        Method method = otherColorEnumClass.getMethod("getEnum", new 
Class[]{String.class});
  +        Object enumObject = method.invoke(otherColorEnumClass, new Object[]{color});
           assertNotNull(enumObject);
  -        // the real test, part 1.
  -        try {
  -            ColorEnum testCase = (ColorEnum)enumObject;
  -            fail("Should have thrown a ClassCastException");
  -        } catch (ClassCastException e) {
  -            // normal.
  -        }
  -        // the real test, part 2.
  -        assertEquals("The two objects should match even though they are from 
different class loaders", ColorEnum.RED, enumObject);
  +        assertFalse(ColorEnum.class.equals(enumObject.getClass()));
  +        assertFalse(ColorEnum.class == enumObject.getClass());
  +        return enumObject;
       }
  -    
  +
       public void testEqualsToWrongInstance() {
  -        assertEquals(false, ColorEnum.RED.equals("test"));
  -        assertEquals(false, ColorEnum.RED.equals(new Integer(1)));
  -        assertEquals(false, ColorEnum.RED.equals(new Boolean(true)));
  -        assertEquals(false, ColorEnum.RED.equals(new StringBuffer("test")));
  +        for (Iterator iter = ColorEnum.iterator(); iter.hasNext();) {
  +            ColorEnum element = (ColorEnum) iter.next();
  +            this.testEqualsToWrongInstance(element);
  +        }
  +    }
  +
  +    void testEqualsToWrongInstance(ColorEnum colorEnum) {
  +        assertEquals(false, colorEnum.equals("test"));
  +        assertEquals(false, colorEnum.equals(new Integer(1)));
  +        assertEquals(false, colorEnum.equals(new Boolean(true)));
  +        assertEquals(false, colorEnum.equals(new StringBuffer("test")));
  +        assertEquals(false, colorEnum.equals(new Object()));
  +        assertEquals(false, colorEnum.equals(null));
  +        assertEquals(false, colorEnum.equals(""));
  +        assertEquals(false, colorEnum.equals(ColorEnum.getEnum(null)));
  +        assertEquals(false, colorEnum.equals(ColorEnum.getEnum("")));
  +        assertEquals(false, colorEnum.equals(ColorEnum.getEnum("This ColorEnum does 
not exist.")));
       }
   }
  
  
  
  1.24      +54 -5     
jakarta-commons/lang/src/java/org/apache/commons/lang/ClassUtils.java
  
  Index: ClassUtils.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons/lang/src/java/org/apache/commons/lang/ClassUtils.java,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -u -r1.23 -r1.24
  --- ClassUtils.java   23 Oct 2003 21:03:43 -0000      1.23
  +++ ClassUtils.java   15 Feb 2004 00:51:38 -0000      1.24
  @@ -54,6 +54,7 @@
   package org.apache.commons.lang;
   
   import java.util.ArrayList;
  +import java.util.Comparator;
   import java.util.HashMap;
   import java.util.Iterator;
   import java.util.List;
  @@ -73,22 +74,22 @@
   public class ClassUtils {
   
       /**
  -     * <p>The package separator character: <code>&#x2e;</code>.</p>
  +     * <p>The package separator character: <code>'&#x2e;' == [EMAIL 
PROTECTED]</code>.</p>
        */
       public static final char PACKAGE_SEPARATOR_CHAR = '.';
       
       /**
  -     * <p>The package separator String: <code>&#x2e;</code>.</p>
  +     * <p>The package separator String: <code>"&#x2e;"</code>.</p>
        */
       public static final String PACKAGE_SEPARATOR = 
String.valueOf(PACKAGE_SEPARATOR_CHAR);
       
       /**
  -     * <p>The inner class separator character: <code>$</code>.</p>
  +     * <p>The inner class separator character: <code>'$' == [EMAIL 
PROTECTED]</code>.</p>
        */
       public static final char INNER_CLASS_SEPARATOR_CHAR = '$';
       
       /**
  -     * <p>The inner class separator String: <code>$</code>.</p>
  +     * <p>The inner class separator String: <code>"$"</code>.</p>
        */
       public static final String INNER_CLASS_SEPARATOR = 
String.valueOf(INNER_CLASS_SEPARATOR_CHAR);
       
  @@ -563,5 +564,53 @@
           }
           return (cls.getName().indexOf(INNER_CLASS_SEPARATOR_CHAR) >= 0);
       }
  +    
  +    /**
  +     * Compares two <code>Class</code>s by name.
  +     */
  +    public static final Comparator CLASS_NAME_COMPARATOR = new Comparator() {
  +        /**
  +         * Compares two <code>Class</code>s by name.
  +         * 
  +         * @throws ClassCastException
  +         *                  If <code>o1</code> or <code>o2</code> are not 
<code>Class</code>
  +         *                  instances.
  +         */
  +        public int compare(Object o1, Object o2) {
  +            Class class1 = (Class) o1;
  +            Class class2 = (Class) o2;
  +            if (class1 == null) {
  +                return class2 == null ? 0 : -1;
  +            }
  +            if (class2 == null) {
  +                return 1;
  +            }
  +            return class1.getName().compareTo(class2.getName());
  +        }
  +    };
  +
  +    /**
  +     * Compares two <code>Package</code>s by name.
  +     */
  +    public static final Comparator PACKAGE_NAME_COMPARATOR = new Comparator() {
  +        /**
  +         * Compares two <code>Package</code>s by name.
  +         * 
  +         * @throws ClassCastException
  +         *                  If <code>o1</code> or <code>o2</code> are not 
<code>Package</code>
  +         *                  instances.
  +         */
  +        public int compare(Object o1, Object o2) {
  +            Package package1 = (Package) o1;
  +            Package package2 = (Package) o2;
  +            if (package1 == null) {
  +                return package2 == null ? 0 : -1;
  +            }
  +            if (package2 == null) {
  +                return 1;
  +            }
  +            return package1.getName().compareTo(package2.getName());
  +        }
  +    };
       
   }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to