commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bay...@apache.org
Subject svn commit: r397016 - in /jakarta/commons/proper/lang/trunk/src: java/org/apache/commons/lang/builder/CompareToBuilder.java test/org/apache/commons/lang/builder/CompareToBuilderTest.java
Date Tue, 25 Apr 2006 23:15:09 GMT
Author: bayard
Date: Tue Apr 25 16:15:05 2006
New Revision: 397016

URL: http://svn.apache.org/viewcvs?rev=397016&view=rev
Log:
Applying Pete Gieser's enhancement for the CompareToBuilder - a clone of the EqualsBuilder
and HashCodeBuilder fixes previously applied. Bugzilla issue #39398

Modified:
    jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/builder/CompareToBuilder.java
    jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/builder/CompareToBuilderTest.java

Modified: jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/builder/CompareToBuilder.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/builder/CompareToBuilder.java?rev=397016&r1=397015&r2=397016&view=diff
==============================================================================
--- jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/builder/CompareToBuilder.java
(original)
+++ jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/builder/CompareToBuilder.java
Tue Apr 25 16:15:05 2006
@@ -18,7 +18,10 @@
 import java.lang.reflect.AccessibleObject;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.Comparator;
+import java.util.List;
 
 import org.apache.commons.lang.math.NumberUtils;
 
@@ -134,7 +137,7 @@
      *  with <code>lhs</code>
      */
     public static int reflectionCompare(Object lhs, Object rhs) {
-        return reflectionCompare(lhs, rhs, false, null);
+        return reflectionCompare(lhs, rhs, false, null, null);
     }
 
     /**
@@ -166,7 +169,39 @@
      *  with <code>lhs</code>
      */
     public static int reflectionCompare(Object lhs, Object rhs, boolean compareTransients)
{
-        return reflectionCompare(lhs, rhs, compareTransients, null);
+        return reflectionCompare(lhs, rhs, compareTransients, null, null);
+    }
+
+    /**
+     * <p>Compares two <code>Object</code>s via reflection.</p>
+     *
+     * <p>Fields can be private, thus <code>AccessibleObject.setAccessible</code>
+     * is used to bypass normal access control checks. This will fail under a 
+     * security manager unless the appropriate permissions are set.</p>
+     *
+     * <ul>
+     * <li>Static fields will not be compared</li>
+     * <li>If <code>compareTransients</code> is <code>true</code>,
+     *     compares transient members.  Otherwise ignores them, as they
+     *     are likely derived fields.</li>
+     * <li>Superclass fields will be compared</li>
+     * </ul>
+     *
+     * <p>If both <code>lhs</code> and <code>rhs</code> are
<code>null</code>,
+     * they are considered equal.</p>
+     *
+     * @param lhs  left-hand object
+     * @param rhs  right-hand object
+     * @param excludeFields  fields to exclude
+     * @return a negative integer, zero, or a positive integer as <code>lhs</code>
+     *  is less than, equal to, or greater than <code>rhs</code>
+     * @throws NullPointerException  if either <code>lhs</code> or <code>rhs</code>
+     *  (but not both) is <code>null</code>
+     * @throws ClassCastException  if <code>rhs</code> is not assignment-compatible
+     *  with <code>lhs</code>
+     */
+    public static int reflectionCompare(Object lhs, Object rhs, String[] excludeFields) {
+        return reflectionCompare(lhs, rhs, false, null, excludeFields);
     }
 
     /**
@@ -200,7 +235,7 @@
      *  with <code>lhs</code>
      * @since 2.0
      */
-    public static int reflectionCompare(Object lhs, Object rhs, boolean compareTransients,
Class reflectUpToClass) {
+    public static int reflectionCompare(Object lhs, Object rhs, boolean compareTransients,
Class reflectUpToClass, String[] excludeFields) {
         if (lhs == rhs) {
             return 0;
         }
@@ -212,10 +247,10 @@
             throw new ClassCastException();
         }
         CompareToBuilder compareToBuilder = new CompareToBuilder();
-        reflectionAppend(lhs, rhs, lhsClazz, compareToBuilder, compareTransients);
+        reflectionAppend(lhs, rhs, lhsClazz, compareToBuilder, compareTransients, excludeFields);
         while (lhsClazz.getSuperclass() != null && lhsClazz != reflectUpToClass)
{
             lhsClazz = lhsClazz.getSuperclass();
-            reflectionAppend(lhs, rhs, lhsClazz, compareToBuilder, compareTransients);
+            reflectionAppend(lhs, rhs, lhsClazz, compareToBuilder, compareTransients, excludeFields);
         }
         return compareToBuilder.toComparison();
     }
@@ -229,19 +264,23 @@
      * @param clazz  <code>Class</code> that defines fields to be compared
      * @param builder  <code>CompareToBuilder</code> to append to
      * @param useTransients  whether to compare transient fields
