[jboss-svn-commits] JBL Code SVN: r33691 - in labs/jbossrules/trunk: drools-compiler/src/test/resources/org/drools/integrationtests and 7 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Tue Jun 29 19:12:17 EDT 2010


Author: tirelli
Date: 2010-06-29 19:12:16 -0400 (Tue, 29 Jun 2010)
New Revision: 33691

Added:
   labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_CollectFromMVELAfterOr.drl
Modified:
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/FirstOrderLogicTest.java
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MultithreadTest.java
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/SerializationHelper.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/dataproviders/MVELDataProvider.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/PropagationContextImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/impl/InputMarshaller.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/impl/OutputMarshaller.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/impl/RightTupleKey.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/AccumulateNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/FromNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Collect.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/LogicTransformer.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/DataProvider.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/PropagationContext.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/FromNodeTest.java
Log:
JBRULES-2559: JBRULES-2563: fixing collect node and from node problems as well as serialization.

Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/FirstOrderLogicTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/FirstOrderLogicTest.java	2010-06-29 17:51:19 UTC (rev 33690)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/FirstOrderLogicTest.java	2010-06-29 23:12:16 UTC (rev 33691)
@@ -1318,4 +1318,39 @@
 
     }
 
+    public void testCollectFromMVELAfterOr() throws Exception {
+
+        // read in the source
+        final Reader reader = new InputStreamReader( getClass().getResourceAsStream( "test_CollectFromMVELAfterOr.drl" ) );
+        RuleBase ruleBase = loadRuleBase( reader );
+
+        StatefulSession wm = ruleBase.newStatefulSession();
+        List results = new ArrayList();
+
+        wm.setGlobal( "results",
+                      results );
+
+        Person jill = new Person( "jill" );
+
+        Person bob = new Person( "bob" );
+        List addresses = new ArrayList();
+        addresses.add( new Address( "a" ) );
+        addresses.add( new Address( "b" ) );
+        addresses.add( new Address( "c" ) );
+        bob.setAddresses( addresses );
+
+        wm.insert( jill );
+        wm.insert( bob );
+
+        wm = SerializationHelper.getSerialisedStatefulSession( wm );
+        results = (List) wm.getGlobal( "results" );
+
+        wm.fireAllRules();
+
+        Assert.assertEquals( 1,
+                             results.size() );
+        Assert.assertEquals( 3,
+                             ((Collection) results.get( 0 )).size() );
+    }
+
 }

Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MultithreadTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MultithreadTest.java	2010-06-29 17:51:19 UTC (rev 33690)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MultithreadTest.java	2010-06-29 23:12:16 UTC (rev 33691)
@@ -85,7 +85,7 @@
     }
     
     public void testRuleBaseConcurrentCompilation() {
-        final int THREAD_COUNT = 100;
+        final int THREAD_COUNT = 30;
         try {
             boolean success = true;
             final PackageBuilder builder = new PackageBuilder();

Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/SerializationHelper.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/SerializationHelper.java	2010-06-29 17:51:19 UTC (rev 33690)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/SerializationHelper.java	2010-06-29 23:12:16 UTC (rev 33691)
@@ -5,6 +5,7 @@
 import java.io.IOException;
 import java.io.ObjectOutput;
 import java.io.ObjectOutputStream;
+import java.io.OutputStream;
 
 import org.drools.RuleBase;
 import org.drools.SessionConfiguration;
@@ -81,7 +82,6 @@
         // bytes should be the same.
         if ( !areByteArraysEqual( b1,
                                   b2 ) ) {
-
             throw new IllegalArgumentException( "byte streams for serialisation test are not equal" );
         }
 
@@ -145,6 +145,7 @@
     public static boolean areByteArraysEqual(byte[] b1,
                                              byte[] b2) {
         if ( b1.length != b2.length ) {
+            System.out.println( "Different length: b1=" + b1.length + " b2=" + b2.length );
             return false;
         }
 
@@ -157,4 +158,5 @@
 
         return true;
     }
+    
 }

Added: labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_CollectFromMVELAfterOr.drl
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_CollectFromMVELAfterOr.drl	                        (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_CollectFromMVELAfterOr.drl	2010-06-29 23:12:16 UTC (rev 33691)
@@ -0,0 +1,20 @@
+package org.drools.test;
+
+import org.drools.Address;
+import org.drools.Person;
+import java.util.ArrayList;
+
+dialect "mvel"
+
+global java.util.List results;
+
+rule "After Or Evals Collect from MVEL"
+salience 70
+	when
+		$jill        : Person( name == "jill" )
+        $bob         : Person( name == "bob" )
+		( eval( $jill != null ) || eval( $bob != null ) )
+        $addressList : ArrayList(size > 2) from collect( Address() from $bob.addresses )
+    then
+        results.add($addressList);
+end

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/dataproviders/MVELDataProvider.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/dataproviders/MVELDataProvider.java	2010-06-29 17:51:19 UTC (rev 33690)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/dataproviders/MVELDataProvider.java	2010-06-29 23:12:16 UTC (rev 33691)
@@ -25,16 +25,16 @@
     implements
     DataProvider,
     MVELCompileable,
-    Externalizable  {
+    Externalizable {
 
-    private static final long serialVersionUID = 1901006343031798173L;
+    private static final long       serialVersionUID = 1901006343031798173L;
 
-    private MVELCompilationUnit unit;
-    private String id;
-    
-    private Serializable      expr;
-    private DroolsMVELFactory prototype;
-    
+    private MVELCompilationUnit     unit;
+    private String                  id;
+
+    private Serializable            expr;
+    private DroolsMVELFactory       prototype;
+
     private transient Declaration[] requiredDeclarations;
 
     public MVELDataProvider() {
@@ -42,38 +42,51 @@
     }
 
     public MVELDataProvider(final MVELCompilationUnit unit,
-                              final String id) {
+                            final String id) {
         this.unit = unit;
         this.id = id;
     }
 
-    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+    public void readExternal(ObjectInput in) throws IOException,
+                                            ClassNotFoundException {
         id = in.readUTF();
-        unit = ( MVELCompilationUnit ) in.readObject();
-//        expr    = (Serializable)in.readObject();
-//        prototype   = (DroolsMVELFactory)in.readObject();
+        unit = (MVELCompilationUnit) in.readObject();
+        //        expr    = (Serializable)in.readObject();
+        //        prototype   = (DroolsMVELFactory)in.readObject();
     }
 
     public void writeExternal(ObjectOutput out) throws IOException {
         out.writeUTF( id );
         out.writeObject( unit );
-//        out.writeObject(expr);
-//        out.writeObject(prototype);
+        //        out.writeObject(expr);
+        //        out.writeObject(prototype);
     }
-    
+
     @SuppressWarnings("unchecked")
     public void compile(ClassLoader classLoader) {
         expr = unit.getCompiledExpression( classLoader );
-        prototype = unit.getFactory( );
+        prototype = unit.getFactory();
         Map previousDeclarations = this.unit.getFactory().getPreviousDeclarations();
-        this.requiredDeclarations = (Declaration[]) previousDeclarations.values().toArray(new Declaration[previousDeclarations.size()]);
-    }   
-    
+        this.requiredDeclarations = (Declaration[]) previousDeclarations.values().toArray( new Declaration[previousDeclarations.size()] );
+    }
+
     public Declaration[] getRequiredDeclarations() {
         //return new Declaration[]{};
         return this.requiredDeclarations;
     }
 
+    public void replaceDeclaration(Declaration declaration,
+                                   Declaration resolved) {
+        for ( int i = 0; i < this.requiredDeclarations.length; i++ ) {
+            if ( this.requiredDeclarations[i].equals( declaration ) ) {
+                this.requiredDeclarations[i] = resolved;
+            }
+        }
+        this.unit.replaceDeclaration( declaration,
+                                      resolved );
+        prototype = unit.getFactory();
+    }
+
     public Object createContext() {
         return this.prototype.clone();
     }
@@ -81,32 +94,32 @@
     public Iterator getResults(final Tuple tuple,
                                final WorkingMemory wm,
                                final PropagationContext ctx,
-                               final Object executionContext ) {
+                               final Object executionContext) {
         DroolsMVELFactory factory = (DroolsMVELFactory) executionContext;
 
         factory.setContext( tuple,
-                                 null,
-                                 null,
-                                 wm,
-                                 null );
+                            null,
+                            null,
+                            wm,
+                            null );
 
         //this.expression.
         final Object result = MVEL.executeExpression( this.expr,
-                                                      factory );                
-        
+                                                      factory );
+
         if ( result == null ) {
             return Collections.EMPTY_LIST.iterator();
         } else if ( result instanceof Collection ) {
             return ((Collection) result).iterator();
         } else if ( result instanceof Iterator ) {
             return (Iterator) result;
-        } else if ( result.getClass().isArray() ) { 
+        } else if ( result.getClass().isArray() ) {
             return new ArrayIterator( result );
         } else {
             return Collections.singletonList( result ).iterator();
         }
     }
-    
+
     public DataProvider clone() {
         // not sure this is safe, but at this point we don't have a classloader
         // reference to compile a new copy of the data provider. My require

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/PropagationContextImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/PropagationContextImpl.java	2010-06-29 17:51:19 UTC (rev 33690)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/PropagationContextImpl.java	2010-06-29 23:12:16 UTC (rev 33691)
@@ -20,12 +20,10 @@
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
 
-import org.drools.core.util.ObjectHashMap;
+import org.drools.FactHandle;
 import org.drools.reteoo.LeftTuple;
 import org.drools.rule.EntryPoint;
 import org.drools.rule.Rule;
-import org.drools.FactHandle;
-import org.drools.spi.Activation;
 import org.drools.spi.PropagationContext;
 
 public class PropagationContextImpl
@@ -49,6 +47,8 @@
     public int                 dormantActivations;
 
     private EntryPoint         entryPoint;
+    
+    private int                originOffset;
 
     public PropagationContextImpl() {
 
@@ -67,6 +67,7 @@
         this.activeActivations = 0;
         this.dormantActivations = 0;
         this.entryPoint = EntryPoint.DEFAULT;
+        this.originOffset = -1;
     }
 
     public PropagationContextImpl(final long number,
@@ -85,6 +86,7 @@
         this.activeActivations = activeActivations;
         this.dormantActivations = dormantActivations;
         this.entryPoint = entryPoint;
+        this.originOffset = -1;
     }
 
     public void readExternal(ObjectInput in) throws IOException,
@@ -96,6 +98,7 @@
         this.rule = (Rule) in.readObject();
         this.leftTuple = (LeftTuple) in.readObject();
         this.entryPoint = (EntryPoint) in.readObject();
+        this.originOffset = in.readInt();
     }
 
     public void writeExternal(ObjectOutput out) throws IOException {
@@ -106,6 +109,7 @@
         out.writeObject( this.rule );
         out.writeObject( this.leftTuple );
         out.writeObject( this.entryPoint );
+        out.writeInt( this.originOffset );
     }
 
     public long getPropagationNumber() {
@@ -176,4 +180,13 @@
     public void setFactHandle(InternalFactHandle factHandle) {
         this.factHandle = factHandle;
     }
+    
+    public int getOriginOffset() {
+        return originOffset;
+    }
+
+    public void setOriginOffset(int originOffset) {
+        this.originOffset = originOffset;
+    }
+
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/impl/InputMarshaller.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/impl/InputMarshaller.java	2010-06-29 17:51:19 UTC (rev 33690)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/impl/InputMarshaller.java	2010-06-29 23:12:16 UTC (rev 33691)
@@ -4,6 +4,7 @@
 import java.io.ObjectInputStream;
 import java.io.Serializable;
 import java.util.Date;
+import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Queue;
 
@@ -51,6 +52,7 @@
 import org.drools.reteoo.RuleTerminalNode;
 import org.drools.reteoo.AccumulateNode.AccumulateContext;
 import org.drools.reteoo.AccumulateNode.AccumulateMemory;
+import org.drools.reteoo.FromNode.FromMemory;
 import org.drools.rule.EntryPoint;
 import org.drools.rule.GroupElement;
 import org.drools.rule.Package;
@@ -371,7 +373,8 @@
                                       InternalFactHandle factHandle) throws IOException {
         ObjectInputStream stream = context.stream;
 
-        RightTupleSink sink = (RightTupleSink) context.sinks.get( stream.readInt() );
+        int sinkId = stream.readInt();
+        RightTupleSink sink = (sinkId >= 0) ? (RightTupleSink) context.sinks.get( sinkId ) : null;
 
         RightTuple rightTuple = new RightTuple( factHandle,
                                                 sink );
@@ -379,18 +382,20 @@
                                                     sink ),
                                  rightTuple );
 
