[jboss-svn-commits] JBL Code SVN: r13089 - in labs/jbossrules/trunk/drools-core/src: main/java/org/drools/reteoo and 1 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Wed Jul 4 14:41:53 EDT 2007


Author: tirelli
Date: 2007-07-04 14:41:53 -0400 (Wed, 04 Jul 2007)
New Revision: 13089

Modified:
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/ShadowProxyFactory.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/Rete.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/base/ShadowProxyFactoryTest.java
Log:
JBRULES-966: fixing problem when asserting Maps into working memory

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/ShadowProxyFactory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/ShadowProxyFactory.java	2007-07-04 18:06:02 UTC (rev 13088)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/ShadowProxyFactory.java	2007-07-04 18:41:53 UTC (rev 13089)
@@ -147,6 +147,10 @@
                           className,
                           cw );
 
+        buildConstructor( clazz,
+                          className,
+                          cw );
+
         buildField( ShadowProxyFactory.DELEGATE_FIELD_NAME,
                     Type.getDescriptor( clazz ),
                     cw );
@@ -171,6 +175,10 @@
             buildCollectionClass( clazz,
                                   className,
                                   cw );
+        } else if ( Map.class.isAssignableFrom( clazz ) ) {
+            buildMapClass( clazz,
+                           className,
+                           cw );
         } else {
             buildRegularClass( clazz,
                                className,
@@ -184,16 +192,22 @@
                                              final String className,
                                              final ClassWriter cw) {
 
-        buildConstructor( clazz,
-                          className,
-                          cw );
-
         buildCollectionUpdateProxyMethod( clazz,
                                           className,
                                           cw );
 
     }
 
+    private static void buildMapClass(final Class clazz,
+                                      final String className,
+                                      final ClassWriter cw) {
+
+        buildMapUpdateProxyMethod( clazz,
+                                   className,
+                                   cw );
+
+    }
+
     private static void buildRegularClass(final Class clazz,
                                           final String className,
                                           final ClassWriter cw) {
@@ -230,10 +244,6 @@
             }
         }
 
-        buildConstructor( clazz,
-                          className,
-                          cw );
-
         buildUpdateProxyMethod( fieldTypes,
                                 className,
                                 cw );
@@ -709,7 +719,8 @@
                            className,
                            DELEGATE_FIELD_NAME,
                            Type.getDescriptor( clazz ) );
