[jboss-svn-commits] JBL Code SVN: r30072 - in labs/jbossrules/branches/effective_dated: drools-compiler/src/main/java/org/drools/compiler and 12 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Mon Nov 9 09:37:36 EST 2009


Author: tirelli
Date: 2009-11-09 09:37:35 -0500 (Mon, 09 Nov 2009)
New Revision: 30072

Added:
   labs/jbossrules/branches/effective_dated/drools-compiler/src/test/java/org/drools/Coverage.java
   labs/jbossrules/branches/effective_dated/drools-compiler/src/test/java/org/drools/EmployeeStatus.java
   labs/jbossrules/branches/effective_dated/drools-compiler/src/test/java/org/drools/integrationtests/TemporalFactsTest.java
   labs/jbossrules/branches/effective_dated/drools-compiler/src/test/resources/org/drools/integrationtests/test_TemporalFacts.drl
   labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/base/EffectiveRangeAgendaFilter.java
   labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/common/TemporalFactHandle.java
Modified:
   labs/jbossrules/branches/effective_dated/drools-api/src/main/java/org/drools/runtime/rule/Activation.java
   labs/jbossrules/branches/effective_dated/drools-compiler/src/main/java/org/drools/compiler/PackageBuilder.java
   labs/jbossrules/branches/effective_dated/drools-compiler/src/test/java/org/drools/compiler/PackageBuilderTest.java
   labs/jbossrules/branches/effective_dated/drools-compiler/src/test/java/org/drools/testframework/RuleCoverageListenerTest.java
   labs/jbossrules/branches/effective_dated/drools-compiler/src/test/resources/org/drools/integrationtests/test_FromWithParams.drl
   labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/common/AgendaItem.java
   labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/common/DefaultFactHandle.java
   labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/common/DisconnectedFactHandle.java
   labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/common/EventFactHandle.java
   labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/common/InternalFactHandle.java
   labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/event/rule/impl/SerializableActivation.java
   labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/reteoo/ClassObjectTypeConf.java
   labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/reteoo/FactTemplateTypeConf.java
   labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/reteoo/JoinNode.java
   labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/reteoo/LeftTuple.java
   labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/reteoo/ObjectTypeConf.java
   labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/reteoo/ReteooFactHandleFactory.java
   labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/rule/TypeDeclaration.java
   labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/spi/Tuple.java
   labs/jbossrules/branches/effective_dated/drools-core/src/test/java/org/drools/util/BaseQueueable.java
Log:
JBRULES-2330: Initial commit for the work on the effective dated model support

Modified: labs/jbossrules/branches/effective_dated/drools-api/src/main/java/org/drools/runtime/rule/Activation.java
===================================================================
--- labs/jbossrules/branches/effective_dated/drools-api/src/main/java/org/drools/runtime/rule/Activation.java	2009-11-09 14:22:35 UTC (rev 30071)
+++ labs/jbossrules/branches/effective_dated/drools-api/src/main/java/org/drools/runtime/rule/Activation.java	2009-11-09 14:37:35 UTC (rev 30072)
@@ -25,4 +25,28 @@
      *     The matched FactHandles for this activation
      */
     Collection< ? extends FactHandle> getFactHandles();
+ 
+    /**
+     * Returns true if this activation was created by a temporal
+     * tuple
+     * 
+     * @return
+     */
+    boolean isTemporal();
+    
+    /**
+     * Returns the effective timestamp for this activation if it
+     * is a temporal activation.
+     * 
+     * @return
+     */
+    long getStartTimestamp();
+
+    /**
+     * Returns the end timestamp for this activation if it
+     * is a temporal activation.
+     * 
+     * @return
+     */
+    long getEndTimestamp();
 }

Modified: labs/jbossrules/branches/effective_dated/drools-compiler/src/main/java/org/drools/compiler/PackageBuilder.java
===================================================================
--- labs/jbossrules/branches/effective_dated/drools-compiler/src/main/java/org/drools/compiler/PackageBuilder.java	2009-11-09 14:22:35 UTC (rev 30071)
+++ labs/jbossrules/branches/effective_dated/drools-compiler/src/main/java/org/drools/compiler/PackageBuilder.java	2009-11-09 14:37:35 UTC (rev 30072)
@@ -944,7 +944,7 @@
                 type.setResource( this.resource );
             }
 
-            // is it a regular fact or an event?
+            // what is this type role??
             String role = typeDescr.getMetaAttribute( TypeDeclaration.Role.ID );
             if ( role != null ) {
                 type.setRole( TypeDeclaration.Role.parseRole( role ) );
@@ -998,12 +998,12 @@
 
             String timestamp = typeDescr.getMetaAttribute( TypeDeclaration.ATTR_TIMESTAMP );
             if ( timestamp != null ) {
-                type.setTimestampAttribute( timestamp );
+                type.setStartTimestampAttribute( timestamp );
                 ClassDefinition cd = type.getTypeClassDef();
                 ClassFieldAccessorStore store = pkgRegistry.getPackage().getClassFieldAccessorStore();
                 InternalReadAccessor extractor = store.getReader( type.getTypeClass().getName(),
                                                                   timestamp,
-                                                                  type.new TimestampAccessorSetter() );
+                                                                  type.new StartTimestampAccessorSetter() );
             }
             String duration = typeDescr.getMetaAttribute( TypeDeclaration.ATTR_DURATION );
             if ( duration != null ) {
@@ -1014,6 +1014,15 @@
                                                                   duration,
                                                                   type.new DurationAccessorSetter() );
             }