-        BetaMemory memory = null;
-        switch ( sink.getType() ) {
-            case NodeTypeEnums.AccumulateNode : {
-                memory = ((AccumulateMemory) context.wm.getNodeMemory( (BetaNode) sink )).betaMemory;
-                break;
+        if( sink != null ) {
+            BetaMemory memory = null;
+            switch ( sink.getType() ) {
+                case NodeTypeEnums.AccumulateNode : {
+                    memory = ((AccumulateMemory) context.wm.getNodeMemory( (BetaNode) sink )).betaMemory;
+                    break;
+                }
+                default : {
+                    memory = (BetaMemory) context.wm.getNodeMemory( (BetaNode) sink );
+                    break;
+                }
             }
-            default : {
-                memory = (BetaMemory) context.wm.getNodeMemory( (BetaNode) sink );
-                break;
-            }
+            memory.getRightTupleMemory().add( rightTuple );
         }
-        memory.getRightTupleMemory().add( rightTuple );
     }
 
     public static void readLeftTuples(MarshallerReaderContext context) throws IOException,
@@ -570,6 +575,40 @@
                 stream.readShort(); // Persistence.END
                 break;
             }
+            case NodeTypeEnums.FromNode: {
+//              context.out.println( "FromNode" );
+                // FNs generate new fact handles on-demand to wrap objects and need special procedures when serializing to persistent storage
+                FromMemory memory = (FromMemory) context.wm.getNodeMemory( (NodeMemory) sink );
+                
+                memory.betaMemory.getLeftTupleMemory().add( parentLeftTuple );                
+                Map<Object, RightTuple> matches =  new LinkedHashMap<Object, RightTuple>();
+                memory.betaMemory.getCreatedHandles().put( parentLeftTuple, matches );
+                
+                while( stream.readShort() == PersisterEnums.FACT_HANDLE ) {
+                    // we de-serialize the generated fact handle ID
+                    InternalFactHandle handle = readFactHandle( context );
+                    context.handles.put( handle.getId(),
+                                         handle );
+                    readRightTuples( handle, 
+                                     context );
+                    matches.put( handle.getObject(), handle.getFirstRightTuple() );
+                }
+                while( stream.readShort() == PersisterEnums.RIGHT_TUPLE ) {
+                    LeftTupleSink childSink = (LeftTupleSink) sinks.get( stream.readInt() );
+                    int factHandleId = stream.readInt();
+                    RightTupleKey key = new RightTupleKey( factHandleId,
+                                                           null ); // created tuples in from node always use null sink
+                    RightTuple rightTuple = context.rightTuples.get( key );
+                    LeftTuple childLeftTuple = new LeftTuple( parentLeftTuple,
+                                                              rightTuple,
+                                                              childSink,
+                                                              true );
+                    readLeftTuple( childLeftTuple,
+                                   context );
+                }
+//                context.out.println( "FromNode   ---   END" );
+                break;
+            }
             case NodeTypeEnums.RuleTerminalNode : {
                 int pos = context.terminalTupleMap.size();
                 context.terminalTupleMap.put( pos,

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/impl/OutputMarshaller.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/impl/OutputMarshaller.java	2010-06-29 17:51:19 UTC (rev 33690)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/impl/OutputMarshaller.java	2010-06-29 23:12:16 UTC (rev 33691)
@@ -45,6 +45,7 @@
 import org.drools.reteoo.RuleTerminalNode;
 import org.drools.reteoo.AccumulateNode.AccumulateContext;
 import org.drools.reteoo.AccumulateNode.AccumulateMemory;
+import org.drools.reteoo.FromNode.FromMemory;
 import org.drools.rule.EntryPoint;
 import org.drools.rule.Rule;
 import org.drools.runtime.process.WorkItem;
@@ -69,15 +70,15 @@
 
         context.writeInt( wm.getFactHandleFactory().getId() );
         context.writeLong( wm.getFactHandleFactory().getRecency() );
-//        context.out.println( "FactHandleFactory int:" + wm.getFactHandleFactory().getId() + " long:" + wm.getFactHandleFactory().getRecency() );
+        ////context.out.println( "FactHandleFactory int:" + wm.getFactHandleFactory().getId() + " long:" + wm.getFactHandleFactory().getRecency() );
 
         InternalFactHandle handle = context.wm.getInitialFactHandle();
         context.writeInt( handle.getId() );
         context.writeLong( handle.getRecency() );
-//        context.out.println( "InitialFact int:" + handle.getId() + " long:" + handle.getRecency() );
+        //context.out.println( "InitialFact int:" + handle.getId() + " long:" + handle.getRecency() );
 
         context.writeLong( wm.getPropagationIdCounter() );
-//        context.out.println( "PropagationCounter long:" + wm.getPropagationIdCounter() );
+        //context.out.println( "PropagationCounter long:" + wm.getPropagationIdCounter() );
 
         writeAgenda( context );
 
@@ -207,12 +208,12 @@
             stream.writeInt( key.getStatus() );
             InternalFactHandle handle = key.getFactHandle();
             stream.writeInt( handle.getId() );
-//            context.out.println( "EqualityKey int:" + key.getStatus() + " int:" + handle.getId() );
+            //context.out.println( "EqualityKey int:" + key.getStatus() + " int:" + handle.getId() );
             if ( key.getOtherFactHandle() != null && !key.getOtherFactHandle().isEmpty() ) {
                 for ( InternalFactHandle handle2 : key.getOtherFactHandle() ) {
                     stream.writeShort( PersisterEnums.FACT_HANDLE );
                     stream.writeInt( handle2.getId() );
-//                    context.out.println( "OtherHandle int:" + handle2.getId() );
+                    //context.out.println( "OtherHandle int:" + handle2.getId() );
                 }
             }
             stream.writeShort( PersisterEnums.END );
@@ -269,8 +270,8 @@
         stream.writeInt( handle.getId() );
         stream.writeLong( handle.getRecency() );
 
-//        context.out.println( "Object : int:" + handle.getId() + " long:" + handle.getRecency() );
-//        context.out.println( handle.getObject() );
+        //context.out.println( "Object : int:" + handle.getId() + " long:" + handle.getRecency() );
+        //context.out.println( handle.getObject() );
 
         Object object = handle.getObject();
 
@@ -331,19 +332,19 @@
         if ( initialFactNode != null ) {
             ObjectHashSet initialFactMemory = (ObjectHashSet) context.wm.getNodeMemory( initialFactNode );
             if ( initialFactMemory != null && !initialFactMemory.isEmpty() ) {
-//                context.out.println( "InitialFactMemory true int:" + initialFactNode.getId() );
+                //context.out.println( "InitialFactMemory true int:" + initialFactNode.getId() );
                 stream.writeBoolean( true );
                 stream.writeInt( initialFactNode.getId() );
 
-//                context.out.println( "InitialFact RightTuples" );
+                //context.out.println( "InitialFact RightTuples" );
                 writeRightTuples( context.wm.getInitialFactHandle(),
                                   context );
             } else {
-//                context.out.println( "InitialFactMemory false " );
+                //context.out.println( "InitialFactMemory false " );
                 stream.writeBoolean( false );
             }
         } else {
-//            context.out.println( "InitialFactMemory false " );
+            //context.out.println( "InitialFactMemory false " );
             stream.writeBoolean( false );
         }
     }
@@ -351,25 +352,25 @@
     public static void writeInitialFactHandleLeftTuples(MarshallerWriteContext context) throws IOException {
         ObjectOutputStream stream = context.stream;
 
-//        context.out.println( "InitialFact LeftTuples Start" );
+        //context.out.println( "InitialFact LeftTuples Start" );
         InternalFactHandle handle = context.wm.getInitialFactHandle();
         for ( LeftTuple leftTuple = handle.getFirstLeftTuple(); leftTuple != null; leftTuple = (LeftTuple) leftTuple.getLeftParentNext() ) {
             stream.writeShort( PersisterEnums.LEFT_TUPLE );
 
             stream.writeInt( leftTuple.getLeftTupleSink().getId() );
-//            context.out.println( "LeftTuple sinkId:" + leftTuple.getLeftTupleSink().getId() );
+            //context.out.println( "LeftTuple sinkId:" + leftTuple.getLeftTupleSink().getId() );
             writeLeftTuple( leftTuple,
                             context,
                             true );
         }
         stream.writeShort( PersisterEnums.END );
-//        context.out.println( "InitialFact LeftTuples End" );
+        //context.out.println( "InitialFact LeftTuples End" );
     }
 
     public static void writeRightTuples(InternalFactHandle handle,
                                         MarshallerWriteContext context) throws IOException {
         ObjectOutputStream stream = context.stream;
-//        context.out.println( "RightTuples Start" );
+        //context.out.println( "RightTuples Start" );
         
         for (RightTuple rightTuple = handle.getFirstRightTuple(); rightTuple != null; rightTuple = (RightTuple) rightTuple.getHandleNext() ) {
             stream.writeShort( PersisterEnums.RIGHT_TUPLE );
@@ -377,15 +378,17 @@
                              context );
         }
         stream.writeShort( PersisterEnums.END );
-//        context.out.println( "RightTuples END" );
+        //context.out.println( "RightTuples END" );
     }
 
     public static void writeRightTuple(RightTuple rightTuple,
                                        MarshallerWriteContext context) throws IOException {
         ObjectOutputStream stream = context.stream;
         InternalWorkingMemory wm = context.wm;
-        stream.writeInt( rightTuple.getRightTupleSink().getId() );
-//        context.out.println( "RightTuple sinkId:" + rightTuple.getRightTupleSink().getId() );
+        // right tuples created in a "FromNode" have no sink, so we need to handle that appropriatelly
+        int id = rightTuple.getRightTupleSink() != null ? rightTuple.getRightTupleSink().getId() : -1; 
+        stream.writeInt( id );
+        //context.out.println( "RightTuple sinkId:" + (rightTuple.getRightTupleSink() != null ? rightTuple.getRightTupleSink().getId() : -1) );
     }
 
     public static void writeLeftTuples(MarshallerWriteContext context) throws IOException {
@@ -393,7 +396,7 @@
         InternalWorkingMemory wm = context.wm;
 
         // Write out LeftTuples
-//        context.out.println( "LeftTuples Start" );
+        //context.out.println( "LeftTuples Start" );
         for ( InternalFactHandle handle : orderFacts( wm.getObjectStore() ) ) {
             //InternalFactHandle handle = (InternalFactHandle) it.next();
 
@@ -403,14 +406,14 @@
                 stream.writeInt( leftTuple.getLeftTupleSink().getId() );
                 stream.writeInt( handle.getId() );
 
-//                context.out.println( "LeftTuple sinkId:" + leftTuple.getLeftTupleSink().getId() + " handleId:" + handle.getId() );
+                //context.out.println( "LeftTuple sinkId:" + leftTuple.getLeftTupleSink().getId() + " handleId:" + handle.getId() );
                 writeLeftTuple( leftTuple,
                                 context,
                                 true );
             }
         }
         stream.writeShort( PersisterEnums.END );
