[jboss-svn-commits] JBL Code SVN: r13162 - in labs/jbossrules/trunk/drools-core/src: test/java/org/drools/util and 1 other directory.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Fri Jul 6 09:17:56 EDT 2007


Author: tirelli
Date: 2007-07-06 09:17:56 -0400 (Fri, 06 Jul 2007)
New Revision: 13162

Added:
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/util/ShadowProxyUtilsTest.java
Modified:
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/ShadowProxyUtils.java
Log:
JBRULES-976: fixing problems with collections clonning and adding unit tests

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/ShadowProxyUtils.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/ShadowProxyUtils.java	2007-07-06 13:05:30 UTC (rev 13161)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/ShadowProxyUtils.java	2007-07-06 13:17:56 UTC (rev 13162)
@@ -20,6 +20,7 @@
 import java.lang.reflect.Array;
 import java.lang.reflect.Method;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Map;
 
 /**
@@ -29,6 +30,12 @@
  */
 public class ShadowProxyUtils {
 
+    /* Collections.UnmodifiableCollection is a package
+     * private class, thus the confusing bit above
+     * to get a Class to compare to. */
+    private static final Class UNMODIFIABLE_MAP        = Collections.unmodifiableMap( Collections.EMPTY_MAP ).getClass();
+    private static final Class UNMODIFIABLE_COLLECTION = Collections.unmodifiableCollection( Collections.EMPTY_LIST ).getClass();
+
     private ShadowProxyUtils() {
     }
 
@@ -41,24 +48,37 @@
                 clone = cloneMethod.invoke( original,
                                             new Object[0] );
             } catch ( Exception e ) {
-                // Nothing to do
+                /* Failed to clone.  Don't worry about it, and just return
+                 * the original object. */
             }
         }
 
         if ( clone == null ) {
             try {
-                if ( original instanceof Map ) {
+                if ( original instanceof Map && 
+                     original != Collections.EMPTY_MAP && 
+                     !UNMODIFIABLE_MAP.isAssignableFrom( original.getClass() ) ) {
+                    
+                    /* empty and unmodifiable maps can't (and don't need to) be shadowed */
                     clone = original.getClass().newInstance();
                     ((Map) clone).putAll( (Map) original );
-                } else if ( original instanceof Collection ) {
+                    
+                } else if ( original instanceof Collection && 
+                            original != Collections.EMPTY_LIST && 
+                            original != Collections.EMPTY_SET && 
+                            !UNMODIFIABLE_COLLECTION.isAssignableFrom( original.getClass() ) ) {
+                    
+                    /* empty and unmodifiable collections can't (and don't need to) be shadowed */
                     clone = original.getClass().newInstance();
                     ((Collection) clone).addAll( (Collection) original );
+                    
                 } else if ( original.getClass().isArray() ) {
                     clone = cloneArray( original );
                 }
+                
             } catch ( Exception e ) {
-                e.printStackTrace();
-                // nothing to do
+                /* Failed to clone.  Don't worry about it, and just return
+                 * the original object. */
             }
         }
 
@@ -85,10 +105,13 @@
                 // cannot be invoked reflectively, so need to do copy construction:
                 result = Array.newInstance( componentType,
                                             arrayLength );
-                
-                if( componentType.isArray() ) {
-                    for( int i = 0; i < arrayLength; i++ ) {
-                        Array.set( result, i, cloneArray( Array.get( original, i ) ) );
+
+                if ( componentType.isArray() ) {
+                    for ( int i = 0; i < arrayLength; i++ ) {
+                        Array.set( result,
+                                   i,
+                                   cloneArray( Array.get( original,
+                                                          i ) ) );
                     }
                 } else {
                     System.arraycopy( original,

Added: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/util/ShadowProxyUtilsTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/util/ShadowProxyUtilsTest.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/util/ShadowProxyUtilsTest.java	2007-07-06 13:17:56 UTC (rev 13162)
@@ -0,0 +1,134 @@
+package org.drools.util;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+import junit.framework.TestCase;
+
+public class ShadowProxyUtilsTest extends TestCase {
+
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    public void testCloneList() {
+        List list = new ArrayList();
+        list.add( "a" );
+        list.add( "b" );
+
+        List clone = (List) ShadowProxyUtils.cloneObject( list );
+        assertEquals( list,
+                      clone );
+        assertNotSame( list,
+                       clone );
+    }
+
+    public void testCloneMap() {
+        Map map = new TreeMap();
+        map.put( "a",
+                 "a" );
+        map.put( "b",
+                 "b" );
+
+        Map clone = (Map) ShadowProxyUtils.cloneObject( map );
+        assertEquals( map,
+                      clone );
+        assertNotSame( map,
+                       clone );
+    }
+
+    public void testCloneArray() {
+        int[][] array = new int[][]{{0, 0}, {0, 1}, {1, 0}, {1, 1}};
+
+        int[][] clone = (int[][]) ShadowProxyUtils.cloneObject( array );
+        assertTrue( Arrays.deepEquals( array,
+                                       clone ) );
+        assertNotSame( array,
+                       clone );
+    }
+
+    public void testCloneUnmodifiableSet() {
+        Set set = new HashSet();
+        set.add( "a" );
+        set.add( "b" );
+
+        Set unmod = Collections.unmodifiableSet( set );
+
+        Set clone = (Set) ShadowProxyUtils.cloneObject( unmod );
+        assertEquals( unmod,
+                      clone );
+        assertSame( unmod,
+                    clone );
+    }
+
+    public void testCloneUnmodifiableMap() {
+        Map map = new TreeMap();
+        map.put( "a",
+                 "a" );
+        map.put( "b",
+                 "b" );
+        Map unmod = Collections.unmodifiableMap( map );
+
+        Map clone = (Map) ShadowProxyUtils.cloneObject( unmod );
+        assertEquals( unmod,
+                      clone );
+        assertSame( unmod,
+                    clone );
+    }
+    
+    public void testCloneEmptyList() {
+        List list = Collections.EMPTY_LIST;
+
+        List clone = (List) ShadowProxyUtils.cloneObject( list );
+        assertEquals( list,
+                      clone );
+        assertSame( list,
+                    clone );
+    }
+
+    public void testCloneEmptySet() {
+        Set set = Collections.EMPTY_SET;
+
+        Set clone = (Set) ShadowProxyUtils.cloneObject( set );
+        assertEquals( set,
+                      clone );
+        assertSame( set,
+                    clone );
+    }
+
+    public void testCloneEmptyMap() {
+        Map map = Collections.EMPTY_MAP;
+
+        Map clone = (Map) ShadowProxyUtils.cloneObject( map );
+        assertEquals( map,
+                      clone );
+        assertSame( map,
+                    clone );
+    }
+    
+    public void testCloneRegularObject() {
+        // this is never supposed to happen, 
+        // but we don't want the method to blow up if it happens
+        Object obj = new Object();
+
+        Object clone = (Object) ShadowProxyUtils.cloneObject( obj );
+        assertEquals( obj,
+                      clone );
+        assertSame( obj,
+                    clone );
+        
+    }
+    
+    
+
+}




More information about the jboss-svn-commits mailing list