+            String endTimestamp = typeDescr.getMetaAttribute( TypeDeclaration.ATTR_END_TIMESTAMP );
+            if ( timestamp != null ) {
+                type.setEndTimestampAttribute( endTimestamp );
+                ClassDefinition cd = type.getTypeClassDef();
+                ClassFieldAccessorStore store = pkgRegistry.getPackage().getClassFieldAccessorStore();
+                InternalReadAccessor extractor = store.getReader( type.getTypeClass().getName(),
+                                                                  endTimestamp,
+                                                                  type.new EndTimestampAccessorSetter() );
+            }
             String expiration = typeDescr.getMetaAttribute( TypeDeclaration.ATTR_EXPIRE );
             if ( expiration != null ) {
                 if ( timeParser == null ) {

Added: labs/jbossrules/branches/effective_dated/drools-compiler/src/test/java/org/drools/Coverage.java
===================================================================
--- labs/jbossrules/branches/effective_dated/drools-compiler/src/test/java/org/drools/Coverage.java	                        (rev 0)
+++ labs/jbossrules/branches/effective_dated/drools-compiler/src/test/java/org/drools/Coverage.java	2009-11-09 14:37:35 UTC (rev 30072)
@@ -0,0 +1,59 @@
+package org.drools;
+
+import java.util.Date;
+
+public class Coverage {
+    
+    private String employeeId;
+    private String type;
+    private Date start;
+    private Date end;
+    
+    public Coverage() {
+        super();
+    }
+    
+    public Coverage(String employeeId,
+                    String type,
+                    Date start,
+                    Date end) {
+        super();
+        this.employeeId = employeeId;
+        this.type = type;
+        this.start = start;
+        this.end = end;
+    }
+    
+    public String getEmployeeId() {
+        return employeeId;
+    }
+
+    public void setEmployeeId(String employeeId) {
+        this.employeeId = employeeId;
+    }
+
+    public String getType() {
+        return type;
+    }
+    public void setType(String type) {
+        this.type = type;
+    }
+    public Date getStart() {
+        return start;
+    }
+    public void setStart(Date start) {
+        this.start = start;
+    }
+    public Date getEnd() {
+        return end;
+    }
+    public void setEnd(Date end) {
+        this.end = end;
+    }
+    
+    @Override
+    public String toString() {
+        return "Coverage( id="+employeeId+" type="+type+" start="+start+" end="+end+" )";
+    }
+
+}

Added: labs/jbossrules/branches/effective_dated/drools-compiler/src/test/java/org/drools/EmployeeStatus.java
===================================================================
--- labs/jbossrules/branches/effective_dated/drools-compiler/src/test/java/org/drools/EmployeeStatus.java	                        (rev 0)
+++ labs/jbossrules/branches/effective_dated/drools-compiler/src/test/java/org/drools/EmployeeStatus.java	2009-11-09 14:37:35 UTC (rev 30072)
@@ -0,0 +1,57 @@
+package org.drools;
+
+import java.util.Date;
+
+public class EmployeeStatus {
+    
+    private String employeeId;
+    private String status;
+    private Date startDate;
+    private Date endDate;
+    
+    public EmployeeStatus() {
+        super();
+    }
+    
+    public EmployeeStatus(String employeeId,
+                          String status,
+                          Date startDate,
+                          Date endDate) {
+        super();
+        this.employeeId = employeeId;
+        this.status = status;
+        this.startDate = startDate;
+        this.endDate = endDate;
+    }
+    
+    public String getEmployeeId() {
+        return employeeId;
+    }
+    public void setEmployeeId(String employeeId) {
+        this.employeeId = employeeId;
+    }
+    public String getStatus() {
+        return status;
+    }
+    public void setStatus(String status) {
+        this.status = status;
+    }
+    public Date getStartDate() {
+        return startDate;
+    }
+    public void setStartDate(Date startDate) {
+        this.startDate = startDate;
+    }
+    public Date getEndDate() {
+        return endDate;
+    }
+    public void setEndDate(Date endDate) {
+        this.endDate = endDate;
+    }
+    
+    @Override
+    public String toString() {
+        return "EmployeeStatus( id="+employeeId+" status="+status+" start="+startDate+" end="+endDate+" )";
+    }    
+
+}

Modified: labs/jbossrules/branches/effective_dated/drools-compiler/src/test/java/org/drools/compiler/PackageBuilderTest.java
===================================================================
--- labs/jbossrules/branches/effective_dated/drools-compiler/src/test/java/org/drools/compiler/PackageBuilderTest.java	2009-11-09 14:22:35 UTC (rev 30071)
+++ labs/jbossrules/branches/effective_dated/drools-compiler/src/test/java/org/drools/compiler/PackageBuilderTest.java	2009-11-09 14:37:35 UTC (rev 30072)
@@ -1632,6 +1632,21 @@
             // TODO Auto-generated method stub
             return null;
         }
+
+        public long getEndTimestamp() {
+            // TODO Auto-generated method stub
+            return 0;
+        }
+
+        public long getStartTimestamp() {
+            // TODO Auto-generated method stub
+            return 0;
+        }
+
+        public boolean isTemporal() {
+            // TODO Auto-generated method stub
+            return false;
+        }
     }
 
     class MockTuple
@@ -1672,5 +1687,20 @@
             return 0;
         }
 
+        public long getEndTimestamp() {
+            // TODO Auto-generated method stub
+            return 0;
+        }
+
+        public long getStartTimestamp() {
+            // TODO Auto-generated method stub
+            return 0;
+        }
+
+        public boolean isTemporal() {
+            // TODO Auto-generated method stub
+            return false;
+        }
+
     }
 }
\ No newline at end of file

