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

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Sun Nov 9 19:37:44 EST 2008


Author: tirelli
Date: 2008-11-09 19:37:43 -0500 (Sun, 09 Nov 2008)
New Revision: 23799

Added:
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/time/TemporalDependencyMatrix.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/StockTick.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/builder/BuildUtilsTest.java
Modified:
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/CepEspTest.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/BaseEvaluator.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/AfterEvaluatorDefinition.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/BeforeEvaluatorDefinition.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/CoincidesEvaluatorDefinition.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/DuringEvaluatorDefinition.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/FinishedByEvaluatorDefinition.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/FinishesEvaluatorDefinition.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/IncludesEvaluatorDefinition.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/MeetsEvaluatorDefinition.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/MetByEvaluatorDefinition.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/OverlappedByEvaluatorDefinition.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/OverlapsEvaluatorDefinition.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/StartedByEvaluatorDefinition.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/StartsEvaluatorDefinition.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/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/PatternBuilder.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/ReteooRuleBuilder.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/AbstractCompositeConstraint.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/VariableConstraint.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/VariableRestriction.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/Constraint.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/Evaluator.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/time/Interval.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/time/JobContext.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/rule/GroupElementTest.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/rule/LogicTransformerTest.java
Log:
Wiring up temporal dependency analysis

Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/CepEspTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/CepEspTest.java	2008-11-09 23:37:42 UTC (rev 23798)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/CepEspTest.java	2008-11-10 00:37:43 UTC (rev 23799)
@@ -18,6 +18,7 @@
 import org.drools.SessionConfiguration;
 import org.drools.StatefulSession;
 import org.drools.StockTick;
+import org.drools.RuleBaseConfiguration.EventProcessingMode;
 import org.drools.common.EventFactHandle;
 import org.drools.common.InternalFactHandle;
 import org.drools.compiler.DrlParser;
@@ -44,6 +45,14 @@
     private RuleBase loadRuleBase(final Reader reader) throws IOException,
                                                       DroolsParserException,
                                                       Exception {
+        return loadRuleBase( reader,
+                             null );
+    }
+
+    private RuleBase loadRuleBase(final Reader reader,
+                                  final RuleBaseConfiguration conf) throws IOException,
+                                                                   DroolsParserException,
+                                                                   Exception {
         final DrlParser parser = new DrlParser();
         final PackageDescr packageDescr = parser.parse( reader );
         if ( parser.hasErrors() ) {
@@ -56,7 +65,7 @@
         final Package pkg = builder.getPackage();
 
         // add the package to a rulebase
-        RuleBase ruleBase = getRuleBase();
+        RuleBase ruleBase = getRuleBase( conf );
         ruleBase.addPackage( pkg );
         // load up the rulebase
         ruleBase = SerializationHelper.serializeObject( ruleBase );
@@ -71,10 +80,10 @@
         SessionConfiguration conf = new SessionConfiguration();
         conf.setClockType( ClockType.PSEUDO_CLOCK );
         StatefulSession session = ruleBase.newStatefulSession( conf );
-        
+
         final List results = new ArrayList();
 
-        session.setGlobal( "results",    
+        session.setGlobal( "results",
                            results );
 
         StockTick tick1 = new StockTick( 1,
@@ -192,7 +201,10 @@
     public void testTimeRelationalOperators() throws Exception {
         // read in the source
         final Reader reader = new InputStreamReader( getClass().getResourceAsStream( "test_CEP_TimeRelationalOperators.drl" ) );
-        final RuleBase ruleBase = loadRuleBase( reader );
+        final RuleBaseConfiguration rbconf = new RuleBaseConfiguration();
+        rbconf.setEventProcessingMode( EventProcessingMode.STREAM );
+        final RuleBase ruleBase = loadRuleBase( reader,
+                                                rbconf );
 
         SessionConfiguration conf = new SessionConfiguration();
         conf.setClockType( ClockType.PSEUDO_CLOCK );
@@ -284,17 +296,22 @@
                                          3 );
 
         InternalFactHandle handle1 = (InternalFactHandle) wm.insert( tick1 );
-        clock.advanceTime( 4, TimeUnit.MILLISECONDS );
+        clock.advanceTime( 4,
+                           TimeUnit.MILLISECONDS );
         InternalFactHandle handle2 = (InternalFactHandle) wm.insert( tick2 );
-        clock.advanceTime( 4, TimeUnit.MILLISECONDS );
+        clock.advanceTime( 4,
+                           TimeUnit.MILLISECONDS );
         InternalFactHandle handle3 = (InternalFactHandle) wm.insert( tick3 );
-        clock.advanceTime( 4, TimeUnit.MILLISECONDS );
+        clock.advanceTime( 4,
+                           TimeUnit.MILLISECONDS );
         InternalFactHandle handle4 = (InternalFactHandle) wm.insert( tick4 );
         InternalFactHandle handle5 = (InternalFactHandle) wm.insert( tick5 );
-        clock.advanceTime( 1, TimeUnit.MILLISECONDS );
+        clock.advanceTime( 1,
+                           TimeUnit.MILLISECONDS );
         InternalFactHandle handle6 = (InternalFactHandle) wm.insert( tick6 );
         InternalFactHandle handle7 = (InternalFactHandle) wm.insert( tick7 );
-        clock.advanceTime( 2, TimeUnit.MILLISECONDS );
+        clock.advanceTime( 2,
+                           TimeUnit.MILLISECONDS );
         InternalFactHandle handle8 = (InternalFactHandle) wm.insert( tick8 );
 
         assertNotNull( handle1 );
@@ -392,7 +409,10 @@
     public void testSimpleTimeWindow() throws Exception {
         // read in the source
         final Reader reader = new InputStreamReader( getClass().getResourceAsStream( "test_CEP_SimpleTimeWindow.drl" ) );
-        final RuleBase ruleBase = loadRuleBase( reader );
+        final RuleBaseConfiguration rbconf = new RuleBaseConfiguration();
+        rbconf.setEventProcessingMode( EventProcessingMode.STREAM );
+        final RuleBase ruleBase = loadRuleBase( reader,
+                                                rbconf );
 
         SessionConfiguration conf = new SessionConfiguration();
         conf.setClockType( ClockType.PSEUDO_CLOCK );
@@ -407,7 +427,8 @@
         // how to configure the clock?
         SessionPseudoClock clock = (SessionPseudoClock) wm.getSessionClock();
 
-        clock.advanceTime( 5, TimeUnit.SECONDS ); // 5 seconds
+        clock.advanceTime( 5,
+                           TimeUnit.SECONDS ); // 5 seconds
         EventFactHandle handle1 = (EventFactHandle) wm.insert( new OrderEvent( "1",
                                                                                "customer A",
                                                                                70 ) );
@@ -416,10 +437,10 @@
         assertEquals( 0,
                       handle1.getDuration() );
 
-//        wm  = SerializationHelper.getSerialisedStatefulSession( wm );
-//        results = (List) wm.getGlobal( "results" );
-//        clock = (SessionPseudoClock) wm.getSessionClock();
-        
+        //        wm  = SerializationHelper.getSerialisedStatefulSession( wm );
+        //        results = (List) wm.getGlobal( "results" );
+        //        clock = (SessionPseudoClock) wm.getSessionClock();
+
         wm.fireAllRules();
 
         assertEquals( 1,
@@ -428,7 +449,8 @@
                       ((Number) results.get( 0 )).intValue() );
 
         // advance clock and assert new data
-        clock.advanceTime( 10, TimeUnit.SECONDS ); // 10 seconds
+        clock.advanceTime( 10,
+                           TimeUnit.SECONDS ); // 10 seconds
         EventFactHandle handle2 = (EventFactHandle) wm.insert( new OrderEvent( "2",
                                                                                "customer A",
                                                                                60 ) );
@@ -445,7 +467,8 @@
                       ((Number) results.get( 1 )).intValue() );
 
         // advance clock and assert new data
-        clock.advanceTime( 10, TimeUnit.SECONDS ); // 10 seconds
+        clock.advanceTime( 10,
+                           TimeUnit.SECONDS ); // 10 seconds
         EventFactHandle handle3 = (EventFactHandle) wm.insert( new OrderEvent( "3",
                                                                                "customer A",
                                                                                50 ) );
@@ -462,7 +485,8 @@
                       ((Number) results.get( 2 )).intValue() );
 
         // advance clock and assert new data
-        clock.advanceTime( 10, TimeUnit.SECONDS ); // 10 seconds
+        clock.advanceTime( 10,
+                           TimeUnit.SECONDS ); // 10 seconds
         EventFactHandle handle4 = (EventFactHandle) wm.insert( new OrderEvent( "4",
                                                                                "customer A",
                                                                                25 ) );
@@ -478,7 +502,8 @@
                       results.size() );
 
         // advance clock and assert new data
-        clock.advanceTime( 10, TimeUnit.SECONDS ); // 10 seconds
+        clock.advanceTime( 10,
+                           TimeUnit.SECONDS ); // 10 seconds
         EventFactHandle handle5 = (EventFactHandle) wm.insert( new OrderEvent( "5",
                                                                                "customer A",
                                                                                70 ) );
@@ -495,7 +520,8 @@
                       results.size() );
 
         // advance clock and assert new data
-        clock.advanceTime( 10, TimeUnit.SECONDS ); // 10 seconds
+        clock.advanceTime( 10,
+                           TimeUnit.SECONDS ); // 10 seconds
         EventFactHandle handle6 = (EventFactHandle) wm.insert( new OrderEvent( "6",
                                                                                "customer A",
                                                                                115 ) );
@@ -512,11 +538,14 @@
                       ((Number) results.get( 3 )).intValue() );
 
     }
