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

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Thu Jan 11 15:10:58 EST 2007


Author: tirelli
Date: 2007-01-11 15:10:15 -0500 (Thu, 11 Jan 2007)
New Revision: 8828

Added:
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleTerminalNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/BuildContext.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/BuildUtils.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/CollectBuilder.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/ColumnBuilder.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/EvalBuilder.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/FromBuilder.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/GroupElementBuilder.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/ReteooComponentBuilder.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/ReteooRuleBuilder.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/builder/
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/builder/ReteooRuleBuilderTest.java
Removed:
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/TerminalNode.java
Modified:
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InstanceEqualsConstraint.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InstanceNotEqualsConstraint.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/AlphaNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/BetaNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/EvalConditionNode.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/LeftInputAdapterNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/MemoryVisitor.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/ObjectSource.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectTypeNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/QueryTerminalNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteTuple.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooBuilder.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooRuleBase.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RightInputAdapterNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/TupleSource.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Accumulate.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/Column.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Declaration.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/EvalCondition.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/From.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/GroupElement.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/PredicateConstraint.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/RuleConditionElement.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/mvel/conversion/ShortCH.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/AgendaTest.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/LogicalAssertionTest.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/SchedulerTest.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/rule/DeclarationTest.java
   labs/jbossrules/trunk/drools-core/src/test/resources/correct_processTree1.dat
   labs/jbossrules/trunk/drools-core/src/test/resources/correct_transform1.dat