Added: labs/jbossrules/branches/effective_dated/drools-compiler/src/test/java/org/drools/integrationtests/TemporalFactsTest.java
===================================================================
--- labs/jbossrules/branches/effective_dated/drools-compiler/src/test/java/org/drools/integrationtests/TemporalFactsTest.java	                        (rev 0)
+++ labs/jbossrules/branches/effective_dated/drools-compiler/src/test/java/org/drools/integrationtests/TemporalFactsTest.java	2009-11-09 14:37:35 UTC (rev 30072)
@@ -0,0 +1,205 @@
+/**
+ * 
+ */
+package org.drools.integrationtests;
+
+import java.util.Calendar;
+
+import junit.framework.TestCase;
+
+import org.drools.Coverage;
+import org.drools.EmployeeStatus;
+import org.drools.KnowledgeBase;
+import org.drools.KnowledgeBaseFactory;
+import org.drools.base.EffectiveRangeAgendaFilter;
+import org.drools.builder.KnowledgeBuilder;
+import org.drools.builder.KnowledgeBuilderFactory;
+import org.drools.builder.ResourceType;
+import org.drools.common.TemporalFactHandle;
+import org.drools.io.ResourceFactory;
+import org.drools.runtime.StatefulKnowledgeSession;
+import org.drools.runtime.rule.FactHandle;
+
+/**
+ * @author etirelli
+ *
+ */
+public class TemporalFactsTest extends TestCase {
+
+    public void testTemporalFactCreation() {
+        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
+        kbuilder.add( ResourceFactory.newInputStreamResource( getClass().getResourceAsStream( "test_TemporalFacts.drl" ) ),
+                      ResourceType.DRL );
+
+        assertFalse( kbuilder.getErrors().toString(),
+                     kbuilder.hasErrors() );
+
+        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
+        kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );
+
+        StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
+
+        Calendar start = Calendar.getInstance();
+        start.set( 2009,
+                   07,
+                   10 );
+        Calendar end = Calendar.getInstance();
+        end.set( 2009,
+                 10,
+                 25 );
+
+        EmployeeStatus es1 = new EmployeeStatus( "e1",
+                                                 "full time",
+                                                 start.getTime(),
+                                                 end.getTime() );
+
+        FactHandle handle = ksession.insert( es1 );
+
+        assertNotNull( handle );
+        assertTrue( handle instanceof TemporalFactHandle );
+        TemporalFactHandle thandle = (TemporalFactHandle) handle;
+        assertEquals( start.getTimeInMillis(),
+                      thandle.getStartTimestamp() );
+        assertEquals( end.getTimeInMillis(),
+                      thandle.getEndTimestamp() );
+        assertEquals( end.getTimeInMillis() - start.getTimeInMillis(),
+                      thandle.getDuration() );
+        
+        ksession.fireAllRules();
+
+    }
+    
+    public void testTemporalMatching() {
+        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
+        kbuilder.add( ResourceFactory.newInputStreamResource( getClass().getResourceAsStream( "test_TemporalFacts.drl" ) ),
+                      ResourceType.DRL );
+
+        assertFalse( kbuilder.getErrors().toString(),
+                     kbuilder.hasErrors() );
+
+        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
+        kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );
+
+        StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
+
+        Calendar t1 = Calendar.getInstance();
+        t1.set( 2009,
+                   9,
+                   1 );
+        Calendar t2 = Calendar.getInstance();
+        t2.set( 2009,
+                 9,
+                 15 );
+        Calendar t3 = Calendar.getInstance();
+        t3.set( 2009,
+                 10,
+                 7 );
+        Calendar t4 = Calendar.getInstance();
+        t4.set( 2009,
+                 10,
+                 25 );
+        Calendar t5 = Calendar.getInstance();
+        t5.set( 2009,
+                 10,
+                 30 );
+        Calendar t6 = Calendar.getInstance();
+        t6.set( 2009,
+                 11,
+                 12 );
+        Calendar t7 = Calendar.getInstance();
+        t7.set( 2009,
+                 11,
+                 20 );
+
+        EmployeeStatus es1 = new EmployeeStatus( "e1",
+                                                 "full time",
+                                                 t1.getTime(),
+                                                 t3.getTime() );
+        EmployeeStatus es2 = new EmployeeStatus( "e1",
+                                                 "full time",
+                                                 t5.getTime(),
+                                                 t7.getTime() );
+        Coverage c1 = new Coverage("e1",
+                                   "A",
+                                   t2.getTime(),
+                                   t4.getTime() );
+        Coverage c2 = new Coverage("e1",
+                                   "A",
+                                   t5.getTime(),
+                                   t6.getTime() );
+
+        ksession.insert( es1 );
+        ksession.insert( es2 );
+        ksession.insert( c1 );
+        ksession.insert( c2 );
+        
+        ksession.fireAllRules();
+    }
+
+    public void testTemporalAgendaFilter() {
+        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
+        kbuilder.add( ResourceFactory.newInputStreamResource( getClass().getResourceAsStream( "test_TemporalFacts.drl" ) ),
+                      ResourceType.DRL );
+
+        assertFalse( kbuilder.getErrors().toString(),
+                     kbuilder.hasErrors() );
+
+        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
+        kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );
+
+        StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
+
+        Calendar t1 = Calendar.getInstance();
+        t1.set( 2009,
+                   9,
+                   1 );
+        Calendar t2 = Calendar.getInstance();
+        t2.set( 2009,
+                 9,
+                 15 );
+        Calendar t3 = Calendar.getInstance();
+        t3.set( 2009,
+                 10,
+                 7 );
+        Calendar t4 = Calendar.getInstance();
+        t4.set( 2009,
+                 10,
+                 25 );
+        Calendar t5 = Calendar.getInstance();
+        t5.set( 2009,
+                 10,
+                 30 );
+        Calendar t6 = Calendar.getInstance();
+        t6.set( 2009,
+                 11,
+                 12 );
+        Calendar t7 = Calendar.getInstance();
+        t7.set( 2009,
+                 11,
+                 20 );
+
+        EmployeeStatus es1 = new EmployeeStatus( "e1",
+                                                 "full time",
+                                                 t1.getTime(),
+                                                 t3.getTime() );
+        EmployeeStatus es2 = new EmployeeStatus( "e1",
+                                                 "full time",
+                                                 t5.getTime(),
+                                                 t7.getTime() );
+        Coverage c1 = new Coverage("e1",
+                                   "A",
+                                   t2.getTime(),
+                                   t4.getTime() );
+        Coverage c2 = new Coverage("e1",
+                                   "A",
+                                   t5.getTime(),
+                                   t6.getTime() );
+
+        ksession.insert( es1 );
+        ksession.insert( es2 );
+        ksession.insert( c1 );
+        ksession.insert( c2 );
+        
+        ksession.fireAllRules(new EffectiveRangeAgendaFilter( t1.getTime(), t4.getTime() ));
+    }
+}

Modified: labs/jbossrules/branches/effective_dated/drools-compiler/src/test/java/org/drools/testframework/RuleCoverageListenerTest.java
===================================================================
--- labs/jbossrules/branches/effective_dated/drools-compiler/src/test/java/org/drools/testframework/RuleCoverageListenerTest.java	2009-11-09 14:22:35 UTC (rev 30071)
+++ labs/jbossrules/branches/effective_dated/drools-compiler/src/test/java/org/drools/testframework/RuleCoverageListenerTest.java	2009-11-09 14:37:35 UTC (rev 30072)
@@ -144,4 +144,19 @@
         return null;
     }
 
+    public long getEndTimestamp() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    public long getStartTimestamp() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    public boolean isTemporal() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
 }

Modified: labs/jbossrules/branches/effective_dated/drools-compiler/src/test/resources/org/drools/integrationtests/test_FromWithParams.drl
===================================================================
--- labs/jbossrules/branches/effective_dated/drools-compiler/src/test/resources/org/drools/integrationtests/test_FromWithParams.drl	2009-11-09 14:22:35 UTC (rev 30071)
+++ labs/jbossrules/branches/effective_dated/drools-compiler/src/test/resources/org/drools/integrationtests/test_FromWithParams.drl	2009-11-09 14:37:35 UTC (rev 30072)
@@ -10,7 +10,10 @@
 rule "test from"
 	when
 		$person : Person()
-		$object : Object() from testObject.toList(globalObject, $person, "literal", 42, [ $person : globalObject, "key1" : [ "key2" : "value2"]], [$person, 42, ["x", "y"]])		
+		$object : Object() from testObject.toList(globalObject, $person, "literal", 42, 
+		                                          [ $person : globalObject, 
+		                                          "key1" : [ "key2" : "value2"]], 
+		                                          [$person, 42, ["x", "y"]])		
 	then
 		list.add( $object );
 end