-    
+
     public void testSimpleLengthWindow() throws Exception {
         // read in the source
         final Reader reader = new InputStreamReader( getClass().getResourceAsStream( "test_CEP_SimpleLengthWindow.drl" ) );
-        final RuleBase ruleBase = loadRuleBase( reader );
+        final RuleBaseConfiguration rbconf = new RuleBaseConfiguration();
+        rbconf.setEventProcessingMode( EventProcessingMode.STREAM );
+        final RuleBase ruleBase = loadRuleBase( reader,
+                                                rbconf );
 
         SessionConfiguration conf = new SessionConfiguration();
         conf.setClockType( ClockType.REALTIME_CLOCK );
@@ -594,7 +623,7 @@
                       ((Number) results.get( 3 )).intValue() );
 
     }
-    
+
     //    public void FIXME_testTransactionCorrelation() throws Exception {
     //        // read in the source
     //        final Reader reader = new InputStreamReader( getClass().getResourceAsStream( "test_TransactionCorrelation.drl" ) );
@@ -608,5 +637,5 @@
     //
     //
     //    }
-    
+
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/BaseEvaluator.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/BaseEvaluator.java	2008-11-09 23:37:42 UTC (rev 23798)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/BaseEvaluator.java	2008-11-10 00:37:43 UTC (rev 23799)
@@ -24,6 +24,7 @@
 import org.drools.base.evaluators.Operator;
 import org.drools.common.InternalFactHandle;
 import org.drools.spi.Evaluator;
