[jboss-svn-commits] JBL Code SVN: r32530 - in labs/jbossrules/trunk: drools-compiler/src/main/java/org/drools/rule/builder and 10 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Mon Apr 12 23:58:03 EDT 2010


Author: mark.proctor at jboss.com
Date: 2010-04-12 23:58:01 -0400 (Mon, 12 Apr 2010)
New Revision: 32530

Added:
   labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/LiteralDescr.java
   labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/VariableDescr.java
   labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/QueryElementBuilder.java
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/compiler/QueryBuilderTest.java
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/PseudoSchedulerRemoveJobTest.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/ArrayElements.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/QueryElementFactHandle.java
Removed:
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/Arguments.java
Modified:
   labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/PatternBuilder.java
   labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/QueryBuilder.java
   labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/dialect/java/JavaConsequenceBuilder.java
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/compiler/PackageBuilderTest.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/DefaultQueryResultsCollector.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/DroolsQuery.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/extractors/ArrayElementReader.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/CompositeLeftTupleSinkAdapter.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/EmptyLeftTupleSinkAdapter.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/LeftTupleSinkPropagator.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/QueryElementNode.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/SingleLeftTupleSinkAdapter.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/QueryElementBuilder.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/QueryElement.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/QueryElementNodeTest.java
Log:
JBRULES-46 Proloq Style Query Based Backward Chaining
-Now works end to end, except parser. Have added full example constructing descrs directly.

Added: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/LiteralDescr.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/LiteralDescr.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/LiteralDescr.java	2010-04-13 03:58:01 UTC (rev 32530)
@@ -0,0 +1,59 @@
+package org.drools.lang.descr;
+
+import java.text.DecimalFormat;
+import java.text.ParseException;
+import java.util.Locale;
+
+public class LiteralDescr extends BaseDescr {
+    public static final int   TYPE_NULL        = 1;
+    public static final int   TYPE_NUMBER      = 2;
+    public static final int   TYPE_STRING      = 3;
+    public static final int   TYPE_BOOLEAN     = 4;
+
+    private static final long serialVersionUID = 400L;
+    private int               type;
+    
+    private String            text;
+
+    public LiteralDescr(){
+    }
+
+    public LiteralDescr(final String text,
+                             final int type) {
+        this.text = text;
+        this.type = type;
+    }
+
+    public String toString() {
+        return "[LiteralValue: " + getValue().getClass() + " " + getValue() + "]";
+    }
+
+    public int getType() {
+        return type;
+    }
+
+    public void setType(int type) {
+        this.type = type;
+    }
+    
+    public String getText() {
+        return this.text;
+    }
+
+    public Object getValue() {
+        switch ( this.type ) {
+            case TYPE_NUMBER :
+                try {
+                    // in the DRL, we always use US number formatting 
+                    return DecimalFormat.getInstance(Locale.US).parse( this.getText() );
+                } catch ( ParseException e ) {
+                    // return String anyway
+                    return this.getText();
+                }
+            case TYPE_BOOLEAN :
+                return Boolean.valueOf( this.getText() );
+            default :
+                return this.getText();
+        }
+    }
+}

Added: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/VariableDescr.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/VariableDescr.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/lang/descr/VariableDescr.java	2010-04-13 03:58:01 UTC (rev 32530)
@@ -0,0 +1,15 @@
+package org.drools.lang.descr;
+
+public class VariableDescr extends BaseDescr {
+    private String identifier;
+
+    public VariableDescr(String identifier) {
+        this.identifier = identifier;
+    }
+
+    public String getIdentifier() {
+        return identifier;
+    }
+    
+    
+}

Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/PatternBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/PatternBuilder.java	2010-04-13 03:55:47 UTC (rev 32529)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/PatternBuilder.java	2010-04-13 03:58:01 UTC (rev 32530)
@@ -68,8 +68,10 @@
 import org.drools.rule.Pattern;
 import org.drools.rule.PatternSource;
 import org.drools.rule.PredicateConstraint;
+import org.drools.rule.Query;
 import org.drools.rule.ReturnValueConstraint;
 import org.drools.rule.ReturnValueRestriction;
+import org.drools.rule.Rule;
 import org.drools.rule.RuleConditionElement;
 import org.drools.rule.SlidingLengthWindow;
 import org.drools.rule.SlidingTimeWindow;
@@ -144,11 +146,24 @@
                 objectType = new ClassObjectType( userProvidedClass,
                                                   isEvent );
             } catch ( final ClassNotFoundException e ) {
+                // swallow as we'll do another check in a moment and then record the problem
+            }
+        }
+        
+        // lets see if it maps to a query
+        if ( objectType == null ) {
+            Rule rule = context.getPkg().getRule( patternDescr.getObjectType() );            
+            if ( rule != null && rule instanceof Query ) {
+                // it's a query so delegate to the QueryElementBuilder
+                QueryElementBuilder qeBuilder = new QueryElementBuilder();
+                return qeBuilder.build( context, descr, prefixPattern );
+            } else { 
+                // this isn't a query either, so log an error
                 context.getErrors().add( new DescrBuildError( context.getParentDescr(),
                                                               patternDescr,
                                                               null,
                                                               "Unable to resolve ObjectType '" + patternDescr.getObjectType() + "'" ) );
-                return null;
+                return null;                
             }
         }
 

Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/QueryBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/QueryBuilder.java	2010-04-13 03:55:47 UTC (rev 32529)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/QueryBuilder.java	2010-04-13 03:58:01 UTC (rev 32530)
@@ -1,6 +1,6 @@
 package org.drools.rule.builder;
 
-import org.drools.base.Arguments;
+import org.drools.base.ArrayElements;
 import org.drools.base.ClassObjectType;
 import org.drools.base.DroolsQuery;
 import org.drools.base.FieldFactory;
@@ -42,9 +42,9 @@
         // adds appropriate constraint to the pattern
         pattern.addConstraint( constraint );
 
-        ObjectType argsObjectType = new ClassObjectType( Arguments.class );
+        ObjectType argsObjectType = new ClassObjectType( ArrayElements.class );
         
-        InternalReadAccessor arrayExtractor = PatternBuilder.getFieldReadAccessor( context, queryDescr, argsObjectType, "arguments", null, true );
+        InternalReadAccessor arrayExtractor = PatternBuilder.getFieldReadAccessor( context, queryDescr, argsObjectType, "elements", null, true );
 
         String[] params = queryDescr.getParameters();
         String[] types = queryDescr.getParameterTypes();
@@ -60,7 +60,7 @@
                 ArrayElementReader reader = new ArrayElementReader( arrayExtractor,
                                         i,
                                         context.getDialect().getTypeResolver().resolveType( types[i] ) );
-                PatternBuilder.registerReadAccessor( context, argsObjectType, "arguments", reader );
+                PatternBuilder.registerReadAccessor( context, argsObjectType, "elements", reader );
                 
                 declr.setReadAccessor( reader );
                 