Added: labs/jbossrules/branches/effective_dated/drools-compiler/src/test/resources/org/drools/integrationtests/test_TemporalFacts.drl
===================================================================
--- labs/jbossrules/branches/effective_dated/drools-compiler/src/test/resources/org/drools/integrationtests/test_TemporalFacts.drl	                        (rev 0)
+++ labs/jbossrules/branches/effective_dated/drools-compiler/src/test/resources/org/drools/integrationtests/test_TemporalFacts.drl	2009-11-09 14:37:35 UTC (rev 30072)
@@ -0,0 +1,26 @@
+package org.drools
+
+import java.util.Date
+
+declare EmployeeStatus
+    @role( temporal )
+    @timestamp( startDate )
+    @endTimestamp( endDate )
+end
+
+declare Coverage
+    @role( temporal )
+    @timestamp( start )
+    @endTimestamp( end )
+end
+
+rule "Employee is full time worker"
+when
+    $e : EmployeeStatus( status == "full time" )
+    $c : Coverage( employeeId == $e.employeeId, type == "A" )
+then
+    System.out.println( $e ); 
+    System.out.println( $c );
+    System.out.println( "Start = "+new Date(drools.getActivation().getStartTimestamp()) );
+    System.out.println( "End   = "+new Date(drools.getActivation().getEndTimestamp()) );
+end
\ No newline at end of file

Added: labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/base/EffectiveRangeAgendaFilter.java
===================================================================
--- labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/base/EffectiveRangeAgendaFilter.java	                        (rev 0)
+++ labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/base/EffectiveRangeAgendaFilter.java	2009-11-09 14:37:35 UTC (rev 30072)
@@ -0,0 +1,63 @@
+package org.drools.base;
+
+/*
+ * Copyright 2005 JBoss Inc
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.Date;
+
+import org.drools.runtime.rule.Activation;
+import org.drools.runtime.rule.AgendaFilter;
+
+/**
+ * Filters activations based on an exact match of a rule name.
+ * 
+ * @author <a href="mailto:simon at redhillconsulting.com.au">Simon Harris </a>
+ */
+public class EffectiveRangeAgendaFilter
+    implements
+    AgendaFilter {
+    private final long startTimestamp;
+    private final long endTimestamp;
+
+    private final boolean accept;
+
+    public EffectiveRangeAgendaFilter(final Date start, final Date end) {
+        this( start.getTime(),
+              end.getTime(),
+              true );
+    }
+
+    public EffectiveRangeAgendaFilter(final long start, final long end) {
+        this( start,
+              end,
+              true );
+    }
+
+    public EffectiveRangeAgendaFilter(final long start,
+                                      final long end,
+                                      final boolean accept) {
+        this.startTimestamp = start;
+        this.endTimestamp = end;
+        this.accept = accept;
+    }
+
+    public boolean accept(final Activation activation) {
+        long start = activation.getStartTimestamp();
+        long end = activation.getEndTimestamp();
+        return (!this.accept) ^ ( (start >= this.startTimestamp && start <= this.endTimestamp ) ||
+                (end >= this.startTimestamp && end <= this.endTimestamp ) );
+    }
+}
\ No newline at end of file

Modified: labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/common/AgendaItem.java
===================================================================
--- labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/common/AgendaItem.java	2009-11-09 14:22:35 UTC (rev 30071)
+++ labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/common/AgendaItem.java	2009-11-09 14:37:35 UTC (rev 30072)
@@ -313,4 +313,16 @@
         }
         return Collections.unmodifiableCollection( list );
     }
+
+    public long getEndTimestamp() {
+        return tuple.getEndTimestamp();
+    }
+
+    public long getStartTimestamp() {
+        return tuple.getStartTimestamp();
+    }
+
+    public boolean isTemporal() {
+        return tuple.isTemporal();
+    }
 }

Modified: labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/common/DefaultFactHandle.java
===================================================================
--- labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/common/DefaultFactHandle.java	2009-11-09 14:22:35 UTC (rev 30071)
+++ labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/common/DefaultFactHandle.java	2009-11-09 14:37:35 UTC (rev 30072)
@@ -226,4 +226,16 @@
         clone.objectHashCode = this.objectHashCode;
         return clone;
     }
+
+    public long getEndTimestamp() {
+        return Long.MAX_VALUE;
+    }
+
+    public long getStartTimestamp() {
+        return Long.MIN_VALUE;
+    }
+
+    public boolean isTemporal() {
+        return false;
+    }
 }

Modified: labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/common/DisconnectedFactHandle.java
===================================================================
--- labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/common/DisconnectedFactHandle.java	2009-11-09 14:22:35 UTC (rev 30071)
+++ labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/common/DisconnectedFactHandle.java	2009-11-09 14:37:35 UTC (rev 30072)
@@ -115,4 +115,16 @@
         return "0:" + this.id + ":" + this.identityHashCode + ":" + this.objectHashCode + ":" + this.recency;
     }
 
+    public long getEndTimestamp() {
+        throw new UnsupportedOperationException( "DisonnectedFactHandle does not support this method" );
+    }
+
+    public long getStartTimestamp() {
+        throw new UnsupportedOperationException( "DisonnectedFactHandle does not support this method" );
+    }
+
+    public boolean isTemporal() {
+        throw new UnsupportedOperationException( "DisonnectedFactHandle does not support this method" );
+    }
+
 }

Modified: labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/common/EventFactHandle.java
===================================================================
--- labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/common/EventFactHandle.java	2009-11-09 14:22:35 UTC (rev 30071)
+++ labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/common/EventFactHandle.java	2009-11-09 14:37:35 UTC (rev 30072)
@@ -139,10 +139,10 @@
 
     public EventFactHandle clone() {
         EventFactHandle clone = new EventFactHandle( getId(),
-                                                      getObject(),
-                                                      getRecency(),
-                                                      startTimestamp,
-                                                      duration );
+                                                     getObject(),
+                                                     getRecency(),
+                                                     startTimestamp,
+                                                     duration );
         clone.activationsCount = activationsCount;
         clone.expired = expired;
         clone.setEntryPoint( getEntryPoint() );

Modified: labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/common/InternalFactHandle.java
===================================================================
--- labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/common/InternalFactHandle.java	2009-11-09 14:22:35 UTC (rev 30071)
+++ labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/common/InternalFactHandle.java	2009-11-09 14:37:35 UTC (rev 30072)
@@ -70,5 +70,11 @@
     public InternalFactHandle clone();
     
     public String toExternalForm();
+
+    public boolean isTemporal();
     
+    public long getStartTimestamp();
+    
+    public long getEndTimestamp();
+    
 }
\ No newline at end of file