-//        context.out.println( "LeftTuples End" );
+        //context.out.println( "LeftTuples End" );
     }
 
     public static void writeLeftTuple(LeftTuple leftTuple,
@@ -424,22 +427,22 @@
 
         switch ( sink.getType() ) {
             case NodeTypeEnums.JoinNode : {
-//                context.out.println( "JoinNode" );
+                //context.out.println( "JoinNode" );
                 for ( LeftTuple childLeftTuple = leftTuple.firstChild; childLeftTuple != null; childLeftTuple = (LeftTuple) childLeftTuple.getLeftParentNext() ) {
                     stream.writeShort( PersisterEnums.RIGHT_TUPLE );
                     stream.writeInt( childLeftTuple.getLeftTupleSink().getId() );
                     stream.writeInt( childLeftTuple.getRightParent().getFactHandle().getId() );
-//                    context.out.println( "RightTuple int:" + childLeftTuple.getLeftTupleSink().getId() + " int:" + childLeftTuple.getRightParent().getFactHandle().getId() );
+                    //context.out.println( "RightTuple int:" + childLeftTuple.getLeftTupleSink().getId() + " int:" + childLeftTuple.getRightParent().getFactHandle().getId() );
                     writeLeftTuple( childLeftTuple,
                                     context,
                                     recurse );
                 }
                 stream.writeShort( PersisterEnums.END );
-//                context.out.println( "JoinNode   ---   END" );
+                //context.out.println( "JoinNode   ---   END" );
                 break;
             }
             case NodeTypeEnums.EvalConditionNode : {
-//                context.out.println( "EvalConditionNode" );
+                //context.out.println( ".... EvalConditionNode" );
                 for ( LeftTuple childLeftTuple = leftTuple.firstChild; childLeftTuple != null; childLeftTuple = (LeftTuple) childLeftTuple.getLeftParentNext() ) {
                     stream.writeShort( PersisterEnums.LEFT_TUPLE );
                     stream.writeInt( childLeftTuple.getLeftTupleSink().getId() );
@@ -448,6 +451,7 @@
                                     recurse );
                 }
                 stream.writeShort( PersisterEnums.END );
+                //context.out.println( "---- EvalConditionNode   ---   END" );
                 break;
             }
             case NodeTypeEnums.NotNode : 
@@ -491,7 +495,7 @@
                 break;
             }
             case NodeTypeEnums.AccumulateNode : {
-//                context.out.println( "AccumulateNode" );
+                //context.out.println( ".... AccumulateNode" );
                 // accumulate nodes generate new facts on-demand and need special procedures when serializing to persistent storage
                 AccumulateMemory memory = (AccumulateMemory) context.wm.getNodeMemory( (BetaNode) sink );
                 AccumulateContext accctx = (AccumulateContext) memory.betaMemory.getCreatedHandles().get( leftTuple );
@@ -509,12 +513,12 @@
                 for ( LeftTuple childLeftTuple = leftTuple.firstChild; childLeftTuple != null; childLeftTuple = (LeftTuple) childLeftTuple.getLeftParentNext() ) {
                     if( leftTuple.getLeftTupleSink().getId() == childLeftTuple.getLeftTupleSink().getId()) {
                         // this is a matching record, so, associate the right tuples
-//                        context.out.println( "RightTuple(match) int:" + childLeftTuple.getLeftTupleSink().getId() + " int:" + childLeftTuple.getRightParent().getFactHandle().getId() );
+                        //context.out.println( "RightTuple(match) int:" + childLeftTuple.getLeftTupleSink().getId() + " int:" + childLeftTuple.getRightParent().getFactHandle().getId() );
                         stream.writeShort( PersisterEnums.RIGHT_TUPLE );
                         stream.writeInt( childLeftTuple.getRightParent().getFactHandle().getId() );
                     } else {
                         // this is a propagation record
-//                        context.out.println( "RightTuple(propagation) int:" + childLeftTuple.getLeftTupleSink().getId() + " int:" + childLeftTuple.getRightParent().getFactHandle().getId() );
+                        //context.out.println( "RightTuple(propagation) int:" + childLeftTuple.getLeftTupleSink().getId() + " int:" + childLeftTuple.getRightParent().getFactHandle().getId() );
                         stream.writeShort( PersisterEnums.LEFT_TUPLE );
                         stream.writeInt( childLeftTuple.getLeftTupleSink().getId() );
                         writeLeftTuple( childLeftTuple,
@@ -523,27 +527,57 @@
                     }
                 }
                 stream.writeShort( PersisterEnums.END );
-//                context.out.println( "AccumulateNode   ---   END" );
+                //context.out.println( "---- AccumulateNode   ---   END" );
                 break;
             }
             case NodeTypeEnums.RightInputAdaterNode : {
-//                context.out.println( "RightInputAdapterNode" );
+                //context.out.println( ".... RightInputAdapterNode" );
                 // RIANs generate new fact handles on-demand to wrap tuples and need special procedures when serializing to persistent storage
                 ObjectHashMap memory = (ObjectHashMap) context.wm.getNodeMemory( (NodeMemory) sink );
                 InternalFactHandle ifh = (InternalFactHandle) memory.get( leftTuple );
                 // first we serialize the generated fact handle ID
-//                context.out.println( "FactHandle id:"+ifh.getId() );
+                //context.out.println( "FactHandle id:"+ifh.getId() );
                 stream.writeInt( ifh.getId() );
                 stream.writeLong( ifh.getRecency() );
                 
                 writeRightTuples( ifh, context );
 
                 stream.writeShort( PersisterEnums.END );
-//                context.out.println( "RightInputAdapterNode   ---   END" );
+                //context.out.println( "---- RightInputAdapterNode   ---   END" );
                 break;
             }
+            case NodeTypeEnums.FromNode: {
+              //context.out.println( ".... FromNode" );
+              // FNs generate new fact handles on-demand to wrap objects and need special procedures when serializing to persistent storage
+              FromMemory memory = (FromMemory) context.wm.getNodeMemory( (NodeMemory) sink );
+
+              Map<Object, RightTuple> matches = (Map<Object, RightTuple>) memory.betaMemory.getCreatedHandles().get( leftTuple );
+              for ( RightTuple rightTuples : matches.values() ) {
+                  // first we serialize the generated fact handle ID
+                  stream.writeShort( PersisterEnums.FACT_HANDLE );
+                  writeFactHandle( context,
+                                   stream,
+                                   context.objectMarshallingStrategyStore,
+                                   rightTuples.getFactHandle() );
+                  writeRightTuples( rightTuples.getFactHandle(), 
+                                    context );
+              }
+              stream.writeShort( PersisterEnums.END );
+              for ( LeftTuple childLeftTuple = leftTuple.firstChild; childLeftTuple != null; childLeftTuple = (LeftTuple) childLeftTuple.getLeftParentNext() ) {
+                  stream.writeShort( PersisterEnums.RIGHT_TUPLE );
+                  stream.writeInt( childLeftTuple.getLeftTupleSink().getId() );
+                  stream.writeInt( childLeftTuple.getRightParent().getFactHandle().getId() );
+                  //context.out.println( "RightTuple int:" + childLeftTuple.getLeftTupleSink().getId() + " int:" + childLeftTuple.getRightParent().getFactHandle().getId() );
+                  writeLeftTuple( childLeftTuple,
+                                  context,
+                                  recurse );
+              }
+              stream.writeShort( PersisterEnums.END );
+              //context.out.println( "---- FromNode   ---   END" );
+              break;
+          }
             case NodeTypeEnums.RuleTerminalNode : {
-//                context.out.println( "RuleTerminalNode" );
+                //context.out.println( "RuleTerminalNode" );
                 int pos = context.terminalTupleMap.size();
                 context.terminalTupleMap.put( leftTuple,
                                               pos );
@@ -601,30 +635,30 @@
         stream.writeUTF( rule.getPackage() );
         stream.writeUTF( rule.getName() );
 
-//        context.out.println( "Rule " + rule.getPackage() + "." + rule.getName() );
+        //context.out.println( "Rule " + rule.getPackage() + "." + rule.getName() );
 
-//        context.out.println( "AgendaItem long:" + agendaItem.getPropagationContext().getPropagationNumber() );
+        //context.out.println( "AgendaItem long:" + agendaItem.getPropagationContext().getPropagationNumber() );
         stream.writeLong( agendaItem.getPropagationContext().getPropagationNumber() );
 
         if ( agendaItem.getActivationGroupNode() != null ) {
             stream.writeBoolean( true );
-//            context.out.println( "ActivationGroup bool:" + true );
+            //context.out.println( "ActivationGroup bool:" + true );
             stream.writeUTF( agendaItem.getActivationGroupNode().getActivationGroup().getName() );
-//            context.out.println( "ActivationGroup string:" + agendaItem.getActivationGroupNode().getActivationGroup().getName() );
+            //context.out.println( "ActivationGroup string:" + agendaItem.getActivationGroupNode().getActivationGroup().getName() );
         } else {
             stream.writeBoolean( false );
-//            context.out.println( "ActivationGroup bool:" + false );
+            //context.out.println( "ActivationGroup bool:" + false );
         }
 
         stream.writeBoolean( agendaItem.isActivated() );
-//        context.out.println( "AgendaItem bool:" + agendaItem.isActivated() );
+        //context.out.println( "AgendaItem bool:" + agendaItem.isActivated() );
 
         org.drools.core.util.LinkedList list = agendaItem.getLogicalDependencies();
         if ( list != null && !list.isEmpty() ) {
             for ( LogicalDependency node = (LogicalDependency) list.getFirst(); node != null; node = (LogicalDependency) node.getNext() ) {
                 stream.writeShort( PersisterEnums.LOGICAL_DEPENDENCY );
                 stream.writeInt( ((InternalFactHandle) node.getFactHandle()).getId() );
-//                context.out.println( "Logical Depenency : int " + ((InternalFactHandle) node.getFactHandle()).getId() );
+                //context.out.println( "Logical Depenency : int " + ((InternalFactHandle) node.getFactHandle()).getId() );
             }
         }
         stream.writeShort( PersisterEnums.END );

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/impl/RightTupleKey.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/impl/RightTupleKey.java	2010-06-29 17:51:19 UTC (rev 33690)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/impl/RightTupleKey.java	2010-06-29 23:12:16 UTC (rev 33691)
@@ -28,7 +28,7 @@
         final int prime = 31;
         int result = 1;
         result = prime * result + id;
-        result = prime * result + sink.getId();
+        result = prime * result + ((sink!=null) ? sink.getId() : 17 );
         return result;
     }
 
@@ -44,5 +44,10 @@
         } else if ( sink.getId() != other.sink.getId() ) return false;
         return true;
     }