Added: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/QueryElementBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/QueryElementBuilder.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/QueryElementBuilder.java	2010-04-13 03:58:01 UTC (rev 32530)
@@ -0,0 +1,104 @@
+package org.drools.rule.builder;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.drools.base.ArrayElements;
+import org.drools.base.ClassObjectType;
+import org.drools.base.extractors.ArrayElementReader;
+import org.drools.base.extractors.SelfReferenceClassFieldReader;
+import org.drools.lang.descr.LiteralDescr;
+import org.drools.lang.descr.BaseDescr;
+import org.drools.lang.descr.PatternDescr;
+import org.drools.lang.descr.VariableDescr;
+import org.drools.rule.Declaration;
+import org.drools.rule.Pattern;
+import org.drools.rule.Query;
+import org.drools.rule.QueryElement;
+import org.drools.rule.Rule;
+import org.drools.rule.RuleConditionElement;
+import org.drools.rule.Variable;
+import org.drools.spi.InternalReadAccessor;
+import org.drools.spi.ObjectType;
+
+public class QueryElementBuilder
+    implements
+    RuleConditionBuilder {
+
+    public RuleConditionElement build(RuleBuildContext context,
+                                      BaseDescr descr) {
+        return this.build( context,
+                           descr,
+                           null );
+    }
+
+    public RuleConditionElement build(RuleBuildContext context,
+                                      BaseDescr descr,
+                                      Pattern prefixPattern) {
+        PatternDescr patternDescr = (PatternDescr) descr;
+        Query query = (Query) context.getPkg().getRule( patternDescr.getObjectType() );
+
+        Declaration[] params = query.getParameters();
+
+        List<BaseDescr> args = (List<BaseDescr>) patternDescr.getDescrs();
+        List<Integer> declrIndexes = new ArrayList<Integer>();
+        List<Integer> varIndexes = new ArrayList<Integer>();
+        List<Object> arguments = new ArrayList<Object>();
+        List<Declaration> requiredDeclarations = new ArrayList<Declaration>();
+
+        ObjectType argsObjectType = new ClassObjectType( Object[].class );
+        InternalReadAccessor arrayReader = new SelfReferenceClassFieldReader(Object[].class, "this");
+        Pattern pattern = new Pattern( context.getNextPatternId(),
+                                       0,
+                                       argsObjectType,
+                                       null );
+
+        for ( int i = 0, length = args.size(); i < length; i++ ) {
+            BaseDescr arg = args.get( i );
+
+            if ( arg instanceof LiteralDescr ) {
+                arguments.add( ((LiteralDescr) arg).getValue() );
+            } else if ( arg instanceof VariableDescr ) {
+                String var = ((VariableDescr) arg).getIdentifier();
+                Declaration declr = context.getDeclarationResolver().getDeclaration( query,
+                                                                                     var );
+                if ( declr != null ) {
+                    // declaration
+                    declrIndexes.add( i );
+                    arguments.add( declr );
+                    requiredDeclarations.add( declr );
+                } else {
+                    // unification variable                    
+                    declr = pattern.addDeclaration( var );
+
+                    // this bit is different, notice its the ArrayElementReader that we wire up to, not the declaration.
+                    ArrayElementReader reader = new ArrayElementReader( arrayReader,
+                                                                        varIndexes.size(),
+                                                                        params[i].getExtractor().getExtractToClass() );
+
+                    declr.setReadAccessor( reader );
+
+                    varIndexes.add( i );
+                    arguments.add( new Variable() );
+                }
+            }
+        }
+        Declaration[] declrsArray = requiredDeclarations.toArray( new Declaration[requiredDeclarations.size()] );
+        int[] declrIndexArray = new int[declrIndexes.size()];
+        for( int i = 0; i < declrsArray.length; i++ ) {
+            declrIndexArray[i] = declrIndexes.get( i );
+        }
+        int[] varIndexesArray = new int[varIndexes.size()];
+        for( int i = 0; i < varIndexesArray.length; i++ ) {
+            varIndexesArray[i] = varIndexes.get( i );
+        }
+        
+        return new QueryElement( pattern,
+                                 query.getName(),
+                                 arguments.toArray( new Object[arguments.size()] ),
+                                 declrsArray,
+                                 declrIndexArray,
+                                 varIndexesArray );
+    }
+
+}

Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/dialect/java/JavaConsequenceBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/dialect/java/JavaConsequenceBuilder.java	2010-04-13 03:55:47 UTC (rev 32529)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/dialect/java/JavaConsequenceBuilder.java	2010-04-13 03:58:01 UTC (rev 32530)
@@ -132,8 +132,7 @@
                           className,
                           map,
                           context.getRule(),
-                          ruleDescr );
-
+                          ruleDescr );      
         // popping Rule.getLHS() from the build stack
         context.getBuildStack().pop();
     }

Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/compiler/PackageBuilderTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/compiler/PackageBuilderTest.java	2010-04-13 03:55:47 UTC (rev 32529)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/compiler/PackageBuilderTest.java	2010-04-13 03:58:01 UTC (rev 32530)
@@ -837,57 +837,6 @@
                       builder.getErrors().getErrors() );
     }
 