Added: labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/common/TemporalFactHandle.java
===================================================================
--- labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/common/TemporalFactHandle.java	                        (rev 0)
+++ labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/common/TemporalFactHandle.java	2009-11-09 14:37:35 UTC (rev 30072)
@@ -0,0 +1,141 @@
+package org.drools.common;
+
+import org.drools.FactHandle;
+import org.drools.spi.ReadAccessor;
+
+public class TemporalFactHandle extends DefaultFactHandle {
+
+    private static final long serialVersionUID = 5997141759543399455L;
+
+    private ReadAccessor      startTimestamp;
+    private ReadAccessor      endTimestamp;
+    private ReadAccessor      duration;
+
+    // ----------------------------------------------------------------------
+    // Constructors
+    // ----------------------------------------------------------------------
+
+    public TemporalFactHandle() {
+        this( 0,
+              null,
+              0 );
+    }
+
+    public TemporalFactHandle(final int id,
+                              final Object object) {
+        this( id,
+              object,
+              id );
+    }
+
+    /**
+     * Construct.
+     *
+     * @param id
+     *            Handle id.
+     */
+    public TemporalFactHandle(final int id,
+                              final Object object,
+                              final long recency) {
+        super( id,
+               object,
+               recency );
+    }
+
+    /**
+     * Creates a new event fact handle.
+     *
+     * @param id this event fact handle ID
+     * @param object the event object encapsulated in this event fact handle
+     * @param recency the recency of this event fact handle
+     * @param startTimestamp the field accessor to the start timestamp of the occurrence of this event
+     * @param endTimestamp the field accessor to the end timestamp of the occurrence of this event
+     * @param duration the duration of this event. May be 0 (zero) in case this is a primitive event.
+     */
+    public TemporalFactHandle(final int id,
+                              final Object object,
+                              final long recency,
+                              final ReadAccessor startTimestamp,
+                              final ReadAccessor endTimestamp,
+                              final ReadAccessor duration) {
+        super( id,
+               object,
+               recency );
+        this.startTimestamp = startTimestamp;
+        this.endTimestamp = endTimestamp;
+        this.duration = duration;
+    }
+
+    /**
+     * @see FactHandle
+     */
+    public String toExternalForm() {
+        return "[temporal fid:" + getId() + ":" + getRecency() + ":" + getObject() + " start="+ getStartTimestamp()+" duration="+getDuration()+"]";
+    }
+
+    /**
+     * @see Object
+     */
+    public String toString() {
+        return toExternalForm();
+    }
+
+    /**
+     * Always returns false, since the TemporalFactHandle is
+     * not used for Events
+     */
+    public boolean isEvent() {
+        return false;
+    }
+
+    /**
+     * Returns the start timestamp of the occurrence of this temporal fact.
+     * @return
+     */
+    @Override
+    public long getStartTimestamp() {
+        return startTimestamp != null ? startTimestamp.getLongValue( getObject() ) : Long.MIN_VALUE;
+    }
+
+    /**
+     * Returns the duration of this temporal fact. 
+     *
+     * @return
+     */
+    public long getDuration() {
+        return duration != null ? duration.getLongValue( getObject() ) : ( getEndTimestamp() - getStartTimestamp() );
+    }
+
+    /**
+     * Returns the end timestamp for this temporal fact.
+     *
+     * startTimestamp + duration
+     *
+     * @return
+     */
+    @Override
+    public long getEndTimestamp() {
+        return endTimestamp != null ? endTimestamp.getLongValue( getObject() ) : 
+               ((duration != null) ? getStartTimestamp() + getDuration() : Long.MAX_VALUE );
+    }
+
+    public TemporalFactHandle clone() {
+        TemporalFactHandle clone = new TemporalFactHandle( getId(),
+                                                           getObject(),
+                                                           getRecency(),
+                                                           startTimestamp,
+                                                           endTimestamp,
+                                                           duration );
+        clone.setEntryPoint( getEntryPoint() );
+        clone.setEqualityKey( getEqualityKey() );
+        clone.setLeftTuple( getLeftTuple() );
+        clone.setRightTuple( getRightTuple() );
+        clone.setObjectHashCode( getObjectHashCode() );
+        return clone;
+    }
+    
+    @Override
+    public boolean isTemporal() {
+        return true;
+    }
+}

Modified: labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/event/rule/impl/SerializableActivation.java
===================================================================
--- labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/event/rule/impl/SerializableActivation.java	2009-11-09 14:22:35 UTC (rev 30071)
+++ labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/event/rule/impl/SerializableActivation.java	2009-11-09 14:37:35 UTC (rev 30072)
@@ -18,15 +18,21 @@
     private Rule                              rule;
     private Collection< ? extends FactHandle> factHandles;
     private PropagationContext                propgationContext;
+    private boolean                           temporal;
+    private long                              startTimestamp;
+    private long                              endTimestamp;
 
     public SerializableActivation() {
-        
+
     }
-    
+
     public SerializableActivation(Activation activation) {
         this.rule = activation.getRule();
         this.factHandles = activation.getFactHandles();
         this.propgationContext = activation.getPropagationContext();
+        this.temporal = activation.isTemporal();
+        this.startTimestamp = activation.getStartTimestamp();
+        this.endTimestamp = activation.getEndTimestamp();
     }
 
     public void readExternal(ObjectInput in) throws IOException,
@@ -47,4 +53,16 @@
     public PropagationContext getPropagationContext() {
         return this.propgationContext;
     }
+
+    public long getEndTimestamp() {
+        return endTimestamp;
+    }
+
+    public long getStartTimestamp() {
+        return startTimestamp;
+    }
+
+    public boolean isTemporal() {
+        return temporal;
+    }
 }

Modified: labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/reteoo/ClassObjectTypeConf.java
===================================================================
--- labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/reteoo/ClassObjectTypeConf.java	2009-11-09 14:22:35 UTC (rev 30071)
+++ labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/reteoo/ClassObjectTypeConf.java	2009-11-09 14:37:35 UTC (rev 30072)
@@ -54,6 +54,8 @@
 
     private TypeDeclaration            typeDecl;
 
+    private TypeDeclaration.Role       role;
+
     public ClassObjectTypeConf() {
 
     }
@@ -65,7 +67,9 @@
         this.ruleBase = ruleBase;
         this.entryPoint = entryPoint;
         this.typeDecl = ruleBase.getTypeDeclaration( clazz );
-        final boolean isEvent = typeDecl != null && typeDecl.getRole() == TypeDeclaration.Role.EVENT;
+        this.role = ( typeDecl != null ) ? typeDecl.getRole() : TypeDeclaration.Role.FACT;
+        final boolean isEvent = role == TypeDeclaration.Role.EVENT;
+        
 
         ObjectType objectType = ((AbstractRuleBase) ruleBase).getClassFieldAccessorCache().getClassObjectType( new ClassObjectType( clazz,
                                                                                                                                     isEvent ) );
@@ -188,8 +192,12 @@
     public TypeDeclaration getTypeDeclaration() {
         return typeDecl;
     }
-    
+
     public boolean isDynamic() {
         return (typeDecl != null) ? typeDecl.isDynamic() : false;
     }
+
+    public TypeDeclaration.Role getRole() {
+        return this.role;
+    }
 }
\ No newline at end of file