+    
+    @Override
+    public String toString() {
+        return "RightTupleKey( id="+id+" sink="+sink+" )";
+    }
 
 }
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/AccumulateNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/AccumulateNode.java	2010-06-29 17:51:19 UTC (rev 33690)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/AccumulateNode.java	2010-06-29 23:12:16 UTC (rev 33691)
@@ -24,7 +24,6 @@
 import java.util.Arrays;
 
 import org.drools.RuleBaseConfiguration;
-import org.drools.RuntimeDroolsException;
 import org.drools.base.DroolsQuery;
 import org.drools.common.BetaConstraints;
 import org.drools.common.InternalFactHandle;

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/FromNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/FromNode.java	2010-06-29 17:51:19 UTC (rev 33690)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/FromNode.java	2010-06-29 23:12:16 UTC (rev 33691)
@@ -4,7 +4,7 @@
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
 import java.io.Serializable;
-import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.Map;
 
 import org.drools.RuleBaseConfiguration;
@@ -96,7 +96,7 @@
         Map<Object, RightTuple> matches = null;
         if ( this.tupleMemoryEnabled ) {
             memory.betaMemory.getLeftTupleMemory().add( leftTuple );
-            matches = new HashMap<Object, RightTuple>();
+            matches = new LinkedHashMap<Object, RightTuple>();
             memory.betaMemory.getCreatedHandles().put( leftTuple,
                                                        matches );
         }