+import org.drools.time.Interval;
 
 /**
  * BaseEvaluator is an Object Comparator that is operator aware
@@ -75,6 +76,15 @@
     public Object prepareObject(InternalFactHandle handle) {
         return handle.getObject();
     }
+    
+    public boolean isTemporal() {
+        return false;
+    }
+    
+    public Interval getInterval() {
+        // returns an open bound interval
+        return new Interval();
+    }
 
     public boolean equals(final Object object) {
         if ( this == object ) {

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/AfterEvaluatorDefinition.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/AfterEvaluatorDefinition.java	2008-11-09 23:37:42 UTC (rev 23798)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/AfterEvaluatorDefinition.java	2008-11-10 00:37:43 UTC (rev 23799)
@@ -20,6 +20,7 @@
 import java.io.IOException;
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
@@ -35,6 +36,7 @@
 import org.drools.spi.Evaluator;
 import org.drools.spi.FieldValue;
 import org.drools.spi.InternalReadAccessor;
+import org.drools.time.Interval;
 
 /**
  * The implementation of the 'after' evaluator definition
@@ -44,7 +46,7 @@
 public class AfterEvaluatorDefinition
     implements
     EvaluatorDefinition {
-
+    
     public static final Operator   AFTER         = Operator.addOperatorToRegistry( "after",
                                                                                    false );
     public static final Operator   NOT_AFTER     = Operator.addOperatorToRegistry( "after",
@@ -174,6 +176,33 @@
             return handle;
         }
 
+        @Override
+        public boolean isTemporal() {
+            return true;
+        }
+        
+        @Override
+        public Interval getInterval() {
+            long init = this.initRange;
+            long end = this.finalRange;
+            if( this.getOperator().isNegated() ) {
+                if( init == Interval.MIN && end != Interval.MAX ) {
+                    init = finalRange+1;
+                    end = Interval.MAX;
+                } else if( init != Interval.MIN && end == Interval.MAX ) {
+                    init = Interval.MIN;
+                    end = initRange-1;
+                } else if( init == Interval.MIN && end == Interval.MAX ) {
+                    init = 0;
+                    end = -1;
+                } else {
+                    init = Interval.MIN;
+                    end = Interval.MAX;
+                }
+            }
+            return new Interval( init, end );
+        }
+        
         public boolean evaluate(InternalWorkingMemory workingMemory,
                                 final InternalReadAccessor extractor,
                                 final Object object1,

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/BeforeEvaluatorDefinition.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/BeforeEvaluatorDefinition.java	2008-11-09 23:37:42 UTC (rev 23798)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/BeforeEvaluatorDefinition.java	2008-11-10 00:37:43 UTC (rev 23799)
@@ -35,6 +35,7 @@
 import org.drools.spi.Evaluator;
 import org.drools.spi.FieldValue;
 import org.drools.spi.InternalReadAccessor;
+import org.drools.time.Interval;
 
 /**
  * The implementation of the 'before' evaluator definition
@@ -174,6 +175,33 @@
             return handle;
         }
 
+        @Override
+        public boolean isTemporal() {
+            return true;
+        }
+        
+        @Override
+        public Interval getInterval() {
+            long init = ( this.finalRange == Interval.MAX ) ? Interval.MIN : -this.finalRange;
+            long end = ( this.initRange == Interval.MIN ) ? Interval.MAX : -this.initRange;
+            if( this.getOperator().isNegated() ) {
+                if( init == Interval.MIN && end != Interval.MAX ) {
+                    init = finalRange+1;
+                    end = Interval.MAX;
+                } else if( init != Interval.MIN && end == Interval.MAX ) {
+                    init = Interval.MIN;
+                    end = initRange-1;
+                } else if( init == Interval.MIN && end == Interval.MAX ) {
+                    init = 0;
+                    end = -1;
+                } else {
+                    init = Interval.MIN;
+                    end = Interval.MAX;
+                }
+            }
+            return new Interval( init, end );
+        }
+        
         public boolean evaluate(InternalWorkingMemory workingMemory,
                                 final InternalReadAccessor extractor,
                                 final Object object1,

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/CoincidesEvaluatorDefinition.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/CoincidesEvaluatorDefinition.java	2008-11-09 23:37:42 UTC (rev 23798)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/CoincidesEvaluatorDefinition.java	2008-11-10 00:37:43 UTC (rev 23799)
@@ -35,6 +35,7 @@
 import org.drools.spi.Evaluator;
 import org.drools.spi.FieldValue;
 import org.drools.spi.InternalReadAccessor;
+import org.drools.time.Interval;
 
 /**
  * The implementation of the 'coincides' evaluator definition
@@ -174,6 +175,19 @@
             return handle;
         }
 
+        @Override
+        public boolean isTemporal() {
+            return true;
+        }
+        
+        @Override
+        public Interval getInterval() {
+            if( this.getOperator().isNegated() ) {
+                return new Interval( Interval.MIN, Interval.MAX );
+            }
+            return new Interval( 0, 0 );
+        }
+        
         public boolean evaluate(InternalWorkingMemory workingMemory,
                                 final InternalReadAccessor extractor,
                                 final Object object1,

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/DuringEvaluatorDefinition.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/DuringEvaluatorDefinition.java	2008-11-09 23:37:42 UTC (rev 23798)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/DuringEvaluatorDefinition.java	2008-11-10 00:37:43 UTC (rev 23799)
@@ -35,6 +35,7 @@
 import org.drools.spi.Evaluator;
 import org.drools.spi.FieldValue;
 import org.drools.spi.InternalReadAccessor;
+import org.drools.time.Interval;
 
 /**
  * The implementation of the 'during' evaluator definition
@@ -178,6 +179,19 @@
             return handle;
         }
 
+        @Override
+        public boolean isTemporal() {
+            return true;
+        }
+        
+        @Override
+        public Interval getInterval() {
+            if( this.getOperator().isNegated() ) {
+                return new Interval( Interval.MIN, Interval.MAX );
+            }
+            return new Interval( 0, Interval.MAX );
+        }
+        
         public boolean evaluate(InternalWorkingMemory workingMemory,
                                 final InternalReadAccessor extractor,
                                 final Object object1,

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/FinishedByEvaluatorDefinition.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/FinishedByEvaluatorDefinition.java	2008-11-09 23:37:42 UTC (rev 23798)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/FinishedByEvaluatorDefinition.java	2008-11-10 00:37:43 UTC (rev 23799)
@@ -35,6 +35,7 @@
 import org.drools.spi.Evaluator;
 import org.drools.spi.FieldValue;
 import org.drools.spi.InternalReadAccessor;
+import org.drools.time.Interval;
 
 /**
  * The implementation of the 'finishedby' evaluator definition
@@ -176,6 +177,19 @@
             return handle;
         }
 
+        @Override
+        public boolean isTemporal() {
+            return true;
+        }
+        
+        @Override
+        public Interval getInterval() {
+            if( this.getOperator().isNegated() ) {
+                return new Interval( Interval.MIN, Interval.MAX );
+            }
+            return new Interval( Interval.MIN, 0 );
+        }
+        
         public boolean evaluate(InternalWorkingMemory workingMemory,
                                 final InternalReadAccessor extractor,
                                 final Object object1,

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/FinishesEvaluatorDefinition.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/FinishesEvaluatorDefinition.java	2008-11-09 23:37:42 UTC (rev 23798)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/FinishesEvaluatorDefinition.java	2008-11-10 00:37:43 UTC (rev 23799)
@@ -35,6 +35,7 @@
 import org.drools.spi.Evaluator;
 import org.drools.spi.FieldValue;
 import org.drools.spi.InternalReadAccessor;
+import org.drools.time.Interval;
 
 /**
  * The implementation of the 'finishes' evaluator definition
@@ -178,6 +179,19 @@
             return handle;
         }
 
+        @Override
+        public boolean isTemporal() {
+            return true;
+        }
+        
+        @Override
+        public Interval getInterval() {
+            if( this.getOperator().isNegated() ) {
+                return new Interval( Interval.MIN, Interval.MAX );
+            }
+            return new Interval( 0, Interval.MAX );
+        }
+        
         public boolean evaluate(InternalWorkingMemory workingMemory,
                                 final InternalReadAccessor extractor,
                                 final Object object1,

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/IncludesEvaluatorDefinition.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/IncludesEvaluatorDefinition.java	2008-11-09 23:37:42 UTC (rev 23798)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/IncludesEvaluatorDefinition.java	2008-11-10 00:37:43 UTC (rev 23799)
@@ -35,6 +35,7 @@
 import org.drools.spi.Evaluator;
 import org.drools.spi.FieldValue;
 import org.drools.spi.InternalReadAccessor;
+import org.drools.time.Interval;
 
 /**
  * The implementation of the 'includes' evaluator definition
@@ -178,6 +179,19 @@
             return handle;
         }
 
+        @Override
+        public boolean isTemporal() {
+            return true;
+        }
+        
+        @Override
+        public Interval getInterval() {
+            if( this.getOperator().isNegated() ) {
+                return new Interval( Interval.MIN, Interval.MAX );
+            }
+            return new Interval( Interval.MIN, 0 );
+        }
+        
         public boolean evaluate(InternalWorkingMemory workingMemory,
                                 final InternalReadAccessor extractor,
                                 final Object object1,

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/MeetsEvaluatorDefinition.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/MeetsEvaluatorDefinition.java	2008-11-09 23:37:42 UTC (rev 23798)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/MeetsEvaluatorDefinition.java	2008-11-10 00:37:43 UTC (rev 23799)
@@ -35,6 +35,7 @@
 import org.drools.spi.Evaluator;
 import org.drools.spi.FieldValue;
 import org.drools.spi.InternalReadAccessor;
+import org.drools.time.Interval;
 
 /**
  * The implementation of the 'meets' evaluator definition
@@ -171,6 +172,19 @@
             return handle;
         }
 
+        @Override
+        public boolean isTemporal() {
+            return true;
+        }
+        
+        @Override
+        public Interval getInterval() {
+            if( this.getOperator().isNegated() ) {
+                return new Interval( Interval.MIN, Interval.MAX );
+            }
+            return new Interval( 0, Interval.MAX );
+        }
+        
         public boolean evaluate(InternalWorkingMemory workingMemory,
                                 final InternalReadAccessor extractor,
                                 final Object object1,

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/MetByEvaluatorDefinition.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/MetByEvaluatorDefinition.java	2008-11-09 23:37:42 UTC (rev 23798)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/MetByEvaluatorDefinition.java	2008-11-10 00:37:43 UTC (rev 23799)
@@ -35,6 +35,7 @@
 import org.drools.spi.Evaluator;
 import org.drools.spi.FieldValue;
 import org.drools.spi.InternalReadAccessor;
+import org.drools.time.Interval;
 
 /**
  * The implementation of the 'metby' evaluator definition
@@ -171,6 +172,19 @@
             return handle;
         }
 
+        @Override
+        public boolean isTemporal() {
+            return true;
+        }
+        
+        @Override
+        public Interval getInterval() {
+            if( this.getOperator().isNegated() ) {
+                return new Interval( Interval.MIN, Interval.MAX );
+            }
+            return new Interval( Interval.MIN, 0 );
+        }
+        
         public boolean evaluate(InternalWorkingMemory workingMemory,
                                 final InternalReadAccessor extractor,
                                 final Object object1,

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/OverlappedByEvaluatorDefinition.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/OverlappedByEvaluatorDefinition.java	2008-11-09 23:37:42 UTC (rev 23798)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/OverlappedByEvaluatorDefinition.java	2008-11-10 00:37:43 UTC (rev 23799)
@@ -35,6 +35,7 @@
 import org.drools.spi.Evaluator;
 import org.drools.spi.FieldValue;
 import org.drools.spi.InternalReadAccessor;
+import org.drools.time.Interval;
 
 /**
  * The implementation of the 'overlappedby' evaluator definition
@@ -178,6 +179,19 @@
             return handle;
         }
 
+        @Override
+        public boolean isTemporal() {
+            return true;
+        }
+        
+        @Override
+        public Interval getInterval() {
+            if( this.getOperator().isNegated() ) {
+                return new Interval( Interval.MIN, Interval.MAX );
+            }
+            return new Interval( 0, Interval.MAX );
+        }
+        
         public boolean evaluate(InternalWorkingMemory workingMemory,
                                 final InternalReadAccessor extractor,
                                 final Object object1,

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/OverlapsEvaluatorDefinition.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/OverlapsEvaluatorDefinition.java	2008-11-09 23:37:42 UTC (rev 23798)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/OverlapsEvaluatorDefinition.java	2008-11-10 00:37:43 UTC (rev 23799)
@@ -35,6 +35,7 @@
 import org.drools.spi.Evaluator;
 import org.drools.spi.FieldValue;
 import org.drools.spi.InternalReadAccessor;
+import org.drools.time.Interval;
 
 /**
  * The implementation of the 'overlaps' evaluator definition
@@ -178,6 +179,19 @@
             return handle;
         }
 
+        @Override
+        public boolean isTemporal() {
+            return true;
+        }
+        
+        @Override
+        public Interval getInterval() {
+            if( this.getOperator().isNegated() ) {
+                return new Interval( Interval.MIN, Interval.MAX );
+            }
+            return new Interval( Interval.MIN, 0 );
+        }
+        
         public boolean evaluate(InternalWorkingMemory workingMemory,
                                 final InternalReadAccessor extractor,
                                 final Object object1,

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/StartedByEvaluatorDefinition.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/StartedByEvaluatorDefinition.java	2008-11-09 23:37:42 UTC (rev 23798)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/StartedByEvaluatorDefinition.java	2008-11-10 00:37:43 UTC (rev 23799)
@@ -35,6 +35,7 @@
 import org.drools.spi.Evaluator;
 import org.drools.spi.FieldValue;
 import org.drools.spi.InternalReadAccessor;
+import org.drools.time.Interval;
 
 /**
  * The implementation of the 'startedby' evaluator definition
@@ -176,6 +177,19 @@
             return handle;
         }
 
+        @Override
+        public boolean isTemporal() {
+            return true;
+        }
+        
+        @Override
+        public Interval getInterval() {
+            if( this.getOperator().isNegated() ) {
+                return new Interval( Interval.MIN, Interval.MAX );
+            }
+            return new Interval( 0, 0 );
+        }
+        
         public boolean evaluate(InternalWorkingMemory workingMemory,
                                 final InternalReadAccessor extractor,
                                 final Object object1,

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/StartsEvaluatorDefinition.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/StartsEvaluatorDefinition.java	2008-11-09 23:37:42 UTC (rev 23798)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/StartsEvaluatorDefinition.java	2008-11-10 00:37:43 UTC (rev 23799)
@@ -35,6 +35,7 @@
 import org.drools.spi.Evaluator;
 import org.drools.spi.FieldValue;
 import org.drools.spi.InternalReadAccessor;
+import org.drools.time.Interval;
 
 /**
  * The implementation of the 'starts' evaluator definition
@@ -176,6 +177,19 @@
             return handle;
         }
 
+        @Override
+        public boolean isTemporal() {
+            return true;
+        }
+        
+        @Override
+        public Interval getInterval() {
+            if( this.getOperator().isNegated() ) {
+                return new Interval( Interval.MIN, Interval.MAX );
+            }
+            return new Interval( 0, 0 );
+        }
+        
         public boolean evaluate(InternalWorkingMemory workingMemory,
                                 final InternalReadAccessor extractor,
                                 final Object object1,

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	2008-11-09 23:37:42 UTC (rev 23798)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectTypeNode.java	2008-11-10 00:37:43 UTC (rev 23799)
@@ -82,6 +82,8 @@
     private boolean           skipOnModify     = false;
 
     private boolean           objectMemoryEnabled;
+    
+    private long              expirationOffset = -1;
 
     public ObjectTypeNode() {
 
@@ -141,18 +143,6 @@
         return this.objectType;
     }
 
-//    /**
-//     * Tests the provided object to see if this <code>ObjectTypeNode</code> can receive the object
-//     * for assertion and retraction propagations.
-//     *
-//     * @param object
-//     * @return
-//     *      boolean value indicating whether the <code>ObjectTypeNode</code> can receive the object.
-//     */
-//    public boolean matches(final Object object) {
-//        return this.objectType.matches( object );
-//    }
-
     public boolean isAssignableFrom(final ObjectType objectType) {
         return this.objectType.isAssignableFrom( objectType );
     }