Modified: labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/reteoo/FactTemplateTypeConf.java
===================================================================
--- labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/reteoo/FactTemplateTypeConf.java	2009-11-09 14:22:35 UTC (rev 30071)
+++ labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/reteoo/FactTemplateTypeConf.java	2009-11-09 14:37:35 UTC (rev 30072)
@@ -30,6 +30,7 @@
 import org.drools.reteoo.builder.PatternBuilder;
 import org.drools.rule.EntryPoint;
 import org.drools.rule.TypeDeclaration;
+import org.drools.rule.TypeDeclaration.Role;
 import org.drools.spi.ObjectType;
 
 public class FactTemplateTypeConf
@@ -129,4 +130,8 @@
         return false;
     }
 
+    public Role getRole() {
+        return TypeDeclaration.Role.FACT;
+    }
+
 }
\ No newline at end of file

Modified: labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/reteoo/JoinNode.java
===================================================================
--- labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/reteoo/JoinNode.java	2009-11-09 14:22:35 UTC (rev 30071)
+++ labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/reteoo/JoinNode.java	2009-11-09 14:37:35 UTC (rev 30072)
@@ -113,17 +113,31 @@
             final InternalFactHandle handle = rightTuple.getFactHandle();
             if ( this.constraints.isAllowedCachedLeft( memory.getContext(),
                                                        handle ) ) {
-                this.sink.propagateAssertLeftTuple( leftTuple,
-                                                    rightTuple,
-                                                    context,
-                                                    workingMemory,
-                                                    this.tupleMemoryEnabled );
+                if ( thereIsTemporalOverlap( leftTuple,
+                                             handle ) ) {
+                    this.sink.propagateAssertLeftTuple( leftTuple,
+                                                        rightTuple,
+                                                        context,
+                                                        workingMemory,
+                                                        this.tupleMemoryEnabled );
+
+                }
             }
         }
 
         this.constraints.resetTuple( memory.getContext() );
     }
 
+    private boolean thereIsTemporalOverlap(final LeftTuple leftTuple,
+                                           final InternalFactHandle handle) {
+        boolean result = true;
+        if ( leftTuple.isTemporal() || handle.isTemporal() ) {
+            result = (leftTuple.getStartTimestamp() >= handle.getStartTimestamp() && leftTuple.getStartTimestamp() <= handle.getEndTimestamp())
+                     || (leftTuple.getEndTimestamp() >= handle.getStartTimestamp() && leftTuple.getEndTimestamp() <= handle.getEndTimestamp());
+        }
+        return result;
+    }
+
     //    public void assertLeftTuple(final LeftTuple leftTuple,
     //                                RightTuple rightTuple,
     //                                final PropagationContext context,
@@ -205,11 +219,14 @@
             if ( this.constraints.isAllowedCachedRight( memory.getContext(),
                                                         leftTuple ) ) {
                 // wm.marshaller.write( i, leftTuple )
-                this.sink.propagateAssertLeftTuple( leftTuple,
-                                                    rightTuple,
-                                                    context,
-                                                    workingMemory,
-                                                    this.tupleMemoryEnabled );
+                if ( thereIsTemporalOverlap( leftTuple,
+                                             rightTuple.getFactHandle() ) ) {
+                    this.sink.propagateAssertLeftTuple( leftTuple,
+                                                        rightTuple,
+                                                        context,
+                                                        workingMemory,
+                                                        this.tupleMemoryEnabled );
+                }
             }
             i++;
         }

Modified: labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/reteoo/LeftTuple.java
===================================================================
--- labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/reteoo/LeftTuple.java	2009-11-09 14:22:35 UTC (rev 30071)
+++ labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/reteoo/LeftTuple.java	2009-11-09 14:37:35 UTC (rev 30072)
@@ -46,8 +46,16 @@
 
     private LeftTupleSink      sink;
 
+    // temporal info
+    private long               startTimestamp;
+    private long               endTimestamp;
+
     public LeftTuple() {
         // constructor needed for serialisation
+        
+        // by default start and end timestamps are -INFINITY and +INFINITY respectively
+        this.startTimestamp = Long.MIN_VALUE;
+        this.endTimestamp = Long.MAX_VALUE;
     }
 
     // ------------------------------------------------------------
@@ -57,6 +65,7 @@
                      LeftTupleSink sink,
                      boolean leftTupleMemoryEnabled) {
         this.handle = factHandle;
+        adjustTimeRange();
 
         if ( leftTupleMemoryEnabled ) {
             LeftTuple currentFirst = handle.getLeftTuple();
@@ -76,6 +85,7 @@
         this.index = leftTuple.index;
         this.parent = leftTuple.parent;
         this.handle = leftTuple.handle;
+        adjustTimeRange();
 
         if ( leftTupleMemoryEnabled ) {
             this.leftParent = leftTuple;
@@ -85,7 +95,7 @@
             }
             this.leftParent.children = this;
         }
-        
+
         this.sink = sink;
     }
 
@@ -96,6 +106,7 @@
         this.handle = rightTuple.getFactHandle();
         this.index = leftTuple.index + 1;
         this.parent = leftTuple;
+        adjustTimeRange();
 
         if ( leftTupleMemoryEnabled ) {
             this.rightParent = rightTuple;
@@ -112,10 +123,22 @@
             }
             this.leftParent.children = this;
         }
-        
+
         this.sink = sink;
     }
 