@@ -181,7 +181,7 @@
         memory.betaMemory.getLeftTupleMemory().add( leftTuple );
 
         final Map<Object, RightTuple> previousMatches = (Map<Object, RightTuple>) memory.betaMemory.getCreatedHandles().remove( leftTuple );
-        final Map<Object, RightTuple> newMatches = new HashMap<Object, RightTuple>();
+        final Map<Object, RightTuple> newMatches = new LinkedHashMap<Object, RightTuple>();
         memory.betaMemory.getCreatedHandles().put( leftTuple,
                                                    newMatches );
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Collect.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Collect.java	2010-06-29 17:51:19 UTC (rev 33690)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Collect.java	2010-06-29 23:12:16 UTC (rev 33691)
@@ -40,12 +40,12 @@
     implements
     PatternSource {
 
-    private static final long      serialVersionUID = 400L;
+    private static final long         serialVersionUID = 400L;
 
-    private Pattern                sourcePattern;
-    private Pattern                resultPattern;
+    private Pattern                   sourcePattern;
+    private Pattern                   resultPattern;
 
-    private Class<Collection< Object >> cls;
+    private Class<Collection<Object>> cls;
 
     public Collect() {
     }
@@ -69,8 +69,18 @@
     }
 
     public Object clone() {
-        return new Collect( this.sourcePattern,
-                            this.resultPattern );
+        PatternSource source = this.resultPattern.getSource();
+        if ( source == this ) {
+            this.resultPattern.setSource( null );
+        }
+        Pattern clonedResultPattern = (Pattern) this.resultPattern.clone();
+
+        Collect collect = new Collect( (Pattern) this.sourcePattern.clone(),
+                                       clonedResultPattern );
+        if ( source == this ) {
+            collect.getResultPattern().setSource( collect );
+        }
+        return collect;
     }
 
     public Pattern getResultPattern() {
@@ -82,14 +92,16 @@
     }
 
     @SuppressWarnings("unchecked")