Log:
JBRULES-218: refactoring Reteoo Builder

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InstanceEqualsConstraint.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InstanceEqualsConstraint.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InstanceEqualsConstraint.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -64,7 +64,7 @@
 
     public boolean isAllowedCachedRight(final ReteTuple tuple,
                                         final ContextEntry context) {
-        return tuple.get( this.otherColumn.getFactIndex() ).getObject() == ((InstanceEqualsConstraintContextEntry) context).right;
+        return tuple.get( this.otherColumn.getOffset() ).getObject() == ((InstanceEqualsConstraintContextEntry) context).right;
     }
 
     public String toString() {
@@ -91,6 +91,9 @@
     public static class InstanceEqualsConstraintContextEntry
         implements
         ContextEntry {
+
+        private static final long serialVersionUID = 5841221599619051196L;
+        
         public Object        left;
         public Object        right;
 
@@ -110,7 +113,7 @@
         }
 
         public void updateFromTuple(final InternalWorkingMemory workingMemory, final ReteTuple tuple) {
-            this.left = tuple.get( this.column.getFactIndex() ).getObject();
+            this.left = tuple.get( this.column.getOffset() ).getObject();
         } 
 
         public void updateFromFactHandle(final InternalWorkingMemory workingMemory, final InternalFactHandle handle) {

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InstanceNotEqualsConstraint.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InstanceNotEqualsConstraint.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InstanceNotEqualsConstraint.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -60,7 +60,7 @@
 
     public boolean isAllowedCachedRight(final ReteTuple tuple,
                                         final ContextEntry context) {
-        return tuple.get( this.otherColumn.getFactIndex() ).getObject() != ((InstanceNotEqualsConstraintContextEntry) context).right;
+        return tuple.get( this.otherColumn.getOffset() ).getObject() != ((InstanceNotEqualsConstraintContextEntry) context).right;
     }
 
     public String toString() {
@@ -87,6 +87,8 @@
     public static class InstanceNotEqualsConstraintContextEntry
         implements
         ContextEntry {
+
+        private static final long serialVersionUID = -1229222687367782322L;
         public Object        left;
         public Object        right;
 
@@ -106,7 +108,7 @@
         }
 
         public void updateFromTuple(final InternalWorkingMemory workingMemory, final ReteTuple tuple) {
-            this.left = tuple.get( this.column.getFactIndex() ).getObject();
+            this.left = tuple.get( this.column.getOffset() ).getObject();
         }
 
         public void updateFromFactHandle(final InternalWorkingMemory workingMemory, final InternalFactHandle handle) {

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/AlphaNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/AlphaNode.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/AlphaNode.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -39,7 +39,7 @@
  * @author <a href="mailto:bob at werken.com">Bob McWhirter</a>
  *
  */
-class AlphaNode extends ObjectSource
+public class AlphaNode extends ObjectSource
     implements
     ObjectSinkNode,
     NodeMemory {
@@ -64,7 +64,7 @@
      * @param constraint
      * @param objectSource
      */
-    AlphaNode(final int id,
+    public AlphaNode(final int id,
               final AlphaNodeFieldConstraint constraint,
               final ObjectSource objectSource) {
         this( id,
@@ -86,7 +86,7 @@
      * @param objectSource Node's object source
      * @param hasMemory true if node shall be configured with local memory. False otherwise.
      */
-    AlphaNode(final int id,
+    public AlphaNode(final int id,
               final AlphaNodeFieldConstraint constraint,
               final ObjectSource objectSource,
               final boolean hasMemory,

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/BetaNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/BetaNode.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/BetaNode.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -135,8 +135,8 @@
 
         final TupleSink[] sinks = this.sink.getSinks();
         for ( int i = 0, length = sinks.length; i < length; i++ ) {
-            if ( sinks[i].getClass() == TerminalNode.class ) {
-                list.add( ((TerminalNode) sinks[i]).getRule().getName() );
+            if ( sinks[i].getClass() == RuleTerminalNode.class ) {
+                list.add( ((RuleTerminalNode) sinks[i]).getRule().getName() );
             } else if ( sinks[i] instanceof BetaNode ) {
                 list.addAll( ((BetaNode) sinks[i]).getRules() );
             }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/EvalConditionNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/EvalConditionNode.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/EvalConditionNode.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -41,7 +41,7 @@
  * @author <a href="mailto:mark.proctor at jboss.com">Mark Proctor</a>
  * @author <a href="mailto:bob at werken.com">Bob McWhirter</a>
  */
-class EvalConditionNode extends TupleSource
+public class EvalConditionNode extends TupleSource
     implements
     TupleSinkNode,
     NodeMemory {
@@ -76,7 +76,7 @@
      *            The source of incoming <code>Tuples</code>.
      * @param eval
      */
-    EvalConditionNode(final int id,
+    public EvalConditionNode(final int id,
                       final TupleSource tupleSource,
                       final EvalCondition eval) {
         super( id );

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-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ExistsNode.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -60,9 +60,9 @@
      * @param rightInput
      *            The right input <code>ObjectSource</code>.
      */
-    ExistsNode(final int id,
-               final TupleSource leftInput,
-               final ObjectSource rightInput) {
+    public ExistsNode(final int id,
+                      final TupleSource leftInput,
+                      final ObjectSource rightInput) {
         super( id,
                leftInput,
                rightInput,
@@ -81,10 +81,10 @@
      * @param joinNodeBinder
      *            The constraints to be aplied to the right objects
      */
-    ExistsNode(final int id,
-            final TupleSource leftInput,
-            final ObjectSource rightInput,
-            final BetaConstraints joinNodeBinder) {
+    public ExistsNode(final int id,
+                      final TupleSource leftInput,
+                      final ObjectSource rightInput,
+                      final BetaConstraints joinNodeBinder) {
         super( id,
                leftInput,
                rightInput,
@@ -156,10 +156,10 @@
                 tuple.setMatches( matches + 1 );
 
                 // if this is the first match, propagate tuple
-                if( tuple.getMatches() == 1 ) {
+                if ( tuple.getMatches() == 1 ) {
                     this.sink.propagateAssertTuple( tuple,
-                                                     context,
-                                                     workingMemory );
+                                                    context,
+                                                    workingMemory );
                 }
             }
         }
@@ -193,8 +193,8 @@
                 tuple.setMatches( tuple.getMatches() - 1 );
                 if ( tuple.getMatches() == 0 ) {
                     this.sink.propagateRetractTuple( tuple,
-                                                    context,
-                                                    workingMemory );
+                                                     context,
+                                                     workingMemory );
                 }
             }
         }

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-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/JoinNode.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -48,7 +48,7 @@
  * @author <a href="mailto:bob at werken.com">Bob McWhirter</a>
  *
  */
-class JoinNode extends BetaNode {
+public class JoinNode extends BetaNode {
     // ------------------------------------------------------------
     // Instance methods
     // ------------------------------------------------------------
@@ -66,7 +66,7 @@
      * @param rightInput
      *            The right input <code>TupleSource</code>.
      */
-    JoinNode(final int id,
+    public JoinNode(final int id,
              final TupleSource leftInput,
              final ObjectSource rightInput) {
         super( id,
@@ -74,7 +74,7 @@
                rightInput );
     }
 
-    JoinNode(final int id,
+    public JoinNode(final int id,
              final TupleSource leftInput,
              final ObjectSource rightInput,
              final BetaConstraints binder) {

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/LeftInputAdapterNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/LeftInputAdapterNode.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/LeftInputAdapterNode.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -39,7 +39,7 @@
  * @author <a href="mailto:bob at werken.com">Bob McWhirter</a>
  *
  */
-class LeftInputAdapterNode extends TupleSource
+public class LeftInputAdapterNode extends TupleSource
     implements
     ObjectSinkNode,
     NodeMemory {

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/MemoryVisitor.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/MemoryVisitor.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/MemoryVisitor.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -3,7 +3,7 @@
 import java.lang.reflect.Field;
 
 import org.drools.common.InternalWorkingMemory;
-import org.drools.reteoo.TerminalNode.TerminalNodeMemory;
+import org.drools.reteoo.RuleTerminalNode.TerminalNodeMemory;
 import org.drools.util.AbstractHashTable;
 import org.drools.util.Entry;
 import org.drools.util.FactHashTable;
@@ -170,7 +170,7 @@
         this.indent--;
     }
 
-    public void visitTerminalNode(final TerminalNode node) {
+    public void visitTerminalNode(final RuleTerminalNode node) {
         System.out.println( indent() + node );
         final TerminalNodeMemory memory = (TerminalNodeMemory) this.workingMemory.getNodeMemory( node );
         checkTupleMemory( memory.getTupleMemory() );

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-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/NotNode.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -59,9 +59,9 @@
      * @param rightInput
      *            The right input <code>TupleSource</code>.
      */
-    NotNode(final int id,
-            final TupleSource leftInput,
-            final ObjectSource rightInput) {
+    public NotNode(final int id,
+                   final TupleSource leftInput,
+                   final ObjectSource rightInput) {
         super( id,
                leftInput,
                rightInput,
@@ -76,10 +76,10 @@
      * @param rightInput
      *            The right input <code>TupleSource</code>.
      */
-    NotNode(final int id,
-            final TupleSource leftInput,
-            final ObjectSource rightInput,
-            final BetaConstraints joinNodeBinder) {
+    public NotNode(final int id,
+                   final TupleSource leftInput,
+                   final ObjectSource rightInput,
+                   final BetaConstraints joinNodeBinder) {
         super( id,
                leftInput,
                rightInput,
@@ -105,7 +105,8 @@
         memory.getTupleMemory().add( leftTuple );
 
         final Iterator it = memory.getFactHandleMemory().iterator( leftTuple );
-        this.constraints.updateFromTuple( workingMemory, leftTuple );
+        this.constraints.updateFromTuple( workingMemory,
+                                          leftTuple );
         int matches = 0;
         for ( FactEntry entry = (FactEntry) it.next(); entry != null; entry = (FactEntry) it.next() ) {
             final InternalFactHandle handle = entry.getFactHandle();
@@ -142,7 +143,8 @@
         memory.getFactHandleMemory().add( handle );
 
         final Iterator it = memory.getTupleMemory().iterator( handle );
-        this.constraints.updateFromFactHandle( workingMemory, handle );
+        this.constraints.updateFromFactHandle( workingMemory,
+                                               handle );
         for ( ReteTuple tuple = (ReteTuple) it.next(); tuple != null; tuple = (ReteTuple) it.next() ) {
             if ( this.constraints.isAllowedCachedRight( tuple ) ) {
                 final int matches = tuple.getMatches();
@@ -179,7 +181,8 @@
         }
 
         final Iterator it = memory.getTupleMemory().iterator( handle );
-        this.constraints.updateFromFactHandle( workingMemory, handle );
+        this.constraints.updateFromFactHandle( workingMemory,
+                                               handle );
         for ( ReteTuple tuple = (ReteTuple) it.next(); tuple != null; tuple = (ReteTuple) it.next() ) {
             if ( this.constraints.isAllowedCachedRight( tuple ) ) {
                 tuple.setMatches( tuple.getMatches() - 1 );

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectSource.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectSource.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectSource.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -17,7 +17,6 @@
  */
 
 import java.io.Serializable;
-import java.util.List;
 
 import org.drools.common.BaseNode;
 import org.drools.common.DefaultFactHandle;
@@ -37,7 +36,7 @@
  * @author <a href="mailto:mark.proctor at jboss.com">Mark Proctor</a>
  * @author <a href="mailto:bob at werken.com">Bob McWhirter</a>
  */
-abstract class ObjectSource extends BaseNode
+public abstract class ObjectSource extends BaseNode
     implements
     Serializable {
     // ------------------------------------------------------------

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectTypeNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectTypeNode.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectTypeNode.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -19,7 +19,6 @@
 import java.io.Serializable;
 
 import org.drools.RuleBaseConfiguration;
-import org.drools.base.ClassObjectType;
 import org.drools.base.ShadowProxy;
 import org.drools.common.BaseNode;
 import org.drools.common.InternalFactHandle;
@@ -51,7 +50,7 @@
  * @author <a href="mailto:mark.proctor at jboss.com">Mark Proctor</a>
  * @author <a href="mailto:bob at werken.com">Bob McWhirter</a>
  */
-class ObjectTypeNode extends ObjectSource
+public class ObjectTypeNode extends ObjectSource
     implements
     ObjectSink,
     Serializable,

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/QueryTerminalNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/QueryTerminalNode.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/QueryTerminalNode.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -34,10 +34,11 @@
  * 
  * @author <a href="mailto:bob at eng.werken.com">bob mcwhirter </a>
  */
-final class QueryTerminalNode extends BaseNode
+public final class QueryTerminalNode extends BaseNode
     implements
     TupleSink,
-    NodeMemory {
+    NodeMemory,
+    TerminalNode {
     // ------------------------------------------------------------
     // Instance members
     // ------------------------------------------------------------
@@ -62,9 +63,9 @@
      * @param rule
      *            The rule.
      */
-    QueryTerminalNode(final int id,
-                      final TupleSource source,
-                      final Rule rule) {
+    public QueryTerminalNode(final int id,
+                             final TupleSource source,
+                             final Rule rule) {
         super( id );
         this.rule = rule;
         this.tupleSource = source;
@@ -134,7 +135,9 @@
                                                                                       PropagationContext.RULE_ADDITION,
                                                                                       null,
                                                                                       null );
-            this.tupleSource.updateSink( this, propagationContext, workingMemory );
+            this.tupleSource.updateSink( this,
+                                         propagationContext,
+                                         workingMemory );
         }
     }
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteTuple.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteTuple.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteTuple.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -103,7 +103,7 @@
     }
 
     public InternalFactHandle get(final Declaration declaration) {
-        return get( declaration.getColumn().getFactIndex() );
+        return get( declaration.getColumn().getOffset() );
     }
 
     public Activation getActivation() {

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooBuilder.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooBuilder.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -42,6 +42,7 @@
 import org.drools.common.QuadroupleBetaConstraints;
 import org.drools.common.SingleBetaConstraints;
 import org.drools.common.TripleBetaConstraints;
+import org.drools.reteoo.builder.ReteooRuleBuilder;
 import org.drools.rule.Accumulate;
 import org.drools.rule.Collect;
 import org.drools.rule.Column;
@@ -67,7 +68,7 @@
  * @author <a href="mailto:bob at werken.com">Bob McWhirter</a>
  * 
  */
-class ReteooBuilder
+public class ReteooBuilder
     implements
     Serializable {
     // ------------------------------------------------------------
@@ -90,21 +91,13 @@
     /** Nodes that have been attached. */
     private final Map                       attachedNodes;
 
-    private TupleSource                     tupleSource;
-
-    private ObjectSource                    objectSource;
-
-    private Map                             declarations;
-
-    private int                             id;
-
     private Map                             rules;
 
-    private Map                             objectType;
-
-    private int                             currentOffsetAdjustment;
-    
     private final boolean                   removeIdentities;
+    
+    private transient ReteooRuleBuilder     ruleBuilder;
+    
+    private IdGenerator                     idGenerator;
 
     // ------------------------------------------------------------
     // Constructors
@@ -121,8 +114,9 @@
         this.rules = new HashMap();
 
         //Set to 1 as Rete node is set to 0
-        this.id = 1;
+        this.idGenerator = new IdGenerator(1);
         this.removeIdentities = this.ruleBase.getConfiguration().isRemoveIdentities();
+        this.ruleBuilder = new ReteooRuleBuilder();
     }
 
     /**
@@ -157,613 +151,89 @@
      * @throws InvalidPatternException
      */
     void addRule(final Rule rule) throws InvalidPatternException {
-        // reset working memories for potential propagation
-        this.workingMemories = (ReteooWorkingMemory[]) this.ruleBase.getWorkingMemories().toArray( new ReteooWorkingMemory[this.ruleBase.getWorkingMemories().size()] );
-        this.currentOffsetAdjustment = 0;
+        List terminals = this.ruleBuilder.addRule( rule, this.ruleBase, this.attachedNodes, this.idGenerator );
+        
 
-        final List nodes = new ArrayList();
-        final GroupElement[] and = rule.getTransformedLhs();
-
-        for ( int i = 0; i < and.length; i++ ) {
-            if ( !hasColumns( and[i] ) ) {
-                addInitialFactMatch( and[i] );
-            }
-
-            addRule( and[i],
-                     rule );
-            BaseNode node = null;
-            if ( !(rule instanceof Query) ) {
-                // Check a consequence is set
-                if ( rule.getConsequence() == null ) {
-                    throw new InvalidPatternException( "Rule '" + rule.getName() + "' has no Consequence" );
-                }
-                node = new TerminalNode( this.id++,
-                                         this.tupleSource,
-                                         rule );
-            } else {
-                // Check there is no consequence
-                if ( rule.getConsequence() != null ) {
-                    throw new InvalidPatternException( "Query '" + rule.getName() + "' should have no Consequence" );
-                }
-                node = new QueryTerminalNode( this.id++,
-                                              this.tupleSource,
-                                              rule );
-            }
-
-            nodes.add( node );
-
-            if ( this.workingMemories.length == 0 ) {
-                node.attach();
-            } else {
-                node.attach( this.workingMemories );
-            }
-        }
-
         this.rules.put( rule,
-                        nodes.toArray( new BaseNode[nodes.size()] ) );
+                        terminals.toArray( new BaseNode[terminals.size()] ) );
     }
 
-    private boolean hasColumns(final GroupElement ge) {
-        for ( final Iterator it = ge.getChildren().iterator(); it.hasNext(); ) {
-            final Object object = it.next();
-            if ( object instanceof Column || (object instanceof GroupElement && hasColumns( (GroupElement) object )) ) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private void addInitialFactMatch(final GroupElement and) {
-        GroupElement temp = null;
-
-        // If we have children we know there are no columns but we need to make sure that InitialFact is first
-        if ( !and.getChildren().isEmpty() ) {
-            temp = (GroupElement) and.clone();
-            and.getChildren().clear();
-        }
-        final Column column = new Column( 0,
-                                          new ClassObjectType( InitialFact.class ) );
-        and.addChild( column );
-
-        // now we know InitialFact is first add all the previous constrains
-        if ( temp != null ) {
-            and.getChildren().addAll( temp.getChildren() );
-        }
-        this.currentOffsetAdjustment = 1;
-    }
-
-    private void addRule(final GroupElement and,
-                         final Rule rule) throws InvalidPatternException {
-        this.objectSource = null;
-        this.tupleSource = null;
-        this.declarations = new HashMap();
-        this.objectType = new LinkedHashMap();
-
-        if ( rule instanceof Query ) {
-            attachQuery( rule.getName() );
-        }
-
-        for ( final Iterator it = and.getChildren().iterator(); it.hasNext(); ) {
-            final Object object = it.next();
-
-            if ( object instanceof EvalCondition ) {
-                final EvalCondition eval = (EvalCondition) object;
-                checkUnboundDeclarations( eval.getRequiredDeclarations() );
-                this.tupleSource = attachNode( new EvalConditionNode( this.id++,
-                                                                      this.tupleSource,
-                                                                      eval ) );
-                continue;
-            }
-
-            BetaConstraints binder = null;
-            Column column = null;
-
-            if ( object instanceof Column ) {
-                column = (Column) object;
-
-                // @REMOVEME after the milestone period
-                if(( binder != null) && ( binder != EmptyBetaConstraints.getInstance()))
-                    throw new RuntimeDroolsException("This is a bug! Please report to Drools development team!");
-                
-                binder = attachColumn( (Column) object,
-                                       and,
-                                       this.removeIdentities );
-
-                // If a tupleSource does not exist then we need to adapt this
-                // into
-                // a TupleSource using LeftInputAdapterNode
-                if ( this.tupleSource == null ) {
-                    this.tupleSource = attachNode( new LeftInputAdapterNode( this.id++,
-                                                                             this.objectSource ) );
-
-                    // objectSource is created by the attachColumn method, if we
-                    // adapt this to
-                    // a TupleSource then we need to null the objectSource
-                    // reference.
-                    this.objectSource = null;
-                }
-            } else if ( object instanceof GroupElement ) {
-                // If its not a Column or EvalCondition then it can either be a Not or an Exists
-                GroupElement ce = (GroupElement) object;
-                while ( !(ce.getChildren().get( 0 ) instanceof Column) ) {
-                    ce = (GroupElement) ce.getChildren().get( 0 );
-                }
-                column = (Column) ce.getChildren().get( 0 );
-
-                // If a tupleSource does not exist then we need to adapt an
-                // InitialFact into a a TupleSource using LeftInputAdapterNode
-                if ( this.tupleSource == null ) {
-                    // adjusting offset as all tuples will now contain initial-fact at index 0
-                    this.currentOffsetAdjustment = 1;
-
-                    final ObjectSource objectSource = attachNode( new ObjectTypeNode( this.id++,
-                                                                                      new ClassObjectType( InitialFact.class ),
-                                                                                      this.rete,
-                                                                                      this.ruleBase.getConfiguration().getAlphaNodeHashingThreshold()) );
-
-                    this.tupleSource = attachNode( new LeftInputAdapterNode( this.id++,
-                                                                             objectSource ) );
-                }
-
-                // @REMOVEME after the milestone period
-                if(( binder != null) && ( binder != EmptyBetaConstraints.getInstance()))
-                    throw new RuntimeDroolsException("This is a bug! Please report to Drools development team!");
-
-                binder = attachColumn( column,
-                                       and,
-                                       this.removeIdentities );
-            }
-
-            if (( object instanceof GroupElement ) && (((GroupElement)object).isNot())) {
-                attachNot( this.tupleSource,
-                           (GroupElement) object,
-                           this.objectSource,
-                           binder,
-                           column );
-                binder = null;
-            } else if (( object instanceof GroupElement ) && (((GroupElement)object).isExists())) {
-                attachExists( this.tupleSource,
-                              (GroupElement) object,
-                              this.objectSource,
-                              binder,
-                              column );
-                binder = null;
-            } else if ( object.getClass() == From.class ) {
-                attachFrom( this.tupleSource,
-                            (From) object );
-            } else if ( object.getClass() == Accumulate.class ) {
-                attachAccumulate( this.tupleSource,
-                                  and,
-                                  (Accumulate) object );
-            } else if ( object.getClass() == Collect.class ) {
-                attachCollect( this.tupleSource,
-                               and,
-                               (Collect) object );
-            } else if ( this.objectSource != null ) {
-                this.tupleSource = attachNode( new JoinNode( this.id++,
-                                                             this.tupleSource,
-                                                             this.objectSource,
-                                                             binder ) );
-                binder = null;
-            }
-        }
-    }
-
     public BaseNode[] getTerminalNodes(final Rule rule) {
         return (BaseNode[]) this.rules.remove( rule );
     }
 
-    private void attachQuery(final String queryName) {
-        // incrementing offset adjustment, since we are adding a new ObjectNodeType as our
-        // first column
-        this.currentOffsetAdjustment += 1;
+//    private void attachAccumulate(final TupleSource tupleSource,
+//                                  final GroupElement parent,
+//                                  final Accumulate accumulate) {
+//        // If a tupleSource does not exist then we need to adapt an
+//        // InitialFact into a a TupleSource using LeftInputAdapterNode
+//        if ( this.tupleSource == null ) {
+//            // adjusting offset as all tuples will now contain initial-fact at index 0
+//            this.currentOffsetAdjustment = 1;
+//
+//            final ObjectSource auxObjectSource = attachNode( new ObjectTypeNode( this.id++,
+//                                                                                 new ClassObjectType( InitialFact.class ),
+//                                                                                 this.rete,
+//                                                                                 this.ruleBase.getConfiguration().getAlphaNodeHashingThreshold()) );
+//
+//            this.tupleSource = attachNode( new LeftInputAdapterNode( this.id++,
+//                                                                     auxObjectSource ) );
+//        }
+//
+//        final Column sourceColumn = accumulate.getSourceColumn();
+//        final BetaConstraints sourceBinder = attachColumn( sourceColumn,
+//                                                           parent,
+//                                                           true );
+//
+//        final Column column = accumulate.getResultColumn();
+//        // Adjusting offset in case a previous Initial-Fact was added to the network
+//        column.adjustOffset( this.currentOffsetAdjustment );
+//
+//        final List constraints = column.getConstraints();
+//
+//        // Check if the Column is bound
+//        if ( column.getDeclaration() != null ) {
+//            final Declaration declaration = column.getDeclaration();
+//            // Add the declaration the map of previously bound declarations
+//            this.declarations.put( declaration.getIdentifier(),
+//                                   declaration );
+//        }
+//
+//        final List betaConstraints = new ArrayList();
+//        final List alphaConstraints = new ArrayList();
+//
+//        for ( final Iterator it = constraints.iterator(); it.hasNext(); ) {
+//            final Object object = it.next();
+//            // Check if its a declaration
+//            if ( object instanceof Declaration ) {
+//                final Declaration declaration = (Declaration) object;
+//                // Add the declaration the map of previously bound declarations
+//                this.declarations.put( declaration.getIdentifier(),
+//                                       declaration );
+//                continue;
+//            }
+//
+//            final AlphaNodeFieldConstraint fieldConstraint = (AlphaNodeFieldConstraint) object;
+//            if ( fieldConstraint instanceof LiteralConstraint ) {
+//                alphaConstraints.add( fieldConstraint );
+//            } else {
+//                checkUnboundDeclarations( fieldConstraint.getRequiredDeclarations() );
+//                betaConstraints.add( fieldConstraint );
+//            }
+//        }
+//
+//        final BetaConstraints resultsBinder = createBetaNodeConstraint( betaConstraints );
+//
+//        this.tupleSource = attachNode( new AccumulateNode( this.id++,
+//                                                           this.tupleSource,
+//                                                           this.objectSource,
+//                                                           (AlphaNodeFieldConstraint[]) alphaConstraints.toArray( new AlphaNodeFieldConstraint[alphaConstraints.size()] ),
+//                                                           sourceBinder,
+//                                                           resultsBinder,
+//                                                           accumulate ) );
+//    }
+//
 
-        final ObjectSource objectTypeSource = attachNode( new ObjectTypeNode( this.id++,
-                                                                              new ClassObjectType( DroolsQuery.class ),
-                                                                              this.rete,
-                                                                              this.ruleBase.getConfiguration().getAlphaNodeHashingThreshold()) );
-
-        final ClassFieldExtractor extractor = new ClassFieldExtractor( DroolsQuery.class,
-                                                                       "name" );
-
-        final FieldValue field = FieldFactory.getFieldValue( queryName,
-                                                             ValueType.STRING_TYPE );
-
-        final LiteralConstraint constraint = new LiteralConstraint( extractor,
-                                                                    ValueType.STRING_TYPE.getEvaluator( Operator.EQUAL ),
-                                                                    field );
-
-        final ObjectSource alphaNodeSource = attachNode( new AlphaNode( this.id++,
-                                                                        constraint,
-                                                                        objectTypeSource,
-                                                                        this.ruleBase.getConfiguration().isAlphaMemory(),
-                                                                        this.ruleBase.getConfiguration().getAlphaNodeHashingThreshold()) );
-
-        this.tupleSource = attachNode( new LeftInputAdapterNode( this.id++,
-                                                                 alphaNodeSource ) );
-    }
-
-    private BetaConstraints attachColumn(final Column column,
-                                         final GroupElement parent,
-                                         boolean removeIdentities) throws InvalidPatternException {
-        // Adjusting offset in case a previous Initial-Fact was added to the network
-        column.adjustOffset( this.currentOffsetAdjustment );
-
-        // Check if the Column is bound
-        if ( column.getDeclaration() != null ) {
-            final Declaration declaration = column.getDeclaration();
-            // Add the declaration the map of previously bound declarations
-            this.declarations.put( declaration.getIdentifier(),
-                                   declaration );
-        }
-
-        final List predicates = attachAlphaNodes( column,
-                                                  removeIdentities );
-
-        final BetaConstraints binder = createBetaNodeConstraint( predicates );
-
-        return binder;
-    }
-
-    public List attachAlphaNodes(final Column column,
-                                 final boolean removeIdentities) throws InvalidPatternException {
-        final List constraints = column.getConstraints();
-
-        this.objectSource = attachNode( new ObjectTypeNode( this.id++,
-                                                            column.getObjectType(),
-                                                            this.rete,
-                                                            this.ruleBase.getConfiguration().getAlphaNodeHashingThreshold()) );
-
-        final List betaConstraints = new ArrayList();
-
-        if ( removeIdentities && column.getObjectType().getClass() == ClassObjectType.class ) {
-            // Check if this object type exists before
-            // If it does we need stop instance equals cross product
-            final Class thisClass = ((ClassObjectType) column.getObjectType()).getClassType();
-            for ( final Iterator it = this.objectType.entrySet().iterator(); it.hasNext(); ) {
-                final Map.Entry entry = (Map.Entry) it.next();
-                final Class previousClass = ((ClassObjectType) entry.getKey()).getClassType();
-                if ( thisClass.isAssignableFrom( previousClass ) ) {
-                    betaConstraints.add( new InstanceNotEqualsConstraint( (Column) entry.getValue() ) );
-                }
-            }
-
-            // Must be added after the checking, otherwise it matches against itself
-            this.objectType.put( column.getObjectType(),
-                                 column );
-        }
-
-        for ( final Iterator it = constraints.iterator(); it.hasNext(); ) {
-            final Object object = it.next();
-            // Check if its a declaration
-            if ( object instanceof Declaration ) {
-                final Declaration declaration = (Declaration) object;
-                // Add the declaration the map of previously bound declarations
-                this.declarations.put( declaration.getIdentifier(),
-                                       declaration );
-                continue;
-            }
-
-            final Constraint constraint = (Constraint) object;
-            Declaration[] declarations = constraint.getRequiredDeclarations();
-
-            boolean isAlphaConstraint = true;
-            for(int i = 0; isAlphaConstraint && i < declarations.length; i++ ) {
-                if( declarations[i].getColumn() != column ) {
-                    isAlphaConstraint = false;
-                }
-            }
-            if ( isAlphaConstraint ) {
-                this.objectSource = attachNode( new AlphaNode( this.id++,
-                                                               (AlphaNodeFieldConstraint) constraint,
-                                                               this.objectSource ) );
-            } else {
-                checkUnboundDeclarations( constraint.getRequiredDeclarations() );
-                betaConstraints.add( constraint );
-            }
-        }
-
-        return betaConstraints;
-    }
-
-    private void attachNot(final TupleSource tupleSource,
-                           final GroupElement not,
-                           final ObjectSource ObjectSource,
-                           final BetaConstraints binder,
-                           final Column column) {
-        final NotNode notNode = (NotNode) attachNode( new NotNode( this.id++,
-                                                                   tupleSource,
-                                                                   ObjectSource,
-                                                                   binder ) );
-        this.tupleSource = notNode;
-    }
-
-    private void attachExists(final TupleSource tupleSource,
-                              final GroupElement exists,
-                              final ObjectSource ObjectSource,
-                              final BetaConstraints binder,
-                              final Column column) {
-        ExistsNode existsNode = (ExistsNode) attachNode( new ExistsNode( this.id++,
-                                                             tupleSource,
-                                                             ObjectSource,
-                                                             binder ) );
-        this.tupleSource = existsNode;
-    }
-
-    /**
-     * Attaches a node into the network. If a node already exists that could
-     * substitute, it is used instead.
-     * 
-     * @param candidate
-     *            The node to attach.
-     * @param leafNodes
-     *            The list to which the newly added node will be added.
-     */
-    private TupleSource attachNode(final TupleSource candidate) {
-        TupleSource node = (TupleSource) this.attachedNodes.get( candidate );
-
-        if ( this.ruleBase.getConfiguration().isShareBetaNodes() && node !=  null ) {
-            if ( !node.isInUse() ) {
-                if ( this.workingMemories.length == 0 ) {
-                    node.attach();
-                } else {
-                    node.attach( this.workingMemories );
-                }
-            }
-            node.addShare();
-            this.id--;
-        } else {
-            if ( this.workingMemories.length == 0 ) {
-                candidate.attach();
-            } else {
-                candidate.attach( this.workingMemories );
-            }
-
-            this.attachedNodes.put( candidate,
-                                    candidate );
-
-            node = candidate;            
-        }
-        
-        return node;
-    }
-
-    private void attachFrom(final TupleSource tupleSource,
-                            final From from) {
-        final Column column = from.getColumn();
-
-        // If a tupleSource does not exist then we need to adapt an
-        // InitialFact into a a TupleSource using LeftInputAdapterNode
-        if ( this.tupleSource == null ) {
-            // adjusting offset as all tuples will now contain initial-fact at index 0
-            this.currentOffsetAdjustment = 1;
-
-            final ObjectSource objectSource = attachNode( new ObjectTypeNode( this.id++,
-                                                                              new ClassObjectType( InitialFact.class ),
-                                                                              this.rete,
-                                                                              this.ruleBase.getConfiguration().getAlphaNodeHashingThreshold()) );
-
-            this.tupleSource = attachNode( new LeftInputAdapterNode( this.id++,
-                                                                     objectSource ) );
-        }
-
-        // Adjusting offset in case a previous Initial-Fact was added to the network
-        column.adjustOffset( this.currentOffsetAdjustment );
-
-        final List constraints = column.getConstraints();
-
-        // Check if the Column is bound
-        if ( column.getDeclaration() != null ) {
-            final Declaration declaration = column.getDeclaration();
-            // Add the declaration the map of previously bound declarations
-            this.declarations.put( declaration.getIdentifier(),
-                                   declaration );
-        }
-
-        final List betaConstraints = new ArrayList();
-        final List alphaConstraints = new ArrayList();
-
-        for ( final Iterator it = constraints.iterator(); it.hasNext(); ) {
-            final Object object = it.next();
-            // Check if its a declaration
-            if ( object instanceof Declaration ) {
-                final Declaration declaration = (Declaration) object;
-                // Add the declaration the map of previously bound declarations
-                this.declarations.put( declaration.getIdentifier(),
-                                       declaration );
-                continue;
-            }
-
-            final AlphaNodeFieldConstraint fieldConstraint = (AlphaNodeFieldConstraint) object;
-            if ( fieldConstraint instanceof LiteralConstraint ) {
-                alphaConstraints.add( fieldConstraint );
-            } else {
-                checkUnboundDeclarations( fieldConstraint.getRequiredDeclarations() );
-                betaConstraints.add( fieldConstraint );
-            }
-        }
-
-        final BetaConstraints binder = createBetaNodeConstraint( betaConstraints );
-
-        this.tupleSource = attachNode( new FromNode( this.id++,
-                                                     from.getDataProvider(),
-                                                     this.tupleSource,
-                                                     (AlphaNodeFieldConstraint[]) alphaConstraints.toArray( new AlphaNodeFieldConstraint[alphaConstraints.size()] ),
-                                                     binder ) );
-
-    }
-
-    private void attachAccumulate(final TupleSource tupleSource,
-                                  final GroupElement parent,
-                                  final Accumulate accumulate) {
-        // If a tupleSource does not exist then we need to adapt an
-        // InitialFact into a a TupleSource using LeftInputAdapterNode
-        if ( this.tupleSource == null ) {
-            // adjusting offset as all tuples will now contain initial-fact at index 0
-            this.currentOffsetAdjustment = 1;
-
-            final ObjectSource auxObjectSource = attachNode( new ObjectTypeNode( this.id++,
-                                                                                 new ClassObjectType( InitialFact.class ),
-                                                                                 this.rete,
-                                                                                 this.ruleBase.getConfiguration().getAlphaNodeHashingThreshold()) );
-
-            this.tupleSource = attachNode( new LeftInputAdapterNode( this.id++,
-                                                                     auxObjectSource ) );
-        }
-
-        final Column sourceColumn = accumulate.getSourceColumn();
-        final BetaConstraints sourceBinder = attachColumn( sourceColumn,
-                                                           parent,
-                                                           true );
-
-        final Column column = accumulate.getResultColumn();
-        // Adjusting offset in case a previous Initial-Fact was added to the network
-        column.adjustOffset( this.currentOffsetAdjustment );
-
-        final List constraints = column.getConstraints();
-
-        // Check if the Column is bound
-        if ( column.getDeclaration() != null ) {
-            final Declaration declaration = column.getDeclaration();
-            // Add the declaration the map of previously bound declarations
-            this.declarations.put( declaration.getIdentifier(),
-                                   declaration );
-        }
-
-        final List betaConstraints = new ArrayList();
-        final List alphaConstraints = new ArrayList();
-
-        for ( final Iterator it = constraints.iterator(); it.hasNext(); ) {
-            final Object object = it.next();
-            // Check if its a declaration
-            if ( object instanceof Declaration ) {
-                final Declaration declaration = (Declaration) object;
-                // Add the declaration the map of previously bound declarations
-                this.declarations.put( declaration.getIdentifier(),
-                                       declaration );
-                continue;
-            }
-
-            final AlphaNodeFieldConstraint fieldConstraint = (AlphaNodeFieldConstraint) object;
-            if ( fieldConstraint instanceof LiteralConstraint ) {
-                alphaConstraints.add( fieldConstraint );
-            } else {
-                checkUnboundDeclarations( fieldConstraint.getRequiredDeclarations() );
-                betaConstraints.add( fieldConstraint );
-            }
-        }
-
-        final BetaConstraints resultsBinder = createBetaNodeConstraint( betaConstraints );
-
-        this.tupleSource = attachNode( new AccumulateNode( this.id++,
-                                                           this.tupleSource,
-                                                           this.objectSource,
-                                                           (AlphaNodeFieldConstraint[]) alphaConstraints.toArray( new AlphaNodeFieldConstraint[alphaConstraints.size()] ),
-                                                           sourceBinder,
-                                                           resultsBinder,
-                                                           accumulate ) );
-    }
-
-    private void attachCollect(final TupleSource tupleSource,
-                               final GroupElement parent,
-                               final Collect collect) {
-        // If a tupleSource does not exist then we need to adapt an
-        // InitialFact into a a TupleSource using LeftInputAdapterNode
-        if ( this.tupleSource == null ) {
-            // adjusting offset as all tuples will now contain initial-fact at index 0
-            this.currentOffsetAdjustment = 1;
-
-            final ObjectSource auxObjectSource = attachNode( new ObjectTypeNode( this.id++,
-                                                                                 new ClassObjectType( InitialFact.class ),
-                                                                                 this.rete,
-                                                                                 this.ruleBase.getConfiguration().getAlphaNodeHashingThreshold()) );
-
-            this.tupleSource = attachNode( new LeftInputAdapterNode( this.id++,
-                                                                     auxObjectSource ) );
-        }
-
-        final Column sourceColumn = collect.getSourceColumn();
-        final BetaConstraints sourceBinder = attachColumn( sourceColumn,
-                                                           parent,
-                                                           true );
-
-        final Column column = collect.getResultColumn();
-        // Adjusting offset in case a previous Initial-Fact was added to the network
-        column.adjustOffset( this.currentOffsetAdjustment );
-
-        final List constraints = column.getConstraints();
-
-        // Check if the Column is bound
-        if ( column.getDeclaration() != null ) {
-            final Declaration declaration = column.getDeclaration();
-            // Add the declaration the map of previously bound declarations
-            this.declarations.put( declaration.getIdentifier(),
-                                   declaration );
-        }
-
-        final List betaConstraints = new ArrayList();
-        final List alphaConstraints = new ArrayList();
-
-        for ( final Iterator it = constraints.iterator(); it.hasNext(); ) {
-            final Object object = it.next();
-            // Check if its a declaration
-            if ( object instanceof Declaration ) {
-                final Declaration declaration = (Declaration) object;
-                // Add the declaration the map of previously bound declarations
-                this.declarations.put( declaration.getIdentifier(),
-                                       declaration );
-                continue;
-            }
-
-            final AlphaNodeFieldConstraint fieldConstraint = (AlphaNodeFieldConstraint) object;
-            if ( fieldConstraint instanceof LiteralConstraint ) {
-                alphaConstraints.add( fieldConstraint );
-            } else {
-                checkUnboundDeclarations( fieldConstraint.getRequiredDeclarations() );
-                betaConstraints.add( fieldConstraint );
-            }
-        }
-
-        final BetaConstraints resultsBinder = createBetaNodeConstraint( betaConstraints );
-
-        this.tupleSource = attachNode( new CollectNode( this.id++,
-                                                        this.tupleSource,
-                                                        this.objectSource,
-                                                        (AlphaNodeFieldConstraint[]) alphaConstraints.toArray( new AlphaNodeFieldConstraint[alphaConstraints.size()] ),
-                                                        sourceBinder,
-                                                        resultsBinder,
-                                                        collect ) );
-    }
-
-    private ObjectSource attachNode(final ObjectSource candidate) {
-        ObjectSource node = (ObjectSource) this.attachedNodes.get( candidate );
-
-        if ( this.ruleBase.getConfiguration().isShareAlphaNodes() && node != null) {
-            if ( !node.isInUse() ) {
-                if ( this.workingMemories.length == 0 ) {
-                    node.attach();
-                } else {
-                    node.attach( this.workingMemories );
-                }
-            }
-            node.addShare();
-            this.id--;
-        } else {
-            if ( this.workingMemories.length == 0 ) {
-                candidate.attach();
-            } else {
-                candidate.attach( this.workingMemories );
-            }
-
-            this.attachedNodes.put( candidate,
-                                    candidate );
-
-            node = candidate;
-        }
-
-        return node;
-    }
-
     public void removeRule(final Rule rule) {
         // reset working memories for potential propagation
         this.workingMemories = (ReteooWorkingMemory[]) this.ruleBase.getWorkingMemories().toArray( new ReteooWorkingMemory[this.ruleBase.getWorkingMemories().size()] );
@@ -777,55 +247,26 @@
                          this.workingMemories );
         }
     }
+    
+    public static class IdGenerator implements Serializable {
 
-    /**
-     * Make sure the required declarations are previously bound
-     * 
-     * @param declarations
-     * @throws InvalidPatternException
-     */
-    private void checkUnboundDeclarations(final Declaration[] declarations) throws InvalidPatternException {
-        final List list = new ArrayList();
-        for ( int i = 0, length = declarations.length; i < length; i++ ) {
-            if ( this.declarations.get( declarations[i].getIdentifier() ) == null ) {
-                list.add( declarations[i].getIdentifier() );
-            }
-        }
+        private static final long serialVersionUID = -5909710713463187779L;
 
-        // Make sure the required declarations        
-        if ( list.size() != 0 ) {
-            final StringBuffer buffer = new StringBuffer();
-            buffer.append( list.get( 0 ) );
-            for ( int i = 1, size = list.size(); i < size; i++ ) {
-                buffer.append( ", " + list.get( i ) );
-            }
-
-            throw new InvalidPatternException( "Required Declarations not bound: '" + buffer );
+        private int nextId;
+        
+        public IdGenerator( int firstId ) {
+            this.nextId = firstId;
         }
-    }
-
-    public BetaConstraints createBetaNodeConstraint(final List list) {
-        BetaConstraints constraints;
-        switch ( list.size() ) {
-            case 0 :
-                constraints = EmptyBetaConstraints.getInstance();
-                break;
-            case 1 :
-                constraints = new SingleBetaConstraints( (BetaNodeFieldConstraint) list.get( 0 ), this.ruleBase.getConfiguration() );
-                break;
-            case 2 :
-                constraints = new DoubleBetaConstraints( (BetaNodeFieldConstraint[]) list.toArray( new BetaNodeFieldConstraint[list.size()] ), this.ruleBase.getConfiguration() );
-                break;
-            case 3 :
-                constraints = new TripleBetaConstraints( (BetaNodeFieldConstraint[]) list.toArray( new BetaNodeFieldConstraint[list.size()] ), this.ruleBase.getConfiguration() );
-                break;
-            case 4 :
-                constraints = new QuadroupleBetaConstraints( (BetaNodeFieldConstraint[]) list.toArray( new BetaNodeFieldConstraint[list.size()] ), this.ruleBase.getConfiguration() );
-                break;                
-            default :
-                constraints = new DefaultBetaConstraints( (BetaNodeFieldConstraint[]) list.toArray( new BetaNodeFieldConstraint[list.size()] ), this.ruleBase.getConfiguration() );
+        
+        public int getNextId() {
+            return this.nextId++;
         }
-        return constraints;
+        
+        public void releaseLastId() {
+            this.nextId--;
+        }
+        
     }
 
+
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooRuleBase.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooRuleBase.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooRuleBase.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -172,7 +172,7 @@
      * 
      * @return The RETE-OO network.
      */
-    Rete getRete() {
+    public Rete getRete() {
         return this.rete;
     }
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RightInputAdapterNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RightInputAdapterNode.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RightInputAdapterNode.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -17,7 +17,6 @@
  */
 
 import org.drools.common.BaseNode;
-import org.drools.common.InternalFactHandle;
 import org.drools.common.InternalWorkingMemory;
 import org.drools.rule.Column;
 import org.drools.spi.PropagationContext;
@@ -76,7 +75,7 @@
     public void assertTuple(final ReteTuple tuple,
                             final PropagationContext context,
                             final InternalWorkingMemory workingMemory) {
-        this.sink.propagateAssertObject( tuple.get( this.column.getFactIndex() ),
+        this.sink.propagateAssertObject( tuple.get( this.column.getOffset() ),
                                          context,
                                          workingMemory );
     }
@@ -87,7 +86,7 @@
     public void retractTuple(final ReteTuple tuple,
                              final PropagationContext context,
                              final InternalWorkingMemory workingMemory) {
-        this.sink.propagateRetractObject( tuple.get( this.column.getFactIndex() ),
+        this.sink.propagateRetractObject( tuple.get( this.column.getOffset() ),
                                           context,
                                           workingMemory,
                                           true );
@@ -112,7 +111,7 @@
                            final PropagationContext context,
                            final InternalWorkingMemory workingMemory) {
         this.tupleSource.updateSink( new TupleSinkAdapter( sink,
-                                                           this.column.getFactIndex() ),
+                                                           this.column.getOffset() ),
                                      context,
                                      workingMemory );
     }
@@ -136,6 +135,8 @@
     private static class TupleSinkAdapter
         implements
         TupleSink {
+
+        private static final long serialVersionUID = 1636299857108066554L;
         private ObjectSink sink;
         private int        column;
 

Copied: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleTerminalNode.java (from rev 8763, labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/TerminalNode.java)
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/TerminalNode.java	2007-01-08 16:23:00 UTC (rev 8763)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleTerminalNode.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -0,0 +1,397 @@
+package org.drools.reteoo;
+
+/*
+ * Copyright 2005 JBoss Inc
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.Serializable;
+
+import org.drools.RuleBaseConfiguration;
+import org.drools.common.AgendaGroupImpl;
+import org.drools.common.AgendaItem;
+import org.drools.common.BaseNode;
+import org.drools.common.InternalAgenda;
+import org.drools.common.InternalWorkingMemory;
+import org.drools.common.NodeMemory;
+import org.drools.common.PropagationContextImpl;
+import org.drools.common.ScheduledAgendaItem;
+import org.drools.rule.Rule;
+import org.drools.spi.Activation;
+import org.drools.spi.ActivationGroup;
+import org.drools.spi.AgendaGroup;
+import org.drools.spi.Duration;
+import org.drools.spi.PropagationContext;
+import org.drools.util.Iterator;
+import org.drools.util.TupleHashTable;
+
+/**
+ * Leaf Rete-OO node responsible for enacting <code>Action</code> s on a
+ * matched <code>Rule</code>.
+ * 
+ * @see org.drools.rule.Rule
+ * 
+ * @author <a href="mailto:bob at eng.werken.com">bob mcwhirter </a>
+ */
+public final class RuleTerminalNode extends BaseNode
+    implements
+    TupleSinkNode,
+    NodeMemory,
+    TerminalNode {
+    // ------------------------------------------------------------
+    // Instance members
+    // ------------------------------------------------------------
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 320;
+    /** The rule to invoke upon match. */
+    private final Rule        rule;
+    private final TupleSource tupleSource;
+
+    private TupleSinkNode     previousTupleSinkNode;
+    private TupleSinkNode     nextTupleSinkNode;
+
+    // ------------------------------------------------------------
+    // Constructors
+    // ------------------------------------------------------------
+
+    /**
+     * Construct.
+     * 
+     * @param inputSource
+     *            The parent tuple source.
+     * @param rule
+     *            The rule.
+     */
+    public RuleTerminalNode(final int id,
+                            final TupleSource source,
+                            final Rule rule) {
+        super( id );
+        this.rule = rule;
+        this.tupleSource = source;
+    }
+
+    // ------------------------------------------------------------
+    // Instance methods
+    // ------------------------------------------------------------
+
+    /**
+     * Retrieve the <code>Action</code> associated with this node.
+     * 
+     * @return The <code>Action</code> associated with this node.
+     */
+    public Rule getRule() {
+        return this.rule;
+    }
+
+    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+    // org.drools.impl.TupleSink
+    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+    public void assertTuple(final ReteTuple tuple,
+                            final PropagationContext context,
+                            final InternalWorkingMemory workingMemory) {
+        assertTuple( tuple,
+                     context,
+                     workingMemory,
+                     true );
+
+    }
+
+    /**
+     * Assert a new <code>Tuple</code>.
+     * 
+     * @param tuple
+     *            The <code>Tuple</code> being asserted.
+     * @param workingMemory
+     *            The working memory seesion.
+     * @throws AssertionException
+     *             If an error occurs while asserting.
+     */
+    public void assertTuple(final ReteTuple tuple,
+                            final PropagationContext context,
+                            final InternalWorkingMemory workingMemory,
+                            final boolean fireActivationCreated) {
+        //we only have to clone the head fact to make sure the graph is not affected during consequence reads after a modify
+        final ReteTuple cloned = new ReteTuple( tuple );
+
+        // if the current Rule is no-loop and the origin rule is the same then
+        // return
+        if ( this.rule.getNoLoop() && this.rule.equals( context.getRuleOrigin() ) ) {
+            return;
+        }
+        final InternalAgenda agenda = (InternalAgenda) workingMemory.getAgenda();
+
+        final Duration dur = this.rule.getDuration();
+
+        if ( dur != null && dur.getDuration( tuple ) > 0 ) {
+            final ScheduledAgendaItem item = new ScheduledAgendaItem( context.getPropagationNumber(),
+                                                                      cloned,
+                                                                      agenda,
+                                                                      context,
+                                                                      this.rule );
+            final TerminalNodeMemory memory = (TerminalNodeMemory) workingMemory.getNodeMemory( this );
+            if ( this.rule.getActivationGroup() != null ) {
+                // Lazy cache activationGroup
+                if ( memory.getActivationGroup() == null ) {
+                    memory.setActivationGroup( workingMemory.getAgenda().getActivationGroup( this.rule.getActivationGroup() ) );
+                }
+                memory.getActivationGroup().addActivation( item );
+            }
+
+            agenda.scheduleItem( item );
+            tuple.setActivation( item );
+            memory.getTupleMemory().add( tuple );
+
+            item.setActivated( true );
+            workingMemory.getAgendaEventSupport().fireActivationCreated( item,
+                                                                         workingMemory );
+        } else {
+            // -----------------
+            // Lazy instantiation and addition to the Agenda of AgendGroup
+            // implementations
+            // ----------------
+            final TerminalNodeMemory memory = (TerminalNodeMemory) workingMemory.getNodeMemory( this );
+            AgendaGroupImpl agendaGroup = memory.getAgendaGroup();
+            if ( agendaGroup == null ) {
+                if ( this.rule.getAgendaGroup() == null || this.rule.getAgendaGroup().equals( "" ) || this.rule.getAgendaGroup().equals( AgendaGroup.MAIN ) ) {
+                    // Is the Rule AgendaGroup undefined? If it is use MAIN,
+                    // which is added to the Agenda by default
+                    agendaGroup = (AgendaGroupImpl) agenda.getAgendaGroup( AgendaGroup.MAIN );
+                } else {
+                    // AgendaGroup is defined, so try and get the AgendaGroup
+                    // from the Agenda
+                    agendaGroup = (AgendaGroupImpl) agenda.getAgendaGroup( this.rule.getAgendaGroup() );
+                }
+
+                if ( agendaGroup == null ) {
+                    // The AgendaGroup is defined but not yet added to the
+                    // Agenda, so create the AgendaGroup and add to the Agenda.
+                    agendaGroup = new AgendaGroupImpl( this.rule.getAgendaGroup() );
+                    agenda.addAgendaGroup( agendaGroup );
+                }
+
+                memory.setAgendaGroup( agendaGroup );
+            }
+
+            // set the focus if rule autoFocus is true
+            if ( this.rule.getAutoFocus() ) {
+                agenda.setFocus( agendaGroup );
+            }
+
+            final AgendaItem item = new AgendaItem( context.getPropagationNumber(),
+                                                    cloned,
+                                                    context,
+                                                    this.rule );
+
+            if ( this.rule.getActivationGroup() != null ) {
+                // Lazy cache activationGroup
+                if ( memory.getActivationGroup() == null ) {
+                    memory.setActivationGroup( workingMemory.getAgenda().getActivationGroup( this.rule.getActivationGroup() ) );
+                }
+                memory.getActivationGroup().addActivation( item );
+            }
+
+            // Makes sure the Lifo is added to the AgendaGroup priority queue
+            // If the AgendaGroup is already in the priority queue it just
+            // returns.
+            agendaGroup.add( item );
+            tuple.setActivation( item );
+            memory.getTupleMemory().add( tuple );
+
+            item.setActivated( true );
+
+            // We only want to fire an event on a truly new Activation and not on an Activation as a result of a modify
+            if ( fireActivationCreated ) {
+                workingMemory.getAgendaEventSupport().fireActivationCreated( item,
+                                                                             workingMemory );
+            }
+        }
+    }
+
+    public void retractTuple(final ReteTuple leftTuple,
+                             final PropagationContext context,
+                             final InternalWorkingMemory workingMemory) {
+        final TerminalNodeMemory memory = (TerminalNodeMemory) workingMemory.getNodeMemory( this );
+        final ReteTuple tuple = (ReteTuple) memory.getTupleMemory().remove( leftTuple );
+        //an activation is null if the tuple was never propagated as an assert
+        if ( tuple != null && tuple.getActivation() != null ) {
+            final Activation activation = tuple.getActivation();
+            if ( activation.isActivated() ) {
+                activation.remove();
+                workingMemory.getAgendaEventSupport().fireActivationCancelled( activation,
+                                                                               workingMemory );
+            }
+
+            workingMemory.getTruthMaintenanceSystem().removeLogicalDependencies( activation,
+                                                                                 context,
+                                                                                 this.rule );
+        }
+    }
+
+    public String toString() {
+        return "[RuleTerminalNode: rule=" + this.rule.getName() + "]";
+    }
+
+    public void ruleAttached() {
+        // TODO Auto-generated method stub
+
+    }
+
+    public void attach() {
+        this.tupleSource.addTupleSink( this );
+    }
+
+    public void attach(final InternalWorkingMemory[] workingMemories) {
+        attach();
+
+        for ( int i = 0, length = workingMemories.length; i < length; i++ ) {
+            final InternalWorkingMemory workingMemory = workingMemories[i];
+            final PropagationContext propagationContext = new PropagationContextImpl( workingMemory.getNextPropagationIdCounter(),
+                                                                                      PropagationContext.RULE_ADDITION,
+                                                                                      null,
+                                                                                      null );
+            this.tupleSource.updateSink( this,
+                                         propagationContext,
+                                         workingMemory );
+        }
+    }
+
+    public void remove(final BaseNode node,
+                       final InternalWorkingMemory[] workingMemories) {
+        for ( int i = 0, length = workingMemories.length; i < length; i++ ) {
+            final InternalWorkingMemory workingMemory = workingMemories[i];
+
+            final TerminalNodeMemory memory = (TerminalNodeMemory) workingMemory.getNodeMemory( this );
+            final Iterator it = memory.getTupleMemory().iterator();
+            for ( ReteTuple tuple = (ReteTuple) it.next(); tuple != null; tuple = (ReteTuple) it.next() ) {
+                final Activation activation = (Activation) tuple.getActivation();
+
+                if ( activation.isActivated() ) {
+                    activation.remove();
+                    workingMemory.getAgendaEventSupport().fireActivationCancelled( activation,
+                                                                                   workingMemory );
+                }
+
+                final PropagationContext propagationContext = new PropagationContextImpl( workingMemory.getNextPropagationIdCounter(),
+                                                                                          PropagationContext.RULE_REMOVAL,
+                                                                                          null,
+                                                                                          null );
+                workingMemory.getTruthMaintenanceSystem().removeLogicalDependencies( activation,
+                                                                                     propagationContext,
+                                                                                     this.rule );
+            }
+
+            workingMemory.propagateQueuedActions();
+        }
+
+        this.tupleSource.remove( this,
+                                 workingMemories );
+    }
+
+    public Object createMemory(final RuleBaseConfiguration config) {
+        return new TerminalNodeMemory();
+    }
+
+    /**
+     * Returns the next node
+     * @return
+     *      The next TupleSinkNode
+     */
+    public TupleSinkNode getNextTupleSinkNode() {
+        return this.nextTupleSinkNode;
+    }
+
+    /**
+     * Sets the next node 
+     * @param next
+     *      The next TupleSinkNode
+     */
+    public void setNextTupleSinkNode(final TupleSinkNode next) {
+        this.nextTupleSinkNode = next;
+    }
+
+    /**
+     * Returns the previous node
+     * @return
+     *      The previous TupleSinkNode
+     */
+    public TupleSinkNode getPreviousTupleSinkNode() {
+        return this.previousTupleSinkNode;
+    }
+
+    /**
+     * Sets the previous node 
+     * @param previous
+     *      The previous TupleSinkNode
+     */
+    public void setPreviousTupleSinkNode(final TupleSinkNode previous) {
+        this.previousTupleSinkNode = previous;
+    }
+
+    public int hashCode() {
+        return this.rule.hashCode();
+    }
+
+    public boolean equals(final Object object) {
+        if ( object == this ) {
+            return true;
+        }
+
+        if ( object == null || object.getClass() != RuleTerminalNode.class ) {
+            return false;
+        }
+
+        final RuleTerminalNode other = (RuleTerminalNode) object;
+        return this.rule.equals( other.rule );
+    }
+
+    class TerminalNodeMemory
+        implements
+        Serializable {
+        private static final long serialVersionUID = 320L;
+
+        private AgendaGroupImpl   agendaGroup;
+
+        private ActivationGroup   activationGroup;
+
+        private TupleHashTable    tupleMemory;
+
+        public TerminalNodeMemory() {
+            this.tupleMemory = new TupleHashTable();
+        }
+
+        public AgendaGroupImpl getAgendaGroup() {
+            return this.agendaGroup;
+        }
+
+        public void setAgendaGroup(final AgendaGroupImpl agendaGroup) {
+            this.agendaGroup = agendaGroup;
+        }
+
+        public ActivationGroup getActivationGroup() {
+            return this.activationGroup;
+        }
+
+        public void setActivationGroup(final ActivationGroup activationGroup) {
+            this.activationGroup = activationGroup;
+        }
+
+        public TupleHashTable getTupleMemory() {
+            return this.tupleMemory;
+        }
+    }
+}

Deleted: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/TerminalNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/TerminalNode.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/TerminalNode.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -1,392 +0,0 @@
-package org.drools.reteoo;
-
-/*
- * Copyright 2005 JBoss Inc
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- *      http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import java.io.Serializable;
-
-import org.drools.RuleBaseConfiguration;
-import org.drools.common.AgendaGroupImpl;
-import org.drools.common.AgendaItem;
-import org.drools.common.BaseNode;
-import org.drools.common.InternalAgenda;
-import org.drools.common.InternalWorkingMemory;
-import org.drools.common.NodeMemory;
-import org.drools.common.PropagationContextImpl;
-import org.drools.common.ScheduledAgendaItem;
-import org.drools.rule.Rule;
-import org.drools.spi.Activation;
-import org.drools.spi.ActivationGroup;
-import org.drools.spi.AgendaGroup;
-import org.drools.spi.Duration;
-import org.drools.spi.PropagationContext;
-import org.drools.util.Iterator;
-import org.drools.util.TupleHashTable;
-
-/**
- * Leaf Rete-OO node responsible for enacting <code>Action</code> s on a
- * matched <code>Rule</code>.
- * 
- * @see org.drools.rule.Rule
- * 
- * @author <a href="mailto:bob at eng.werken.com">bob mcwhirter </a>
- */
-final class TerminalNode extends BaseNode
-    implements
-    TupleSinkNode,
-    NodeMemory {
-    // ------------------------------------------------------------
-    // Instance members
-    // ------------------------------------------------------------
-
-    /**
-     * 
-     */
-    private static final long serialVersionUID = 320;
-    /** The rule to invoke upon match. */
-    private final Rule        rule;
-    private final TupleSource tupleSource;
-
-    private TupleSinkNode     previousTupleSinkNode;
-    private TupleSinkNode     nextTupleSinkNode;
-
-    // ------------------------------------------------------------
-    // Constructors
-    // ------------------------------------------------------------
-
-    /**
-     * Construct.
-     * 
-     * @param inputSource
-     *            The parent tuple source.
-     * @param rule
-     *            The rule.
-     */
-    TerminalNode(final int id,
-                 final TupleSource source,
-                 final Rule rule) {
-        super( id );
-        this.rule = rule;
-        this.tupleSource = source;
-    }
-
-    // ------------------------------------------------------------
-    // Instance methods
-    // ------------------------------------------------------------
-
-    /**
-     * Retrieve the <code>Action</code> associated with this node.
-     * 
-     * @return The <code>Action</code> associated with this node.
-     */
-    public Rule getRule() {
-        return this.rule;
-    }
-
-    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-    // org.drools.impl.TupleSink
-    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-    public void assertTuple(final ReteTuple tuple,
-                            final PropagationContext context,
-                            final InternalWorkingMemory workingMemory) {
-        assertTuple( tuple,
-                     context,
-                     workingMemory,
-                     true );
-
-    }
-
-    /**
-     * Assert a new <code>Tuple</code>.
-     * 
-     * @param tuple
-     *            The <code>Tuple</code> being asserted.
-     * @param workingMemory
-     *            The working memory seesion.
-     * @throws AssertionException
-     *             If an error occurs while asserting.
-     */
-    public void assertTuple(final ReteTuple tuple,
-                            final PropagationContext context,
-                            final InternalWorkingMemory workingMemory,
-                            final boolean fireActivationCreated) {
-        //we only have to clone the head fact to make sure the graph is not affected during consequence reads after a modify
-        final ReteTuple cloned = new ReteTuple( tuple );
-
-        // if the current Rule is no-loop and the origin rule is the same then
-        // return
-        if ( this.rule.getNoLoop() && this.rule.equals( context.getRuleOrigin() ) ) {
-            return;
-        }
-        final InternalAgenda agenda = (InternalAgenda) workingMemory.getAgenda();
-
-        final Duration dur = this.rule.getDuration();
-
-        if ( dur != null && dur.getDuration( tuple ) > 0 ) {
-            final ScheduledAgendaItem item = new ScheduledAgendaItem( context.getPropagationNumber(),
-                                                                      cloned,
-                                                                      agenda,
-                                                                      context,
-                                                                      this.rule );
-            final TerminalNodeMemory memory = (TerminalNodeMemory) workingMemory.getNodeMemory( this );
-            if ( this.rule.getActivationGroup() != null ) {
-                // Lazy cache activationGroup
-                if ( memory.getActivationGroup() == null ) {
-                    memory.setActivationGroup( workingMemory.getAgenda().getActivationGroup( this.rule.getActivationGroup() ) );
-                }
-                memory.getActivationGroup().addActivation( item );
-            }
-
-            agenda.scheduleItem( item );
-            tuple.setActivation( item );
-            memory.getTupleMemory().add( tuple );
-
-            item.setActivated( true );
-            workingMemory.getAgendaEventSupport().fireActivationCreated( item, workingMemory );
-        } else {
-            // -----------------
-            // Lazy instantiation and addition to the Agenda of AgendGroup
-            // implementations
-            // ----------------
-            final TerminalNodeMemory memory = (TerminalNodeMemory) workingMemory.getNodeMemory( this );
-            AgendaGroupImpl agendaGroup = memory.getAgendaGroup();
-            if ( agendaGroup == null ) {
-                if ( this.rule.getAgendaGroup() == null || this.rule.getAgendaGroup().equals( "" ) || this.rule.getAgendaGroup().equals( AgendaGroup.MAIN ) ) {
-                    // Is the Rule AgendaGroup undefined? If it is use MAIN,
-                    // which is added to the Agenda by default
-                    agendaGroup = (AgendaGroupImpl) agenda.getAgendaGroup( AgendaGroup.MAIN );
-                } else {
-                    // AgendaGroup is defined, so try and get the AgendaGroup
-                    // from the Agenda
-                    agendaGroup = (AgendaGroupImpl) agenda.getAgendaGroup( this.rule.getAgendaGroup() );
-                }
-
-                if ( agendaGroup == null ) {
-                    // The AgendaGroup is defined but not yet added to the
-                    // Agenda, so create the AgendaGroup and add to the Agenda.
-                    agendaGroup = new AgendaGroupImpl( this.rule.getAgendaGroup() );
-                    agenda.addAgendaGroup( agendaGroup );
-                }
-
-                memory.setAgendaGroup( agendaGroup );
-            }
-
-            // set the focus if rule autoFocus is true
-            if ( this.rule.getAutoFocus() ) {
-                agenda.setFocus( agendaGroup );
-            }
-
-            final AgendaItem item = new AgendaItem( context.getPropagationNumber(),
-                                                    cloned,
-                                                    context,
-                                                    this.rule );
-
-            if ( this.rule.getActivationGroup() != null ) {
-                // Lazy cache activationGroup
-                if ( memory.getActivationGroup() == null ) {
-                    memory.setActivationGroup( workingMemory.getAgenda().getActivationGroup( this.rule.getActivationGroup() ) );
-                }
-                memory.getActivationGroup().addActivation( item );
-            }
-
-            // Makes sure the Lifo is added to the AgendaGroup priority queue
-            // If the AgendaGroup is already in the priority queue it just
-            // returns.
-            agendaGroup.add( item );
-            tuple.setActivation( item );
-            memory.getTupleMemory().add( tuple );
-
-            item.setActivated( true );
-
-            // We only want to fire an event on a truly new Activation and not on an Activation as a result of a modify
-            if ( fireActivationCreated ) {
-                workingMemory.getAgendaEventSupport().fireActivationCreated( item, workingMemory  );
-            }
-        }
-    }
-
-    public void retractTuple(final ReteTuple leftTuple,
-                             final PropagationContext context,
-                             final InternalWorkingMemory workingMemory) {
-        final TerminalNodeMemory memory = (TerminalNodeMemory) workingMemory.getNodeMemory( this );
-        final ReteTuple tuple = (ReteTuple) memory.getTupleMemory().remove( leftTuple );
-        //an activation is null if the tuple was never propagated as an assert
-        if ( tuple != null && tuple.getActivation() != null ) {
-            final Activation activation = tuple.getActivation();
-            if ( activation.isActivated() ) {
-                activation.remove();
-                workingMemory.getAgendaEventSupport().fireActivationCancelled( activation, workingMemory  );
-            }
-
-            workingMemory.getTruthMaintenanceSystem().removeLogicalDependencies( activation,
-                                                                                 context,
-                                                                                 this.rule );
-        }
-    }
-
-    public String toString() {
-        return "[TerminalNode: rule=" + this.rule.getName() + "]";
-    }
-
-    public void ruleAttached() {
-        // TODO Auto-generated method stub
-
-    }
-
-    public void attach() {
-        this.tupleSource.addTupleSink( this );
-    }
-
-    public void attach(final InternalWorkingMemory[] workingMemories) {
-        attach();
-
-        for ( int i = 0, length = workingMemories.length; i < length; i++ ) {
-            final InternalWorkingMemory workingMemory = workingMemories[i];
-            final PropagationContext propagationContext = new PropagationContextImpl( workingMemory.getNextPropagationIdCounter(),
-                                                                                      PropagationContext.RULE_ADDITION,
-                                                                                      null,
-                                                                                      null );
-            this.tupleSource.updateSink( this,
-                                         propagationContext,
-                                         workingMemory );
-        }
-    }
-
-    public void remove(final BaseNode node,
-                       final InternalWorkingMemory[] workingMemories) {
-        for ( int i = 0, length = workingMemories.length; i < length; i++ ) {
-            final InternalWorkingMemory workingMemory = workingMemories[i];
-
-            final TerminalNodeMemory memory = (TerminalNodeMemory) workingMemory.getNodeMemory( this );
-            final Iterator it = memory.getTupleMemory().iterator();
-            for ( ReteTuple tuple = (ReteTuple) it.next(); tuple != null; tuple = (ReteTuple) it.next() ) {
-                final Activation activation = (Activation) tuple.getActivation();
-
-                if ( activation.isActivated() ) {
-                    activation.remove();
-                    workingMemory.getAgendaEventSupport().fireActivationCancelled( activation, workingMemory );
-                }
-
-                final PropagationContext propagationContext = new PropagationContextImpl( workingMemory.getNextPropagationIdCounter(),
-                                                                                          PropagationContext.RULE_REMOVAL,
-                                                                                          null,
-                                                                                          null );
-                workingMemory.getTruthMaintenanceSystem().removeLogicalDependencies( activation,
-                                                                                     propagationContext,
-                                                                                     this.rule );
-            }
-
-            workingMemory.propagateQueuedActions();
-        }
-
-        this.tupleSource.remove( this,
-                                 workingMemories );
-    }
-
-    public Object createMemory(final RuleBaseConfiguration config) {
-        return new TerminalNodeMemory();
-    }
-
-    /**
-     * Returns the next node
-     * @return
-     *      The next TupleSinkNode
-     */
-    public TupleSinkNode getNextTupleSinkNode() {
-        return this.nextTupleSinkNode;
-    }
-
-    /**
-     * Sets the next node 
-     * @param next
-     *      The next TupleSinkNode
-     */
-    public void setNextTupleSinkNode(final TupleSinkNode next) {
-        this.nextTupleSinkNode = next;
-    }
-
-    /**
-     * Returns the previous node
-     * @return
-     *      The previous TupleSinkNode
-     */
-    public TupleSinkNode getPreviousTupleSinkNode() {
-        return this.previousTupleSinkNode;
-    }
-
-    /**
-     * Sets the previous node 
-     * @param previous
-     *      The previous TupleSinkNode
-     */
-    public void setPreviousTupleSinkNode(final TupleSinkNode previous) {
-        this.previousTupleSinkNode = previous;
-    }
-
-    public int hashCode() {
-        return this.rule.hashCode();
-    }
-
-    public boolean equals(final Object object) {
-        if ( object == this ) {
-            return true;
-        }
-
-        if ( object == null || object.getClass() != TerminalNode.class ) {
-            return false;
-        }
-
-        final TerminalNode other = (TerminalNode) object;
-        return this.rule.equals( other.rule );
-    }
-
-    class TerminalNodeMemory
-        implements
-        Serializable {
-        private static final long serialVersionUID = 320L;
-
-        private AgendaGroupImpl   agendaGroup;
-
-        private ActivationGroup   activationGroup;
-
-        private TupleHashTable    tupleMemory;
-
-        public TerminalNodeMemory() {
-            this.tupleMemory = new TupleHashTable();
-        }
-
-        public AgendaGroupImpl getAgendaGroup() {
-            return this.agendaGroup;
-        }
-
-        public void setAgendaGroup(final AgendaGroupImpl agendaGroup) {
-            this.agendaGroup = agendaGroup;
-        }
-
-        public ActivationGroup getActivationGroup() {
-            return this.activationGroup;
-        }
-
-        public void setActivationGroup(final ActivationGroup activationGroup) {
-            this.activationGroup = activationGroup;
-        }
-
-        public TupleHashTable getTupleMemory() {
-            return this.tupleMemory;
-        }
-    }
-}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/TupleSource.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/TupleSource.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/TupleSource.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -35,7 +35,7 @@
  * @author <a href="mailto:mark.proctor at jboss.com">Mark Proctor</a>
  * @author <a href="mailto:bob at werken.com">Bob McWhirter</a>
  */
-abstract class TupleSource extends BaseNode
+public abstract class TupleSource extends BaseNode
     implements
     Serializable {
     // ------------------------------------------------------------

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/BuildContext.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/BuildContext.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/BuildContext.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -0,0 +1,250 @@
+/*
+ * Copyright 2006 JBoss Inc
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.reteoo.builder;
+
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.ListIterator;
+import java.util.Map;
+
+import org.drools.common.BaseNode;
+import org.drools.common.BetaConstraints;
+import org.drools.reteoo.ObjectSource;
+import org.drools.reteoo.ReteooBuilder;
+import org.drools.reteoo.ReteooRuleBase;
+import org.drools.reteoo.ReteooWorkingMemory;
+import org.drools.reteoo.TupleSource;
+import org.drools.rule.RuleConditionElement;
+
+/**
+ * A build context for Reteoo Builder
+ * 
+ * @author etirelli
+ */
+public class BuildContext {
+
+    // tuple source to attach next node to
+    private TupleSource               tupleSource;
+
+    // object source to attach next node to
+    private ObjectSource              objectSource;
+
+    // object type cache to check for cross products
+    private Map                       objectType;
+
+    // offset of the column
+    private int                       currentColumnOffset;
+
+    // attached nodes cache
+    private Map                       attachedNodes;
+
+    // rule base to add rules to
+    private ReteooRuleBase            rulebase;
+
+    // working memories attached to the given rulebase
+    private ReteooWorkingMemory[]     workingMemories;
+
+    // id generator
+    private ReteooBuilder.IdGenerator idGenerator;
+
+    // a build stack to track nested elements
+    private LinkedList                buildstack;
+
+    // beta constraints from the last column attached
+    BetaConstraints                   betaconstraints;
+
+    public BuildContext(final ReteooRuleBase rulebase,
+                        final Map attachedNodes,
+                        final ReteooBuilder.IdGenerator idGenerator) {
+        this.rulebase = rulebase;
+        this.workingMemories = (ReteooWorkingMemory[]) this.rulebase.getWorkingMemories().toArray( new ReteooWorkingMemory[this.rulebase.getWorkingMemories().size()] );
+        this.attachedNodes = attachedNodes;
+        this.idGenerator = idGenerator;
+
+        this.objectType = new LinkedHashMap();
+        this.buildstack = new LinkedList();
+
+        this.tupleSource = null;
+        this.objectSource = null;
+
+        this.currentColumnOffset = 0;
+    }
+
+    /**
+     * @return the currentColumnOffset
+     */
+    public int getCurrentColumnOffset() {
+        return currentColumnOffset;
+    }
+
+    /**
+     * @param currentColumnOffset the currentColumnOffset to set
+     */
+    public void setCurrentColumnOffset(int currentColumnIndex) {
+        this.currentColumnOffset = currentColumnIndex;
+    }
+
+    /**
+     * @return the objectSource
+     */
+    public ObjectSource getObjectSource() {
+        return objectSource;
+    }
+
+    /**
+     * @param objectSource the objectSource to set
+     */
+    public void setObjectSource(ObjectSource objectSource) {
+        this.objectSource = objectSource;
+    }
+
+    /**
+     * @return the objectType
+     */
+    public Map getObjectType() {
+        return objectType;
+    }
+
+    /**
+     * @param objectType the objectType to set
+     */
+    public void setObjectType(Map objectType) {
+        this.objectType = objectType;
+    }
+
+    /**
+     * @return the tupleSource
+     */
+    public TupleSource getTupleSource() {
+        return tupleSource;
+    }
+
+    /**
+     * @param tupleSource the tupleSource to set
+     */
+    public void setTupleSource(TupleSource tupleSource) {
+        this.tupleSource = tupleSource;
+    }
+
+    public void incrementCurrentColumnOffset() {
+        this.currentColumnOffset++;
+    }
+
+    public void decrementCurrentColumnOffset() {
+        this.currentColumnOffset--;
+    }
+
+    /**
+     * Checks if the given candidate node is in cache, and if it is returns it. 
+     * Returns null otherwise.
+     *
+     * @param candidate
+     * @return
+     */
+    public BaseNode getNodeFromCache(BaseNode candidate) {
+        return (BaseNode) this.attachedNodes.get( candidate );
+    }
+
+    /**
+     * Adds given node to node cache
+     * @param candidate
+     */
+    public void addNodeToCache(BaseNode node) {
+        this.attachedNodes.put( node,
+                                node );
+    }
+
+    /**
+     * Returns context rulebase
+     * @return
+     */
+    public ReteooRuleBase getRuleBase() {
+        return this.rulebase;
+    }
+
+    /**
+     * Return the array of working memories associated with the given
+     * rulebase.
+     * 
+     * @return
+     */
+    public ReteooWorkingMemory[] getWorkingMemories() {
+        return this.workingMemories;
+    }
+
+    /**
+     * Returns an Id for the next node
+     * @return
+     */
+    public int getNextId() {
+        return this.idGenerator.getNextId();
+    }
+
+    /**
+     * Method used to undo previous id assignment
+     */
+    public void releaseLastId() {
+        this.idGenerator.releaseLastId();
+    }
+
+    /**
+     * Adds the rce to the build stack
+     * @param rce
+     */
+    public void push(RuleConditionElement rce) {
+        this.buildstack.addLast( rce );
+    }
+
+    /**
+     * Removes the top stack element
+     * @return
+     */
+    public RuleConditionElement pop() {
+        return (RuleConditionElement) this.buildstack.removeLast();
+    }
+
+    /**
+     * Returns the top stack element without removing it
+     * @return
+     */
+    public RuleConditionElement peek() {
+        return (RuleConditionElement) this.buildstack.getLast();
+    }
+
+    /**
+     * Returns a list iterator to iterate over the stacked elements
+     * @return
+     */
+    public ListIterator stackIterator() {
+        return this.buildstack.listIterator();
+    }
+
+    /**
+     * @return the betaconstraints
+     */
+    public BetaConstraints getBetaconstraints() {
+        return betaconstraints;
+    }
+
+    /**
+     * @param betaconstraints the betaconstraints to set
+     */
+    public void setBetaconstraints(BetaConstraints betaconstraints) {
+        this.betaconstraints = betaconstraints;
+    }
+
+}


Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/BuildContext.java
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:keywords
   + id author date revision
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/BuildUtils.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/BuildUtils.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/BuildUtils.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -0,0 +1,199 @@
+/*
+ * Copyright 2006 JBoss Inc
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.reteoo.builder;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+
+import org.drools.common.BaseNode;
+import org.drools.common.BetaConstraints;
+import org.drools.common.DefaultBetaConstraints;
+import org.drools.common.DoubleBetaConstraints;
+import org.drools.common.EmptyBetaConstraints;
+import org.drools.common.QuadroupleBetaConstraints;
+import org.drools.common.SingleBetaConstraints;
+import org.drools.common.TripleBetaConstraints;
+import org.drools.reteoo.ObjectSource;
+import org.drools.reteoo.TupleSource;
+import org.drools.rule.Declaration;
+import org.drools.rule.InvalidPatternException;
+import org.drools.rule.RuleConditionElement;
+import org.drools.spi.BetaNodeFieldConstraint;
+
+/**
+ * Utility functions for reteoo build
+ * 
+ * @author etirelli
+ */
+public class BuildUtils {
+
+    private Map componentBuilders = new HashMap();
+
+    /**
+     * Adds the given builder for the given target to the builders map
+     * 
+     * @param target
+     * @param builder
+     */
+    public void addBuilder(Class target,
+                           ReteooComponentBuilder builder) {
+        this.componentBuilders.put( target, builder );
+    }
+    
+    /**
+     * Returns a builder for the given target from the builders map
+     * 
+     * @param target
+     * @return returns null if not found
+     */
+    public ReteooComponentBuilder getBuilderFor( RuleConditionElement target ) {
+        return (ReteooComponentBuilder) this.componentBuilders.get( target.getClass() );
+    }
+
+    /**
+     * Attaches a node into the network. If a node already exists that could
+     * substitute, it is used instead.
+     *
+     * @param context
+     *            The current build context
+     * @param candidate
+     *            The node to attach.
+     *            
+     * @return the actual attached node that may be the one given as parameter
+     *         or eventualy one that was already in the cache if sharing is enabled
+     */
+    public BaseNode attachNode(final BuildContext context,
+                               final BaseNode candidate) {
+        // checks if node is in the cache
+        BaseNode node = (BaseNode) context.getNodeFromCache( candidate );
+
+        // if node sharing is enabled and node was found in the cache
+        if ( (node != null) && isSharingEnabledForNode( context,
+                                                        node ) ) {
+            // if node was not previously in use, attach it
+            if ( !node.isInUse() ) {
+                if ( context.getWorkingMemories().length == 0 ) {
+                    node.attach();
+                } else {
+                    node.attach( context.getWorkingMemories() );
+                }
+            }
+            // increment share counter
+            node.addShare();
+            // undo previous id assignment
+            context.releaseLastId();
+        } else {
+            // attach candidate node
+            if ( context.getWorkingMemories().length == 0 ) {
+                candidate.attach();
+            } else {
+                candidate.attach( context.getWorkingMemories() );
+            }
+
+            // add it to cache
+            context.addNodeToCache( candidate );
+
+            node = candidate;
+        }
+
+        return node;
+    }
+
+    /**
+     * Utility function to check if sharing is enabled for nodes of the given class
+     * 
+     * @param context
+     * @param node
+     * @return
+     */
+    private boolean isSharingEnabledForNode(BuildContext context,
+                                            BaseNode node) {
+        if ( node instanceof TupleSource ) {
+            return context.getRuleBase().getConfiguration().isShareBetaNodes();
+        } else if ( node instanceof ObjectSource ) {
+            return context.getRuleBase().getConfiguration().isShareAlphaNodes();
+        }
+        return false;
+    }
+    
+    /**
+     * Creates and returns a BetaConstraints object for the given list of constraints
+     * 
+     * @param context the current build context
+     * @param list the list of constraints
+     * 
+     * @return
+     */
+    public BetaConstraints createBetaNodeConstraint(final BuildContext context,
+                                                    final List list) {
+        BetaConstraints constraints;
+        switch ( list.size() ) {
+            case 0 :
+                constraints = EmptyBetaConstraints.getInstance();
+                break;
+            case 1 :
+                constraints = new SingleBetaConstraints( (BetaNodeFieldConstraint) list.get( 0 ), context.getRuleBase().getConfiguration() );
+                break;
+            case 2 :
+                constraints = new DoubleBetaConstraints( (BetaNodeFieldConstraint[]) list.toArray( new BetaNodeFieldConstraint[list.size()] ), context.getRuleBase().getConfiguration() );
+                break;
+            case 3 :
+                constraints = new TripleBetaConstraints( (BetaNodeFieldConstraint[]) list.toArray( new BetaNodeFieldConstraint[list.size()] ), context.getRuleBase().getConfiguration() );
+                break;
+            case 4 :
+                constraints = new QuadroupleBetaConstraints( (BetaNodeFieldConstraint[]) list.toArray( new BetaNodeFieldConstraint[list.size()] ), context.getRuleBase().getConfiguration() );
+                break;                
+            default :
+                constraints = new DefaultBetaConstraints( (BetaNodeFieldConstraint[]) list.toArray( new BetaNodeFieldConstraint[list.size()] ), context.getRuleBase().getConfiguration() );
+        }
+        return constraints;
+    }
+    
+    /**
+     * Make sure the required declarations are previously bound
+     * 
+     * @param declarations
+     * @throws InvalidPatternException
+     */
+    public void checkUnboundDeclarations(final BuildContext context,
+                                         final Declaration[] declarations) throws InvalidPatternException {
+        final List list = new ArrayList();
+        for ( int i = 0, length = declarations.length; i < length; i++ ) {
+            for( ListIterator it = context.stackIterator(); it.hasPrevious(); ) {
+                RuleConditionElement rce = (RuleConditionElement) it.previous();
+                if( rce.resolveDeclaration( declarations[i].getIdentifier() ) == null ) {
+                    list.add( declarations[i].getIdentifier() );
+                }
+            }
+        }
+
+        // Make sure the required declarations        
+        if ( list.size() != 0 ) {
+            final StringBuffer buffer = new StringBuffer();
+            buffer.append( list.get( 0 ) );
+            for ( int i = 1, size = list.size(); i < size; i++ ) {
+                buffer.append( ", " + list.get( i ) );
+            }
+
+            throw new InvalidPatternException( "Required Declarations not bound: '" + buffer );
+        }
+    }
+
+}


Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/BuildUtils.java
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:keywords
   + id author date revision
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/CollectBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/CollectBuilder.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/CollectBuilder.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2006 JBoss Inc
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.reteoo.builder;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.drools.common.BetaConstraints;
+import org.drools.reteoo.CollectNode;
+import org.drools.reteoo.TupleSource;
+import org.drools.rule.Collect;
+import org.drools.rule.Column;
+import org.drools.rule.Declaration;
+import org.drools.rule.LiteralConstraint;
+import org.drools.rule.RuleConditionElement;
+import org.drools.spi.AlphaNodeFieldConstraint;
+
+/**
+ * @author etirelli
+ *
+ */
+public class CollectBuilder
+    implements
+    ReteooComponentBuilder {
+
+    /**
+     * @inheritDoc
+     */
+    public void build(BuildContext context,
+                      BuildUtils utils,
+                      RuleConditionElement rce) {
+        
+        Collect collect = (Collect) rce;
+        
+        final Column sourceColumn = collect.getSourceColumn();
+        
+        // get builder for the column
+        ReteooComponentBuilder builder = utils.getBuilderFor( sourceColumn );
+
+        // builds the source column
+        builder.build( context,
+                       utils,
+                       sourceColumn );
+
+        final Column column = collect.getResultColumn();
+        // adjusting target column offset to be the same as the source column
+        column.setOffset( context.getCurrentColumnOffset()-1 );
+
+        final List constraints = column.getConstraints();
+
+        final List betaConstraints = new ArrayList();
+        final List alphaConstraints = new ArrayList();
+
+        for ( final Iterator it = constraints.iterator(); it.hasNext(); ) {
+            final Object object = it.next();
+            // Check if its a declaration
+            if ( object instanceof Declaration ) {
+                continue;
+            }
+
+            final AlphaNodeFieldConstraint fieldConstraint = (AlphaNodeFieldConstraint) object;
+            if ( fieldConstraint instanceof LiteralConstraint ) {
+                alphaConstraints.add( fieldConstraint );
+            } else {
+                utils.checkUnboundDeclarations( context,
+                                                fieldConstraint.getRequiredDeclarations() );
+                betaConstraints.add( fieldConstraint );
+            }
+        }
+
+        final BetaConstraints resultsBinder = utils.createBetaNodeConstraint( context,
+                                                                              betaConstraints );
+
+        context.setTupleSource( (TupleSource) utils.attachNode( context,
+                                                                new CollectNode( context.getNextId(),
+                                                        context.getTupleSource(),
+                                                        context.getObjectSource(),
+                                                        (AlphaNodeFieldConstraint[]) alphaConstraints.toArray( new AlphaNodeFieldConstraint[alphaConstraints.size()] ),
+                                                        context.getBetaconstraints(),
+                                                        resultsBinder,
+                                                        collect ) ) );
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public boolean requiresLeftActivation(BuildUtils utils,
+                                          RuleConditionElement rce) {
+        return true;
+    }
+
+    
+    
+}


Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/CollectBuilder.java
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:keywords
   + id author date revision
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/ColumnBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/ColumnBuilder.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/ColumnBuilder.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2006 JBoss Inc
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.reteoo.builder;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.drools.base.ClassObjectType;
+import org.drools.common.BetaConstraints;
+import org.drools.common.InstanceNotEqualsConstraint;
+import org.drools.reteoo.AlphaNode;
+import org.drools.reteoo.ObjectSource;
+import org.drools.reteoo.ObjectTypeNode;
+import org.drools.rule.Column;
+import org.drools.rule.Declaration;
+import org.drools.rule.InvalidPatternException;
+import org.drools.rule.RuleConditionElement;
+import org.drools.spi.AlphaNodeFieldConstraint;
+import org.drools.spi.Constraint;
+
+/**
+ * A builder for columns
+ * 
+ * @author etirelli
+ */
+public class ColumnBuilder
+    implements
+    ReteooComponentBuilder {
+
+    /**
+     * @inheritDoc
+     */
+    public void build(BuildContext context,
+                      BuildUtils utils,
+                      RuleConditionElement rce) {
+
+        Column column = (Column) rce;
+
+        context.setBetaconstraints( this.attachColumn( context,
+                                                       utils,
+                                                       (Column) column ) );
+
+    }
+
+    private BetaConstraints attachColumn(final BuildContext context,
+                                         final BuildUtils utils,
+                                         final Column column) throws InvalidPatternException {
+
+        // Adjusting offset in case a previous Initial-Fact was added to the network
+        column.setOffset( context.getCurrentColumnOffset() );
+        
+        context.incrementCurrentColumnOffset();
+
+        // Attach alpha nodes
+        final List predicates = attachAlphaNodes( context,
+                                                  utils,
+                                                  column );
+
+        // Create BetaConstraints object
+        final BetaConstraints binder = utils.createBetaNodeConstraint( context,
+                                                                       predicates );
+
+        return binder;
+    }
+
+    public List attachAlphaNodes(final BuildContext context,
+                                 final BuildUtils utils,
+                                 final Column column) throws InvalidPatternException {
+
+        final List constraints = column.getConstraints();
+
+        context.setObjectSource( (ObjectSource) utils.attachNode( context,
+                                                                  new ObjectTypeNode( context.getNextId(),
+                                                                                      column.getObjectType(),
+                                                                                      context.getRuleBase().getRete(),
+                                                                                      context.getRuleBase().getConfiguration().getAlphaNodeHashingThreshold() ) ) );
+
+        final List betaConstraints = new ArrayList();
+
+        // check if cross products for identity columns should be disabled
+        checkRemoveIdentities( context,
+                               column,
+                               betaConstraints );
+
+        for ( final Iterator it = constraints.iterator(); it.hasNext(); ) {
+            final Object object = it.next();
+            // Check if its a declaration
+            if ( object instanceof Declaration ) {
+                // nothing to be done
+                continue;
+            }
+
+            final Constraint constraint = (Constraint) object;
+            Declaration[] declarations = constraint.getRequiredDeclarations();
+
+            boolean isAlphaConstraint = true;
+            for ( int i = 0; isAlphaConstraint && i < declarations.length; i++ ) {
+                if ( declarations[i].getColumn() != column ) {
+                    isAlphaConstraint = false;
+                }
+            }
+            if ( isAlphaConstraint ) {
+                context.setObjectSource( (ObjectSource) utils.attachNode( context,
+                                                                          new AlphaNode( context.getNextId(),
+                                                                                         (AlphaNodeFieldConstraint) constraint,
+                                                                                         context.getObjectSource() ) ) );
+            } else {
+                utils.checkUnboundDeclarations( context,
+                                                constraint.getRequiredDeclarations() );
+                betaConstraints.add( constraint );
+            }
+        }
+
+        return betaConstraints;
+    }
+
+    /**
+     * @param context
+     * @param column
+     * @param betaConstraints
+     */
+    private void checkRemoveIdentities(final BuildContext context,
+                                       final Column column,
+                                       final List betaConstraints) {
+        if ( context.getRuleBase().getConfiguration().isRemoveIdentities() && column.getObjectType().getClass() == ClassObjectType.class ) {
+            // Check if this object type exists before
+            // If it does we need stop instance equals cross product
+            final Class thisClass = ((ClassObjectType) column.getObjectType()).getClassType();
+            for ( final Iterator it = context.getObjectType().entrySet().iterator(); it.hasNext(); ) {
+                final Map.Entry entry = (Map.Entry) it.next();
+                final Class previousClass = ((ClassObjectType) entry.getKey()).getClassType();
+                if ( thisClass.isAssignableFrom( previousClass ) ) {
+                    betaConstraints.add( new InstanceNotEqualsConstraint( (Column) entry.getValue() ) );
+                }
+            }
+
+            // Must be added after the checking, otherwise it matches against itself
+            context.getObjectType().put( column.getObjectType(),
+                                         column );
+        }
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public boolean requiresLeftActivation( BuildUtils utils, RuleConditionElement rce ) {
+        return false;
+    }
+}


Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/ColumnBuilder.java
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:keywords
   + id author date revision
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/EvalBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/EvalBuilder.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/EvalBuilder.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2006 JBoss Inc
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.reteoo.builder;
+
+import org.drools.reteoo.EvalConditionNode;
+import org.drools.reteoo.TupleSource;
+import org.drools.rule.EvalCondition;
+import org.drools.rule.RuleConditionElement;
+
+/**
+ * @author etirelli
+ *
+ */
+public class EvalBuilder
+    implements
+    ReteooComponentBuilder {
+
+    /**
+     * @inheritDoc
+     */
+    public void build(BuildContext context,
+                      BuildUtils utils,
+                      RuleConditionElement rce) {
+
+        final EvalCondition eval = (EvalCondition) rce;
+        utils.checkUnboundDeclarations( context,
+                                        eval.getRequiredDeclarations() );
+        context.setTupleSource( (TupleSource) utils.attachNode( context,
+                                                                new EvalConditionNode( context.getNextId(),
+                                                                                       context.getTupleSource(),
+                                                                                       eval ) ) );
+
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public boolean requiresLeftActivation(BuildUtils utils,
+                                          RuleConditionElement rce) {
+        return true;
+    }
+
+}


Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/EvalBuilder.java
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:keywords
   + id author date revision
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/FromBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/FromBuilder.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/FromBuilder.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2006 JBoss Inc
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.reteoo.builder;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.drools.common.BetaConstraints;
+import org.drools.reteoo.FromNode;
+import org.drools.reteoo.TupleSource;
+import org.drools.rule.Column;
+import org.drools.rule.Declaration;
+import org.drools.rule.From;
+import org.drools.rule.LiteralConstraint;
+import org.drools.rule.RuleConditionElement;
+import org.drools.spi.AlphaNodeFieldConstraint;
+
+/**
+ * @author etirelli
+ *
+ */
+public class FromBuilder
+    implements
+    ReteooComponentBuilder {
+
+    /* (non-Javadoc)
+     * @see org.drools.reteoo.builder.ReteooComponentBuilder#build(org.drools.reteoo.builder.BuildContext, org.drools.reteoo.builder.BuildUtils, org.drools.rule.RuleConditionElement)
+     */
+    public void build(BuildContext context,
+                      BuildUtils utils,
+                      RuleConditionElement rce) {
+        From from = (From) rce;
+
+        final Column column = from.getColumn();
+        
+        // setting and incrementing column offset as appropriate
+        column.setOffset( context.getCurrentColumnOffset() );
+        context.incrementCurrentColumnOffset();
+
+        final List constraints = column.getConstraints();
+
+        final List betaConstraints = new ArrayList();
+        final List alphaConstraints = new ArrayList();
+
+        for ( final Iterator it = constraints.iterator(); it.hasNext(); ) {
+            final Object object = it.next();
+
+            // Check if its a declaration
+            if ( object instanceof Declaration ) {
+                continue;
+            }
+
+            final AlphaNodeFieldConstraint fieldConstraint = (AlphaNodeFieldConstraint) object;
+            if ( fieldConstraint instanceof LiteralConstraint ) {
+                alphaConstraints.add( fieldConstraint );
+            } else {
+                utils.checkUnboundDeclarations( context,
+                                                fieldConstraint.getRequiredDeclarations() );
+                betaConstraints.add( fieldConstraint );
+            }
+        }
+
+        final BetaConstraints binder = utils.createBetaNodeConstraint( context,
+                                                                       betaConstraints );
+
+        context.setTupleSource( (TupleSource) utils.attachNode( context,
+                                                                new FromNode( context.getNextId(),
+                                                                              from.getDataProvider(),
+                                                                              context.getTupleSource(),
+                                                                              (AlphaNodeFieldConstraint[]) alphaConstraints.toArray( new AlphaNodeFieldConstraint[alphaConstraints.size()] ),
+                                                                              binder ) ) );
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public boolean requiresLeftActivation(BuildUtils utils,
+                                          RuleConditionElement rce) {
+        return true;
+    }
+
+}


Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/FromBuilder.java
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:keywords
   + id author date revision
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/GroupElementBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/GroupElementBuilder.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/GroupElementBuilder.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -0,0 +1,387 @@
+/*
+ * Copyright 2006 JBoss Inc
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.reteoo.builder;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.drools.RuntimeDroolsException;
+import org.drools.reteoo.ExistsNode;
+import org.drools.reteoo.JoinNode;
+import org.drools.reteoo.LeftInputAdapterNode;
+import org.drools.reteoo.NotNode;
+import org.drools.reteoo.TupleSource;
+import org.drools.rule.Column;
+import org.drools.rule.GroupElement;
+import org.drools.rule.RuleConditionElement;
+
+/**
+ * @author etirelli
+ *
+ */
+public class GroupElementBuilder
+    implements
+    ReteooComponentBuilder {
+
+    private Map geBuilders = new HashMap();
+
+    public GroupElementBuilder() {
+        geBuilders.put( GroupElement.AND,
+                        new AndBuilder() );
+        geBuilders.put( GroupElement.OR,
+                        new OrBuilder() );
+        geBuilders.put( GroupElement.NOT,
+                        new NotBuilder() );
+        geBuilders.put( GroupElement.EXISTS,
+                        new ExistsBuilder() );
+    }
+
+    /**
+     * @inheritDoc
+     * 
+     * 
+     */
+    public void build(BuildContext context,
+                      BuildUtils utils,
+                      RuleConditionElement rce) {
+        GroupElement ge = (GroupElement) rce;
+
+        ReteooComponentBuilder builder = (ReteooComponentBuilder) geBuilders.get( ge.getType() );
+
+        builder.build( context,
+                       utils,
+                       rce );
+
+        //        for ( final Iterator it = subrule.getChildren().iterator(); it.hasNext(); ) {
+        //            final Object object = it.next();
+        //
+        //            if ( object instanceof EvalCondition ) {
+        //                final EvalCondition eval = (EvalCondition) object;
+        //                checkUnboundDeclarations( eval.getRequiredDeclarations() );
+        //                this.tupleSource = attachNode( new EvalConditionNode( this.id++,
+        //                                                                      this.tupleSource,
+        //                                                                      eval ) );
+        //                continue;
+        //            }
+        //
+        //            BetaConstraints binder = null;
+        //            Column column = null;
+        //
+        //            if ( object instanceof Column ) {
+        //                column = (Column) object;
+        //
+        //                // @REMOVEME after the milestone period
+        //                if ( (binder != null) && (binder != EmptyBetaConstraints.getInstance()) ) throw new RuntimeDroolsException( "This is a bug! Please report to Drools development team!" );
+        //
+        //                binder = attachColumn( (Column) object,
+        //                                       subrule,
+        //                                       this.removeIdentities );
+        //
+        //                // If a tupleSource does not exist then we need to adapt this
+        //                // into
+        //                // a TupleSource using LeftInputAdapterNode
+        //                if ( this.tupleSource == null ) {
+        //                    this.tupleSource = attachNode( new LeftInputAdapterNode( this.id++,
+        //                                                                             this.objectSource ) );
+        //
+        //                    // objectSource is created by the attachColumn method, if we
+        //                    // adapt this to
+        //                    // a TupleSource then we need to null the objectSource
+        //                    // reference.
+        //                    this.objectSource = null;
+        //                }
+        //            } else if ( object instanceof GroupElement ) {
+        //                // If its not a Column or EvalCondition then it can either be a Not or an Exists
+        //                GroupElement ce = (GroupElement) object;
+        //                while ( !(ce.getChildren().get( 0 ) instanceof Column) ) {
+        //                    ce = (GroupElement) ce.getChildren().get( 0 );
+        //                }
+        //                column = (Column) ce.getChildren().get( 0 );
+        //
+        //                // If a tupleSource does not exist then we need to adapt an
+        //                // InitialFact into a a TupleSource using LeftInputAdapterNode
+        //                if ( this.tupleSource == null ) {
+        //                    // adjusting offset as all tuples will now contain initial-fact at index 0
+        //                    this.currentOffsetAdjustment = 1;
+        //
+        //                    final ObjectSource objectSource = attachNode( new ObjectTypeNode( this.id++,
+        //                                                                                      new ClassObjectType( InitialFact.class ),
+        //                                                                                      this.rete,
+        //                                                                                      this.ruleBase.getConfiguration().getAlphaNodeHashingThreshold() ) );
+        //
+        //                    this.tupleSource = attachNode( new LeftInputAdapterNode( this.id++,
+        //                                                                             objectSource ) );
+        //                }
+        //
+        //                // @REMOVEME after the milestone period
+        //                if ( (binder != null) && (binder != EmptyBetaConstraints.getInstance()) ) throw new RuntimeDroolsException( "This is a bug! Please report to Drools development team!" );
+        //
+        //                binder = attachColumn( column,
+        //                                       subrule,
+        //                                       this.removeIdentities );
+        //            }
+        //
+        //            if ( (object instanceof GroupElement) && (((GroupElement) object).isNot()) ) {
+        //                attachNot( this.tupleSource,
+        //                           (GroupElement) object,
+        //                           this.objectSource,
+        //                           binder,
+        //                           column );
+        //                binder = null;
+        //            } else if ( (object instanceof GroupElement) && (((GroupElement) object).isExists()) ) {
+        //                attachExists( this.tupleSource,
+        //                              (GroupElement) object,
+        //                              this.objectSource,
+        //                              binder,
+        //                              column );
+        //                binder = null;
+        //            } else if ( object.getClass() == From.class ) {
+        //                attachFrom( this.tupleSource,
+        //                            (From) object );
+        //            } else if ( object.getClass() == Accumulate.class ) {
+        //                attachAccumulate( this.tupleSource,
+        //                                  subrule,
+        //                                  (Accumulate) object );
+        //            } else if ( object.getClass() == Collect.class ) {
+        //                attachCollect( this.tupleSource,
+        //                               subrule,
+        //                               (Collect) object );
+        //            } else if ( this.objectSource != null ) {
+        //                this.tupleSource = attachNode( new JoinNode( this.id++,
+        //                                                             this.tupleSource,
+        //                                                             this.objectSource,
+        //                                                             binder ) );
+        //                binder = null;
+        //            }
+        //        }
+
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public boolean requiresLeftActivation( BuildUtils utils, RuleConditionElement rce ) {
+        GroupElement ge = (GroupElement) rce;
+
+        ReteooComponentBuilder builder = (ReteooComponentBuilder) geBuilders.get( ge.getType() );
+        
+        return builder.requiresLeftActivation( utils, rce );
+    }
+
+    private static class AndBuilder
+        implements
+        ReteooComponentBuilder {
+
+        /**
+         * @inheritDoc
+         * 
+         * And group elements just iterate over their children
+         * selecting and calling the build procedure for each one
+         * 
+         */
+        public void build(BuildContext context,
+                          BuildUtils utils,
+                          RuleConditionElement rce) {
+
+            GroupElement ge = (GroupElement) rce;
+
+            // iterate over each child and build it
+            for ( Iterator it = ge.getChildren().iterator(); it.hasNext(); ) {
+
+                RuleConditionElement child = (RuleConditionElement) it.next();
+
+                ReteooComponentBuilder builder = utils.getBuilderFor( child );
+
+                builder.build( context,
+                               utils,
+                               child );
+
+                // if a previous object source was bound, but no tuple source
+                if ( context.getObjectSource() != null && context.getTupleSource() == null ) {
+                    // adapt it to a Tuple source
+                    context.setTupleSource( (TupleSource) utils.attachNode( context,
+                                                                            new LeftInputAdapterNode( context.getNextId(),
+                                                                                                      context.getObjectSource() ) ) );
+
+                    context.setObjectSource( null );
+                }
+
+                // if there was a previous tuple source, then a join node is needed
+                if ( context.getObjectSource() != null && context.getTupleSource() != null ) {
+                    // so, create the tuple source and clean up the constraints and object source
+                    context.setTupleSource( (TupleSource) utils.attachNode( context,
+                                                                            new JoinNode( context.getNextId(),
+                                                                                          context.getTupleSource(),
+                                                                                          context.getObjectSource(),
+                                                                                          context.getBetaconstraints() ) ) );
+                    context.setBetaconstraints( null );
+                    context.setObjectSource( null );
+                }
+            }
+        }
+
+        public boolean requiresLeftActivation(BuildUtils utils, RuleConditionElement rce) {
+            GroupElement and = (GroupElement) rce;
+
+            // need to check this because in the case of an empty rule, the root AND
+            // will have no child
+            if( and.getChildren().isEmpty() ) {
+                return true;
+            } 
+            
+            RuleConditionElement child = (RuleConditionElement) and.getChildren().get( 0 );
+            ReteooComponentBuilder builder = utils.getBuilderFor( child );
+            
+            return builder.requiresLeftActivation( utils, child );
+        }
+    }
+
+    private static class OrBuilder
+        implements
+        ReteooComponentBuilder {
+
+        /**
+         * @inheritDoc
+         */
+        public void build(BuildContext context,
+                          BuildUtils utils,
+                          RuleConditionElement rce) {
+            throw new RuntimeDroolsException( "BUG: Can't build a rete network with an inner OR group element" );
+        }
+
+        public boolean requiresLeftActivation(BuildUtils utils, RuleConditionElement rce) {
+            return false;
+        }
+    }
+
+    private static class NotBuilder
+        implements
+        ReteooComponentBuilder {
+
+        /**
+         * @inheritDoc
+         * 
+         * Not must verify what is the class of its child:
+         * 
+         * If it is a column, a simple NotNode is added to the rulebase
+         * If it is a group element, than a subnetwork must be created
+         */
+        public void build(BuildContext context,
+                          BuildUtils utils,
+                          RuleConditionElement rce) {
+            GroupElement not = (GroupElement) rce;
+            
+            // NOT must save current column index in order to restore it later
+            int currentColumnIndex = context.getCurrentColumnOffset();
+
+            // get child
+            RuleConditionElement child = (RuleConditionElement) not.getChildren().get( 0 );
+
+            // get builder for child
+            ReteooComponentBuilder builder = utils.getBuilderFor( child );
+
+            // builds the child
+            builder.build( context,
+                           utils,
+                           child );
+
+            // if child is a column 
+            if ( child instanceof Column ) {
+                // then no sub-network needed... just a simple NOT node
+                context.setTupleSource( (TupleSource) utils.attachNode( context,
+                                                                        new NotNode( context.getNextId(),
+                                                                                     context.getTupleSource(),
+                                                                                     context.getObjectSource(),
+                                                                                     context.getBetaconstraints() ) ) );
+                context.setBetaconstraints( null );
+                context.setObjectSource( null );
+
+            } else {
+                // TODO: otherwise attach subnetwork
+            }
+            
+            // restore column index
+            context.setCurrentColumnOffset( currentColumnIndex );
+        }
+
+        public boolean requiresLeftActivation(BuildUtils utils,
+                                              RuleConditionElement rce) {
+            return true;
+        }
+    }
+
+    private static class ExistsBuilder
+        implements
+        ReteooComponentBuilder {
+
+        /**
+         * @inheritDoc
+         * 
+         * Exists must verify what is the class of its child:
+         * 
+         * If it is a column, a simple ExistsNode is added to the rulebase
+         * If it is a group element, than a subnetwork must be created
+         */
+        public void build(BuildContext context,
+                          BuildUtils utils,
+                          RuleConditionElement rce) {
+            GroupElement exists = (GroupElement) rce;
+
+            // EXISTS must save current column index in order to restore it later
+            int currentColumnIndex = context.getCurrentColumnOffset();
+
+            // get child
+            RuleConditionElement child = (RuleConditionElement) exists.getChildren().get( 0 );
+
+            // get builder for child
+            ReteooComponentBuilder builder = utils.getBuilderFor( child );
+
+            // builds the child
+            builder.build( context,
+                           utils,
+                           child );
+
+            // if child is a column 
+            if ( child instanceof Column ) {
+                // then no sub-network needed... just a simple EXISTS node
+                context.setTupleSource( (TupleSource) utils.attachNode( context,
+                                                                        new ExistsNode( context.getNextId(),
+                                                                                     context.getTupleSource(),
+                                                                                     context.getObjectSource(),
+                                                                                     context.getBetaconstraints() ) ) );
+                context.setBetaconstraints( null );
+                context.setObjectSource( null );
+
+            } else {
+                // TODO: otherwise attach subnetwork
+            }
+            
+            // restore column index
+            context.setCurrentColumnOffset( currentColumnIndex );
+        }
+
+        /**
+         * @inheritDoc
+         */
+        public boolean requiresLeftActivation(BuildUtils utils,
+                                              RuleConditionElement rce) {
+            return true;
+        }
+    }
+
+}


Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/GroupElementBuilder.java
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:keywords
   + id author date revision
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/ReteooComponentBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/ReteooComponentBuilder.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/ReteooComponentBuilder.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2006 JBoss Inc
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.reteoo.builder;
+
+import org.drools.rule.RuleConditionElement;
+
+/**
+ * An interface for Reteoo Component builders
+ * 
+ * @author etirelli
+ */
+public interface ReteooComponentBuilder {
+    
+    /**
+     * Builds and attach if needed the given RuleConditionalElement
+     * 
+     * @param context current build context
+     * @param rce 
+     */
+    public void build( BuildContext context, BuildUtils utils, RuleConditionElement rce );
+    
+    /**
+     * A boolean function that indicates if the builder requires a previous left 
+     * (tuple) activation in order to corretly build the given component.
+     * 
+     * In other words, if it returns true and no previous TupleSource is already created,
+     * an InitialFact column must be added with appropriate left input adapter for 
+     * the network to be correctly built.
+     * 
+     * For instance, NOT / EXISTS / ACCUMULATE are examples of builders that must return true 
+     * for this method, while COLUMN must return false.
+     * 
+     * @param rce the element to be built
+     * 
+     * @return true if a tuple source is required, false otherwise.
+     */
+    public boolean requiresLeftActivation( BuildUtils utils, RuleConditionElement rce );
+
+}


Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/ReteooComponentBuilder.java
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:keywords
   + id author date revision
Name: svn:eol-style
   + native

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/ReteooRuleBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/ReteooRuleBuilder.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/ReteooRuleBuilder.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -0,0 +1,226 @@
+/*
+ * Copyright 2006 JBoss Inc
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.reteoo.builder;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.drools.InitialFact;
+import org.drools.RuleIntegrationException;
+import org.drools.base.ClassFieldExtractor;
+import org.drools.base.ClassObjectType;
+import org.drools.base.DroolsQuery;
+import org.drools.base.FieldFactory;
+import org.drools.base.ValueType;
+import org.drools.base.evaluators.Operator;
+import org.drools.common.BaseNode;
+import org.drools.reteoo.QueryTerminalNode;
+import org.drools.reteoo.ReteooBuilder;
+import org.drools.reteoo.ReteooRuleBase;
+import org.drools.reteoo.RuleTerminalNode;
+import org.drools.reteoo.TerminalNode;
+import org.drools.rule.Collect;
+import org.drools.rule.Column;
+import org.drools.rule.EvalCondition;
+import org.drools.rule.From;
+import org.drools.rule.GroupElement;
+import org.drools.rule.InvalidPatternException;
+import org.drools.rule.LiteralConstraint;
+import org.drools.rule.Query;
+import org.drools.rule.Rule;
+import org.drools.spi.FieldValue;
+
+/**
+ * @author etirelli
+ *
+ */
+public class ReteooRuleBuilder {
+
+    private BuildUtils utils;
+
+    public ReteooRuleBuilder() {
+        this.utils = new BuildUtils();
+
+        utils.addBuilder( GroupElement.class,
+                          new GroupElementBuilder() );
+        utils.addBuilder( Column.class,
+                          new ColumnBuilder() );
+        utils.addBuilder( EvalCondition.class,
+                          new EvalBuilder() );
+        utils.addBuilder( From.class,
+                          new FromBuilder() );
+        utils.addBuilder( Collect.class,
+                          new CollectBuilder() );
+        //utils.addBuilder( Accumulate.class, new AccumulateBuilder() );
+    }
+
+    /**
+     * Creates the corresponting Rete network for the given <code>Rule</code> and adds it to
+     * the given rule base.
+     * 
+     * @param rule
+     *            The rule to add.
+     * @param rulebase
+     *            The rulebase to add the rule to.
+     *            
+     * @return a List<BaseNode> of terminal nodes for the rule             
+     * 
+     * @throws RuleIntegrationException
+     *             if an error prevents complete construction of the network for
+     *             the <code>Rule</code>.
+     * @throws InvalidPatternException
+     */
+    public List addRule(final Rule rule,
+                        final ReteooRuleBase rulebase,
+                        final Map attachedNodes,
+                        final ReteooBuilder.IdGenerator idGenerator) throws InvalidPatternException {
+
+        // the list of terminal nodes
+        final List nodes = new ArrayList();
+
+        // transform rule and gets the array of subrules
+        final GroupElement[] subrules = rule.getTransformedLhs();
+
+        for ( int i = 0; i < subrules.length; i++ ) {
+            // creates a clean build context for each subrule
+            BuildContext context = new BuildContext( rulebase,
+                                                     attachedNodes,
+                                                     idGenerator );
+            // adds subrule
+            TerminalNode node = this.addSubRule( context,
+                                                 subrules[i],
+                                                 rule );
+
+            // adds the terminal node to the list of terminal nodes
+            nodes.add( node );
+
+        }
+
+        return nodes;
+    }
+
+    private TerminalNode addSubRule(BuildContext context,
+                                    final GroupElement subrule,
+                                    final Rule rule) throws InvalidPatternException {
+
+        // if it is a query, needs to add the query column
+        if ( rule instanceof Query ) {
+            this.addQueryColumn( context,
+                                 subrule,
+                                 (Query) rule );
+        }
+
+        // gets the appropriate builder
+        ReteooComponentBuilder builder = this.utils.getBuilderFor( subrule );
+
+        // checks if an initial-fact is needed
+        if ( builder.requiresLeftActivation( utils,
+                                             subrule ) ) {
+            this.addInitialFactColumn( context,
+                                       subrule,
+                                       rule );
+        }
+
+        // builds and attach
+        builder.build( context,
+                       this.utils,
+                       subrule );
+
+        TerminalNode terminal = null;
+
+        if ( !(rule instanceof Query) ) {
+            // Check a consequence is set
+            if ( rule.getConsequence() == null ) {
+                throw new InvalidPatternException( "Rule '" + rule.getName() + "' has no Consequence" );
+            }
+            terminal = new RuleTerminalNode( context.getNextId(),
+                                             context.getTupleSource(),
+                                             rule );
+        } else {
+            // Check there is no consequence
+            if ( rule.getConsequence() != null ) {
+                throw new InvalidPatternException( "Query '" + rule.getName() + "' should have no Consequence" );
+            }
+            terminal = new QueryTerminalNode( context.getNextId(),
+                                              context.getTupleSource(),
+                                              rule );
+        }
+        if ( context.getWorkingMemories().length == 0 ) {
+            ((BaseNode) terminal).attach();
+        } else {
+            ((BaseNode) terminal).attach( context.getWorkingMemories() );
+        }
+
+        return terminal;
+    }
+
+    /**
+     * Adds a query column to the given subrule
+     * 
+     * @param context
+     * @param subrule
+     * @param query
+     */
+    private void addQueryColumn(final BuildContext context,
+                                final GroupElement subrule,
+                                final Query query) {
+
+        // creates a column for initial fact
+        final Column column = new Column( 0,
+                                          new ClassObjectType( DroolsQuery.class ) );
+
+        final ClassFieldExtractor extractor = new ClassFieldExtractor( DroolsQuery.class,
+                                                                       "name" );
+
+        final FieldValue field = FieldFactory.getFieldValue( query.getName(),
+                                                             ValueType.STRING_TYPE );
+
+        final LiteralConstraint constraint = new LiteralConstraint( extractor,
+                                                                    ValueType.STRING_TYPE.getEvaluator( Operator.EQUAL ),
+                                                                    field );
+
+        // adds appropriate constraint to the column
+        column.addConstraint( constraint );
+
+        // adds the column as the first child of the given AND group element
+        subrule.addChild( 0,
+                          column );
+
+    }
+
+    /**
+     * Adds a query column to the given subrule
+     * 
+     * @param context
+     * @param subrule
+     * @param query
+     */
+    private void addInitialFactColumn(final BuildContext context,
+                                      final GroupElement subrule,
+                                      final Rule rule) {
+
+        // creates a column for initial fact
+        final Column column = new Column( 0,
+                                          new ClassObjectType( InitialFact.class ) );
+
+        // adds the column as the first child of the given AND group element
+        subrule.addChild( 0,
+                          column );
+    }
+
+}


Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/ReteooRuleBuilder.java
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:keywords
   + id author date revision
Name: svn:eol-style
   + native

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Accumulate.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Accumulate.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Accumulate.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -118,4 +118,11 @@
         return this.resultColumn.getOuterDeclarations();
     }
 
+    /**
+     * @inheritDoc
+     */
+    public Declaration resolveDeclaration(String identifier) {
+        return (Declaration) this.sourceColumn.getInnerDeclarations().get( identifier );
+    }
+
 }

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	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Collect.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -77,4 +77,11 @@
     public Map getOuterDeclarations() {
         return this.resultColumn.getOuterDeclarations();
     }
+
+    /**
+     * @inheritDoc
+     */
+    public Declaration resolveDeclaration(String identifier) {
+        return (Declaration) this.sourceColumn.getInnerDeclarations().get( identifier );
+    }
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Column.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Column.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Column.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -19,7 +19,6 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
@@ -41,14 +40,14 @@
     private Map               declarations;
     private final int         index;
 
-    // this is the negative offset of the related fact inside a tuple. i.e:
-    // tuple_fact_index = column_index + offset; 
+    // this is the offset of the related fact inside a tuple. i.e:
+    // the position of the related fact inside the tuple; 
     private int               offset;
 
     public Column(final int index,
                   final ObjectType objectType) {
         this( index,
-              0,
+              index,
               objectType,
               null );
     }
@@ -57,7 +56,7 @@
                   final ObjectType objectType,
                   final String identifier) {
         this( index,
-              0,
+              index,
               objectType,
               identifier );
     }
@@ -125,14 +124,17 @@
     }
 
     /**
+     * The offset of the fact related to this column 
+     * inside the tuple
+     * 
      * @return the offset
      */
     public int getOffset() {
         return this.offset;
     }
-
-    public int getFactIndex() {
-        return this.index + this.offset;
+    
+    public void setOffset(final int offset) {
+        this.offset = offset;
     }
 
     /**
@@ -141,16 +143,6 @@
      */
     public void adjustOffset(final int adjust) {
         this.offset += adjust;
-
-        if ( this.declaration != null ) {
-            this.declaration.setColumn( this );
-        }
-        for ( final Iterator i = this.constraints.iterator(); i.hasNext(); ) {
-            final Object constr = i.next();
-            if ( constr instanceof Declaration ) {
-                ((Declaration) constr).setColumn( this );
-            }
-        }
     }
 
     public Map getInnerDeclarations() {
@@ -160,6 +152,10 @@
     public Map getOuterDeclarations() {
         return ( this.declarations != null ) ? this.declarations : Collections.EMPTY_MAP;
     }
+    
+    public Declaration resolveDeclaration( String identifier ) {
+        return ( this.declarations != null ) ? (Declaration) this.declarations.get( identifier ) : null;
+    }
 
     public String toString() {
         return "Column type='" + ((this.objectType == null) ? "null" : this.objectType.toString()) + "', index='" + this.index + "', offset='" + this.getOffset() + "', identifer='" + ((this.declaration == null) ? "" : this.declaration.toString()) + "'";

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Declaration.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Declaration.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Declaration.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -200,7 +200,7 @@
     public int hashCode() {
         final int PRIME = 31;
         int result = 1;
-        result = PRIME * this.column.getFactIndex();
+        result = PRIME * this.column.getOffset();
         result = PRIME * this.extractor.hashCode();
         result = PRIME * this.identifier.hashCode();
         return result;
@@ -217,7 +217,7 @@
 
         final Declaration other = (Declaration) object;
 
-        return this.column.getFactIndex() == other.column.getFactIndex() && this.identifier.equals( other.identifier ) && this.extractor.equals( other.extractor );
+        return this.column.getOffset() == other.column.getOffset() && this.identifier.equals( other.identifier ) && this.extractor.equals( other.extractor );
     }
 
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/EvalCondition.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/EvalCondition.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/EvalCondition.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -102,7 +102,7 @@
         }
 
         for ( int i = 0, length = this.requiredDeclarations.length; i < length; i++ ) {
-            if ( this.requiredDeclarations[i].getColumn().getFactIndex() != other.requiredDeclarations[i].getColumn().getFactIndex() ) {
+            if ( this.requiredDeclarations[i].getColumn().getOffset() != other.requiredDeclarations[i].getColumn().getOffset() ) {
                 return false;
             }
 
@@ -121,4 +121,13 @@
     public Map getOuterDeclarations() {
         return Collections.EMPTY_MAP;
     }
+    
+    /**
+     * @inheritDoc
+     */
+    public Declaration resolveDeclaration(String identifier) {
+        return (Declaration) null;
+    }
+
+    
 };
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/From.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/From.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/From.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -41,4 +41,12 @@
     public Map getOuterDeclarations() {
         return this.column.getOuterDeclarations();
     }
+    
+    /**
+     * @inheritDoc
+     */
+    public Declaration resolveDeclaration(String identifier) {
+        return (Declaration) this.column.getInnerDeclarations().get( identifier );
+    }
+    
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/GroupElement.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/GroupElement.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/GroupElement.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -61,6 +61,15 @@
         this.children.add( child );
     }
 
+    /**
+     * Adds the given child as the (index)th child of the this GroupElement 
+     * @param index
+     * @param rce
+     */
+    public void addChild(int index, RuleConditionElement rce) {
+        this.children.add( index, rce );
+    }
+    
     public List getChildren() {
         return this.children;
     }
@@ -80,6 +89,13 @@
     }
 
     /**
+     * @inheritDoc
+     */
+    public Declaration resolveDeclaration(String identifier) {
+        return (Declaration) this.type.getInnerDeclarations( this.children ).get( identifier );
+    }
+
+    /**
      * Optimize the group element subtree by removing redundancies
      * like an AND inside another AND, OR inside OR, single branches
      * AND/OR, etc.
@@ -545,4 +561,5 @@
         }
     }
 
+
 }
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/PredicateConstraint.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/PredicateConstraint.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/PredicateConstraint.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -136,7 +136,7 @@
             return false;
         }
 
-        if ( this.declaration.getColumn().getFactIndex() != other.declaration.getColumn().getFactIndex() ) {
+        if ( this.declaration.getColumn().getOffset() != other.declaration.getColumn().getOffset() ) {
             return false;
         }
 
@@ -145,7 +145,7 @@
         }
 
         for ( int i = 0, length = this.previousDeclarations.length; i < length; i++ ) {
-            if ( this.previousDeclarations[i].getColumn().getFactIndex() != other.previousDeclarations[i].getColumn().getFactIndex() ) {
+            if ( this.previousDeclarations[i].getColumn().getOffset() != other.previousDeclarations[i].getColumn().getOffset() ) {
                 return false;
             }
 
@@ -155,7 +155,7 @@
         }
 
         for ( int i = 0, length = this.localDeclarations.length; i < length; i++ ) {
-            if ( this.localDeclarations[i].getColumn().getFactIndex() != other.localDeclarations[i].getColumn().getFactIndex() ) {
+            if ( this.localDeclarations[i].getColumn().getOffset() != other.localDeclarations[i].getColumn().getOffset() ) {
                 return false;
             }
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/RuleConditionElement.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/RuleConditionElement.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/RuleConditionElement.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -34,7 +34,7 @@
      * 
      * @return
      */
-    public abstract Map getInnerDeclarations();
+    public Map getInnerDeclarations();
 
     /**
      * Returns a Map of declarations that are visible
@@ -42,6 +42,16 @@
      * 
      * @return
      */
-    public abstract Map getOuterDeclarations();
+    public Map getOuterDeclarations();
+    
+    /**
+     * Resolves the given identifier in the current scope and
+     * returns the Declaration object for the declaration.
+     * Returns null if identifier can not be resolved.
+     *  
+     * @param identifier
+     * @return
+     */
+    public Declaration resolveDeclaration( String identifier );
 
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/mvel/conversion/ShortCH.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/mvel/conversion/ShortCH.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/mvel/conversion/ShortCH.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -128,8 +128,7 @@
         CNV.put(Boolean.class,
                 new Converter() {
                     public Short convert(Object o) {
-                        if ((Boolean) o) return 1;
-                        else return 0;
+                        return ((Boolean) o).booleanValue() ? (short)1: (short)0;
                     }
                 }
         );

Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/AgendaTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/AgendaTest.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/AgendaTest.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -54,7 +54,7 @@
 
         final Rule rule1 = new Rule( "test-rule1" );
 
-        final TerminalNode node1 = new TerminalNode( 3,
+        final RuleTerminalNode node1 = new RuleTerminalNode( 3,
                                                      new MockTupleSource( 2 ),
                                                      rule1 );
 
@@ -105,7 +105,7 @@
         final InternalAgenda agenda = (InternalAgenda) workingMemory.getAgenda();
 
         final Rule rule = new Rule( "test-rule" );
-        final TerminalNode node = new TerminalNode( 3,
+        final RuleTerminalNode node = new RuleTerminalNode( 3,
                                                     new MockTupleSource( 2 ),
                                                     rule );
 
@@ -227,7 +227,7 @@
 
         // create a rule for each agendaGroup
         final Rule rule0 = new Rule( "test-rule0" );
-        final TerminalNode node0 = new TerminalNode( 3,
+        final RuleTerminalNode node0 = new RuleTerminalNode( 3,
                                                      new MockTupleSource( 2 ),
                                                      rule0 );
         rule0.setConsequence( consequence );
@@ -238,7 +238,7 @@
 
         final Rule rule1 = new Rule( "test-rule1",
                                      "agendaGroup1" );
-        final TerminalNode node1 = new TerminalNode( 5,
+        final RuleTerminalNode node1 = new RuleTerminalNode( 5,
                                                      new MockTupleSource( 4 ),
                                                      rule1 );
         rule1.setConsequence( consequence );
@@ -249,7 +249,7 @@
 
         final Rule rule2 = new Rule( "test-rule2",
                                      "agendaGroup2" );
-        final TerminalNode node2 = new TerminalNode( 7,
+        final RuleTerminalNode node2 = new RuleTerminalNode( 7,
                                                      new MockTupleSource( 6 ),
                                                      rule2 );
         rule2.setConsequence( consequence );
@@ -260,7 +260,7 @@
 
         final Rule rule3 = new Rule( "test-rule3",
                                      "agendaGroup3" );
-        final TerminalNode node3 = new TerminalNode( 9,
+        final RuleTerminalNode node3 = new RuleTerminalNode( 9,
                                                      new MockTupleSource( 8 ),
                                                      rule3 );
         rule3.setConsequence( consequence );
@@ -440,7 +440,7 @@
         // create a rule for the agendaGroup
         final Rule rule = new Rule( "test-rule",
                                     "agendaGroup" );
-        final TerminalNode node = new TerminalNode( 2,
+        final RuleTerminalNode node = new RuleTerminalNode( 2,
                                                     new MockTupleSource( 2 ),
                                                     rule );
         rule.setConsequence( consequence );
@@ -516,7 +516,7 @@
         // create a rule for each agendaGroup
         final Rule rule0 = new Rule( "test-rule0" );
         rule0.setXorGroup( "activation-group-0" );
-        final TerminalNode node0 = new TerminalNode( 3,
+        final RuleTerminalNode node0 = new RuleTerminalNode( 3,
                                                      new MockTupleSource( 2 ),
                                                      rule0 );
         rule0.setConsequence( consequence );
@@ -527,7 +527,7 @@
 
         final Rule rule1 = new Rule( "test-rule1" );
         rule1.setXorGroup( "activation-group-0" );
-        final TerminalNode node1 = new TerminalNode( 5,
+        final RuleTerminalNode node1 = new RuleTerminalNode( 5,
                                                      new MockTupleSource( 4 ),
                                                      rule1 );
         rule1.setConsequence( consequence );
@@ -537,7 +537,7 @@
                                                                         null );
 
         final Rule rule2 = new Rule( "test-rule2" );
-        final TerminalNode node2 = new TerminalNode( 7,
+        final RuleTerminalNode node2 = new RuleTerminalNode( 7,
                                                      new MockTupleSource( 6 ),
                                                      rule2 );
         rule2.setConsequence( consequence );
@@ -549,7 +549,7 @@
         final Rule rule3 = new Rule( "test-rule3",
                                      "agendaGroup3" );
         rule3.setXorGroup( "activation-group-3" );
-        final TerminalNode node3 = new TerminalNode( 9,
+        final RuleTerminalNode node3 = new RuleTerminalNode( 9,
                                                      new MockTupleSource( 8 ),
                                                      rule3 );
         rule3.setConsequence( consequence );

Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/LogicalAssertionTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/LogicalAssertionTest.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/LogicalAssertionTest.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -50,7 +50,7 @@
         objectTypeNode.addObjectSink( sink );
 
         final Rule rule1 = new Rule( "test-rule1" );
-        final TerminalNode node = new TerminalNode( 2,
+        final RuleTerminalNode node = new RuleTerminalNode( 2,
                                                     new MockTupleSource( 2 ),
                                                     rule1 );
         final ReteooWorkingMemory workingMemory = (ReteooWorkingMemory) ruleBase.newWorkingMemory();
@@ -148,7 +148,7 @@
         final MockObjectSink sink = new MockObjectSink();
         objectTypeNode.addObjectSink( sink );
 
-        final TerminalNode node = new TerminalNode( 2,
+        final RuleTerminalNode node = new RuleTerminalNode( 2,
                                                     new MockTupleSource( 2 ),
                                                     rule1 );
 
@@ -235,7 +235,7 @@
         objectTypeNode.attach();
         final MockObjectSink sink = new MockObjectSink();
         objectTypeNode.addObjectSink( sink );
-        final TerminalNode node = new TerminalNode( 2,
+        final RuleTerminalNode node = new RuleTerminalNode( 2,
                                                     new MockTupleSource( 2 ),
                                                     rule1 );
         final RuleBase ruleBase = RuleBaseFactory.newRuleBase();
@@ -368,7 +368,7 @@
         objectTypeNode.attach();
         final MockObjectSink sink = new MockObjectSink();
         objectTypeNode.addObjectSink( sink );
-        final TerminalNode node = new TerminalNode( 2,
+        final RuleTerminalNode node = new RuleTerminalNode( 2,
                                                     new MockTupleSource( 2 ),
                                                     rule1 );
         final RuleBaseConfiguration conf = new RuleBaseConfiguration();
@@ -457,7 +457,7 @@
         objectTypeNode.attach();
         final MockObjectSink sink = new MockObjectSink();
         objectTypeNode.addObjectSink( sink );
-        final TerminalNode node = new TerminalNode( 2,
+        final RuleTerminalNode node = new RuleTerminalNode( 2,
                                                     new MockTupleSource( 2 ),
                                                     rule1 );
         final RuleBase ruleBase = RuleBaseFactory.newRuleBase();
@@ -501,7 +501,7 @@
 
         // create the second activation to justify the "logical" fact
         final Rule rule2 = new Rule( "test-rule2" );
-        final TerminalNode node2 = new TerminalNode( 4,
+        final RuleTerminalNode node2 = new RuleTerminalNode( 4,
                                                      new MockTupleSource( 3 ),
                                                      rule2 );
         rule2.setConsequence( consequence );
@@ -553,7 +553,7 @@
         objectTypeNode.attach();
         final MockObjectSink sink = new MockObjectSink();
         objectTypeNode.addObjectSink( sink );
-        final TerminalNode node = new TerminalNode( 2,
+        final RuleTerminalNode node = new RuleTerminalNode( 2,
                                                     new MockTupleSource( 2 ),
                                                     rule1 );
         final ReteooWorkingMemory workingMemory = (ReteooWorkingMemory) ruleBase.newWorkingMemory();
@@ -590,7 +590,7 @@
 
         // Create the second justifer
         final Rule rule2 = new Rule( "test-rule2" );
-        final TerminalNode node2 = new TerminalNode( 4,
+        final RuleTerminalNode node2 = new RuleTerminalNode( 4,
                                                      new MockTupleSource( 3 ),
                                                      rule2 );
         rule2.setConsequence( consequence );
@@ -678,7 +678,7 @@
         objectTypeNode.attach();
         final MockObjectSink sink = new MockObjectSink();
         objectTypeNode.addObjectSink( sink );
-        final TerminalNode node = new TerminalNode( 2,
+        final RuleTerminalNode node = new RuleTerminalNode( 2,
                                                     new MockTupleSource( 2 ),
                                                     rule1 );
         final RuleBase ruleBase = RuleBaseFactory.newRuleBase();
@@ -776,7 +776,7 @@
         objectTypeNode.attach();
         final MockObjectSink sink = new MockObjectSink();
         objectTypeNode.addObjectSink( sink );
-        final TerminalNode node = new TerminalNode( 2,
+        final RuleTerminalNode node = new RuleTerminalNode( 2,
                                                     new MockTupleSource( 2 ),
                                                     rule1 );
         final RuleBase ruleBase = RuleBaseFactory.newRuleBase();

Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/SchedulerTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/SchedulerTest.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/SchedulerTest.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -43,7 +43,7 @@
         final ReteooWorkingMemory workingMemory = (ReteooWorkingMemory) ruleBase.newWorkingMemory();
 
         final Rule rule = new Rule( "test-rule" );
-        final TerminalNode node = new TerminalNode( 1,
+        final RuleTerminalNode node = new RuleTerminalNode( 1,
                                                     new MockTupleSource( 2 ),
                                                     rule );
         final List data = new ArrayList();
@@ -105,7 +105,7 @@
         final Agenda agenda = workingMemory.getAgenda();
 
         final Rule rule = new Rule( "test-rule" );
-        final TerminalNode node = new TerminalNode( 1,
+        final RuleTerminalNode node = new RuleTerminalNode( 1,
                                                     new MockTupleSource( 2 ),
                                                     rule );
         final List data = new ArrayList();
@@ -183,7 +183,7 @@
         final Rule rule = new Rule( "test-rule" );
         final List data = new ArrayList();
 
-        final TerminalNode node = new TerminalNode( 1,
+        final RuleTerminalNode node = new RuleTerminalNode( 1,
                                                     new MockTupleSource( 2 ),
                                                     rule );
 

Added: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/builder/ReteooRuleBuilderTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/builder/ReteooRuleBuilderTest.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/builder/ReteooRuleBuilderTest.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2006 JBoss Inc
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.reteoo.builder;
+
+import java.util.HashMap;
+import java.util.List;
+
+import org.drools.WorkingMemory;
+import org.drools.base.ClassObjectType;
+import org.drools.reteoo.JoinNode;
+import org.drools.reteoo.ReteooBuilder;
+import org.drools.reteoo.ReteooRuleBase;
+import org.drools.reteoo.RuleTerminalNode;
+import org.drools.rule.Column;
+import org.drools.rule.GroupElement;
+import org.drools.rule.GroupElementFactory;
+import org.drools.rule.Rule;
+import org.drools.spi.Consequence;
+import org.drools.spi.KnowledgeHelper;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+/**
+ * @author etirelli
+ *
+ */
+public class ReteooRuleBuilderTest extends TestCase {
+    private ReteooRuleBuilder builder;
+    private ReteooRuleBase    rulebase;
+
+    /* (non-Javadoc)
+     * @see junit.framework.TestCase#setUp()
+     */
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        builder = new ReteooRuleBuilder();
+        rulebase = new ReteooRuleBase( "default" );
+    }
+
+    /* (non-Javadoc)
+     * @see junit.framework.TestCase#tearDown()
+     */
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    /**
+     * Test method for {@link org.drools.reteoo.builder.ReteooRuleBuilder#addRule(org.drools.rule.Rule, org.drools.reteoo.ReteooRuleBase, java.util.Map, int)}.
+     */
+    public void testAddRuleWithColumns() {
+        Rule rule = new Rule( "only columns" );
+        Column c1 = new Column( 0,
+                                new ClassObjectType( String.class ) );
+        Column c2 = new Column( 1,
+                                new ClassObjectType( String.class ) );
+        Column c3 = new Column( 2,
+                                new ClassObjectType( String.class ) );
+
+        GroupElement lhsroot = GroupElementFactory.newAndInstance();
+        lhsroot.addChild( c1 );
+        lhsroot.addChild( c2 );
+        lhsroot.addChild( c3 );
+
+        rule.setLhs( lhsroot );
+        
+        Consequence consequence = new Consequence() {
+            public void evaluate(KnowledgeHelper knowledgeHelper,
+                                 WorkingMemory workingMemory) throws Exception {
+                System.out.println("Consequence!");
+            }
+            
+        };
+        
+        rule.setConsequence( consequence );
+
+        List terminals = this.builder.addRule( rule,
+                                               this.rulebase,
+                                               new HashMap(),
+                                               new ReteooBuilder.IdGenerator(1) );
+        
+        Assert.assertEquals( "Rule must have a single terminal node", 1, terminals.size() );
+        
+        RuleTerminalNode terminal = (RuleTerminalNode) terminals.get( 0 );
+
+    }
+
+}


Property changes on: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/builder/ReteooRuleBuilderTest.java
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:keywords
   + id author date revision
Name: svn:eol-style
   + native

Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/rule/DeclarationTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/rule/DeclarationTest.java	2007-01-11 16:23:34 UTC (rev 8827)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/rule/DeclarationTest.java	2007-01-11 20:10:15 UTC (rev 8828)
@@ -51,8 +51,8 @@
         assertSame( extractor,
                     declaration.getExtractor() );
 
-        assertEquals( 5,
-                      declaration.getColumn().getFactIndex() );
+        assertEquals( 5, 
+                      declaration.getColumn().getOffset() );
 
     }
 

Modified: labs/jbossrules/trunk/drools-core/src/test/resources/correct_processTree1.dat
===================================================================
(Binary files differ)

Modified: labs/jbossrules/trunk/drools-core/src/test/resources/correct_transform1.dat
===================================================================
(Binary files differ)




More information about the jboss-svn-commits mailing list