-    public void testQuery() throws Exception {
-        final PackageBuilder builder = new PackageBuilder();
-
-        final PackageDescr packageDescr = new PackageDescr( "p1" );
-        final QueryDescr queryDescr = new QueryDescr( "query1" );
-        queryDescr.setParameters( new String[]{"$type"} );
-        queryDescr.setParameterTypes( new String[]{"String"} );
-
-        packageDescr.addRule( queryDescr );
-
-        final AndDescr lhs = new AndDescr();
-        queryDescr.setLhs( lhs );
-
-        final PatternDescr pattern = new PatternDescr( Cheese.class.getName(),
-                                                       "stilton" );
-        lhs.addDescr( pattern );
-
-        final FieldConstraintDescr literalDescr = new FieldConstraintDescr( "type" );
-        literalDescr.addRestriction( new VariableRestrictionDescr( "==",
-                                                                   "$type" ) );
-
-        pattern.addConstraint( literalDescr );
-
-        queryDescr.setConsequence( "update(stilton);" );
-
-        builder.addPackage( packageDescr );
-
-        assertLength( 0,
-                      builder.getErrors().getErrors() );
-
-        RuleBase ruleBase = RuleBaseFactory.newRuleBase();
-        ruleBase.addPackage( builder.getPackage() );
-
-        StatefulSession session = ruleBase.newStatefulSession();
-
-        session.insert( new Cheese( "stilton",
-                                    15 ) );
-
-        QueryResults results = session.getQueryResults( "query1",
-                                                        new Object[]{"stilton"} );
-        assertEquals( 1,
-                      results.size() );
-        Object object = results.get( 0 ).get( 0 );
-        assertEquals( new Cheese( "stilton",
-                                  15 ),
-                      object );
-
-        results = session.getQueryResults( "query1",
-                                           new Object[]{"cheddar"} );
-    }
-
     public void testDuplicateRuleNames() throws Exception {
 
         final PackageBuilder builder = new PackageBuilder();

Added: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/compiler/QueryBuilderTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/compiler/QueryBuilderTest.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/compiler/QueryBuilderTest.java	2010-04-13 03:58:01 UTC (rev 32530)
@@ -0,0 +1,132 @@
+package org.drools.compiler;
+
+import org.drools.Cheese;
+import org.drools.DroolsTestCase;
+import org.drools.Person;
+import org.drools.QueryResults;
+import org.drools.RuleBase;
+import org.drools.RuleBaseFactory;
+import org.drools.StatefulSession;
+import org.drools.lang.descr.AndDescr;
+import org.drools.lang.descr.FieldBindingDescr;
+import org.drools.lang.descr.FieldConstraintDescr;
+import org.drools.lang.descr.LiteralDescr;
+import org.drools.lang.descr.PackageDescr;
+import org.drools.lang.descr.PatternDescr;
+import org.drools.lang.descr.QueryDescr;
+import org.drools.lang.descr.RuleDescr;
+import org.drools.lang.descr.VariableDescr;
+import org.drools.lang.descr.VariableRestrictionDescr;
+
+public class QueryBuilderTest extends DroolsTestCase {
+    public void testRuleWithQuery() throws Exception {
+        final PackageBuilder builder = new PackageBuilder();
+
+        final PackageDescr packageDescr = new PackageDescr( "p1" );
+
+        QueryDescr queryDescr = new QueryDescr( "query1" );
+        queryDescr.setParameters( new String[]{"$name", "$age", "$likes"} );
+        queryDescr.setParameterTypes( new String[]{"String", "int", "String"} );
+        packageDescr.addRule( queryDescr );
+        AndDescr lhs = new AndDescr();
+        queryDescr.setLhs( lhs );
+        PatternDescr pattern = new PatternDescr( Person.class.getName() );
+        lhs.addDescr( pattern );
+        FieldConstraintDescr literalDescr = new FieldConstraintDescr( "name" );
+        literalDescr.addRestriction( new VariableRestrictionDescr( "==",
+                                                                   "$name" ) );
+        pattern.addConstraint( literalDescr );
+        
+        literalDescr = new FieldConstraintDescr( "age" );
+        literalDescr.addRestriction( new VariableRestrictionDescr( "==",
+                                                                   "$age" ) );
+        pattern.addConstraint( literalDescr );
+        
+        literalDescr = new FieldConstraintDescr( "likes" );
+        literalDescr.addRestriction( new VariableRestrictionDescr( "==",
+                                                                   "$likes" ) );
+        pattern.addConstraint( literalDescr );        
+        
+        RuleDescr ruleDescr = new RuleDescr( "rule-1" );
+        packageDescr.addRule( ruleDescr );
+        lhs = new AndDescr();
+        ruleDescr.setLhs( lhs );
+        
+        pattern = new PatternDescr( Cheese.class.getName()  );
+        lhs.addDescr( pattern );       
+        pattern.addConstraint( new FieldBindingDescr( "type", "$type" ) );
+        
+        pattern = new PatternDescr( "query1" );
+        lhs.addDescr( pattern );
+        pattern.addConstraint( new LiteralDescr( "bobba",
+                                                 LiteralDescr.TYPE_STRING ) );
+        pattern.addConstraint( new VariableDescr( "$age" ) );
+        pattern.addConstraint( new VariableDescr( "$type" ) );
+        ruleDescr.setConsequence( "System.out.println(\"age: \" + $age);" );
+        
+        builder.addPackage( packageDescr );
+        assertLength( 0,
+                      builder.getErrors().getErrors() );
+
+        RuleBase rbase = RuleBaseFactory.newRuleBase();
+        rbase.addPackage( builder.getPackage() );
+        StatefulSession session = rbase.newStatefulSession();
+        
+        session.insert( new Person( "bobba", "stilton", 90 ) );
+        session.insert( new Person( "bobba", "brie", 80 ) );
+        session.insert( new Person( "bobba", "brie", 75 ) );
+        session.insert( new Person( "darth", "brie", 100 ) );
+        session.insert( new Person( "luke", "brie", 25 ) );
+        session.insert( new Cheese( "brie", 25 ) );
+        session.fireAllRules();
+    }
+
+    public void testQuery() throws Exception {
+        final PackageBuilder builder = new PackageBuilder();
+
+        final PackageDescr packageDescr = new PackageDescr( "p1" );
+        final QueryDescr queryDescr = new QueryDescr( "query1" );
+        queryDescr.setParameters( new String[]{"$type"} );
+        queryDescr.setParameterTypes( new String[]{"String"} );
+
+        packageDescr.addRule( queryDescr );
+
+        final AndDescr lhs = new AndDescr();
+        queryDescr.setLhs( lhs );
+
+        final PatternDescr pattern = new PatternDescr( Cheese.class.getName(),
+                                                       "stilton" );
+        lhs.addDescr( pattern );
+
+        final FieldConstraintDescr literalDescr = new FieldConstraintDescr( "type" );
+        literalDescr.addRestriction( new VariableRestrictionDescr( "==",
+                                                                   "$type" ) );
+
+        pattern.addConstraint( literalDescr );
+
+        builder.addPackage( packageDescr );
+
+        assertLength( 0,
+                      builder.getErrors().getErrors() );
+
+        RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+        ruleBase.addPackage( builder.getPackage() );
+
+        StatefulSession session = ruleBase.newStatefulSession();
+
+        session.insert( new Cheese( "stilton",
+                                    15 ) );
+
+        QueryResults results = session.getQueryResults( "query1",
+                                                        new Object[]{"stilton"} );
+        assertEquals( 1,
+                      results.size() );
+        Object object = results.get( 0 ).get( 0 );
+        assertEquals( new Cheese( "stilton",
+                                  15 ),
+                      object );
+
+        results = session.getQueryResults( "query1",
+                                           new Object[]{"cheddar"} );
+    }
+}

Added: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/PseudoSchedulerRemoveJobTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/PseudoSchedulerRemoveJobTest.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/PseudoSchedulerRemoveJobTest.java	2010-04-13 03:58:01 UTC (rev 32530)
@@ -0,0 +1,77 @@
+package org.drools.integrationtests;
+
+
+import java.io.Serializable;
+import java.io.StringReader;
+
+import junit.framework.TestCase;
+
+import org.drools.KnowledgeBase;
+import org.drools.KnowledgeBaseConfiguration;
+import org.drools.KnowledgeBaseFactory;
+import org.drools.builder.KnowledgeBuilder;
+import org.drools.builder.KnowledgeBuilderFactory;
+import org.drools.builder.ResourceType;
+import org.drools.conf.EventProcessingOption;
+import org.drools.io.ResourceFactory;
+import org.drools.runtime.KnowledgeSessionConfiguration;
+import org.drools.runtime.StatefulKnowledgeSession;
+import org.drools.runtime.conf.ClockTypeOption;
+import org.drools.runtime.rule.FactHandle;
+import org.drools.time.impl.PseudoClockScheduler;
+
+/**
+ * @author mproch
+ * 
+ */
+public class PseudoSchedulerRemoveJobTest extends TestCase {
+
+    KnowledgeBase knowledgeBase;
+
+    StatefulKnowledgeSession ksession;
+
+    PseudoClockScheduler pseudoClock;
+
+    public void setUp() throws Exception {
+        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory
+                .newKnowledgeBuilder();
+        kbuilder.add(ResourceFactory.newReaderResource(new StringReader(str)),
+                ResourceType.DRL);
+        if (kbuilder.hasErrors()) {
+            throw new RuntimeException(kbuilder.getErrors().toString());
+        }
+        KnowledgeBaseConfiguration config = KnowledgeBaseFactory
+                .newKnowledgeBaseConfiguration();
+        config.setOption(EventProcessingOption.STREAM);
+
+        KnowledgeSessionConfiguration sessionConfig = KnowledgeBaseFactory
+                .newKnowledgeSessionConfiguration();
+        sessionConfig.setOption(ClockTypeOption.get("pseudo"));
+        knowledgeBase = KnowledgeBaseFactory.newKnowledgeBase(config);
+        knowledgeBase.addKnowledgePackages(kbuilder.getKnowledgePackages());
+        ksession = knowledgeBase.newStatefulKnowledgeSession(sessionConfig,
+                KnowledgeBaseFactory.newEnvironment());
+        pseudoClock = ksession.getSessionClock();
+    }
+
+    public void testRule() throws Exception {
+        FactHandle h = ksession.insert(new A());
+        ksession.retract(h);
+    }
+
+    public static class A implements Serializable {
+    }
+
+    String str = "import org.drools.integrationtests.PseudoSchedulerRemoveJobTest.A\n" + 
+            "declare A\n" + 
+            "    @role( event )\n" + 
+            "end\n" + 
+            "rule A\n" + 
+            "when\n" + 
+            "   $a : A()\n" + 
+            "   not A(this after [1s,10s] $a)\n" + 
+            "then\n" + 
+            "end";
+
+}
+

Deleted: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/Arguments.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/Arguments.java	2010-04-13 03:55:47 UTC (rev 32529)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/Arguments.java	2010-04-13 03:58:01 UTC (rev 32530)
@@ -1,47 +0,0 @@
-package org.drools.base;
-
-import java.util.Arrays;
-
-
-public class Arguments {
-    private final Object[] args;
-    
-    private static final Object[] EMPTY_PARAMS = new Object[0];
-    
-    public Arguments() {
-        this(null);
-    }
-    
-    public Arguments(final Object[] params) {
-        if ( params != null ) {
-            this.args = params;
-        } else {
-            this.args = EMPTY_PARAMS;
-        }
-    }    
-    
-    public Object[] getArguments() {
-        return this.args;
-    }
-
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + Arrays.hashCode( args );
-        return result;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if ( this == obj ) return true;
-        if ( obj == null ) return false;
-        if ( getClass() != obj.getClass() ) return false;
-        Arguments other = (Arguments) obj;
-        if ( !Arrays.equals( args,
-                             other.args ) ) return false;
-        return true;
-    }
-    
-    
-}