-    public Collection< Object > instantiateResultObject(InternalWorkingMemory wm) throws RuntimeDroolsException {
+    public Collection<Object> instantiateResultObject(InternalWorkingMemory wm) throws RuntimeDroolsException {
         try {
             // Collect can only be used with a Collection implementation, so
             // FactTemplateObject type is not allowed
             if ( this.cls == null ) {
                 ClassObjectType objType = ((ClassObjectType) this.resultPattern.getObjectType());
                 String className = determineResultClassName( objType );
-                this.cls = (Class<Collection<Object>>) Class.forName( className, true, ((InternalRuleBase) wm.getRuleBase()).getRootClassLoader() );
+                this.cls = (Class<Collection<Object>>) Class.forName( className,
+                                                                      true,
+                                                                      ((InternalRuleBase) wm.getRuleBase()).getRootClassLoader() );
             }
             return this.cls.newInstance();
         } catch ( final ClassCastException cce ) {

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/LogicTransformer.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/LogicTransformer.java	2010-06-29 17:51:19 UTC (rev 33690)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/LogicTransformer.java	2010-06-29 23:12:16 UTC (rev 33691)
@@ -24,6 +24,7 @@
 import java.util.Stack;
 
 import org.drools.spi.Constraint;
+import org.drools.spi.DataProvider;
 import org.drools.spi.DeclarationScopeResolver;
 
 /**
@@ -75,8 +76,7 @@
 
     public GroupElement[] transform(final GroupElement cloned) throws InvalidPatternException {
         //moved cloned to up
-    	//final GroupElement cloned = (GroupElement) and.clone();
-        
+        //final GroupElement cloned = (GroupElement) and.clone();
 
         processTree( cloned );
         cloned.pack();
@@ -157,11 +157,12 @@
                 Constraint constraint = (Constraint) next;
                 Declaration[] decl = constraint.getRequiredDeclarations();
                 for ( int i = 0; i < decl.length; i++ ) {
-                    Declaration resolved = resolver.getDeclaration(null, decl[i].getIdentifier() );
+                    Declaration resolved = resolver.getDeclaration( null,
+                                                                    decl[i].getIdentifier() );
                     if ( resolved != null && resolved != decl[i] ) {
                         constraint.replaceDeclaration( decl[i],
                                                        resolved );
-                    } else if( resolved == null ) {
+                    } else if ( resolved == null ) {
                         // it is probably an implicit declaration, so find the corresponding pattern
                         Pattern old = decl[i].getPattern();
                         Pattern current = resolver.findPatternByIndex( old.getIndex() );
@@ -169,7 +170,8 @@
                             resolved = new Declaration( decl[i].getIdentifier(),
                                                         decl[i].getExtractor(),
                                                         current );
-                            constraint.replaceDeclaration( decl[i], resolved );
+                            constraint.replaceDeclaration( decl[i],
+                                                           resolved );
                         }
                     }
                 }
@@ -177,12 +179,35 @@
         } else if ( element instanceof EvalCondition ) {
             Declaration[] decl = ((EvalCondition) element).getRequiredDeclarations();
             for ( int i = 0; i < decl.length; i++ ) {
-                Declaration resolved = resolver.getDeclaration(null, decl[i].getIdentifier() );
+                Declaration resolved = resolver.getDeclaration( null,
+                                                                decl[i].getIdentifier() );
                 if ( resolved != null && resolved != decl[i] ) {
                     ((EvalCondition) element).replaceDeclaration( decl[i],
                                                                   resolved );
                 }
             }
+        } else if ( element instanceof From ) {
+            DataProvider provider = ((From) element).getDataProvider();
+            Declaration[] decl = provider.getRequiredDeclarations();
+            for ( int i = 0; i < decl.length; i++ ) {
+                Declaration resolved = resolver.getDeclaration( null,
+                                                                decl[i].getIdentifier() );
+                if ( resolved != null && resolved != decl[i] ) {
+                    provider.replaceDeclaration( decl[i],
+                                                 resolved );
+                } else if ( resolved == null ) {
+                    // it is probably an implicit declaration, so find the corresponding pattern
+                    Pattern old = decl[i].getPattern();
+                    Pattern current = resolver.findPatternByIndex( old.getIndex() );
+                    if ( current != null && old != current ) {
+                        resolved = new Declaration( decl[i].getIdentifier(),
+                                                    decl[i].getExtractor(),
+                                                    current );
+                        provider.replaceDeclaration( decl[i],
+                                                     resolved );
+                    }
+                }
+            }
         } else {
             contextStack.push( element );
             for ( Iterator it = element.getNestedElements().iterator(); it.hasNext(); ) {

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/DataProvider.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/DataProvider.java	2010-06-29 17:51:19 UTC (rev 33690)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/DataProvider.java	2010-06-29 23:12:16 UTC (rev 33691)
@@ -6,10 +6,13 @@
 import org.drools.rule.Declaration;
 import org.drools.WorkingMemory;
 
-public interface DataProvider extends Serializable, Cloneable {
+public interface DataProvider
+    extends
+    Serializable,
+    Cloneable {
 
     public Declaration[] getRequiredDeclarations();
-    
+
     public Object createContext();
 
     public Iterator getResults(Tuple tuple,
@@ -19,4 +22,7 @@
 
     public DataProvider clone();
 
+    public void replaceDeclaration(Declaration declaration,
+                                   Declaration resolved);
+
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/PropagationContext.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/PropagationContext.java	2010-06-29 17:51:19 UTC (rev 33690)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/PropagationContext.java	2010-06-29 23:12:16 UTC (rev 33691)
@@ -34,6 +34,23 @@
 
     public LeftTuple getLeftTupleOrigin();
 
+    /**
+     * Returns the offset of the fact that initiated this propagation
+     * in the current propagation context. This attribute is mutable
+     * as the same fact might have different offsets in different rules
+     * or logical branches.
+     * 
+     * @return -1 for not set, and from 0 to the tuple length-1.
+     */
+    public int getOriginOffset();
+    
+    /**
+     * Sets the origin offset to the given offset.
+     * 
+     * @param offset -1 to unset or from 0 to tuple length-1
+     */
+    public void setOriginOffset( int offset );
+
     public int getActiveActivations();
 
     public int getDormantActivations();
@@ -41,5 +58,6 @@
     public void releaseResources();
 
     public EntryPoint getEntryPoint();
+    
 
 }
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/FromNodeTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/FromNodeTest.java	2010-06-29 17:51:19 UTC (rev 33690)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/FromNodeTest.java	2010-06-29 23:12:16 UTC (rev 33691)
@@ -40,16 +40,17 @@
 public class FromNodeTest extends TestCase {
     EqualityEvaluatorsDefinition equals = new EqualityEvaluatorsDefinition();
 
-    ClassFieldAccessorStore store = new ClassFieldAccessorStore();
-    private ReteooRuleBase ruleBase;
-    private BuildContext buildContext;
+    ClassFieldAccessorStore      store  = new ClassFieldAccessorStore();
+    private ReteooRuleBase       ruleBase;
+    private BuildContext         buildContext;
 
     protected void setUp() throws Exception {
         store.setClassFieldAccessorCache( new ClassFieldAccessorCache( Thread.currentThread().getContextClassLoader() ) );
         store.setEagerWire( true );
 
         ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase();
-        buildContext = new BuildContext( ruleBase, new ReteooBuilder.IdGenerator() );
+        buildContext = new BuildContext( ruleBase,
+                                         new ReteooBuilder.IdGenerator() );
     }
 
     public void testAlphaNode() {
@@ -58,15 +59,17 @@
                                                                        null,
                                                                        null,
                                                                        null );
-        final ReteooWorkingMemory workingMemory = new ReteooWorkingMemory( 1, ruleBase );
+        final ReteooWorkingMemory workingMemory = new ReteooWorkingMemory( 1,
+                                                                           ruleBase );
 
         final ClassFieldReader extractor = store.getReader( Cheese.class,
-                                                                  "type",
-                                                                  getClass().getClassLoader() );
+                                                            "type",
+                                                            getClass().getClassLoader() );
 
         final FieldValue field = FieldFactory.getFieldValue( "stilton" );
         final LiteralConstraint constraint = new LiteralConstraint( extractor,
-                                                                    equals.getEvaluator( ValueType.STRING_TYPE, Operator.EQUAL ),
+                                                                    equals.getEvaluator( ValueType.STRING_TYPE,
+                                                                                         Operator.EQUAL ),
                                                                     field );
 
         final List list = new ArrayList();
@@ -91,11 +94,12 @@
         final Person person1 = new Person( "xxx1",
                                            30 );
         final FactHandle person1Handle = workingMemory.insert( person1 );
-        final LeftTuple tuple1 = new LeftTuple( (DefaultFactHandle) person1Handle, from,
+        final LeftTuple tuple1 = new LeftTuple( (DefaultFactHandle) person1Handle,
+                                                from,
                                                 true );
         from.assertLeftTuple( tuple1,
-                          context,
-                          workingMemory );
+                              context,
+                              workingMemory );
 
         // nothing should be asserted, as cheese1 is cheddar and we are filtering on stilton
         assertEquals( 0,
@@ -106,11 +110,12 @@
         final Person person2 = new Person( "xxx2",
                                            30 );
         final FactHandle person2Handle = workingMemory.insert( person2 );
-        final LeftTuple tuple2 = new LeftTuple( (DefaultFactHandle) person2Handle, from,
+        final LeftTuple tuple2 = new LeftTuple( (DefaultFactHandle) person2Handle,
+                                                from,
                                                 true );
         from.assertLeftTuple( tuple2,
-                          context,
-                          workingMemory );
+                              context,
+                              workingMemory );
 
         final List asserted = sink.getAsserted();
         assertEquals( 1,
@@ -125,11 +130,12 @@
         final Person person3 = new Person( "xxx2",
                                            30 );
         final FactHandle person3Handle = workingMemory.insert( person3 );
-        final LeftTuple tuple3 = new LeftTuple( (DefaultFactHandle) person3Handle, from,
+        final LeftTuple tuple3 = new LeftTuple( (DefaultFactHandle) person3Handle,
+                                                from,
                                                 true );
         from.assertLeftTuple( tuple3,
-                          context,
-                          workingMemory );
+                              context,
+                              workingMemory );
 
         assertEquals( 3,
                       asserted.size() );
@@ -159,12 +165,12 @@
                                                                            (ReteooRuleBase) RuleBaseFactory.newRuleBase() );
 
         final ClassFieldReader priceExtractor = store.getReader( Cheese.class,
-                                                                       "price",
-                                                                       getClass().getClassLoader() );
+                                                                 "price",
+                                                                 getClass().getClassLoader() );
 
         final ClassFieldReader ageExtractor = store.getReader( Person.class,
-                                                                     "age",
-                                                                     getClass().getClassLoader() );
+                                                               "age",
+                                                               getClass().getClassLoader() );
 
         final Pattern pattern = new Pattern( 0,
                                              new ClassObjectType( Person.class ) );
@@ -175,7 +181,8 @@
 
         final VariableConstraint variableConstraint = new VariableConstraint( priceExtractor,
                                                                               declaration,
-                                                                              equals.getEvaluator( ValueType.PINTEGER_TYPE, Operator.EQUAL ) );
+                                                                              equals.getEvaluator( ValueType.PINTEGER_TYPE,
+                                                                                                   Operator.EQUAL ) );
         final RuleBaseConfiguration configuration = new RuleBaseConfiguration();
         configuration.setIndexRightBetaMemory( false );
         configuration.setIndexLeftBetaMemory( false );