+    private void adjustTimeRange() {
+        if( handle.isTemporal() ) {
+            if( parent != null ) {
+                this.startTimestamp = Math.max( parent.getStartTimestamp(), handle.getStartTimestamp() );
+                this.endTimestamp = Math.min( parent.getEndTimestamp(), handle.getEndTimestamp() );
+            } else {
+                this.startTimestamp = handle.getStartTimestamp();
+                this.endTimestamp = handle.getEndTimestamp();
+            }
+        }
+    }
+
     public void unlinkFromLeftParent() {
         LeftTuple previous = this.leftParentPrevious;
         LeftTuple next = this.leftParentNext;
@@ -125,7 +148,7 @@
             this.leftParentPrevious.leftParentNext = this.leftParentNext;
             this.leftParentNext.leftParentPrevious = this.leftParentPrevious;
         } else if ( next != null ) {
-            if ( this.leftParent != null ) { 
+            if ( this.leftParent != null ) {
                 //remove from first
                 this.leftParent.children = this.leftParentNext;
             } else {
@@ -137,7 +160,7 @@
             //remove from end
             this.leftParentPrevious.leftParentNext = null;
         } else {
-            if ( this.leftParent != null ) { 
+            if ( this.leftParent != null ) {
                 this.leftParent.children = null;
             } else {
                 this.handle.setLeftTuple( null );
@@ -184,7 +207,7 @@
         this.rightParentPrevious = null;
         this.rightParentNext = null;
     }
-    
+
     public int getIndex() {
         return this.index;
     }
@@ -306,7 +329,8 @@
         }
         return handles;
     }
-     public InternalFactHandle[] toFactHandles() {
+
+    public InternalFactHandle[] toFactHandles() {
         InternalFactHandle[] handles = new InternalFactHandle[this.index + 1];
         LeftTuple entry = this;
 
@@ -315,7 +339,7 @@
             entry = entry.parent;
         }
         return handles;
-    }    
+    }
 
     public void setBlocker(RightTuple blocker) {
         this.blocker = blocker;
@@ -345,9 +369,9 @@
         this.activation = activation;
     }
 
-//    public int hashCode() {        
-//        return this.hashCode;
-//    }
+    //    public int hashCode() {        
+    //        return this.hashCode;
+    //    }
 
     public String toString() {
         final StringBuilder buffer = new StringBuilder();
@@ -355,16 +379,16 @@
         LeftTuple entry = this;
         while ( entry != null ) {
             //buffer.append( entry.handle );
-            buffer.append(entry.handle).append("\n");
+            buffer.append( entry.handle ).append( "\n" );
             entry = entry.parent;
         }
         return buffer.toString();
     }
 
-    
     public int hashCode() {
         return this.handle.hashCode();
     }
+
     /**
      * We use this equals method to avoid the cast
      * @param tuple
@@ -384,15 +408,15 @@
         if ( this.handle != other.handle ) {
             return false;
         }
-        
-//        if ( this.sink.getId() != other.sink.getId() ) {
-//            return false;
-//        }
-//        
-//        if ( this.index != other.index ) {
-//            return false;
-//        }
 
+        //        if ( this.sink.getId() != other.sink.getId() ) {
+        //            return false;
+        //        }
+        //        
+        //        if ( this.index != other.index ) {
+        //            return false;
+        //        }
+
         if ( this.parent == null ) {
             return (other.parent == null);
         } else {
@@ -450,4 +474,17 @@
     public LeftTuple getParent() {
         return parent;
     }
+    
+    public long getStartTimestamp() {
+        return startTimestamp;
+    }
+
+    public long getEndTimestamp() {
+        return endTimestamp;
+    }
+    
+    public boolean isTemporal() {
+        return handle.isTemporal() || (parent != null && parent.isTemporal() );
+    }
+
 }

Modified: labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/reteoo/ObjectTypeConf.java
===================================================================
--- labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/reteoo/ObjectTypeConf.java	2009-11-09 14:22:35 UTC (rev 30071)
+++ labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/reteoo/ObjectTypeConf.java	2009-11-09 14:37:35 UTC (rev 30072)
@@ -37,4 +37,6 @@
     public boolean isDynamic();
     
     public TypeDeclaration getTypeDeclaration();    
+    
+    public TypeDeclaration.Role getRole();
 }
\ No newline at end of file

Modified: labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/reteoo/ReteooFactHandleFactory.java
===================================================================
--- labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/reteoo/ReteooFactHandleFactory.java	2009-11-09 14:22:35 UTC (rev 30071)
+++ labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/reteoo/ReteooFactHandleFactory.java	2009-11-09 14:37:35 UTC (rev 30072)
@@ -23,7 +23,9 @@
 import org.drools.common.EventFactHandle;
 import org.drools.common.InternalFactHandle;
 import org.drools.common.InternalWorkingMemory;
+import org.drools.common.TemporalFactHandle;
 import org.drools.rule.TypeDeclaration;
+import org.drools.rule.TypeDeclaration.Role;
 import org.drools.spi.FactHandleFactory;
 
 public class ReteooFactHandleFactory extends AbstractFactHandleFactory {
@@ -51,12 +53,12 @@
         if ( conf != null && conf.isEvent() ) {
             TypeDeclaration type = conf.getTypeDeclaration();
             long timestamp;
-            if ( type.getTimestampExtractor() != null ) {
-                if ( Date.class.isAssignableFrom( type.getTimestampExtractor().getExtractToClass() ) ) {
-                    timestamp = ((Date) type.getTimestampExtractor().getValue( workingMemory,
+            if ( type.getStartTimestampExtractor() != null ) {
+                if ( Date.class.isAssignableFrom( type.getStartTimestampExtractor().getExtractToClass() ) ) {
+                    timestamp = ((Date) type.getStartTimestampExtractor().getValue( workingMemory,
                                                                                object )).getTime();
                 } else {
-                    timestamp = type.getTimestampExtractor().getLongValue( workingMemory,
+                    timestamp = type.getStartTimestampExtractor().getLongValue( workingMemory,
                                                                            object );
                 }
             } else {
@@ -72,6 +74,14 @@
                                         recency,
                                         timestamp,
                                         duration );
+        } else if( conf != null && conf.getRole().equals( Role.TEMPORAL ) ) {
+            TypeDeclaration type = conf.getTypeDeclaration();
+            return new TemporalFactHandle( id,
+                                        object,
+                                        recency,
+                                        type.getStartTimestampExtractor(),
+                                        type.getEndTimestampExtractor(),
+                                        type.getDurationExtractor() );
         } else {
             return new DefaultFactHandle( id,
                                           object,

Modified: labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/rule/TypeDeclaration.java
===================================================================
--- labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/rule/TypeDeclaration.java	2009-11-09 14:22:35 UTC (rev 30071)
+++ labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/rule/TypeDeclaration.java	2009-11-09 14:37:35 UTC (rev 30072)
@@ -51,9 +51,10 @@
     public static final String ATTR_TIMESTAMP           = "timestamp";
     public static final String ATTR_EXPIRE              = "expires";
     public static final String ATTR_PROP_CHANGE_SUPPORT = "propertyChangeSupport";
+    public static final String ATTR_END_TIMESTAMP       = "endTimestamp";
 
     public static enum Role {
-        FACT, EVENT;
+        FACT, EVENT, TEMPORAL;
 
         public static final String ID = "role";
 
@@ -62,6 +63,8 @@
                 return EVENT;
             } else if ( "fact".equalsIgnoreCase( role ) ) {
                 return FACT;
+            } else if ( "temporal".equalsIgnoreCase( role ) ) {
+                return TEMPORAL;
             }
             return null;
         }
@@ -85,10 +88,12 @@
     private String               typeName;
     private Role                 role;
     private Format               format;
-    private String               timestampAttribute;
+    private String               startTimestampAttribute;
+    private String               endTimestampAttribute;
     private String               durationAttribute;
     private InternalReadAccessor durationExtractor;
-    private InternalReadAccessor timestampExtractor;
+    private InternalReadAccessor startTimestampExtractor;
+    private InternalReadAccessor endTimestampExtractor;
     private transient Class< ? > typeClass;
     private String               typeClassName;
     private FactTemplate         typeTemplate;
@@ -107,7 +112,7 @@
         this.role = Role.FACT;
         this.format = Format.POJO;
         this.durationAttribute = null;
-        this.timestampAttribute = null;
+        this.startTimestampAttribute = null;
         this.typeTemplate = null;
     }
 
@@ -117,12 +122,13 @@
         this.role = (Role) in.readObject();
         this.format = (Format) in.readObject();
         this.durationAttribute = (String) in.readObject();
-        this.timestampAttribute = (String) in.readObject();
+        this.startTimestampAttribute = (String) in.readObject();
         this.typeClassName = (String) in.readObject();
         this.typeTemplate = (FactTemplate) in.readObject();
         this.typeClassDef = (ClassDefinition) in.readObject();
         this.durationExtractor = (InternalReadAccessor) in.readObject();
-        this.timestampExtractor = (InternalReadAccessor) in.readObject();
+        this.startTimestampExtractor = (InternalReadAccessor) in.readObject();
+        this.endTimestampExtractor = (InternalReadAccessor) in.readObject();
         this.resource = (Resource) in.readObject();
         this.expirationOffset = in.readLong();
         this.dynamic = in.readBoolean();
@@ -133,12 +139,13 @@
         out.writeObject( role );
         out.writeObject( format );
         out.writeObject( durationAttribute );
-        out.writeObject( timestampAttribute );
+        out.writeObject( startTimestampAttribute );
         out.writeObject( typeClassName );
         out.writeObject( typeTemplate );
         out.writeObject( typeClassDef );
         out.writeObject( durationExtractor );
-        out.writeObject( timestampExtractor );
+        out.writeObject( startTimestampExtractor );
+        out.writeObject( endTimestampExtractor );
         out.writeObject( this.resource );
         out.writeLong( expirationOffset );
         out.writeBoolean( dynamic );
@@ -182,18 +189,32 @@
     /**
      * @return the timestampAttribute
      */
-    public String getTimestampAttribute() {
-        return timestampAttribute;
+    public String getStartTimestampAttribute() {
+        return startTimestampAttribute;
     }
 
     /**
      * @param timestampAttribute the timestampAttribute to set
      */
-    public void setTimestampAttribute(String timestampAttribute) {
-        this.timestampAttribute = timestampAttribute;
+    public void setStartTimestampAttribute(String timestampAttribute) {
+        this.startTimestampAttribute = timestampAttribute;
     }
 
     /**
+     * @return the timestampAttribute
+     */
+    public String getEndTimestampAttribute() {
+        return endTimestampAttribute;
+    }
+
+    /**
+     * @param timestampAttribute the timestampAttribute to set
+     */
+    public void setEndTimestampAttribute(String timestampAttribute) {
+        this.endTimestampAttribute = timestampAttribute;
+    }
+
+    /**
      * @return the durationAttribute
      */
     public String getDurationAttribute() {
@@ -263,11 +284,12 @@
         } else if ( obj instanceof TypeDeclaration ) {
             TypeDeclaration that = (TypeDeclaration) obj;
             return isObjectEqual( typeName,
-                                  that.typeName ) && role == that.role && format == that.format && isObjectEqual( timestampAttribute,
-                                                                                                                  that.timestampAttribute ) && isObjectEqual( durationAttribute,
-                                                                                                                                                              that.durationAttribute ) && typeClass == that.typeClass
-                   && isObjectEqual( typeTemplate,
-                                     that.typeTemplate );
+                                  that.typeName ) && role == that.role && format == that.format && isObjectEqual( startTimestampAttribute,
+                                                                                                                  that.startTimestampAttribute ) && isObjectEqual( endTimestampAttribute,
+                                                                                                                                                                   that.endTimestampAttribute ) && isObjectEqual( durationAttribute,
+                                                                                                                                                                                                                  that.durationAttribute )
+                   && typeClass == that.typeClass && isObjectEqual( typeTemplate,
+                                                                    that.typeTemplate );
         }
         return false;
     }
@@ -299,12 +321,12 @@
         this.typeClassDef = typeClassDef;
     }
 