-        if ( Collection.class.isAssignableFrom( clazz ) ) {
+        if ( Collection.class.isAssignableFrom( clazz ) ||
+             Map.class.isAssignableFrom( clazz ) ) {
             Label l1 = new Label();
             mv.visitLabel( l1 );
             mv.visitVarInsn( Opcodes.ALOAD,
@@ -742,6 +753,18 @@
         mv.visitEnd();
     }
 
+    /**
+     * Creates an update proxy method for Map classes
+     * 
+     * public void updateProxy() {
+     *     this.clear();
+     *     this.addAll( this.delegate );
+     * }
+     * 
+     * @param clazz
+     * @param className
+     * @param cw
+     */
     protected static void buildCollectionUpdateProxyMethod(final Class clazz,
                                                            final String className,
                                                            final ClassWriter cw) {
@@ -795,6 +818,70 @@
         mv.visitEnd();
     }
 
+    /**
+     * Creates an update proxy method for Map classes
+     * 
+     * public void updateProxy() {
+     *     this.clear();
+     *     this.putAll( this.delegate );
+     * }
+     * 
+     * @param clazz
+     * @param className
+     * @param cw
+     */
+    protected static void buildMapUpdateProxyMethod(final Class clazz,
+                                                    final String className,
+                                                    final ClassWriter cw) {
+        final MethodVisitor mv = cw.visitMethod( Opcodes.ACC_PUBLIC,
+                                                 ShadowProxyFactory.UPDATE_PROXY,
+                                                 Type.getMethodDescriptor( Type.VOID_TYPE,
+                                                                           new Type[]{} ),
+                                                 null,
+                                                 null );
+        mv.visitCode();
+        final Label l0 = new Label();
+        mv.visitLabel( l0 );
+        // this.clear();
+        mv.visitVarInsn( Opcodes.ALOAD,
+                         0 );
+        mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
+                            className,
+                            "clear",
+                            Type.getMethodDescriptor( Type.VOID_TYPE,
+                                                      new Type[0] ) );
+        Label l1 = new Label();
+        mv.visitLabel( l1 );
+        // this.putAll( this.delegate );
+        mv.visitVarInsn( Opcodes.ALOAD,
+                         0 );
+        mv.visitVarInsn( Opcodes.ALOAD,
+                         0 );
+        mv.visitFieldInsn( Opcodes.GETFIELD,
+                           className,
+                           DELEGATE_FIELD_NAME,
+                           Type.getDescriptor( clazz ) );
+        mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
+                            className,
+                            "putAll",
+                            Type.getMethodDescriptor( Type.VOID_TYPE,
+                                                      new Type[]{Type.getType( Map.class )} ) );
+        Label l2 = new Label();
+        mv.visitLabel( l2 );
+        mv.visitInsn( Opcodes.RETURN );
+        Label l3 = new Label();
+        mv.visitLabel( l3 );
+        mv.visitLocalVariable( "this",
+                               "L" + className + ";",
+                               null,
+                               l0,
+                               l3,
+                               0 );
+        mv.visitMaxs( 0,
+                      0 );
+        mv.visitEnd();
+    }
+
     protected static void buildDelegateMethod(final Method method,
                                               final Class clazz,
                                               final String className,
@@ -1251,7 +1338,7 @@
             mv.visitJumpInsn( Opcodes.IFNE,
                               l1 );
             Label l2 = new Label();
-            
+
             //    this.__hashCache = this.delegate.hashCode();
             mv.visitLabel( l2 );
             mv.visitVarInsn( Opcodes.ALOAD,
@@ -1273,7 +1360,7 @@
                                Type.INT_TYPE.getDescriptor() );
             // }
             mv.visitLabel( l1 );
-            
+
             // return this.__hashCache;
             mv.visitVarInsn( Opcodes.ALOAD,
                              0 );

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/Rete.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/Rete.java	2007-07-04 18:06:02 UTC (rev 13088)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/Rete.java	2007-07-04 18:41:53 UTC (rev 13089)
@@ -22,6 +22,7 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import java.util.Map;
 
 import org.drools.FactException;
 import org.drools.RuleBaseConfiguration;
@@ -374,7 +375,8 @@
             ShadowProxy proxy = null;
             if ( isShadowEnabled() ) {
                 try {
-                    if( Collection.class.isAssignableFrom( this.shadowClass ) ) {
+                    if( Collection.class.isAssignableFrom( this.shadowClass ) ||
+                        Map.class.isAssignableFrom( this.shadowClass ) ) {
                         // if it is a collection, try to instantiate using constructor
                         try {
                             proxy = (ShadowProxy) this.shadowClass.getConstructor( new Class[] { cls } ).newInstance( new Object[] { fact } );

Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/base/ShadowProxyFactoryTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/base/ShadowProxyFactoryTest.java	2007-07-04 18:06:02 UTC (rev 13088)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/base/ShadowProxyFactoryTest.java	2007-07-04 18:41:53 UTC (rev 13089)
@@ -1,7 +1,9 @@
 package org.drools.base;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import junit.framework.Assert;
 import junit.framework.TestCase;
@@ -340,4 +342,46 @@
         }
     }
 
+    public void testProxyForMaps() {
+        try {
+            // creating original object
+            Map originalMap = new HashMap();
+            originalMap.put( "name", "Edson" );
+            originalMap.put( "surname", "Tirelli" );
+            originalMap.put( "age", "28" );
+            
+            // creating proxy
+            final Class proxy = ShadowProxyFactory.getProxy( originalMap.getClass() );
+            final Map mapProxy = (Map) proxy.getConstructor( new Class[]{originalMap.getClass()} ).newInstance( new Object[]{originalMap} );
+            ((ShadowProxy)mapProxy).setShadowedObject( originalMap );
+
+            // proxy is proxying the values
+            Assert.assertEquals( "Edson",
+                                 mapProxy.get( "name" ) );
+            Assert.assertTrue( mapProxy.containsKey( "age" ) );
+            Assert.assertSame( originalMap,
+                               ((ShadowProxy) mapProxy).getShadowedObject() );
+
+            // proxy must recongnize the original object on equals() calls
+            Assert.assertEquals( mapProxy,
+                                 originalMap );
+            
+            originalMap.remove( "age" );
+            originalMap.put( "hair", "brown" );
+            Assert.assertTrue( mapProxy.containsKey( "age" ) );
+            Assert.assertFalse( mapProxy.containsKey( "hair" ) );
+            
+            ((ShadowProxy)mapProxy).updateProxy();
+            Assert.assertFalse( mapProxy.containsKey( "age" ) );
+            Assert.assertTrue( mapProxy.containsKey( "hair" ) );
+            
+            // proxy must recongnize the original object on equals() calls
+            Assert.assertEquals( mapProxy,
+                                 originalMap );
+        } catch ( final Exception e ) {
+            e.printStackTrace();
+            fail( "Error: " + e.getMessage() );
+        }
+    }
+
 }




More information about the jboss-svn-commits mailing list