[jboss-svn-commits] JBL Code SVN: r13088 - in labs/jbossrules/trunk: drools-core/src/main/java/org/drools and 7 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Wed Jul 4 14:06:02 EDT 2007
Author: tirelli
Date: 2007-07-04 14:06:02 -0400 (Wed, 04 Jul 2007)
New Revision: 13088
Modified:
labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBase.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/ShadowProxy.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/ShadowProxyFactory.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/ObjectFactory.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/extractors/SelfReferenceClassFieldExtractor.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ExistsNode.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/JoinNode.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/NotNode.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
labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/JoinNodeTest.java
Log:
JBRULES-966: fixing problem when asserting collection objects into working memory
Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java 2007-07-04 18:03:06 UTC (rev 13087)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java 2007-07-04 18:06:02 UTC (rev 13088)
@@ -61,7 +61,6 @@
import org.drools.TestParam;
import org.drools.WorkingMemory;
import org.drools.Cheesery.Maturity;
-import org.drools.brms.client.modeldriven.brl.RuleAttribute;
import org.drools.common.AbstractWorkingMemory;
import org.drools.common.DroolsObjectInputStream;
import org.drools.compiler.DrlParser;
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBase.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBase.java 2007-07-04 18:03:06 UTC (rev 13087)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBase.java 2007-07-04 18:06:02 UTC (rev 13088)
@@ -19,7 +19,6 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
-import java.util.Set;
import org.drools.rule.Package;
import org.drools.ruleflow.common.core.Process;
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/ShadowProxy.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/ShadowProxy.java 2007-07-04 18:03:06 UTC (rev 13087)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/ShadowProxy.java 2007-07-04 18:06:02 UTC (rev 13088)
@@ -24,5 +24,7 @@
public void updateProxy();
public Object getShadowedObject();
+
+ public void setShadowedObject(Object object);
}
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:03:06 UTC (rev 13087)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/ShadowProxyFactory.java 2007-07-04 18:06:02 UTC (rev 13088)
@@ -19,6 +19,7 @@
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -37,6 +38,8 @@
*/
public class ShadowProxyFactory {
private static final String UPDATE_PROXY = "updateProxy";
+ private static final String SET_SHADOWED_OBJECT = "setShadowedObject";
+ private static final String GET_SHADOWED_OBJECT = "getShadowedObject";
private static final String BASE_INTERFACE = Type.getInternalName( ShadowProxy.class );
@@ -84,22 +87,24 @@
throw new RuntimeDroolsException( e );
}
}
-
- protected static boolean isPossibleToGenerateTheProxyFor( final Class clazz) throws Exception {
+
+ protected static boolean isPossibleToGenerateTheProxyFor(final Class clazz) throws Exception {
if ( (clazz.getModifiers() & Modifier.FINAL) != 0 ) {
return false;
}
try {
- Method equals = clazz.getMethod( "equals", new Class[] { Object.class } );
- if( Modifier.isFinal( equals.getModifiers() ) ) {
+ Method equals = clazz.getMethod( "equals",
+ new Class[]{Object.class} );
+ if ( Modifier.isFinal( equals.getModifiers() ) ) {
return false;
}
} catch ( NoSuchMethodException e ) {
// that's fine
}
try {
- Method hashcode = clazz.getMethod( "hashCode", new Class[0] );
- if( Modifier.isFinal( hashcode.getModifiers() ) ) {
+ Method hashcode = clazz.getMethod( "hashCode",
+ new Class[0] );
+ if ( Modifier.isFinal( hashcode.getModifiers() ) ) {
return false;
}
} catch ( NoSuchMethodException e ) {
@@ -114,9 +119,7 @@
*/
public static String getInternalProxyClassNameForClass(final Class clazz) {
String className = null;
- if ( clazz.getPackage() != null && (
- clazz.getPackage().getName().startsWith( "java." ) || clazz.getPackage().getName().startsWith( "javax." ) )
- ) {
+ if ( clazz.getPackage() != null && (clazz.getPackage().getName().startsWith( "java." ) || clazz.getPackage().getName().startsWith( "javax." )) ) {
className = "org/drools/shadow/" + Type.getInternalName( clazz ) + "ShadowProxy";
} else {
className = Type.getInternalName( clazz ) + "ShadowProxy";
@@ -127,9 +130,7 @@
public static String getProxyClassNameForClass(final Class clazz) {
String className = null;
Package pkg = clazz.getPackage();
- if ( pkg != null &&
- (pkg.getName().startsWith( "java." ) || pkg.getName().startsWith( "javax." ) )
- ) {
+ if ( pkg != null && (pkg.getName().startsWith( "java." ) || pkg.getName().startsWith( "javax." )) ) {
className = "org.drools.shadow." + clazz.getName() + "ShadowProxy";
} else {
className = clazz.getName() + "ShadowProxy";
@@ -150,8 +151,10 @@
Type.getDescriptor( clazz ),
cw );
- final Method getShadowed = ShadowProxy.class.getDeclaredMethod( "getShadowedObject",
- new Class[]{} );
+ final Method getShadowed = ShadowProxy.class.getDeclaredMethod( GET_SHADOWED_OBJECT,
+ new Class[]{} );
+ final Method setShadowed = ShadowProxy.class.getDeclaredMethod( SET_SHADOWED_OBJECT,
+ new Class[]{Object.class} );
buildSimpleGetMethod( ShadowProxyFactory.DELEGATE_FIELD_NAME,
clazz,
getShadowed,
@@ -159,6 +162,41 @@
clazz,
cw );
+ buildSetShadowedObject( clazz,
+ className,
+ setShadowed,
+ cw );
+
+ if ( Collection.class.isAssignableFrom( clazz ) ) {
+ buildCollectionClass( clazz,
+ className,
+ cw );
+ } else {
+ buildRegularClass( clazz,
+ className,
+ cw );
+ }
+
+ return cw.toByteArray();
+ }
+
+ private static void buildCollectionClass(final Class clazz,
+ final String className,
+ final ClassWriter cw) {
+
+ buildConstructor( clazz,
+ className,
+ cw );
+
+ buildCollectionUpdateProxyMethod( clazz,
+ className,
+ cw );
+
+ }
+
+ private static void buildRegularClass(final Class clazz,
+ final String className,
+ final ClassWriter cw) {
final Map fieldTypes = new HashMap();
final Method[] methods = getMethods( clazz );
for ( int i = 0; i < methods.length; i++ ) {
@@ -213,8 +251,6 @@
className,
clazz,
fieldTypes );
-
- return cw.toByteArray();
}
/**
@@ -650,6 +686,115 @@
mv.visitEnd();
}
+ protected static void buildSetShadowedObject(final Class clazz,
+ final String className,
+ final Method setShadowed,
+ final ClassWriter cw) {
+ final MethodVisitor mv = cw.visitMethod( Opcodes.ACC_PUBLIC,
+ setShadowed.getName(),
+ Type.getMethodDescriptor( setShadowed ),
+ null,
+ null );
+ mv.visitCode();
+ Label l0 = new Label();
+ mv.visitLabel( l0 );
+ // this.delegate = (<clazz>) object;
+ mv.visitVarInsn( Opcodes.ALOAD,
+ 0 );
+ mv.visitVarInsn( Opcodes.ALOAD,
+ 1 );
+ mv.visitTypeInsn( Opcodes.CHECKCAST,
+ Type.getInternalName( clazz ) );
+ mv.visitFieldInsn( Opcodes.PUTFIELD,
+ className,
+ DELEGATE_FIELD_NAME,
+ Type.getDescriptor( clazz ) );
+ if ( Collection.class.isAssignableFrom( clazz ) ) {
+ Label l1 = new Label();
+ mv.visitLabel( l1 );
+ mv.visitVarInsn( Opcodes.ALOAD,
+ 0 );
+ mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
+ className,
+ UPDATE_PROXY,
+ Type.getMethodDescriptor( Type.VOID_TYPE,
+ new Type[0] ) );
+ }
+ 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.visitLocalVariable( "object",
+ Type.getDescriptor( Object.class ),
+ null,
+ l0,
+ l3,
+ 1 );
+ mv.visitMaxs( 0,
+ 0 );
+ mv.visitEnd();
+ }
+
+ protected static void buildCollectionUpdateProxyMethod(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.addAll( 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,
+ "addAll",
+ Type.getMethodDescriptor( Type.BOOLEAN_TYPE,
+ new Type[]{Type.getType( Collection.class )} ) );
+ mv.visitInsn( Opcodes.POP );
+ 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,
@@ -725,20 +870,33 @@
final Label l0 = new Label();
mv.visitLabel( l0 );
- // if ( this == object )
+ // if ( this == object || this.delegate == object )
mv.visitVarInsn( Opcodes.ALOAD,
0 );
mv.visitVarInsn( Opcodes.ALOAD,
1 );
final Label l1 = new Label();
- mv.visitJumpInsn( Opcodes.IF_ACMPNE,
+ mv.visitJumpInsn( Opcodes.IF_ACMPEQ,
l1 );
+ mv.visitVarInsn( Opcodes.ALOAD,
+ 0 );
+ mv.visitFieldInsn( Opcodes.GETFIELD,
+ className,
+ DELEGATE_FIELD_NAME,
+ Type.getDescriptor( clazz ) );
+ mv.visitVarInsn( Opcodes.ALOAD,
+ 1 );
+ Label l2 = new Label();
+ mv.visitJumpInsn( Opcodes.IF_ACMPNE,
+ l2 );
+ mv.visitLabel( l1 );
+
// return true;
mv.visitInsn( Opcodes.ICONST_1 );
mv.visitInsn( Opcodes.IRETURN );
// if (( object == null ) || ( ! ( object instanceof <class> ) ) )
- mv.visitLabel( l1 );
+ mv.visitLabel( l2 );
mv.visitVarInsn( Opcodes.ALOAD,
1 );
final Label l3 = new Label();
@@ -989,25 +1147,75 @@
}
}
+ protected static void buildCollectionEquals(final ClassWriter cw,
+ final String className,
+ final Class clazz) {
+
+ final MethodVisitor mv = cw.visitMethod( Opcodes.ACC_PUBLIC,
+ "equals",
+ Type.getMethodDescriptor( Type.BOOLEAN_TYPE,
+ new Type[]{Type.getType( Object.class )} ),
+ null,
+ null );
+ // if ( this == object ) {
+ Label l0 = new Label();
+ mv.visitLabel( l0 );
+ mv.visitVarInsn( Opcodes.ALOAD,
+ 0 );
+ mv.visitVarInsn( Opcodes.ALOAD,
+ 1 );
+ Label l1 = new Label();
+ mv.visitJumpInsn( Opcodes.IF_ACMPNE,
+ l1 );
+ // return true;
+ Label l2 = new Label();
+ mv.visitLabel( l2 );
+ mv.visitInsn( Opcodes.ICONST_1 );
+ mv.visitInsn( Opcodes.IRETURN );
+ // }
+ mv.visitLabel( l1 );
+ // return this.delegate.equals( object );
+ mv.visitVarInsn( Opcodes.ALOAD,
+ 0 );
+ mv.visitFieldInsn( Opcodes.GETFIELD,
+ className,
+ DELEGATE_FIELD_NAME,
+ Type.getDescriptor( clazz ) );
+ mv.visitVarInsn( Opcodes.ALOAD,
+ 1 );
+ mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
+ Type.getInternalName( clazz ),
+ "equals",
+ Type.getMethodDescriptor( Type.BOOLEAN_TYPE,
+ new Type[]{Type.getType( Object.class )} ) );
+ mv.visitInsn( Opcodes.IRETURN );
+ Label l3 = new Label();
+ mv.visitLabel( l3 );
+ mv.visitLocalVariable( "this",
+ "L" + className + ";",
+ null,
+ l0,
+ l3,
+ 0 );
+ mv.visitLocalVariable( "object",
+ Type.getDescriptor( Object.class ),
+ null,
+ l0,
+ l3,
+ 1 );
+ mv.visitMaxs( 0,
+ 0 );
+ mv.visitEnd();
+ }
+
/**
* Sample of generated code for all primitive + object types
*
* public int hashCode() {
- * if( ___hashCache != 0 ) {
- * return __hashCache;
+ * if( ___hashCache == 0 ) {
+ * __hashCache = this.delegate.hashCode();
* }
- * final int PRIME = 31;
- * int result = 1;
- * result = PRIME * result + (booleanAttr ? 1231 : 1237);
- * result = PRIME * result + charAttr;
- * long temp = Double.doubleToLongBits( doubleAttr );
- * result = PRIME * result + (int) (temp ^ (temp >>> 32));
- * result = PRIME * result + Float.floatToIntBits( floatAttr );
- * result = PRIME * result + intAttr;
- * result = PRIME * result + ((listAttr == null) ? 0 : listAttr.hashCode());
- * result = PRIME * result + (int) (longAttr ^ (longAttr >>> 32));
- * result = PRIME * result + shortAttr;
- * return result;
+ * return this.__hashCache;
* }
*
* @param cw
@@ -1020,7 +1228,6 @@
final Class clazz,
final Map fieldTypes) {
MethodVisitor mv;
- boolean hasDoubleAttr = false;
// Building hashcode method
{
mv = cw.visitMethod( Opcodes.ACC_PUBLIC,
@@ -1031,293 +1238,59 @@
null );
mv.visitCode();
- // if( __hashCache != 0 ) {
- final Label ls = new Label();
- mv.visitLabel( ls );
+ // if( this.__hashCache == 0 ) {
+ Label l0 = new Label();
+ mv.visitLabel( l0 );
mv.visitVarInsn( Opcodes.ALOAD,
0 );
mv.visitFieldInsn( Opcodes.GETFIELD,
className,
- ShadowProxyFactory.HASHCACHE_FIELD_NAME,
- Type.getDescriptor( int.class ) );
- final Label afterIfCachedLabel = new Label();
- mv.visitJumpInsn( Opcodes.IFEQ,
- afterIfCachedLabel );
- // return __hashCache;
- // }
+ HASHCACHE_FIELD_NAME,
+ Type.INT_TYPE.getDescriptor() );
+ Label l1 = new Label();
+ mv.visitJumpInsn( Opcodes.IFNE,
+ l1 );
+ Label l2 = new Label();
+
+ // this.__hashCache = this.delegate.hashCode();
+ mv.visitLabel( l2 );
mv.visitVarInsn( Opcodes.ALOAD,
0 );
+ mv.visitVarInsn( Opcodes.ALOAD,
+ 0 );
mv.visitFieldInsn( Opcodes.GETFIELD,
className,
- ShadowProxyFactory.HASHCACHE_FIELD_NAME,
- Type.getDescriptor( int.class ) );
- mv.visitInsn( Opcodes.IRETURN );
- mv.visitLabel( afterIfCachedLabel );
-
- // final int PRIME = 31;
- final Label l0 = new Label();
- mv.visitLabel( l0 );
- mv.visitIntInsn( Opcodes.BIPUSH,
- 31 );
- mv.visitVarInsn( Opcodes.ISTORE,
- 1 );
-
- // int result = 1;
- final Label l1 = new Label();
+ DELEGATE_FIELD_NAME,
+ Type.getDescriptor( clazz ) );
+ mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
+ Type.getInternalName( clazz ),
+ "hashCode",
+ Type.getMethodDescriptor( Type.INT_TYPE,
+ new Type[0] ) );
+ mv.visitFieldInsn( Opcodes.PUTFIELD,
+ className,
+ HASHCACHE_FIELD_NAME,
+ Type.INT_TYPE.getDescriptor() );
+ // }
mv.visitLabel( l1 );
- mv.visitInsn( Opcodes.ICONST_1 );
- mv.visitVarInsn( Opcodes.ISTORE,
- 2 );
-
- // for each field:
- int count = 0;
- for ( final Iterator it = fieldTypes.entrySet().iterator(); it.hasNext(); ) {
- final Map.Entry entry = (Map.Entry) it.next();
- final String fieldName = (String) entry.getKey();
- final Method method = (Method) entry.getValue();
- final Class fieldType = method.getReturnType();
- final String fieldFlag = fieldName + ShadowProxyFactory.FIELD_SET_FLAG;
- count++;
- final Label goNext = new Label();
-
- // if ( ! _fieldIsSet ) {
- final Label l5 = new Label();
- mv.visitLabel( l5 );
- mv.visitVarInsn( Opcodes.ALOAD,
- 0 );
- mv.visitFieldInsn( Opcodes.GETFIELD,
- className,
- fieldFlag,
- Type.BOOLEAN_TYPE.getDescriptor() );
- final Label l6 = new Label();
- mv.visitJumpInsn( Opcodes.IFNE,
- l6 );
-
- // __field = this.delegate.method();
- final Label l7 = new Label();
- mv.visitLabel( l7 );
- mv.visitVarInsn( Opcodes.ALOAD,
- 0 );
- mv.visitVarInsn( Opcodes.ALOAD,
- 0 );
- mv.visitFieldInsn( Opcodes.GETFIELD,
- className,
- ShadowProxyFactory.DELEGATE_FIELD_NAME,
- Type.getDescriptor( clazz ) );
- if ( clazz.isInterface() ) {
- mv.visitMethodInsn( Opcodes.INVOKEINTERFACE,
- Type.getInternalName( clazz ),
- method.getName(),
- Type.getMethodDescriptor( method ) );
- } else {
- mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
- Type.getInternalName( clazz ),
- method.getName(),
- Type.getMethodDescriptor( method ) );
- }
- mv.visitFieldInsn( Opcodes.PUTFIELD,
- className,
- fieldName,
- Type.getDescriptor( fieldType ) );
-
- // __fieldIsSet = true;
- final Label l8 = new Label();
- mv.visitLabel( l8 );
- mv.visitVarInsn( Opcodes.ALOAD,
- 0 );
- mv.visitInsn( Opcodes.ICONST_1 );
- mv.visitFieldInsn( Opcodes.PUTFIELD,
- className,
- fieldFlag,
- Type.BOOLEAN_TYPE.getDescriptor() );
-
- // }
- mv.visitLabel( l6 );
-
- if ( fieldType.isPrimitive() ) {
- // for primitive types
- // result = PRIME * result + <att hashcode>
- final Label l2 = new Label();
- if ( fieldType == Double.TYPE ) {
- hasDoubleAttr = true;
- mv.visitVarInsn( Opcodes.ALOAD,
- 0 );
- mv.visitFieldInsn( Opcodes.GETFIELD,
- className,
- fieldName,
- Type.getDescriptor( fieldType ) );
- mv.visitMethodInsn( Opcodes.INVOKESTATIC,
- Type.getInternalName( Double.class ),
- "doubleToLongBits",
- "(D)J" );
- mv.visitVarInsn( Opcodes.LSTORE,
- 3 );
- }
-
- mv.visitLabel( l2 );
- mv.visitIntInsn( Opcodes.BIPUSH,
- 31 );
- mv.visitVarInsn( Opcodes.ILOAD,
- 2 );
- mv.visitInsn( Opcodes.IMUL );
-
- if ( fieldType != Double.TYPE ) {
- mv.visitVarInsn( Opcodes.ALOAD,
- 0 );
- mv.visitFieldInsn( Opcodes.GETFIELD,
- className,
- fieldName,
- Type.getDescriptor( fieldType ) );
- }
-
- if ( fieldType == Boolean.TYPE ) {
- // att_hashcode ::= ( boolean_attribute ) ? 1231 : 1237;
- final Label z1 = new Label();
- mv.visitJumpInsn( Opcodes.IFEQ,
- z1 );
- mv.visitIntInsn( Opcodes.SIPUSH,
- 1231 );
- final Label z2 = new Label();
- mv.visitJumpInsn( Opcodes.GOTO,
- z2 );
- mv.visitLabel( z1 );
- mv.visitIntInsn( Opcodes.SIPUSH,
- 1237 );
- mv.visitLabel( z2 );
- } else if ( fieldType == Double.TYPE ) {
- // long temp = Double.doubleToLongBits( doubleAttr );
- // att_hashcode ::= (int) (temp ^ ( temp >>> 32 ) );
- final Label d1 = new Label();
- mv.visitLabel( d1 );
- mv.visitVarInsn( Opcodes.LLOAD,
- 3 );
- mv.visitVarInsn( Opcodes.LLOAD,
- 3 );
- mv.visitIntInsn( Opcodes.BIPUSH,
- 32 );
- mv.visitInsn( Opcodes.LUSHR );
- mv.visitInsn( Opcodes.LXOR );
- mv.visitInsn( Opcodes.L2I );
- } else if ( fieldType == Float.TYPE ) {
- // att_hashcode ::= Float.floatToIntBits( floatAttr );
- mv.visitMethodInsn( Opcodes.INVOKESTATIC,
- Type.getInternalName( Float.class ),
- "floatToIntBits",
- "(F)I" );
-
- } else if ( fieldType == Long.TYPE ) {
- // att_hashcode ::= (int) (lontattr ^( longattr >>> 32 ) );
- mv.visitVarInsn( Opcodes.ALOAD,
- 0 );
- mv.visitFieldInsn( Opcodes.GETFIELD,
- className,
- fieldName,
- Type.getDescriptor( fieldType ) );
- mv.visitIntInsn( Opcodes.BIPUSH,
- 32 );
- mv.visitInsn( Opcodes.LUSHR );
- mv.visitInsn( Opcodes.LXOR );
- mv.visitInsn( Opcodes.L2I );
-
- }
- mv.visitInsn( Opcodes.IADD );
- mv.visitVarInsn( Opcodes.ISTORE,
- 2 );
-
- } else {
- // for non primitive types
- // result = PRIME * result + <att hashcode>
- final Label l2 = new Label();
- mv.visitLabel( l2 );
- mv.visitIntInsn( Opcodes.BIPUSH,
- 31 );
- mv.visitVarInsn( Opcodes.ILOAD,
- 2 );
- mv.visitInsn( Opcodes.IMUL );
-
- mv.visitVarInsn( Opcodes.ALOAD,
- 0 );
- mv.visitFieldInsn( Opcodes.GETFIELD,
- className,
- fieldName,
- Type.getDescriptor( fieldType ) );
-
- final Label np1 = new Label();
- mv.visitJumpInsn( Opcodes.IFNONNULL,
- np1 );
- mv.visitInsn( Opcodes.ICONST_0 );
- final Label np2 = new Label();
- mv.visitJumpInsn( Opcodes.GOTO,
- np2 );
- mv.visitLabel( np1 );
- mv.visitVarInsn( Opcodes.ALOAD,
- 0 );
- mv.visitFieldInsn( Opcodes.GETFIELD,
- className,
- fieldName,
- Type.getDescriptor( fieldType ) );
- if ( fieldType.isInterface() ) {
- mv.visitMethodInsn( Opcodes.INVOKEINTERFACE,
- Type.getInternalName( fieldType ),
- "hashCode",
- "()I" );
- } else {
- mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
- Type.getInternalName( fieldType ),
- "hashCode",
- "()I" );
- }
- mv.visitLabel( np2 );
- mv.visitInsn( Opcodes.IADD );
- mv.visitVarInsn( Opcodes.ISTORE,
- 2 );
- }
- mv.visitLabel( goNext );
- }
-
- // __hashCache = result;
+
+ // return this.__hashCache;
mv.visitVarInsn( Opcodes.ALOAD,
0 );
- mv.visitVarInsn( Opcodes.ILOAD,
- 2 );
- mv.visitFieldInsn( Opcodes.PUTFIELD,
+ mv.visitFieldInsn( Opcodes.GETFIELD,
className,
- ShadowProxyFactory.HASHCACHE_FIELD_NAME,
- Type.getDescriptor( int.class ) );
-
- // return result;
- mv.visitVarInsn( Opcodes.ILOAD,
- 2 );
+ HASHCACHE_FIELD_NAME,
+ Type.INT_TYPE.getDescriptor() );
mv.visitInsn( Opcodes.IRETURN );
- final Label lastLabel = new Label();
- mv.visitLabel( lastLabel );
-
+ Label l3 = new Label();
+ mv.visitLabel( l3 );
mv.visitLocalVariable( "this",
"L" + className + ";",
null,
l0,
- lastLabel,
+ l3,
0 );
- mv.visitLocalVariable( "PRIME",
- Type.INT_TYPE.getDescriptor(),
- null,
- l0,
- lastLabel,
- 1 );
- mv.visitLocalVariable( "result",
- Type.INT_TYPE.getDescriptor(),
- null,
- l1,
- lastLabel,
- 2 );
- if ( hasDoubleAttr ) {
- mv.visitLocalVariable( "temp",
- Type.LONG_TYPE.getDescriptor(),
- null,
- l1,
- lastLabel,
- 3 );
- }
+
mv.visitMaxs( 0,
0 );
mv.visitEnd();
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/ObjectFactory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/ObjectFactory.java 2007-07-04 18:03:06 UTC (rev 13087)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/ObjectFactory.java 2007-07-04 18:06:02 UTC (rev 13088)
@@ -19,6 +19,7 @@
import java.util.Collection;
import org.drools.base.BaseEvaluator;
+import org.drools.base.ShadowProxy;
import org.drools.base.ValueType;
import org.drools.common.InternalWorkingMemory;
import org.drools.rule.VariableRestriction.ObjectVariableContextEntry;
@@ -104,6 +105,9 @@
if ( value1 == null ) {
return value2 == null;
}
+ if( value2 != null && value2 instanceof ShadowProxy ) {
+ return value2.equals( value1 );
+ }
return value1.equals( value2 );
}
@@ -113,6 +117,9 @@
if ( value == null ) {
return ((ObjectVariableContextEntry) context).right == null;
}
+ if( ((ObjectVariableContextEntry) context).right != null && ((ObjectVariableContextEntry) context).right instanceof ShadowProxy ) {
+ return ((ObjectVariableContextEntry) context).right.equals( value );
+ }
return value.equals( ((ObjectVariableContextEntry) context).right );
}
@@ -122,6 +129,9 @@
if ( ((ObjectVariableContextEntry) context).left == null ) {
return value == null;
}
+ if( value != null && value instanceof ShadowProxy ) {
+ return value.equals( ((ObjectVariableContextEntry) context).left );
+ }
return ((ObjectVariableContextEntry) context).left.equals( value );
}
@@ -134,6 +144,9 @@
if ( value1 == null ) {
return value2 == null;
}
+ if( value2 != null && value2 instanceof ShadowProxy ) {
+ return value2.equals( value1 );
+ }
return value1.equals( value2 );
}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/extractors/SelfReferenceClassFieldExtractor.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/extractors/SelfReferenceClassFieldExtractor.java 2007-07-04 18:03:06 UTC (rev 13087)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/extractors/SelfReferenceClassFieldExtractor.java 2007-07-04 18:06:02 UTC (rev 13088)
@@ -16,7 +16,6 @@
package org.drools.base.extractors;
-import org.drools.base.ShadowProxy;
import org.drools.base.ValueType;
import org.drools.common.InternalWorkingMemory;
@@ -37,7 +36,8 @@
}
public Object getValue(InternalWorkingMemory workingMemory, final Object object) {
- return (object instanceof ShadowProxy) ? ((ShadowProxy) object).getShadowedObject() : object;
+ //return (object instanceof ShadowProxy) ? ((ShadowProxy) object).getShadowedObject() : object;
+ return object;
}
public boolean isNullValue(InternalWorkingMemory workingMemory, final Object object) {
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java 2007-07-04 18:03:06 UTC (rev 13087)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java 2007-07-04 18:06:02 UTC (rev 13088)
@@ -1167,7 +1167,7 @@
this.agenda.getDormantActivations() );
doRetract( handle,
propagationContext );
-
+
if ( (originalObject != object) || (this.ruleBase.getConfiguration().getAssertBehaviour() != AssertBehaviour.IDENTITY) ) {
// as assertMap may be using an "identity" equality comparator,
// we need to remove the handle from the map, before replacing the object
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ExistsNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ExistsNode.java 2007-07-04 18:03:06 UTC (rev 13087)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ExistsNode.java 2007-07-04 18:06:02 UTC (rev 13088)
@@ -23,7 +23,6 @@
import org.drools.spi.PropagationContext;
import org.drools.util.FactEntry;
import org.drools.util.Iterator;
-import org.drools.util.AbstractHashTable.FactEntryImpl;
/**
* <code>ExistsNode</code> extends <code>BetaNode</code> to perform tests for
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/JoinNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/JoinNode.java 2007-07-04 18:03:06 UTC (rev 13087)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/JoinNode.java 2007-07-04 18:06:02 UTC (rev 13088)
@@ -22,7 +22,6 @@
import org.drools.spi.PropagationContext;
import org.drools.util.FactEntry;
import org.drools.util.Iterator;
-import org.drools.util.AbstractHashTable.FactEntryImpl;
/**
* <code>JoinNode</code> extends <code>BetaNode</code> to perform
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/NotNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/NotNode.java 2007-07-04 18:03:06 UTC (rev 13087)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/NotNode.java 2007-07-04 18:06:02 UTC (rev 13088)
@@ -23,7 +23,6 @@
import org.drools.spi.PropagationContext;
import org.drools.util.FactEntry;
import org.drools.util.Iterator;
-import org.drools.util.AbstractHashTable.FactEntryImpl;
/**
* <code>NotNode</code> extends <code>BetaNode</code> to perform tests for
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:03:06 UTC (rev 13087)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/Rete.java 2007-07-04 18:06:02 UTC (rev 13088)
@@ -19,8 +19,8 @@
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
-import java.lang.reflect.Field;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
import org.drools.FactException;
@@ -310,7 +310,6 @@
protected boolean shadowEnabled;
protected Class shadowClass;
protected transient ObjectInstantiator instantiator;
- protected transient Field delegate;
//private final InternalRuleBase ruleBase;
@@ -355,7 +354,6 @@
this.shadowClass = shadowClass;
this.shadowEnabled = true;
setInstantiator();
- setDelegateFieldObject();
}
}
@@ -372,32 +370,25 @@
this.instantiator = OBJENESIS.getInstantiatorOf( this.shadowClass );
}
- /**
- *
- */
- private void setDelegateFieldObject() {
- try {
- this.delegate = this.shadowClass.getDeclaredField( ShadowProxyFactory.DELEGATE_FIELD_NAME );
- this.delegate.setAccessible( true );
- } catch ( final Exception e ) {
- throw new RuntimeDroolsException( "Error retriving delegate field for shadow proxy class: " + this.shadowClass.getName(),
- e );
- }
- }
-
public Object getShadow(final Object fact) throws RuntimeDroolsException {
ShadowProxy proxy = null;
if ( isShadowEnabled() ) {
try {
- if ( this.delegate == null ) {
- this.setDelegateFieldObject();
+ if( Collection.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 } );
+ } catch ( Exception e ) {
+ // not possible to instantiate using constructor
+ }
}
- if ( this.instantiator == null ) {
- this.setInstantiator();
+ if( proxy == null ) {
+ if ( this.instantiator == null ) {
+ this.setInstantiator();
+ }
+ proxy = (ShadowProxy) this.instantiator.newInstance();
}
- proxy = (ShadowProxy) this.instantiator.newInstance();
- this.delegate.set( proxy,
- fact );
+ proxy.setShadowedObject( fact );
} catch ( final Exception e ) {
throw new RuntimeDroolsException( "Error creating shadow fact for object: " + fact,
e );
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:03:06 UTC (rev 13087)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/base/ShadowProxyFactoryTest.java 2007-07-04 18:06:02 UTC (rev 13088)
@@ -173,12 +173,12 @@
final Cheese cheeseProxy1 = (Cheese) proxy.getConstructor( new Class[]{Cheese.class} ).newInstance( new Object[]{cheese} );
final Cheese cheeseProxy2 = (Cheese) proxy.getConstructor( new Class[]{Cheese.class} ).newInstance( new Object[]{cheese} );
- final int cheesehash = cheeseHashCode( cheese );
+ int cheeseHash = cheese.hashCode();
Assert.assertEquals( cheeseProxy1,
cheeseProxy2 );
Assert.assertEquals( cheeseProxy2,
cheeseProxy1 );
- Assert.assertEquals( cheesehash,
+ Assert.assertEquals( cheeseHash,
cheeseProxy1.hashCode() );
// changing original values
@@ -187,13 +187,14 @@
cheese.setType( actualType );
cheese.setPrice( actualPrice );
- Assert.assertEquals( cheesehash,
+ Assert.assertEquals( cheeseHash,
cheeseProxy1.hashCode() );
// updating proxy1
((ShadowProxy) cheeseProxy1).updateProxy();
+ cheeseHash = cheese.hashCode();
- Assert.assertEquals( cheeseHashCode( cheese ),
+ Assert.assertEquals( cheeseHash,
cheeseProxy1.hashCode() );
// now they are different
@@ -234,13 +235,13 @@
// }
// }
- private int cheeseHashCode(final Cheese cheese) {
- final int PRIME = 31;
- int result = 1;
- result = PRIME * result + ((cheese.getType() == null) ? 0 : cheese.getType().hashCode());
- result = PRIME * result + cheese.getPrice();
- return result;
- }
+// private int cheeseHashCode(final Cheese cheese) {
+// final int PRIME = 31;
+// int result = 1;
+// result = PRIME * result + ((cheese.getType() == null) ? 0 : cheese.getType().hashCode());
+// result = PRIME * result + cheese.getPrice();
+// return result;
+// }
public void testClassWithStaticMethod() {
try {
@@ -255,7 +256,7 @@
final Cheese cheeseProxy1 = (Cheese) proxy.getConstructor( new Class[]{Cheese.class} ).newInstance( new Object[]{cheese} );
final Cheese cheeseProxy2 = (Cheese) proxy.getConstructor( new Class[]{Cheese.class} ).newInstance( new Object[]{cheese} );
- final int cheesehash = cheeseHashCode( cheese );
+ final int cheesehash = cheese.hashCode();
Assert.assertEquals( cheeseProxy1,
cheeseProxy2 );
Assert.assertEquals( cheeseProxy2,
@@ -282,7 +283,7 @@
final Cheese cheeseProxy1 = (Cheese) proxy.getConstructor( new Class[]{Cheese.class} ).newInstance( new Object[]{cheese} );
final Cheese cheeseProxy2 = (Cheese) proxy.getConstructor( new Class[]{Cheese.class} ).newInstance( new Object[]{cheese} );
- final int cheesehash = cheeseHashCode( cheese );
+ final int cheesehash = cheese.hashCode();
Assert.assertEquals( cheeseProxy1,
cheeseProxy2 );
Assert.assertEquals( cheeseProxy2,
@@ -296,4 +297,47 @@
}
}
+ public void testProxyForCollections() {
+ try {
+ // creating original object
+ List originalList = new ArrayList();
+ originalList.add( "a" );
+ originalList.add( "b" );
+ originalList.add( "c" );
+ originalList.add( "d" );
+
+ // creating proxy
+ final Class proxy = ShadowProxyFactory.getProxy( originalList.getClass() );
+ final List listProxy = (List) proxy.getConstructor( new Class[]{originalList.getClass()} ).newInstance( new Object[]{originalList} );
+ ((ShadowProxy)listProxy).setShadowedObject( originalList );
+
+ // proxy is proxying the values
+ Assert.assertEquals( "a",
+ listProxy.get( 0 ) );
+ Assert.assertTrue( listProxy.contains( "c" ) );
+ Assert.assertSame( originalList,
+ ((ShadowProxy) listProxy).getShadowedObject() );
+
+ // proxy must recongnize the original object on equals() calls
+ Assert.assertEquals( listProxy,
+ originalList );
+
+ originalList.remove( "c" );
+ originalList.add( "e" );
+ Assert.assertTrue( listProxy.contains( "c" ) );
+ Assert.assertFalse( listProxy.contains( "e" ) );
+
+ ((ShadowProxy)listProxy).updateProxy();
+ Assert.assertFalse( listProxy.contains( "c" ) );
+ Assert.assertTrue( listProxy.contains( "e" ) );
+
+ // proxy must recongnize the original object on equals() calls
+ Assert.assertEquals( listProxy,
+ originalList );
+ } catch ( final Exception e ) {
+ e.printStackTrace();
+ fail( "Error: " + e.getMessage() );
+ }
+ }
+
}
Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/JoinNodeTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/JoinNodeTest.java 2007-07-04 18:03:06 UTC (rev 13087)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/JoinNodeTest.java 2007-07-04 18:06:02 UTC (rev 13088)
@@ -33,7 +33,6 @@
import org.drools.spi.PropagationContext;
import org.drools.util.FactEntry;
import org.drools.util.Iterator;
-import org.drools.util.AbstractHashTable.FactEntryImpl;
public class JoinNodeTest extends DroolsTestCase {
Rule rule;
More information about the jboss-svn-commits
mailing list