+     * @param excludeFields  fields to exclude
      */
     private static void reflectionAppend(
         Object lhs,
         Object rhs,
         Class clazz,
         CompareToBuilder builder,
-        boolean useTransients) {
+        boolean useTransients,
+        String[] excludeFields) {
         
         Field[] fields = clazz.getDeclaredFields();
+        List excludedFieldList = excludeFields != null ? Arrays.asList(excludeFields) : Collections.EMPTY_LIST;
         AccessibleObject.setAccessible(fields, true);
         for (int i = 0; i < fields.length && builder.comparison == 0; i++) {
             Field f = fields[i];
-            if ((f.getName().indexOf('$') == -1)
+            if (!excludedFieldList.contains(f.getName())
+                && (f.getName().indexOf('$') == -1)
                 && (useTransients || !Modifier.isTransient(f.getModifiers()))
                 && (!Modifier.isStatic(f.getModifiers()))) {
                 try {

Modified: jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/builder/CompareToBuilderTest.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/builder/CompareToBuilderTest.java?rev=397016&r1=397015&r2=397016&view=diff
==============================================================================
--- jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/builder/CompareToBuilderTest.java
(original)
+++ jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/builder/CompareToBuilderTest.java
Tue Apr 25 16:15:05 2006
@@ -111,7 +111,7 @@
             this.t = t;
         }
     }
-
+    
     public void testReflectionCompare() {
         TestObject o1 = new TestObject(4);
         TestObject o2 = new TestObject(4);
@@ -142,11 +142,30 @@
     }
 
     public void testReflectionHierarchyCompare() {
-        testReflectionHierarchyCompare(false);
+        testReflectionHierarchyCompare(false, null);
+    }
+    
+    public void testReflectionHierarchyCompareExcludeFields() {
+        String[] excludeFields = new String[] { "b" };
+        testReflectionHierarchyCompare(true, excludeFields);
+        
+        TestSubObject x;
+        TestSubObject y;
+        TestSubObject z;
+        
+        x = new TestSubObject(1, 1);
+        y = new TestSubObject(2, 1);
+        z = new TestSubObject(3, 1);
+        assertXYZCompareOrder(x, y, z, true, excludeFields);
+
+        x = new TestSubObject(1, 3);
+        y = new TestSubObject(2, 2);
+        z = new TestSubObject(3, 1);
+        assertXYZCompareOrder(x, y, z, true, excludeFields);
     }
     
     public void testReflectionHierarchyCompareTransients() {
-        testReflectionHierarchyCompare(true);
+        testReflectionHierarchyCompare(true, null);
 
         TestTransientSubObject x;
         TestTransientSubObject y;
@@ -155,29 +174,29 @@
         x = new TestTransientSubObject(1, 1);
         y = new TestTransientSubObject(2, 2);
         z = new TestTransientSubObject(3, 3);
-        assertXYZCompareOrder(x, y, z, true);
+        assertXYZCompareOrder(x, y, z, true, null);
         
         x = new TestTransientSubObject(1, 1);
         y = new TestTransientSubObject(1, 2);
         z = new TestTransientSubObject(1, 3);
-        assertXYZCompareOrder(x, y, z, true);  
+        assertXYZCompareOrder(x, y, z, true, null);  
     }
     
-    private void assertXYZCompareOrder(Object x, Object y, Object z, boolean testTransients)
{
-        assertTrue(0 == CompareToBuilder.reflectionCompare(x, x, testTransients));
-        assertTrue(0 == CompareToBuilder.reflectionCompare(y, y, testTransients));
-        assertTrue(0 == CompareToBuilder.reflectionCompare(z, z, testTransients));
-        
-        assertTrue(0 > CompareToBuilder.reflectionCompare(x, y, testTransients));
-        assertTrue(0 > CompareToBuilder.reflectionCompare(x, z, testTransients));
-        assertTrue(0 > CompareToBuilder.reflectionCompare(y, z, testTransients));
-        
-        assertTrue(0 < CompareToBuilder.reflectionCompare(y, x, testTransients));
-        assertTrue(0 < CompareToBuilder.reflectionCompare(z, x, testTransients));
-        assertTrue(0 < CompareToBuilder.reflectionCompare(z, y, testTransients));
+    private void assertXYZCompareOrder(Object x, Object y, Object z, boolean testTransients,
String[] excludeFields) {
+        assertTrue(0 == CompareToBuilder.reflectionCompare(x, x, testTransients, null, excludeFields));
+        assertTrue(0 == CompareToBuilder.reflectionCompare(y, y, testTransients, null, excludeFields));
+        assertTrue(0 == CompareToBuilder.reflectionCompare(z, z, testTransients, null, excludeFields));
+        
+        assertTrue(0 > CompareToBuilder.reflectionCompare(x, y, testTransients, null,
excludeFields));
+        assertTrue(0 > CompareToBuilder.reflectionCompare(x, z, testTransients, null,
excludeFields));
+        assertTrue(0 > CompareToBuilder.reflectionCompare(y, z, testTransients, null,
excludeFields));
+        
+        assertTrue(0 < CompareToBuilder.reflectionCompare(y, x, testTransients, null,
excludeFields));
+        assertTrue(0 < CompareToBuilder.reflectionCompare(z, x, testTransients, null,
excludeFields));
+        assertTrue(0 < CompareToBuilder.reflectionCompare(z, y, testTransients, null,
excludeFields));
     }
     
-    public void testReflectionHierarchyCompare(boolean testTransients) {
+    public void testReflectionHierarchyCompare(boolean testTransients, String[] excludeFields)
{
         TestObject to1 = new TestObject(1);
         TestObject to2 = new TestObject(2);
         TestObject to3 = new TestObject(3);
@@ -185,19 +204,19 @@
         TestSubObject tso2 = new TestSubObject(2, 2);
         TestSubObject tso3 = new TestSubObject(3, 3);
         
-        assertReflectionCompareContract(to1, to1, to1, false);
-        assertReflectionCompareContract(to1, to2, to3, false);
-        assertReflectionCompareContract(tso1, tso1, tso1, false);
-        assertReflectionCompareContract(tso1, tso2, tso3, false);
-        assertReflectionCompareContract("1", "2", "3", false);
+        assertReflectionCompareContract(to1, to1, to1, false, excludeFields);
+        assertReflectionCompareContract(to1, to2, to3, false, excludeFields);
+        assertReflectionCompareContract(tso1, tso1, tso1, false, excludeFields);
+        assertReflectionCompareContract(tso1, tso2, tso3, false, excludeFields);
+        assertReflectionCompareContract("1", "2", "3", false, excludeFields);
         
         assertTrue(0 != CompareToBuilder.reflectionCompare(tso1, new TestSubObject(1, 0),
testTransients));
         assertTrue(0 != CompareToBuilder.reflectionCompare(tso1, new TestSubObject(0, 1),
testTransients));
 
         // root class
-        assertXYZCompareOrder(to1, to2, to3, true);
+        assertXYZCompareOrder(to1, to2, to3, true, null);
         // subclass  
-        assertXYZCompareOrder(tso1, tso2, tso3, true);  
+        assertXYZCompareOrder(tso1, tso2, tso3, true, null);  
     }
 
     /**
@@ -207,20 +226,22 @@
      * @param y an object to compare
      * @param z an object to compare
      * @param testTransients Whether to include transients in the comparison
+     * @param excludeFields fields to exclude
      */
-    public void assertReflectionCompareContract(Object x, Object y, Object z, boolean testTransients)
{
+    public void assertReflectionCompareContract(Object x, Object y, Object z, boolean testTransients,
String[] excludeFields) {
 
         // signum
-        assertTrue(reflectionCompareSignum(x, y, testTransients) == -reflectionCompareSignum(y,
x, testTransients));
+        assertTrue(reflectionCompareSignum(x, y, testTransients, excludeFields) == -reflectionCompareSignum(y,
x, testTransients, excludeFields));
         
         // transitive
-        if (CompareToBuilder.reflectionCompare(x, y, testTransients) > 0 && CompareToBuilder.reflectionCompare(y,
z, testTransients) > 0){
-            assertTrue(CompareToBuilder.reflectionCompare(x, z, testTransients) > 0);
+        if (CompareToBuilder.reflectionCompare(x, y, testTransients, null, excludeFields)
> 0 
+                && CompareToBuilder.reflectionCompare(y, z, testTransients, null,
excludeFields) > 0){
+            assertTrue(CompareToBuilder.reflectionCompare(x, z, testTransients, null, excludeFields)
> 0);
         }
         
         // un-named
-        if (CompareToBuilder.reflectionCompare(x, y, testTransients) == 0) {
-            assertTrue(reflectionCompareSignum(x, z, testTransients) == -reflectionCompareSignum(y,
z, testTransients));
+        if (CompareToBuilder.reflectionCompare(x, y, testTransients, null, excludeFields)
== 0) {
+            assertTrue(reflectionCompareSignum(x, z, testTransients, excludeFields) == -reflectionCompareSignum(y,
z, testTransients, excludeFields));
         }
         
         // strongly recommended but not strictly required
@@ -234,9 +255,10 @@
      * @param lhs The "left-hand-side" of the comparison.
      * @param rhs The "right-hand-side" of the comparison.
      * @param testTransients Whether to include transients in the comparison
+     * @param excludeFields fields to exclude
      * @return int The signum
      */
-    private int reflectionCompareSignum(Object lhs, Object rhs, boolean testTransients) {
+    private int reflectionCompareSignum(Object lhs, Object rhs, boolean testTransients, String[]
excludeFields) {
         return BigInteger.valueOf(CompareToBuilder.reflectionCompare(lhs, rhs, testTransients)).signum();
     }
     



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Mime
View raw message