@@ -204,11 +211,12 @@
         final Person person1 = new Person( "xxx1",
                                            30 );
         final FactHandle person1Handle = workingMemory.insert( person1 );
-        final LeftTuple tuple1 = new LeftTuple( (DefaultFactHandle) person1Handle, from,
+        final LeftTuple tuple1 = new LeftTuple( (DefaultFactHandle) person1Handle,
+                                                from,
                                                 true );
         from.assertLeftTuple( tuple1,
-                          context,
-                          workingMemory );
+                              context,
+                              workingMemory );
 
         // nothing should be asserted, as cheese1 is cheddar and we are filtering on stilton
         assertEquals( 0,
@@ -219,11 +227,12 @@
         final Person person2 = new Person( "xxx2",
                                            30 );
         final FactHandle person2Handle = workingMemory.insert( person2 );
-        final LeftTuple tuple2 = new LeftTuple( (DefaultFactHandle) person2Handle, from,
+        final LeftTuple tuple2 = new LeftTuple( (DefaultFactHandle) person2Handle,
+                                                from,
                                                 true );
         from.assertLeftTuple( tuple2,
-                          context,
-                          workingMemory );
+                              context,
+                              workingMemory );
 
         final List asserted = sink.getAsserted();
         assertEquals( 1,
@@ -238,11 +247,12 @@
         final Person person3 = new Person( "xxx2",
                                            30 );
         final FactHandle person3Handle = workingMemory.insert( person3 );
-        final LeftTuple tuple3 = new LeftTuple( (DefaultFactHandle) person3Handle, from,
+        final LeftTuple tuple3 = new LeftTuple( (DefaultFactHandle) person3Handle,
+                                                from,
                                                 true );
         from.assertLeftTuple( tuple3,
-                          context,
-                          workingMemory );
+                              context,
+                              workingMemory );
 
         assertEquals( 3,
                       asserted.size() );
@@ -270,12 +280,13 @@
         final ReteooWorkingMemory workingMemory = new ReteooWorkingMemory( 1,
                                                                            (ReteooRuleBase) RuleBaseFactory.newRuleBase() );
         final ClassFieldReader extractor = store.getReader( Cheese.class,
-                                                                  "type",
-                                                                  getClass().getClassLoader() );
+                                                            "type",
+                                                            getClass().getClassLoader() );
 
         final FieldValue field = FieldFactory.getFieldValue( "stilton" );
         final LiteralConstraint constraint = new LiteralConstraint( extractor,
-                                                                    equals.getEvaluator( ValueType.STRING_TYPE, Operator.EQUAL ),
+                                                                    equals.getEvaluator( ValueType.STRING_TYPE,
+                                                                                         Operator.EQUAL ),
                                                                     field );
 
         final List list = new ArrayList();
@@ -302,11 +313,12 @@
         final Person person1 = new Person( "xxx2",
                                            30 );
         final FactHandle person1Handle = workingMemory.insert( person1 );
-        final LeftTuple tuple = new LeftTuple( (DefaultFactHandle) person1Handle, from,
+        final LeftTuple tuple = new LeftTuple( (DefaultFactHandle) person1Handle,
+                                               from,
                                                true );
         from.assertLeftTuple( tuple,
-                          context,
-                          workingMemory );
+                              context,
+                              workingMemory );
 
         assertEquals( 2,
                       asserted.size() );
@@ -316,11 +328,10 @@
                       memory.betaMemory.getLeftTupleMemory().size() );
         assertNull( memory.betaMemory.getRightTupleMemory() );
         RightTuple rightTuple2 = tuple.firstChild.getRightParent();