@@ -187,7 +177,7 @@
                                          context,
                                          workingMemory );
     }
-
+    
     /**
      * Retract the <code>FactHandleimpl</code> from the <code>Rete</code> network. Also remove the 
      * <code>FactHandleImpl</code> from the node memory.
@@ -414,4 +404,12 @@
     public EntryPoint getEntryPoint() {
         return ((EntryPointNode) this.source).getEntryPoint();
     }
+
+    public long getExpirationOffset() {
+        return expirationOffset;
+    }
+
+    public void setExpirationOffset(long expirationOffset) {
+        this.expirationOffset = expirationOffset;
+    }
 }

Modified: 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	2008-11-09 23:37:42 UTC (rev 23798)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/BuildContext.java	2008-11-10 00:37:43 UTC (rev 23799)
@@ -30,6 +30,7 @@
 import org.drools.rule.Behavior;
 import org.drools.rule.EntryPoint;
 import org.drools.rule.RuleConditionElement;
+import org.drools.time.TemporalDependencyMatrix;
 
 /**
  * A build context for Reteoo Builder
@@ -89,6 +90,9 @@
     /** Stores the id of the partition this rule will be added to */
     private RuleBasePartitionId       partitionId;
 
+    /** the calculate temporal distance matrix */
+    private TemporalDependencyMatrix  temporal;
+
     public BuildContext(final InternalRuleBase rulebase,
                         final ReteooBuilder.IdGenerator idGenerator) {
         this.rulebase = rulebase;
@@ -110,7 +114,7 @@
         this.objectTypeNodeMemoryEnabled = true;
 
         this.currentEntryPoint = EntryPoint.DEFAULT;
-        
+
         this.nodes = new LinkedList<BaseNode>();
 
         this.partitionId = null;
@@ -404,4 +408,12 @@
         this.partitionId = partitionId;
     }
 
+    public void setTemporalDistance(TemporalDependencyMatrix temporal) {
+        this.temporal = temporal;
+    }
+
+    public TemporalDependencyMatrix getTemporalDistance() {
+        return this.temporal;
+    }
+
 }

Modified: 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	2008-11-09 23:37:42 UTC (rev 23798)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/BuildUtils.java	2008-11-10 00:37:43 UTC (rev 23799)
@@ -17,6 +17,7 @@
 package org.drools.reteoo.builder;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.ListIterator;
@@ -28,6 +29,7 @@
 import org.drools.common.DefaultBetaConstraints;
 import org.drools.common.DoubleBetaConstraints;
 import org.drools.common.EmptyBetaConstraints;
+import org.drools.common.InternalRuleBase;
 import org.drools.common.QuadroupleBetaConstraints;
 import org.drools.common.RuleBasePartitionId;
 import org.drools.common.SingleBetaConstraints;
@@ -38,11 +40,18 @@
 import org.drools.reteoo.ObjectSink;
 import org.drools.reteoo.ObjectSource;
 import org.drools.reteoo.ObjectTypeNode;
+import org.drools.rule.AbstractCompositeConstraint;
 import org.drools.rule.Declaration;
+import org.drools.rule.GroupElement;
 import org.drools.rule.InvalidPatternException;
+import org.drools.rule.Pattern;
 import org.drools.rule.RuleConditionElement;
+import org.drools.rule.VariableConstraint;
 import org.drools.spi.BetaNodeFieldConstraint;
 import org.drools.spi.ObjectType;