Copied: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/ArrayElements.java (from rev 32475, labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/Arguments.java)
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/ArrayElements.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/ArrayElements.java	2010-04-13 03:58:01 UTC (rev 32530)
@@ -0,0 +1,47 @@
+package org.drools.base;
+
+import java.util.Arrays;
+
+
+public class ArrayElements {
+    private final Object[] elements;
+    
+    private static final Object[] EMPTY_ELEMENTS = new Object[0];
+    
+    public ArrayElements() {
+        this(null);
+    }
+    
+    public ArrayElements(final Object[] elements) {
+        if ( elements != null ) {
+            this.elements = elements;
+        } else {
+            this.elements = EMPTY_ELEMENTS;
+        }
+    }    
+    
+    public Object[] getElements() {
+        return this.elements;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + Arrays.hashCode( elements );
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if ( this == obj ) return true;
+        if ( obj == null ) return false;
+        if ( getClass() != obj.getClass() ) return false;
+        ArrayElements other = (ArrayElements) obj;
+        if ( !Arrays.equals( elements,
+                             other.elements ) ) return false;
+        return true;
+    }
+    
+    
+}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/DefaultQueryResultsCollector.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/DefaultQueryResultsCollector.java	2010-04-13 03:55:47 UTC (rev 32529)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/DefaultQueryResultsCollector.java	2010-04-13 03:58:01 UTC (rev 32530)
@@ -47,7 +47,7 @@
         DroolsQuery query = (DroolsQuery) handle.getObject();
 
         // Copy of it's arguments for unification variables.
-        Object[] args = query.getArguments();
+        Object[] args = query.getElements();
         Object[] newArgs = new Object[args.length];
         for ( int i = 0, length = args.length; i < length; i++ ) {
             if ( args[i] instanceof Variable ) {
@@ -60,7 +60,7 @@
                                                                 handle.getIdentityHashCode(),
                                                                 handle.getObjectHashCode(),
                                                                 handle.getRecency(),
-                                                                new Arguments( newArgs ) );
+                                                                new ArrayElements( newArgs ) );
 
         this.results.add( handles );
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/DroolsQuery.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/DroolsQuery.java	2010-04-13 03:55:47 UTC (rev 32529)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/DroolsQuery.java	2010-04-13 03:58:01 UTC (rev 32530)
@@ -22,7 +22,7 @@
  * limitations under the License.
  */
 