-        RightTuple rightTuple1= tuple.firstChild.getLeftParentNext().getRightParent();
+        RightTuple rightTuple1 = tuple.firstChild.getLeftParentNext().getRightParent();
         assertFalse( rightTuple1.equals( rightTuple2 ) );
         assertNull( tuple.firstChild.getLeftParentNext().getLeftParentNext() );
 
-
         final InternalFactHandle handle2 = rightTuple2.getFactHandle();
         final InternalFactHandle handle1 = rightTuple1.getFactHandle();
         assertEquals( handle1.getObject(),
@@ -329,8 +340,8 @@
                       cheese1 );
 
         from.retractLeftTuple( tuple,
-                           context,
-                           workingMemory );
+                               context,
+                               workingMemory );
         assertEquals( 0,
                       memory.betaMemory.getLeftTupleMemory().size() );
         assertNull( memory.betaMemory.getRightTupleMemory() );
@@ -341,9 +352,9 @@
         DataProvider {
 
         private static final long serialVersionUID = -6003158511821491524L;
-        
-        private Collection collection;
 
+        private Collection        collection;
+
         public Declaration[] getRequiredDeclarations() {
             return null;
         }
@@ -355,17 +366,21 @@
         public Iterator getResults(final Tuple tuple,
                                    final WorkingMemory wm,
                                    final PropagationContext ctx,
-                                   final Object providerContext ) {
+                                   final Object providerContext) {
             return this.collection.iterator();
         }
 
         public Object createContext() {
             return null;
         }
-        
+
         public DataProvider clone() {
             return this;
         }
+
+        public void replaceDeclaration(Declaration declaration,
+                                       Declaration resolved) {
+        }
     }
 
     public static class Person {



More information about the jboss-svn-commits mailing list