+import org.drools.time.Interval;
+import org.drools.time.TemporalDependencyMatrix;
+import org.drools.time.TimeUtils;
 
 /**
  * Utility functions for reteoo build
@@ -51,7 +60,7 @@
  */
 public class BuildUtils {
 
-    private final Map<Class<?>, ReteooComponentBuilder> componentBuilders = new HashMap<Class<?>, ReteooComponentBuilder>();
+    private final Map<Class< ? >, ReteooComponentBuilder> componentBuilders = new HashMap<Class< ? >, ReteooComponentBuilder>();
 
     /**
      * Adds the given builder for the given target to the builders map
@@ -59,7 +68,7 @@
      * @param target
      * @param builder
      */
-    public void addBuilder(final Class<?> target,
+    public void addBuilder(final Class< ? > target,
                            final ReteooComponentBuilder builder) {
         this.componentBuilders.put( target,
                                     builder );
@@ -91,50 +100,53 @@
                                final BaseNode candidate) {
         BaseNode node = null;
         RuleBasePartitionId partition = null;
-        if( candidate instanceof EntryPointNode ) {
+        if ( candidate instanceof EntryPointNode ) {
             // entry point nodes are always shared
-            EntryPointNode epn = context.getRuleBase().getRete().getEntryPointNode( ((EntryPointNode)candidate).getEntryPoint() );
-            if( epn != null ) {
+            EntryPointNode epn = context.getRuleBase().getRete().getEntryPointNode( ((EntryPointNode) candidate).getEntryPoint() );
+            if ( epn != null ) {
                 node = epn;
             }
             // all EntryPointNodes belong to the main partition
             partition = RuleBasePartitionId.MAIN_PARTITION;
-        } else if( candidate instanceof ObjectTypeNode ) {
+        } else if ( candidate instanceof ObjectTypeNode ) {
             // object type nodes are always shared
             ObjectTypeNode otn = (ObjectTypeNode) candidate;
             Map<ObjectType, ObjectTypeNode> map = context.getRuleBase().getRete().getObjectTypeNodes( context.getCurrentEntryPoint() );
-            if( map != null ) {
+            if ( map != null ) {
                 otn = map.get( otn.getObjectType() );
                 if ( otn != null ) {
+                    // adjusting expiration offset
+                    otn.setExpirationOffset( Math.max( otn.getExpirationOffset(),
+                                                       ((ObjectTypeNode) candidate).getExpirationOffset() ) );
                     node = otn;
                 }
             }
-            // all EntryPointNodes belong to the main partition
+            // all ObjectTypeNodes belong to the main partition
             partition = RuleBasePartitionId.MAIN_PARTITION;
-        } else if( isSharingEnabledForNode( context, candidate ) ) {
-            if ( (context.getTupleSource() != null) && ( candidate instanceof LeftTupleSink ) ) {
-                node    = context.getTupleSource().getSinkPropagator().getMatchingNode(candidate);
+        } else if ( isSharingEnabledForNode( context,
+                                             candidate ) ) {
+            if ( (context.getTupleSource() != null) && (candidate instanceof LeftTupleSink) ) {
+                node = context.getTupleSource().getSinkPropagator().getMatchingNode( candidate );
             } else if ( (context.getObjectSource() != null) && (candidate instanceof ObjectSink) ) {
-                node    = context.getObjectSource().getSinkPropagator().getMatchingNode(candidate);
+                node = context.getObjectSource().getSinkPropagator().getMatchingNode( candidate );
             } else {
                 throw new RuntimeDroolsException( "This is a bug on node sharing verification. Please report to development team." );
             }
-            if( node != null ) {
+            if ( node != null ) {
                 // shared node found
                 // undo previous id assignment
                 context.releaseId( candidate.getId() );
             }
         }
 
-
         if ( node == null ) {
             // only attach() if it is a new node
             node = candidate;
 
             // new node, so it must be labeled
-            if( partition == null ) {
+            if ( partition == null ) {
                 // if it does not has a predefined label
-                if( context.getPartitionId() == null ) {
+                if ( context.getPartitionId() == null ) {
                     // if no label in current context, create one
                     context.setPartitionId( context.getRuleBase().createNewPartitionId() );
                 }
@@ -182,7 +194,7 @@
      */
     public BetaConstraints createBetaNodeConstraint(final BuildContext context,
                                                     final List<BetaNodeFieldConstraint> list,
-                                                    final boolean disableIndexing ) {
+                                                    final boolean disableIndexing) {
         BetaConstraints constraints;
         switch ( list.size() ) {
             case 0 :
@@ -196,22 +208,22 @@
             case 2 :
                 constraints = new DoubleBetaConstraints( list.toArray( new BetaNodeFieldConstraint[list.size()] ),
                                                          context.getRuleBase().getConfiguration(),
-                                                         disableIndexing  );
+                                                         disableIndexing );
                 break;
             case 3 :
                 constraints = new TripleBetaConstraints( list.toArray( new BetaNodeFieldConstraint[list.size()] ),
                                                          context.getRuleBase().getConfiguration(),
-                                                         disableIndexing  );
+                                                         disableIndexing );
                 break;
             case 4 :
                 constraints = new QuadroupleBetaConstraints( list.toArray( new BetaNodeFieldConstraint[list.size()] ),
                                                              context.getRuleBase().getConfiguration(),
-                                                             disableIndexing  );
+                                                             disableIndexing );
                 break;
             default :
                 constraints = new DefaultBetaConstraints( list.toArray( new BetaNodeFieldConstraint[list.size()] ),
                                                           context.getRuleBase().getConfiguration(),
-                                                          disableIndexing  );
+                                                          disableIndexing );
         }
         return constraints;
     }
@@ -247,4 +259,105 @@
         }
     }
 
+    /**
+     * Calculates the temporal distance between all event patterns in the given 
+     * subrule.
+     * 
+     * @param groupElement the root element of a subrule being added to the rulebase
+     * 
+     */
+    public TemporalDependencyMatrix calculateTemporalDistance(GroupElement groupElement) {
+        // find the events
+        List<Pattern> events = new ArrayList<Pattern>();
+        selectAllEventPatterns( events,
+                                groupElement );
+
+        final int size = events.size();
+        if ( size >= 1 ) {
+            // create the matrix
+            Interval[][] source = new Interval[size][];
+            for ( int row = 0; row < size; row++ ) {
+                source[row] = new Interval[size];
+                for ( int col = 0; col < size; col++ ) {
+                    if ( row == col ) {
+                        source[row][col] = new Interval( 0,
+                                                         0 );
+                    } else {
+                        source[row][col] = new Interval( Interval.MIN,
+                                                         Interval.MAX );
+                    }
+                }
+            }
+
+            Interval[][] result;
+            if ( size > 1 ) {
+                List<Declaration> declarations = new ArrayList<Declaration>();
+                int eventIndex = 0;
+                // populate the matrix
+                for ( Pattern event : events ) {
+                    // references to other events are always backward references, so we can build the list as we go
+                    declarations.add( event.getDeclaration() );
+                    Map<Declaration, Interval> temporal = new HashMap<Declaration, Interval>();
+                    gatherTemporalRelationships( event.getConstraints(),
+                                                 temporal );
+                    // intersect default values with the actual constrained intervals
+                    for ( Map.Entry<Declaration, Interval> entry : temporal.entrySet() ) {
+                        int targetIndex = declarations.indexOf( entry.getKey() );
+                        Interval interval = entry.getValue();
+                        // FIXME: should it always be intersection or sometimes it would be union?????
+                        source[targetIndex][eventIndex].intersect( interval );
+                        source[eventIndex][targetIndex].intersect( new Interval( -interval.getUpperBound(),
+                                                                                 -interval.getLowerBound() ) );
+                    }
+                    eventIndex++;
+                }
+                result = TimeUtils.calculateTemporalDistance( source );
+            } else {
+                result = source;
+            }
+            TemporalDependencyMatrix matrix = new TemporalDependencyMatrix( result,
+                                                                            events );
+            return matrix;
+        }
+        return null;
+    }
+
+    private void gatherTemporalRelationships(List< ? > constraints,
+                                             Map<Declaration, Interval> temporal) {
+        for ( Object obj : constraints ) {
+            if ( obj instanceof VariableConstraint ) {
+                VariableConstraint constr = (VariableConstraint) obj;
+                if ( constr.isTemporal() ) {
+                    // if a constraint already exists, calculate the intersection
+                    Declaration target = constr.getRequiredDeclarations()[0];
+                    Interval interval = temporal.get( target );
+                    if ( interval == null ) {
+                        interval = constr.getInterval();
+                        temporal.put( target,
+                                      interval );
+                    } else {
+                        interval.intersect( constr.getInterval() );
+                    }
+                }
+            } else if ( obj instanceof AbstractCompositeConstraint ) {
+                gatherTemporalRelationships( Arrays.asList( ((AbstractCompositeConstraint) obj).getBetaConstraints() ),
+                                             temporal );
+            }
+        }
+    }
+
+    private void selectAllEventPatterns(List<Pattern> events,
+                                        RuleConditionElement rce) {
+        if ( rce instanceof Pattern ) {
+            Pattern p = (Pattern) rce;
+            if ( p.getObjectType().isEvent() ) {
+                events.add( p );
+            }
+        }
+        for ( RuleConditionElement child : rce.getNestedElements() ) {
+            selectAllEventPatterns( events,
+                                    child );
+        }
+    }
+
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/PatternBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/PatternBuilder.java	2008-11-09 23:37:42 UTC (rev 23798)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/PatternBuilder.java	2008-11-10 00:37:43 UTC (rev 23799)
@@ -21,6 +21,7 @@
 import java.util.List;
 
 import org.drools.RuntimeDroolsException;
+import org.drools.RuleBaseConfiguration.EventProcessingMode;
 import org.drools.base.ClassObjectType;
 import org.drools.base.DroolsQuery;
 import org.drools.common.InstanceNotEqualsConstraint;
@@ -180,7 +181,7 @@
                                                      epn,
                                                      objectType,
                                                      context );
-
+            
             if ( wms.length > 0 ) {
                 otn.attach( wms );
             } else {
@@ -197,7 +198,7 @@
                                  List alphaConstraints) throws InvalidPatternException {
 
         // Drools Query ObjectTypeNode never has memory, but other ObjectTypeNode/AlphaNoesNodes may (if not in sequential), 
-        //so need to preserve, so we can resotre after this node is added. LeftMemory  and Terminal remain the same once set.
+        //so need to preserve, so we can restore after this node is added. LeftMemory  and Terminal remain the same once set.
 
         boolean objectMemory = context.isObjectTypeNodeMemoryEnabled();
         boolean alphaMemory = context.isAlphaMemoryAllowed();
@@ -218,11 +219,16 @@
                                                                                       context.getRuleBase().getRete(),
                                                                                       context ) ) );
 
+        ObjectTypeNode otn = new ObjectTypeNode( context.getNextId(),
+                                                 (EntryPointNode) context.getObjectSource(),
+                                                 objectType,
+                                                 context );
+        if( objectType.isEvent() && EventProcessingMode.STREAM.equals( context.getRuleBase().getConfiguration().getEventProcessingMode() ) ) {
+            otn.setExpirationOffset( context.getTemporalDistance().getExpirationOffset( pattern ) );
+        }
+
         context.setObjectSource( (ObjectSource) utils.attachNode( context,
-                                                                  new ObjectTypeNode( context.getNextId(),
-                                                                                      (EntryPointNode) context.getObjectSource(),
-                                                                                      objectType,
-                                                                                      context ) ) );
+                                                                  otn ) );
 
         for ( final Iterator it = alphaConstraints.iterator(); it.hasNext(); ) {
             final AlphaNodeFieldConstraint constraint = (AlphaNodeFieldConstraint) it.next();

Modified: 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	2008-11-09 23:37:42 UTC (rev 23798)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/ReteooRuleBuilder.java	2008-11-10 00:37:43 UTC (rev 23799)
@@ -21,6 +21,7 @@
 
 import org.drools.InitialFact;
 import org.drools.RuleIntegrationException;
+import org.drools.RuleBaseConfiguration.EventProcessingMode;
 import org.drools.base.ClassObjectType;
 import org.drools.common.BaseNode;
 import org.drools.common.InternalRuleBase;
@@ -39,6 +40,8 @@
 import org.drools.rule.Pattern;
 import org.drools.rule.Query;
 import org.drools.rule.Rule;
+import org.drools.time.Interval;
+import org.drools.time.TemporalDependencyMatrix;
 
 /**
  * @author etirelli
@@ -85,20 +88,27 @@
      *             the <code>Rule</code>.
      * @throws InvalidPatternException
      */
-    public List addRule(final Rule rule,
+    public List<TerminalNode> addRule(final Rule rule,
                         final InternalRuleBase rulebase,
                         final ReteooBuilder.IdGenerator idGenerator) throws InvalidPatternException {
 
         // the list of terminal nodes
-        final List nodes = new ArrayList();
+        final List<TerminalNode> nodes = new ArrayList<TerminalNode>();
 
         // 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
             final BuildContext context = new BuildContext( rulebase,
                                                            idGenerator );
+            
+            // if running in STREAM mode, calculate temporal distance for events
+            if( EventProcessingMode.STREAM.equals( rulebase.getConfiguration().getEventProcessingMode() ) ) {
+                TemporalDependencyMatrix temporal = this.utils.calculateTemporalDistance( subrules[i] );
+                context.setTemporalDistance( temporal );
+            }
            
             if ( rulebase.getConfiguration().isSequential() ) {
                 context.setTupleMemoryEnabled( false );
@@ -176,29 +186,6 @@
         return terminal;
     }
 
-//    /**
-//     * Assigns the current partition ID to the list of created nodes
-//     *
-//     * @param context
-//     */
-//    private void assignPartitionId(BuildContext context) {
-//        if( context.getRuleBase().getConfiguration().isPartitionsEnabled() ) {
-//            org.drools.common.RuleBasePartitionId partitionId = null;
-//            if( context.getPartitionId() != null ) {
-//                // it means it shares nodes with an existing partition, so
-//                // assign the first id to the newly added nodes
-//                partitionId = context.getPartitionId();
-//            } else {
-//                // nodes are independent of existing nodes, so create a new
-//                // partition ID for them
-//                partitionId = context.getRuleBase().createNewPartitionId();
-//            }
-//            for( BaseNode node : context.getNodes() ) {
-//                node.setPartitionId( partitionId );
-//            }
-//        }
-//    }
-
     /**
      * Adds a query pattern to the given subrule
      * 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/AbstractCompositeConstraint.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/AbstractCompositeConstraint.java	2008-11-09 23:37:42 UTC (rev 23798)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/AbstractCompositeConstraint.java	2008-11-10 00:37:43 UTC (rev 23799)
@@ -58,6 +58,15 @@
         out.writeObject(betaConstraints);
         out.writeObject(requiredDeclarations);
     }
+
+    public AlphaNodeFieldConstraint[] getAlphaConstraints() {
+        return alphaConstraints;
+    }
+
+    public BetaNodeFieldConstraint[] getBetaConstraints() {
+        return betaConstraints;
+    }
+
     /**
      * Adds an alpha constraint to the multi field OR constraint
      *

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	2008-11-09 23:37:42 UTC (rev 23798)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/GroupElement.java	2008-11-10 00:37:43 UTC (rev 23799)
@@ -29,43 +29,39 @@
 
 import org.drools.RuntimeDroolsException;
 
-public class GroupElement extends ConditionalElement implements Externalizable {
+public class GroupElement extends ConditionalElement
+    implements
+    Externalizable {
 
     private static final long serialVersionUID = 400L;
 
-    public static final Type  AND              = new AndType();
-    public static final Type  OR               = new OrType();
-    public static final Type  EXISTS           = new ExistsType();
-    public static final Type  NOT              = new NotType();
+    public static final Type AND = Type.AND;
+    public static final Type OR = Type.OR;
+    public static final Type NOT = Type.NOT;
+    public static final Type EXISTS = Type.EXISTS;
 
     private Type              type             = null;
-    private List        children         = new ArrayList();
+    private List              children         = new ArrayList();
 
     public GroupElement() {
-        this( AND );
+        this( Type.AND );
     }
 
     public GroupElement(final Type type) {
         this.type = type;
     }
 
-    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-        String  name    = (String)in.readObject();
-        if ("AND".equals(name))
-            type    = AND;
-        else if ("OR".equals(name))
-            type    = OR;
-        else if ("EXISTS".equals(name))
-            type    = EXISTS;
-        else
-            type    = NOT;
-        children = (List)in.readObject();
+    public void readExternal(ObjectInput in) throws IOException,
+                                            ClassNotFoundException {
+        this.type = (Type) in.readObject();
+        children = (List) in.readObject();
     }
 
     public void writeExternal(ObjectOutput out) throws IOException {
-        out.writeObject(type.toString());
-        out.writeObject(children);
+        out.writeObject( type );
+        out.writeObject( children );
     }
+
     /**
      * Adds a child to the current GroupElement.
      *
@@ -297,19 +293,19 @@
     }
 
     public boolean isAnd() {
-        return this.type.isAnd();
+        return AND.equals( this.type );
     }
 
     public boolean isOr() {
-        return this.type.isOr();
+        return OR.equals( this.type );
     }
 
     public boolean isNot() {
-        return this.type.isNot();
+        return NOT.equals( this.type );
     }
 
     public boolean isExists() {
-        return this.type.isExists();
+        return EXISTS.equals( this.type );
     }
 
     public String toString() {
@@ -325,65 +321,26 @@
     }
 
     /**
-     * A public interface for CE types
+     * A public enum for CE types
      */
-    public static interface Type
-        extends
-        Externalizable {
+    public static enum Type {
 
-        /**
-         * Returns true if this CE type is an AND
-         */
-        public boolean isAnd();
+        AND(false), 
+        OR(false), 
+        NOT(true), 
+        EXISTS(true);
 
-        /**
-         * Returns true if this CE type is an OR
-         */
-        public boolean isOr();
+        private final boolean scopeDelimiter;
 
-        /**
-         * Returns true if this CE type is an NOT
-         */
-        public boolean isNot();
+        Type(final boolean scopeDelimiter) {
+            this.scopeDelimiter = scopeDelimiter;
+        }
 
         /**
-         * Returns true if this CE type is an EXISTS
-         */
-        public boolean isExists();
-
-        /**
          * Returns a map of declarations that are
          * visible inside of an element of this type
          */
-        public Map getInnerDeclarations(List children);
-
-        /**
-         * Returns a map of declarations that are
-         * visible outside of an element of this type
-         */
-        public Map getOuterDeclarations(List children);
-
-        /**
-         * Returns true in case this RuleConditionElement delimits
-         * a pattern visibility scope.
-         *
-         * For instance, AND CE is not a scope delimiter, while
-         * NOT CE is a scope delimiter
-         * @return
-         */
-        public boolean isPatternScopeDelimiter();
-    }
-
-    private static abstract class AbstractType
-        implements
-        Type {
-
-        private static final long serialVersionUID = 400L;
-
-        /**
-         * @inheritDoc
-         */
-        public Map getInnerDeclarations(final List children) {
+        public Map getInnerDeclarations(List children) {
             Map declarations = null;
 
             if ( children.isEmpty() ) {
@@ -401,12 +358,13 @@
         }
 
         /**
-         * @inheritDoc
+         * Returns a map of declarations that are
+         * visible outside of an element of this type
          */
-        public Map getOuterDeclarations(final List children) {
+        public Map getOuterDeclarations(List children) {
             Map declarations = null;
 
-            if ( children.isEmpty() ) {
+            if ( this.scopeDelimiter || children.isEmpty() ) {
                 declarations = Collections.EMPTY_MAP;
             } else if ( children.size() == 1 ) {
                 final RuleConditionElement re = (RuleConditionElement) children.get( 0 );
@@ -419,233 +377,18 @@
             }
             return declarations;
         }
-    }
 
-    /**
-     * An AND CE type
-     */
-    private static class AndType extends AbstractType {
-
-        private static final long serialVersionUID = 400L;
-
-        public AndType() {
-        }
-
-        public boolean isAnd() {
-            return true;
-        }
-
-        public boolean isExists() {
-            return false;
-        }
-
-        public boolean isNot() {
-            return false;
-        }
-
-        public boolean isOr() {
-            return false;
-        }
-
-        public boolean equals(final Object obj) {
-            if ( !(obj instanceof AndType) ) {
-                return false;
-            }
-            return true;
-        }
-
-        public int hashCode() {
-            return 11;
-        }
-
-        public String toString() {
-            return "AND";
-        }
-
-        public boolean isPatternScopeDelimiter() {
-            return false;
-        }
-
-        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-
-        }
-
-        public void writeExternal(ObjectOutput out) throws IOException {
-
-        }
-    }
-
-    /**
-     * An OR CE type
-     */
-    private static class OrType extends AbstractType {
-
-        private static final long serialVersionUID = 400L;
-
-        public OrType() {
-        }
-
-        public boolean isAnd() {
-            return false;
-        }
-
-        public boolean isExists() {
-            return false;
-        }
-
-        public boolean isNot() {
-            return false;
-        }
-
-        public boolean isOr() {
-            return true;
-        }
-
-        public boolean equals(final Object obj) {
-            if ( !(obj instanceof OrType) ) {
-                return false;
-            }
-            return true;
-        }
-
-        public int hashCode() {
-            return 17;
-        }
-
-        public String toString() {
-            return "OR";
-        }
-
-        public boolean isPatternScopeDelimiter() {
-            return false;
-        }
-        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-
-        }
-
-        public void writeExternal(ObjectOutput out) throws IOException {
-
-        }
-    }
-
-    /**
-     * A NOT CE type
-     */
-    private static class NotType extends AbstractType {
-
-        private static final long serialVersionUID = 400L;
-
-        public NotType() {
-        }
-
-        public boolean isAnd() {
-            return false;
-        }
-
-        public boolean isExists() {
-            return false;
-        }
-
-        public boolean isNot() {
-            return true;
-        }
-
-        public boolean isOr() {
-            return false;
-        }
-
         /**
-         * @inheritDoc
+         * Returns true in case this RuleConditionElement delimits
+         * a pattern visibility scope.
+         *
+         * For instance, AND CE is not a scope delimiter, while
+         * NOT CE is a scope delimiter
+         * @return
          */
-        public Map getOuterDeclarations(final List children) {
-            return Collections.EMPTY_MAP;
-        }
-
-        public boolean equals(final Object obj) {
-            if ( !(obj instanceof NotType) ) {
-                return false;
-            }
-            return true;
-        }
-
-        public int hashCode() {
-            return 23;
-        }
-
-        public String toString() {
-            return "NOT";
-        }
-
         public boolean isPatternScopeDelimiter() {
-            return true;
+            return this.scopeDelimiter;
         }
-        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
 
-        }
-
-        public void writeExternal(ObjectOutput out) throws IOException {
-
-        }
     }
-
-    /**
-     * An EXISTS CE type
-     */
-    private static class ExistsType extends AbstractType {
-
-        private static final long serialVersionUID = 400L;
-
-        public ExistsType() {
-        }
-
-        public boolean isAnd() {
-            return false;
-        }
-
-        public boolean isExists() {
-            return true;
-        }
-
-        public boolean isNot() {
-            return false;
-        }
-
-        public boolean isOr() {
-            return false;
-        }
-
-        /**
-         * @inheritDoc
-         */
-        public Map getOuterDeclarations(final List children) {
-            return Collections.EMPTY_MAP;
-        }
-
-        public boolean equals(final Object obj) {
-            if ( !(obj instanceof ExistsType) ) {
-                return false;
-            }
-            return true;
-        }
-
-        public int hashCode() {
-            return 31;
-        }
-
-        public String toString() {
-            return "EXISTS";
-        }
-
-        public boolean isPatternScopeDelimiter() {
-            return true;
-        }
-        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-
-        }
-
-        public void writeExternal(ObjectOutput out) throws IOException {
-
-        }
-    }
-
 }
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/VariableConstraint.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/VariableConstraint.java	2008-11-09 23:37:42 UTC (rev 23798)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/VariableConstraint.java	2008-11-10 00:37:43 UTC (rev 23799)
@@ -27,6 +27,7 @@
 import org.drools.spi.AcceptsReadAccessor;
 import org.drools.spi.Evaluator;
 import org.drools.spi.InternalReadAccessor;
+import org.drools.time.Interval;
 
 public class VariableConstraint extends MutableTypeConstraint
     implements
@@ -111,6 +112,14 @@
         return this.restriction.isAllowedCachedRight( tuple,
                                                       context );
     }
+    
+    public boolean isTemporal() {
+        return this.restriction.isTemporal();
+    }
+    
+    public Interval getInterval() {
+        return this.restriction.getInterval();
+    }
 
     public String toString() {
         return "[VariableConstraint fieldExtractor=" + this.fieldExtractor + " declaration=" + getRequiredDeclarations() + "]";

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/VariableRestriction.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/VariableRestriction.java	2008-11-09 23:37:42 UTC (rev 23798)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/VariableRestriction.java	2008-11-10 00:37:43 UTC (rev 23799)
@@ -30,6 +30,7 @@
 import org.drools.spi.InternalReadAccessor;
 import org.drools.spi.ReadAccessor;
 import org.drools.spi.Restriction;
+import org.drools.time.Interval;
 
 public class VariableRestriction
     implements
@@ -116,6 +117,14 @@
                                                    (VariableContextEntry) context,
                                                    this.evaluator.prepareObject( tuple.get( this.declaration ) ) );
     }
+    
+    public boolean isTemporal() {
+        return this.evaluator.isTemporal();
+    }
+    
+    public Interval getInterval() {
+        return this.evaluator.getInterval();
+    }
 
     public String toString() {
         return "[VariableRestriction declaration=" + this.declaration + "]";

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/Constraint.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/Constraint.java	2008-11-09 23:37:42 UTC (rev 23798)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/Constraint.java	2008-11-10 00:37:43 UTC (rev 23799)
@@ -4,6 +4,7 @@
 import java.io.IOException;
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
+import java.io.Serializable;
 
 import org.drools.rule.Declaration;
 
@@ -63,67 +64,25 @@
      * @return
      */
     public ConstraintType getType();
-
+    
     /**
-     * A java 1.4 type-safe enum
+     * An enum for Constraint Types
      */
-    public static class ConstraintType implements Externalizable {
+    public static enum ConstraintType {
 
-        private static final long serialVersionUID = 4865182371013556266L;
+        UNKNOWN("UNKNOWN"),
+        ALPHA("ALPHA"),
+        BETA("BETA");
 
-        public static final ConstraintType UNKNOWN = new ConstraintType(0, "UNKNOWN");
-        public static final ConstraintType ALPHA = new ConstraintType(1, "ALPHA");
-        public static final ConstraintType BETA = new ConstraintType(2, "BETA");
-
-        private int type;
         private String desc;
 
-        public ConstraintType() {
-
-        }
-
-        private ConstraintType( int type, String desc ) {
-            this.type = type;
+        private ConstraintType( String desc ) {
             this.desc = desc;
         }
 
-        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-            type    = in.readInt();
-            desc    = (String)in.readObject();
-        }
-
-        public void writeExternal(ObjectOutput out) throws IOException {
-            out.writeInt(type);
-            out.writeObject(desc);
-        }
-        /**
-         * @inheritDoc
-         *
-         * @see java.lang.Object#hashCode()
-         */
-        public int hashCode() {
-            final int prime = 31;
-            int result = 1;
-            result = prime * result + type;
-            return result;
-        }
-
-        /**
-         * @inheritDoc
-         *
-         * @see java.lang.Object#equals(java.lang.Object)
-         */
-        public boolean equals(Object obj) {
-            if ( this == obj ) return true;
-            if ( obj == null ) return false;
-            if ( getClass() != obj.getClass() ) return false;
-            final ConstraintType other = (ConstraintType) obj;
-            if ( type != other.type ) return false;
-            return true;
-        }
-
         public String toString() {
             return "ConstraintType::"+this.desc;
         }
     }
+    
 }
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/Evaluator.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/Evaluator.java	2008-11-09 23:37:42 UTC (rev 23798)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/Evaluator.java	2008-11-10 00:37:43 UTC (rev 23799)
@@ -23,6 +23,7 @@
 import org.drools.common.InternalFactHandle;
 import org.drools.common.InternalWorkingMemory;
 import org.drools.rule.VariableRestriction.VariableContextEntry;
+import org.drools.time.Interval;
 
 /**
  * A public interface to be implemented by all evaluators
@@ -199,5 +200,23 @@
     public boolean evaluateCachedRight(InternalWorkingMemory workingMemory,
                                        VariableContextEntry context,
                                        Object left);
+    
+    /**
+     * Returns true if this evaluator implements a temporal evaluation,
+     * i.e., a time sensitive evaluation whose properties of matching
+     * only events within an specific time interval can be used for
+     * determining event expirations automatically. 
+     * 
+     * @return true if the evaluator is a temporal evaluator. 
+     */
+    public boolean isTemporal();
 
+    /**
+     * In case this is a temporal evaluator, returns the interval 
+     * in which this evaluator may match the target fact
+     * 
+     * @return
+     */
+    public Interval getInterval();
+
 }
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/time/Interval.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/time/Interval.java	2008-11-09 23:37:42 UTC (rev 23798)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/time/Interval.java	2008-11-10 00:37:43 UTC (rev 23799)
@@ -1,5 +1,18 @@
-/**
+/*
+ * Copyright 2008 Red Hat
  * 
+ * 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.time;
 
@@ -15,8 +28,8 @@
  * @author etirelli
  */
 public class Interval implements Cloneable {
-    private static final long MIN = Long.MIN_VALUE;
-    private static final long MAX = Long.MAX_VALUE;
+    public static final long MIN = Long.MIN_VALUE;
+    public static final long MAX = Long.MAX_VALUE;
     
     private long lowerBound;
     private long upperBound;

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/time/JobContext.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/time/JobContext.java	2008-11-09 23:37:42 UTC (rev 23798)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/time/JobContext.java	2008-11-10 00:37:43 UTC (rev 23799)
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2008 Red Hat
+ * 
+ * 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.time;
 
 public interface JobContext {    

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/time/TemporalDependencyMatrix.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/time/TemporalDependencyMatrix.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/time/TemporalDependencyMatrix.java	2008-11-10 00:37:43 UTC (rev 23799)
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2008 Red Hat
+ * 
+ * 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.time;
+
+import java.util.List;
+
+import org.drools.rule.Pattern;
+
+/**
+ * A class to abstract the management of temporal
+ * dependency management information
+ * 
+ * @author etirelli
+ */
+public class TemporalDependencyMatrix {
+    
+    private Interval[][] matrix;
+    private List<Pattern> events;
+    
+    public TemporalDependencyMatrix(Interval[][] matrix,
+                                    List<Pattern> events) {
+        super();
+        this.matrix = matrix;
+        this.events = events;
+    }
+
+    public Interval[][] getMatrix() {
+        return matrix;
+    }
+
+    public void setMatrix(Interval[][] matrix) {
+        this.matrix = matrix;
+    }
+
+    public List<Pattern> getEvents() {
+        return events;
+    }
+
+    public void setEvents(List<Pattern> events) {
+        this.events = events;
+    }
+
+    public long getExpirationOffset(Pattern pattern) {
+        long expiration = 0;
+        int index = events.indexOf( pattern );
+        for( Interval interval : matrix[index] ) {
+           expiration = Math.max( expiration, interval.getUpperBound() ); 
+        }
+        return expiration;
+    }
+    
+}

Added: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/StockTick.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/StockTick.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/StockTick.java	2008-11-10 00:37:43 UTC (rev 23799)
@@ -0,0 +1,82 @@
+package org.drools;
+
+import java.io.Serializable;
+
+public class StockTick implements Serializable {
+    private long seq;
+    private String company;
+    private double price;
+    private long time;
+    private long duration;
+    
+    public StockTick() {
+    }
+
+    public StockTick(long seq,
+                     String company,
+                     double price,
+                     long time) {
+        super();
+        this.seq = seq;
+        this.company = company;
+        this.price = price;
+        this.time = time;
+    }
+
+    public StockTick(long seq,
+                     String company,
+                     double price,
+                     long time, 
+                     long duration ) {
+        super();
+        this.seq = seq;
+        this.company = company;
+        this.price = price;
+        this.time = time;
+        this.duration = duration;
+    }
+
+    public String getCompany() {
+        return company;
+    }
+    public void setCompany(String company) {
+        this.company = company;
+    }
+    public double getPrice() {
+        return price;
+    }
+    public void setPrice(double price) {
+        this.price = price;
+    }
+    public long getSeq() {
+        return seq;
+    }
+    public void setSeq(long seq) {
+        this.seq = seq;
+    }
+    public long getTime() {
+        return time;
+    }
+    public void setTime(long time) {
+        this.time = time;
+    }
+
+    public String toString() {
+        return "StockTick( "+this.seq+" : " +this.company +" : "+ this.price +" )";
+    }
+
+    /**
+     * @return the duration
+     */
+    public long getDuration() {
+        return duration;
+    }
+
+    /**
+     * @param duration the duration to set
+     */
+    public void setDuration(long duration) {
+        this.duration = duration;
+    }
+
+}

Added: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/builder/BuildUtilsTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/builder/BuildUtilsTest.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/builder/BuildUtilsTest.java	2008-11-10 00:37:43 UTC (rev 23799)
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2008 Red Hat
+ * 
+ * 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.StockTick;
+import org.drools.base.ClassObjectType;
+import org.drools.base.ValueType;
+import org.drools.base.evaluators.AfterEvaluatorDefinition;
+import org.drools.base.extractors.SelfReferenceClassFieldReader;
+import org.drools.rule.GroupElement;
+import org.drools.rule.Pattern;
+import org.drools.rule.VariableConstraint;
+import org.drools.rule.VariableRestriction;
+import org.drools.rule.GroupElement.Type;
+import org.drools.time.Interval;
+import org.drools.time.TemporalDependencyMatrix;
+
+import junit.framework.TestCase;
+
+import static org.drools.time.Interval.*;
+
+/**
+ * @author admin
+ *
+ */
+public class BuildUtilsTest extends TestCase {
+    
+    private BuildUtils utils;
+
+    @Override
+    protected void setUp() throws Exception {
+        utils = new BuildUtils();
+    }
+
+    /**
+     * Test method for {@link org.drools.reteoo.builder.BuildUtils#calculateTemporalDistance(org.drools.common.InternalRuleBase, org.drools.rule.GroupElement)}.
+     */
+    public void testCalculateTemporalDistance() {
+        // input is here just for "documentation" purposes
+        Interval[][] input = new Interval[][] {
+                                                { new Interval(0,0), new Interval(-2,2), new Interval(-3, 4), new Interval(MIN, MAX), new Interval(MIN, MAX) },
+                                                { new Interval(-2,2), new Interval(0,0), new Interval(MIN, MAX), new Interval(1,2), new Interval(MIN, MAX) },
+                                                { new Interval(-4,3), new Interval(MIN,MAX), new Interval(0, 0), new Interval(2, 3), new Interval(MIN, MAX) },
+                                                { new Interval(MIN,MAX), new Interval(-2,-1), new Interval(-3, -2), new Interval(0, 0), new Interval(1, 10) },
+                                                { new Interval(MIN,MAX), new Interval(MIN,MAX), new Interval(MIN,MAX), new Interval(-10, -1), new Interval(0,0) }
+                                        };
+        Interval[][] expected = new Interval[][] {
+                                                { new Interval(0,0), new Interval(-2,2), new Interval(-3, 2), new Interval(-1, 4), new Interval(0, 14) },
+                                                { new Interval(-2,2), new Interval(0,0), new Interval(-2, 0), new Interval(1,2), new Interval(2, 12) },
+                                                { new Interval(-2,3), new Interval(0,2), new Interval(0, 0), new Interval(2, 3), new Interval(3, 13) },
+                                                { new Interval(-4,1), new Interval(-2,-1), new Interval(-3, -2), new Interval(0, 0), new Interval(1, 10) },
+                                                { new Interval(-14,0), new Interval(-12,-2), new Interval(-13,-3), new Interval(-10, -1), new Interval(0,0) }
+                                        };
+
+        AfterEvaluatorDefinition evals = new AfterEvaluatorDefinition();
+        ClassObjectType ot = new ClassObjectType(StockTick.class, true);
+        
+        Pattern a = new Pattern( 0, ot, "$a" );
+        Pattern b = new Pattern( 1, ot, "$b" );
+        b.addConstraint( new VariableConstraint( 
+                         new SelfReferenceClassFieldReader( StockTick.class, "this" ), 
+                         new VariableRestriction( null, a.getDeclaration(), evals.getEvaluator( ValueType.OBJECT_TYPE, 
+                                                                                                AfterEvaluatorDefinition.AFTER, 
+                                                                                                "-2,2" ) ) ) );
+        Pattern c = new Pattern( 2, ot, "$c" );
+        c.addConstraint( new VariableConstraint( 
+                                                new SelfReferenceClassFieldReader( StockTick.class, "this" ), 
+                                                new VariableRestriction( null, a.getDeclaration(), evals.getEvaluator( ValueType.OBJECT_TYPE, 
+                                                                                                                       AfterEvaluatorDefinition.AFTER, 
+                                                                                                                       "-3,4" ) ) ) );
+        Pattern d = new Pattern( 3, ot, "$d" );
+        d.addConstraint( new VariableConstraint( 
+                                                new SelfReferenceClassFieldReader( StockTick.class, "this" ), 
+                                                new VariableRestriction( null, b.getDeclaration(), evals.getEvaluator( ValueType.OBJECT_TYPE, 
+                                                                                                                       AfterEvaluatorDefinition.AFTER, 
+                                                                                                                       "1,2" ) ) ) );
+        d.addConstraint( new VariableConstraint( 
+                                                new SelfReferenceClassFieldReader( StockTick.class, "this" ), 
+                                                new VariableRestriction( null, c.getDeclaration(), evals.getEvaluator( ValueType.OBJECT_TYPE, 
+                                                                                                                       AfterEvaluatorDefinition.AFTER, 
+                                                                                                                       "2,3" ) ) ) );
+        Pattern e = new Pattern( 4, ot, "$e" );
+        e.addConstraint( new VariableConstraint( 
+                                                new SelfReferenceClassFieldReader( StockTick.class, "this" ), 
+                                                new VariableRestriction( null, d.getDeclaration(), evals.getEvaluator( ValueType.OBJECT_TYPE, 
+                                                                                                                       AfterEvaluatorDefinition.AFTER, 
+                                                                                                                       "1,10" ) ) ) );
+
+        GroupElement not = new GroupElement( Type.NOT );
+        not.addChild( e );
+        GroupElement and = new GroupElement( Type.AND );
+        and.addChild( a );
+        and.addChild( b );
+        and.addChild( c );
+        and.addChild( d );
+        and.addChild( not );
+        
+        TemporalDependencyMatrix matrix = utils.calculateTemporalDistance( and );
+        //printMatrix( matrix.getMatrix() );
+        assertEqualsMatrix( expected, matrix.getMatrix() );
+        
+        assertEquals( 14, matrix.getExpirationOffset( a ) );
+        assertEquals( 10, matrix.getExpirationOffset( d ) );
+        assertEquals( 0, matrix.getExpirationOffset( e ) );
+        
+    }
+
+    public void assertEqualsMatrix( Interval[][] expected, Interval[][] matrix ) {
+        for( int i = 0; i < matrix.length; i++ ) {
+            for( int j = 0; j < matrix[i].length; j++ ) {
+                assertEquals( "Wrong value at ("+i+", "+j, expected[i][j], matrix[i][j] );
+            }
+        }
+    }
+
+    public void printMatrix( Interval[][] matrix ) {
+        System.out.println("------------------------------------------------------------------");
+        for( int i = 0; i < matrix.length; i++ ) {
+            System.out.print("|  ");
+            for( int j = 0; j < matrix[i].length; j++ ) {
+                System.out.print( matrix[i][j] + "  ");
+            }
+            System.out.println("|");
+        }
+        System.out.println("------------------------------------------------------------------");
+    }
+    
+}

Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/rule/GroupElementTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/rule/GroupElementTest.java	2008-11-09 23:37:42 UTC (rev 23798)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/rule/GroupElementTest.java	2008-11-10 00:37:43 UTC (rev 23799)
@@ -221,7 +221,7 @@
         and2.pack();
 
         // and2 now is in fact transformed into an OR
-        assertEquals( GroupElement.OR,
+        assertEquals( GroupElement.Type.OR,
                       and2.getType() );
 
         assertEquals( 2,

Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/rule/LogicTransformerTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/rule/LogicTransformerTest.java	2008-11-09 23:37:42 UTC (rev 23798)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/rule/LogicTransformerTest.java	2008-11-10 00:37:43 UTC (rev 23799)
@@ -166,7 +166,7 @@
 
         LogicTransformer.getInstance().applyOrTransformation( parent );
 
-        assertEquals( GroupElement.OR,
+        assertEquals( GroupElement.Type.OR,
                       parent.getType() );
 
         assertLength( 4,




More information about the jboss-svn-commits mailing list