-public final class DroolsQuery extends Arguments {
+public final class DroolsQuery extends ArrayElements {
     private final String         name;
     private QueryResultCollector resultsCollector;
     private Query                query;

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/extractors/ArrayElementReader.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/extractors/ArrayElementReader.java	2010-04-13 03:55:47 UTC (rev 32529)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/extractors/ArrayElementReader.java	2010-04-13 03:58:01 UTC (rev 32530)
@@ -4,120 +4,177 @@
 import java.io.IOException;
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
+import java.lang.reflect.Array;
 import java.lang.reflect.Method;
 import java.math.BigDecimal;
 import java.math.BigInteger;
+import java.util.Arrays;
 
+import org.drools.RuntimeDroolsException;
 import org.drools.base.ValueType;
 import org.drools.common.InternalWorkingMemory;
 import org.drools.core.util.ClassUtils;
 import org.drools.core.util.MathUtils;
+import org.drools.core.util.StringUtils;
 import org.drools.spi.AcceptsReadAccessor;
 import org.drools.spi.InternalReadAccessor;
 
-public class ArrayElementReader implements AcceptsReadAccessor, InternalReadAccessor, Externalizable  {
+public class ArrayElementReader
+    implements
+    AcceptsReadAccessor,
+    InternalReadAccessor,
+    Externalizable {
     private InternalReadAccessor arrayReadAccessor;
-    private int index;
-    private Class<?> type;
+    private int                  index;
+    private Class< ? >           type;
 
     public ArrayElementReader() {
 
     }
 
-    public ArrayElementReader(InternalReadAccessor arrayExtractor, int index, Class<?> type) {
+    public ArrayElementReader(InternalReadAccessor arrayExtractor,
+                              int index,
+                              Class< ? > type) {
         this.arrayReadAccessor = arrayExtractor;
         this.index = index;
         this.type = type;
     }
 
-    public Class<?> getExtractToClass() {
+    public Class< ? > getExtractToClass() {
         return type;
     }
 
-    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-        arrayReadAccessor  = (InternalReadAccessor)in.readObject();
-        index           = in.readInt();
-        type            = (Class<?>)in.readObject();
+    public void readExternal(ObjectInput in) throws IOException,
+                                            ClassNotFoundException {
+        arrayReadAccessor = (InternalReadAccessor) in.readObject();
+        index = in.readInt();
+        type = (Class< ? >) in.readObject();
     }
 
     public void writeExternal(ObjectOutput out) throws IOException {
-        out.writeObject(arrayReadAccessor);
-        out.writeInt(index);
-        out.writeObject(type);
+        out.writeObject( arrayReadAccessor );
+        out.writeInt( index );
+        out.writeObject( type );
     }
-    
+
     public void setReadAccessor(InternalReadAccessor readAccessor) {
         this.arrayReadAccessor = readAccessor;
-    }    
+    }
 
     public String getExtractToClassName() {
         return ClassUtils.canonicalName( type );
     }
 
-    public boolean getBooleanValue(InternalWorkingMemory workingMemory, Object object) {
-        Object[] array = ( Object[] ) this.arrayReadAccessor.getValue( workingMemory, object );
-        return ( (Boolean)array[ this.index ]).booleanValue();
+    public boolean getBooleanValue(InternalWorkingMemory workingMemory,
+                                   Object object) {
+        Object[] array = (Object[]) this.arrayReadAccessor.getValue( workingMemory,
+                                                                     object );
+        return ((Boolean) array[this.index]).booleanValue();
     }
-    public byte getByteValue(InternalWorkingMemory workingMemory, Object object) {
-        Object[] array = ( Object[] ) this.arrayReadAccessor.getValue( workingMemory, object );
-        return ( (Number)array[ this.index ]).byteValue();
+
+    public byte getByteValue(InternalWorkingMemory workingMemory,
+                             Object object) {
+        Object[] array = (Object[]) this.arrayReadAccessor.getValue( workingMemory,
+                                                                     object );
+        return ((Number) array[this.index]).byteValue();
     }
-    public char getCharValue(InternalWorkingMemory workingMemory, Object object) {
-        Object[] array = ( Object[] ) this.arrayReadAccessor.getValue( workingMemory, object );
-        return ( (Character)array[ this.index ]).charValue();
+
+    public char getCharValue(InternalWorkingMemory workingMemory,
+                             Object object) {
+        Object[] array = (Object[]) this.arrayReadAccessor.getValue( workingMemory,
+                                                                     object );
+        return ((Character) array[this.index]).charValue();
     }
-    public double getDoubleValue(InternalWorkingMemory workingMemory, Object object) {
-        Object[] array = ( Object[] ) this.arrayReadAccessor.getValue( workingMemory, object );
-        return ( (Number)array[ this.index ]).doubleValue();
+
+    public double getDoubleValue(InternalWorkingMemory workingMemory,
+                                 Object object) {
+        Object[] array = (Object[]) this.arrayReadAccessor.getValue( workingMemory,
+                                                                     object );
+        return ((Number) array[this.index]).doubleValue();
     }
 
-    public float getFloatValue(InternalWorkingMemory workingMemory, Object object) {
-        Object[] array = ( Object[] ) this.arrayReadAccessor.getValue( workingMemory, object );
-        return ( (Number)array[ this.index ]).floatValue();
+    public float getFloatValue(InternalWorkingMemory workingMemory,
+                               Object object) {
+        Object[] array = (Object[]) this.arrayReadAccessor.getValue( workingMemory,
+                                                                     object );
+        return ((Number) array[this.index]).floatValue();
     }
 
-    public int getIntValue(InternalWorkingMemory workingMemory, Object object) {
-        Object[] array = ( Object[] ) this.arrayReadAccessor.getValue( workingMemory, object );
-        return ( (Number)array[ this.index ]).intValue();
+    public int getIntValue(InternalWorkingMemory workingMemory,
+                           Object object) {
+        Object[] array = (Object[]) this.arrayReadAccessor.getValue( workingMemory,
+                                                                     object );
+        return ((Number) array[this.index]).intValue();
     }
-    public long getLongValue(InternalWorkingMemory workingMemory, Object object) {
-        Object[] array = ( Object[] ) this.arrayReadAccessor.getValue( workingMemory, object );
-        return ( (Number) array[ this.index ]).longValue();
+
+    public long getLongValue(InternalWorkingMemory workingMemory,
+                             Object object) {
+        Object[] array = (Object[]) this.arrayReadAccessor.getValue( workingMemory,
+                                                                     object );
+        return ((Number) array[this.index]).longValue();
     }
+
     public Method getNativeReadMethod() {
-        throw new UnsupportedOperationException("cannot call a method on an array extractor" );
+        try {
+            String method = "";
+            if ( type.isPrimitive() ) {
+                method = StringUtils.ucFirst( type.getName() );
+            }
+
+            return this.getClass().getDeclaredMethod( "get" + method + "Value",
+                                                      new Class[]{InternalWorkingMemory.class, Object.class} );
+
+        } catch ( final Exception e ) {
+            throw new RuntimeDroolsException( "This is a bug. Please report to development team: " + e.getMessage(),
+                                              e );
+        }
     }
-    public short getShortValue(InternalWorkingMemory workingMemory, Object object) {
-        Object[] array = ( Object[] ) this.arrayReadAccessor.getValue( workingMemory, object );
-        return ( (Number)array[ this.index ]).shortValue();
+
+    public short getShortValue(InternalWorkingMemory workingMemory,
+                               Object object) {
+        Object[] array = (Object[]) this.arrayReadAccessor.getValue( workingMemory,
+                                                                     object );
+        return ((Number) array[this.index]).shortValue();
     }
-    public Object getValue(InternalWorkingMemory workingMemory, Object object) {
-        Object[] array = ( Object[] ) this.arrayReadAccessor.getValue( workingMemory, object );
-        return array[ this.index ];
+
+    public Object getValue(InternalWorkingMemory workingMemory,
+                           Object object) {
+        Object[] array = (Object[]) this.arrayReadAccessor.getValue( workingMemory,
+                                                                     object );
+        return array[this.index];
     }
+
     public BigDecimal getBigDecimalValue(InternalWorkingMemory workingMemory,
                                          Object object) {
-        Object[] array = ( Object[] ) this.arrayReadAccessor.getValue( workingMemory, object );
-        return MathUtils.getBigDecimal( array[ this.index ] );
+        Object[] array = (Object[]) this.arrayReadAccessor.getValue( workingMemory,
+                                                                     object );
+        return MathUtils.getBigDecimal( array[this.index] );
     }
 
     public BigInteger getBigIntegerValue(InternalWorkingMemory workingMemory,
                                          Object object) {
-        Object[] array = ( Object[] ) this.arrayReadAccessor.getValue( workingMemory, object );
-        return MathUtils.getBigInteger( array[ this.index ] );
+        Object[] array = (Object[]) this.arrayReadAccessor.getValue( workingMemory,
+                                                                     object );
+        return MathUtils.getBigInteger( array[this.index] );
     }
+
     public ValueType getValueType() {
         return ValueType.OBJECT_TYPE;
     }
-    public boolean isNullValue(InternalWorkingMemory workingMemory, Object object ) {
-        Object[] array = ( Object[] ) this.arrayReadAccessor.getValue( workingMemory, object );
-        return array[ this.index ] == null;
+
+    public boolean isNullValue(InternalWorkingMemory workingMemory,
+                               Object object) {
+        Object[] array = (Object[]) this.arrayReadAccessor.getValue( workingMemory,
+                                                                     object );
+        return array[this.index] == null;
     }
 
-  public int getHashCode(InternalWorkingMemory workingMemory, Object object) {
-      Object[] array = ( Object[] ) this.arrayReadAccessor.getValue( workingMemory, object );
-      return array[ this.index ].hashCode();
-  }
+    public int getHashCode(InternalWorkingMemory workingMemory,
+                           Object object) {
+        Object[] array = (Object[]) this.arrayReadAccessor.getValue( workingMemory,
+                                                                     object );
+        return array[this.index].hashCode();
+    }
 
     public int hashCode() {
         final int PRIME = 31;
@@ -142,7 +199,7 @@
     public boolean isGlobal() {
         return false;
     }
-    
+
     public boolean isSelfReference() {
         return false;
     }

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/QueryElementFactHandle.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/QueryElementFactHandle.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/QueryElementFactHandle.java	2010-04-13 03:58:01 UTC (rev 32530)
@@ -0,0 +1,145 @@
+package org.drools.common;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+
+import org.drools.reteoo.LeftTuple;
+import org.drools.reteoo.RightTuple;
+import org.drools.runtime.rule.WorkingMemoryEntryPoint;
+
+ at XmlAccessorType(XmlAccessType.NONE)
+public class QueryElementFactHandle
+    implements
+    InternalFactHandle {
+    private Object object;
+
+	protected QueryElementFactHandle() {}
+	
+    public QueryElementFactHandle(Object object) {
+        this.object = object;
+    }    
+
+    public int getId() {
+        return -1;
+    }
+
+    public int getIdentityHashCode() {
+        return this.object.hashCode();
+    }
+
+    public int getObjectHashCode() {
+        return this.object.hashCode();
+    }
+
+    public long getRecency() {
+        return 0;
+    }
+
+    public LeftTuple getLastLeftTuple() {
+        throw new UnsupportedOperationException( "DisonnectedFactHandle does not support this method" );
+    }
+
+    public Object getObject() {
+        if ( this.object != null ) {
+            return this.object;
+        }
+        throw new UnsupportedOperationException( "DisonnectedFactHandle does not support this method" );
+    }
+
+    public WorkingMemoryEntryPoint getEntryPoint() {
+        throw new UnsupportedOperationException( "DisonnectedFactHandle does not support this method" );
+    }
+
+    public EqualityKey getEqualityKey() {
+        throw new UnsupportedOperationException( "DisonnectedFactHandle does not support this method" );
+    }
+
+    public RightTuple getRightTuple() {
+        throw new UnsupportedOperationException( "DisonnectedFactHandle does not support this method" );
+    }
+
+    public void invalidate() {
+        throw new UnsupportedOperationException( "DisonnectedFactHandle does not support this method" );
+    }
+
+    public boolean isEvent() {
+        return false;
+    }
+
+    public boolean isValid() {
+        return true;
+    }
+
+    public void setEntryPoint(WorkingMemoryEntryPoint ep) {
+        throw new UnsupportedOperationException( "DisonnectedFactHandle does not support this method" );
+    }
+
+    public void setEqualityKey(EqualityKey key) {
+        throw new UnsupportedOperationException( "DisonnectedFactHandle does not support this method" );
+    }
+
+    public void setFirstLeftTuple(LeftTuple leftTuple) {
+        throw new UnsupportedOperationException( "DisonnectedFactHandle does not support this method" );
+    }
+
+    public void setObject(Object object) {
+        throw new UnsupportedOperationException( "DisonnectedFactHandle does not support this method" );
+    }
+
+    public void setRecency(long recency) {
+        throw new UnsupportedOperationException( "DisonnectedFactHandle does not support this method" );
+    }
+
+    public void setRightTuple(RightTuple rightTuple) {
+        throw new UnsupportedOperationException( "DisonnectedFactHandle does not support this method" );
+    }
+
+    public DefaultFactHandle clone() {
+        throw new UnsupportedOperationException( "DisonnectedFactHandle does not support this method" );
+    }
+
+    public String toExternalForm() {
+        return "QueryElementFactHandl: " + this.object;
+    }
+    
+    @XmlAttribute(name="external-form")
+    public String getExternalForm() {
+    	return toExternalForm();
+    }
+
+    
+    public LeftTuple getFirstLeftTuple() {
+        throw new UnsupportedOperationException( "DisonnectedFactHandle does not support this method" );
+    }
+
+    
+    public RightTuple getFirstRightTuple() {
+        throw new UnsupportedOperationException( "DisonnectedFactHandle does not support this method" );
+    }
+
+    
+    public RightTuple getLastRightTuple() {
+        throw new UnsupportedOperationException( "DisonnectedFactHandle does not support this method" );
+    }
+
+    
+    public void setFirstRightTuple(RightTuple rightTuple) {
+        throw new UnsupportedOperationException( "DisonnectedFactHandle does not support this method" );
+    }
+
+    
+    public void setLastLeftTuple(LeftTuple leftTuple) {
+        throw new UnsupportedOperationException( "DisonnectedFactHandle does not support this method" );
+    }
+
+    
+    public void setLastRightTuple(RightTuple rightTuple) {
+        throw new UnsupportedOperationException( "DisonnectedFactHandle does not support this method" );
+    }
+
+    public String toTupleTree(int indent) {
+        return null;
+    }
+
+}

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/CompositeLeftTupleSinkAdapter.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/CompositeLeftTupleSinkAdapter.java	2010-04-13 03:55:47 UTC (rev 32529)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/CompositeLeftTupleSinkAdapter.java	2010-04-13 03:58:01 UTC (rev 32530)
@@ -29,6 +29,23 @@
     public void removeTupleSink(final LeftTupleSink sink) {
         this.sinks.remove( (LeftTupleSinkNode) sink );
     }
+    
+    public void createChildLeftTuplesforQuery(final LeftTuple leftTuple,
+                                              final RightTuple rightTuple,
+                                              boolean leftTupleMemoryEnabled) {
+        
+        for ( LeftTupleSinkNode sink = this.sinks.getFirst(); sink != null; sink = sink.getNextLeftTupleSinkNode() ) {
+            LeftTuple child = new LeftTuple( leftTuple,
+                                             rightTuple,
+                                             null,
+                                             null,
+                                             sink,
+                                             leftTupleMemoryEnabled );
+            
+            child.setLeftParentNext( leftTuple.firstChild );
+            leftTuple.firstChild = child;
+        }
+    }
 
     public void propagateAssertLeftTuple(final LeftTuple leftTuple,
                                          final RightTuple rightTuple,
@@ -163,6 +180,13 @@
         super.writeExternal( out );
         out.writeObject( this.sinks );
     }
+    
+    public void doPropagateAssertLeftTuple(PropagationContext context,
+                                           InternalWorkingMemory workingMemory,
+                                           LeftTuple leftTuple,
+                                           LeftTupleSink sink) {
+     sink.assertLeftTuple( leftTuple, context, workingMemory );
+ }    
 
     /**
      * This is a hook method that may be overriden by subclasses. Please keep it

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/EmptyLeftTupleSinkAdapter.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/EmptyLeftTupleSinkAdapter.java	2010-04-13 03:55:47 UTC (rev 32529)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/EmptyLeftTupleSinkAdapter.java	2010-04-13 03:58:01 UTC (rev 32530)
@@ -122,4 +122,19 @@
                                       InternalWorkingMemory workingMemory) {
     }
 
+    public void createChildLeftTuplesforQuery(LeftTuple leftTuple,
+                                              RightTuple rightTuple,
+                                              boolean leftTupleMemoryEnabled) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    public void doPropagateAssertLeftTuple(PropagationContext context,
+                                           InternalWorkingMemory workingMemory,
+                                           LeftTuple leftTuple,
+                                           LeftTupleSink sink) {
+        // TODO Auto-generated method stub
+        
+    }
+
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/LeftTupleSinkPropagator.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/LeftTupleSinkPropagator.java	2010-04-13 03:55:47 UTC (rev 32529)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/LeftTupleSinkPropagator.java	2010-04-13 03:58:01 UTC (rev 32530)
@@ -10,6 +10,11 @@
 public interface LeftTupleSinkPropagator
     extends
     Externalizable {
+    
+    public void createChildLeftTuplesforQuery(final LeftTuple leftTuple,
+                                              final RightTuple rightTuple,
+                                              boolean leftTupleMemoryEnabled);
+    
     public void propagateAssertLeftTuple(LeftTuple leftTuple,
                                          RightTuple rightTuple,
                                          LeftTuple currentLeftChild, // insert new tuple before this child in the child list
@@ -40,6 +45,11 @@
                                            PropagationContext context,
                                            InternalWorkingMemory workingMemory);
 
+    public void doPropagateAssertLeftTuple(PropagationContext context,
+                                              InternalWorkingMemory workingMemory,
+                                              LeftTuple leftTuple,
+                                              LeftTupleSink sink);
+    
     public BaseNode getMatchingNode(BaseNode candidate);
 
     public LeftTupleSink[] getSinks();

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/QueryElementNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/QueryElementNode.java	2010-04-13 03:55:47 UTC (rev 32529)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/QueryElementNode.java	2010-04-13 03:58:01 UTC (rev 32530)
@@ -2,16 +2,19 @@
 
 import org.drools.QueryResults;
 import org.drools.RuleBaseConfiguration;
+import org.drools.base.ArrayElements;
 import org.drools.base.DefaultQueryResultsCollector;
 import org.drools.base.DroolsQuery;
 import org.drools.base.QueryResultCollector;
 import org.drools.common.BaseNode;
 import org.drools.common.BetaConstraints;
+import org.drools.common.DisconnectedFactHandle;
 import org.drools.common.EmptyBetaConstraints;
 import org.drools.common.InternalFactHandle;
 import org.drools.common.InternalWorkingMemory;
 import org.drools.common.NodeMemory;
 import org.drools.common.PropagationContextImpl;
+import org.drools.common.QueryElementFactHandle;
 import org.drools.core.util.Entry;
 import org.drools.reteoo.builder.BuildContext;
 import org.drools.rule.Declaration;
@@ -109,15 +112,16 @@
 
         int[] declIndexes = this.queryElement.getDeclIndexes();
 
-        for ( int i = 0, length = declIndexes.length; i > length; i++ ) {
+        for ( int i = 0, length = declIndexes.length; i < length; i++ ) {
             Declaration declr = (Declaration) arguments[declIndexes[i]];
-            inputArgs[i] = declr.getValue( workingMemory,
+            inputArgs[declIndexes[i]] = declr.getValue( workingMemory,
                                            leftTuple.get( declr ).getObject() );
         }
 
         UnificationNodeQueryResultsCollector collector = new UnificationNodeQueryResultsCollector( leftTuple,
                                                                                                    this.queryElement.getVariables(),
-                                                                                                   this.sink );
+                                                                                                   this.sink,
+                                                                                                   this.tupleMemoryEnabled );
         
         DroolsQuery queryObject = new DroolsQuery( this.queryElement.getQueryName(),
                                                    inputArgs,
@@ -137,6 +141,16 @@
                                                                                                     queryObject ) );
 
         workingMemory.getFactHandleFactory().destroyFactHandle( handle );
+        
+        LeftTuple childLeftTuple = leftTuple.firstChild;
+        LeftTuple temp = null;
+        while ( childLeftTuple != null ) {
+            temp = childLeftTuple;
+            this.sink.doPropagateAssertLeftTuple( context, workingMemory, childLeftTuple, childLeftTuple.getLeftTupleSink() );
+            childLeftTuple = childLeftTuple.getLeftParentNext();
+            temp.setLeftParentNext( null );
+        }
+        leftTuple.firstChild = null;
 
     }
 
@@ -149,13 +163,17 @@
 
         private DroolsQuery               query;
         private int[]                     variables;
+        
+        private boolean                   tupleMemoryEnabled;
 
         public UnificationNodeQueryResultsCollector(LeftTuple leftTuple,
                                                     int[] variables,
-                                                    LeftTupleSinkPropagator sink) {
+                                                    LeftTupleSinkPropagator sink,
+                                                    boolean                   tupleMemoryEnabled) {
             this.leftTuple = leftTuple;
             this.variables = variables;
             this.sink = sink;
+            this.tupleMemoryEnabled = tupleMemoryEnabled;
         }
 
         public void setDroolsQuery(DroolsQuery query) {
@@ -166,27 +184,19 @@
                         PropagationContext context,
                         InternalWorkingMemory workingMemory) {
 
-            Object[] args = query.getArguments();
+            Object[] args = query.getElements();
             Object[] objects = new Object[this.variables.length];
 
             for ( int i = 0, length = this.variables.length; i < length; i++ ) {
                 objects[i] = ((Variable) args[ this.variables[i]] ).getValue();
-            }
+            }        
 
-            final InternalFactHandle handle = workingMemory.getFactHandleFactory().newFactHandle( objects,
-                                                                                                  null, // set this to null, otherwise it uses the driver fact's entrypoint
-                                                                                                  workingMemory );
-
-            RightTuple rightTuple = new RightTuple( handle,
-                                                    null );
-
-            this.sink.propagateAssertLeftTuple( this.leftTuple,
-                                                rightTuple,
-                                                null,
-                                                null,
-                                                context,
-                                                workingMemory,
-                                                false );
+            QueryElementFactHandle handle = new QueryElementFactHandle(objects );
+            RightTuple rightTuple = new RightTuple( handle ); 
+            
+            this.sink.createChildLeftTuplesforQuery( this.leftTuple, 
+                                                     rightTuple, 
+                                                     this.tupleMemoryEnabled );
         }
 
     }

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	2010-04-13 03:55:47 UTC (rev 32529)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/QueryTerminalNode.java	2010-04-13 03:58:01 UTC (rev 32530)
@@ -23,7 +23,7 @@
 import java.util.List;
 
 import org.drools.RuleBaseConfiguration;
-import org.drools.base.Arguments;
+import org.drools.base.ArrayElements;
 import org.drools.base.DroolsQuery;
 import org.drools.common.BaseNode;
 import org.drools.common.DisconnectedFactHandle;

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/SingleLeftTupleSinkAdapter.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/SingleLeftTupleSinkAdapter.java	2010-04-13 03:55:47 UTC (rev 32529)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/SingleLeftTupleSinkAdapter.java	2010-04-13 03:58:01 UTC (rev 32530)
@@ -23,6 +23,20 @@
         super( partitionId );
         this.sink = sink;
     }
+    
+    public void createChildLeftTuplesforQuery(final LeftTuple leftTuple,
+                                              final RightTuple rightTuple,
+                                              boolean leftTupleMemoryEnabled) {
+        LeftTuple child = new LeftTuple( leftTuple,
+                                         rightTuple,
+                                         null,
+                                         null,
+                                         this.sink,
+                                         leftTupleMemoryEnabled );
+        
+        child.setLeftParentNext( leftTuple.firstChild );
+        leftTuple.firstChild = child;
+    }
 
     public void propagateAssertLeftTuple(final LeftTuple leftTuple,
                                          final RightTuple rightTuple,
@@ -137,6 +151,13 @@
         super.writeExternal( out );
         out.writeObject( this.sink );
     }
+    
+    public void doPropagateAssertLeftTuple(PropagationContext context,
+                                              InternalWorkingMemory workingMemory,
+                                              LeftTuple leftTuple,
+                                              LeftTupleSink sink) {
+        sink.assertLeftTuple( leftTuple, context, workingMemory );
+    }
 
     /**
      * This is a hook method that may be overriden by subclasses. Please keep it

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/QueryElementBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/QueryElementBuilder.java	2010-04-13 03:55:47 UTC (rev 32529)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/QueryElementBuilder.java	2010-04-13 03:58:01 UTC (rev 32530)
@@ -34,6 +34,9 @@
                       final RuleConditionElement rce) {
 
         final QueryElement qe = (QueryElement) rce;
+        
+        qe.getResultPattern().setOffset( context.getCurrentPatternOffset() );
+        
         utils.checkUnboundDeclarations( context,
                                         qe.getRequiredDeclarations() );
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/QueryElement.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/QueryElement.java	2010-04-13 03:55:47 UTC (rev 32529)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/QueryElement.java	2010-04-13 03:58:01 UTC (rev 32530)
@@ -12,6 +12,8 @@
 public class QueryElement extends ConditionalElement
     implements
     Externalizable {
+    
+    private Pattern       resultPattern;
     private String        queryName;
     private Object[]      arguments;
     private int[]         declIndexes;
@@ -19,12 +21,14 @@
 
     private Declaration[] requiredDeclarations;
 
-    public QueryElement(String queryName,
+    public QueryElement(Pattern       resultPattern,
+                        String queryName,
                         Object[] arguments,
                         Declaration[] requiredDeclarations,
                         int[] declIndexes,
                         int[] variables) {
         super();
+        this.resultPattern = resultPattern;
         this.queryName = queryName;
         this.arguments = arguments;
         this.requiredDeclarations = requiredDeclarations;
@@ -49,16 +53,20 @@
     }
 
     public Map getInnerDeclarations() {
-        return Collections.EMPTY_MAP;
+        return this.resultPattern.getInnerDeclarations();
     }
 
     public Map getOuterDeclarations() {
-        return Collections.EMPTY_MAP;
+        return this.resultPattern.getOuterDeclarations();
     }
 
     public List getNestedElements() {
         return Collections.EMPTY_LIST;
     }
+    
+    public Pattern getResultPattern() {
+        return this.resultPattern;
+    }
 
     public boolean isPatternScopeDelimiter() {
         return true;
@@ -72,7 +80,7 @@
      * @inheritDoc
      */
     public Declaration resolveDeclaration(final String identifier) {
-        return null;
+        return this.resultPattern.resolveDeclaration( identifier );
     }
 
     public void replaceDeclaration(Declaration declaration,
@@ -84,41 +92,14 @@
         }
     }
 
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + Arrays.hashCode( arguments );
-        result = prime * result + Arrays.hashCode( declIndexes );
-        result = prime * result + ((queryName == null) ? 0 : queryName.hashCode());
-        result = prime * result + Arrays.hashCode( variables );
-        return result;
-    }
 
     @Override
-    public boolean equals(Object obj) {
-        if ( this == obj ) return true;
-        if ( obj == null ) return false;
-        if ( getClass() != obj.getClass() ) return false;
-        QueryElement other = (QueryElement) obj;
-        if ( !Arrays.equals( arguments,
-                             other.arguments ) ) return false;
-        if ( !Arrays.equals( declIndexes,
-                             other.declIndexes ) ) return false;
-        if ( queryName == null ) {
-            if ( other.queryName != null ) return false;
-        } else if ( !queryName.equals( other.queryName ) ) return false;
-        if ( !Arrays.equals( variables,
-                             other.variables ) ) return false;
-        return true;
-    }
-
-    @Override
     public Object clone() {
-        return new QueryElement( queryName, arguments, requiredDeclarations, declIndexes, variables );
+        return new QueryElement( resultPattern, queryName, arguments, requiredDeclarations, declIndexes, variables );
     }
     
     public void writeExternal(ObjectOutput out) throws IOException {
+       out.writeObject( this.resultPattern );
        out.writeObject( this.queryName );
        out.writeObject( this.arguments );
        out.writeObject( this.requiredDeclarations );
@@ -128,6 +109,7 @@
 
     public void readExternal(ObjectInput in) throws IOException,
                                             ClassNotFoundException {
+        this.resultPattern = ( Pattern ) in.readObject();
         this.queryName = (String) in.readObject();
         this.arguments = (Object[]) in.readObject();
         this.requiredDeclarations = ( Declaration[] ) in.readObject();

Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/QueryElementNodeTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/QueryElementNodeTest.java	2010-04-13 03:55:47 UTC (rev 32529)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/QueryElementNodeTest.java	2010-04-13 03:58:01 UTC (rev 32530)
@@ -30,6 +30,7 @@
 import org.drools.reteoo.QueryElementNode.UnificationNodeQueryResultsCollector;
 import org.drools.reteoo.builder.BuildContext;
 import org.drools.rule.Declaration;
+import org.drools.rule.Pattern;
 import org.drools.rule.QueryElement;
 import org.drools.rule.Rule;
 import org.drools.rule.Variable;
@@ -84,11 +85,14 @@
     }
 
     public void test1() {
-        QueryElement qe = new QueryElement( "queryName1",
+        Pattern p = new Pattern();
+        QueryElement qe = new QueryElement( p,
+                                            "queryName1",
                                             new Object[]{new Variable(), "x1", new Variable(), "x3", "x4", new Variable(),"x6",},
                                             new Declaration[0],
                                             new int[0],
                                             new int[] { 0, 2, 5 } );
+       
 
         final MockTupleSource source = new MockTupleSource( 12 );
 
@@ -155,7 +159,7 @@
                 DroolsQuery query = ( DroolsQuery ) object;
                 UnificationNodeQueryResultsCollector collector = ( UnificationNodeQueryResultsCollector ) query.getQueryResultCollector();
                 for ( int i = 0; i < 3; i++ ) {
-                    Object[] args = query.getArguments();
+                    Object[] args = query.getElements();
                     ((Variable)args[0]).setValue( "string_0_" + i );
                     ((Variable)args[2]).setValue( "string_2_" + i );
                     ((Variable)args[5]).setValue( "string_5_" + i );



More information about the jboss-svn-commits mailing list