-    public InternalReadAccessor getTimestampExtractor() {
-        return timestampExtractor;
+    public InternalReadAccessor getStartTimestampExtractor() {
+        return startTimestampExtractor;
     }
 
-    public void setTimestampExtractor(InternalReadAccessor timestampExtractor) {
-        this.timestampExtractor = timestampExtractor;
+    public void setStartTimestampExtractor(InternalReadAccessor timestampExtractor) {
+        this.startTimestampExtractor = timestampExtractor;
     }
 
     public class DurationAccessorSetter
@@ -318,17 +340,28 @@
         }
     }
 
-    public class TimestampAccessorSetter
+    public class StartTimestampAccessorSetter
         implements
         AcceptsReadAccessor,
         Serializable {
         private static final long serialVersionUID = 8656678871125722903L;
 
         public void setReadAccessor(InternalReadAccessor readAccessor) {
-            setTimestampExtractor( readAccessor );
+            setStartTimestampExtractor( readAccessor );
         }
     }
 
+    public class EndTimestampAccessorSetter
+        implements
+        AcceptsReadAccessor,
+        Serializable {
+        private static final long serialVersionUID = 8656678871125722903L;
+
+        public void setReadAccessor(InternalReadAccessor readAccessor) {
+            setEndTimestampExtractor( readAccessor );
+        }
+    }
+
     public Resource getResource() {
         return resource;
     }
@@ -372,4 +405,12 @@
         this.dynamic = dynamic;
     }
 
+    public InternalReadAccessor getEndTimestampExtractor() {
+        return this.endTimestampExtractor;
+    }
+
+    public void setEndTimestampExtractor(InternalReadAccessor endTimestampExtractor) {
+        this.endTimestampExtractor = endTimestampExtractor;
+    }
+
 }

Modified: labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/spi/Tuple.java
===================================================================
--- labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/spi/Tuple.java	2009-11-09 14:22:35 UTC (rev 30071)
+++ labs/jbossrules/branches/effective_dated/drools-core/src/main/java/org/drools/spi/Tuple.java	2009-11-09 14:37:35 UTC (rev 30072)
@@ -65,4 +65,9 @@
      */
     int size();
 
+    public long getStartTimestamp();
+
+    public long getEndTimestamp();
+    
+    public boolean isTemporal();
 }
\ No newline at end of file

Modified: labs/jbossrules/branches/effective_dated/drools-core/src/test/java/org/drools/util/BaseQueueable.java
===================================================================
--- labs/jbossrules/branches/effective_dated/drools-core/src/test/java/org/drools/util/BaseQueueable.java	2009-11-09 14:22:35 UTC (rev 30071)
+++ labs/jbossrules/branches/effective_dated/drools-core/src/test/java/org/drools/util/BaseQueueable.java	2009-11-09 14:37:35 UTC (rev 30072)
@@ -135,4 +135,19 @@
         // TODO Auto-generated method stub
         return null;
     }
+
+    public long getEndTimestamp() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    public long getStartTimestamp() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    public boolean isTemporal() {
+        // TODO Auto-generated method stub
+        return false;
+    }
 }
\ No newline at end of file



More information about the jboss-svn-commits mailing list