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

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Fri Dec 19 15:51:24 EST 2008


Author: tirelli
Date: 2008-12-19 15:51:24 -0500 (Fri, 19 Dec 2008)
New Revision: 24444

Added:
   labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_CEP_CoincidesOperatorDates.drl
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/evaluators/BeforeEvaluatorDefinition.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/CoincidesEvaluatorDefinition.java
Log:
JBRULES-1894: adding support to arbitrary date time for 'coincides' operator

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-12-19 20:22:33 UTC (rev 24443)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/CepEspTest.java	2008-12-19 20:51:24 UTC (rev 24444)
@@ -602,6 +602,57 @@
                       results.get( 3 ) );
     }
 
+    public void testCoincidesOnArbitraryDates() throws Exception {
+        // read in the source
+        final Reader reader = new InputStreamReader( getClass().getResourceAsStream( "test_CEP_CoincidesOperatorDates.drl" ) );
+        final RuleBaseConfiguration rbconf = new RuleBaseConfiguration();
+        final RuleBase ruleBase = loadRuleBase( reader,
+                                                rbconf );
+
+        SessionConfiguration conf = new SessionConfiguration();
+        conf.setClockType( ClockType.PSEUDO_CLOCK );
+        StatefulSession wm = ruleBase.newStatefulSession( conf );
+
+        final List<?> results = new ArrayList<Object>();
+
+        wm.setGlobal( "results",
+                      results );
+
+        StockTick tick1 = new StockTick( 1,
+                                         "DROO",
+                                         50,
+                                         100000, // arbitrary timestamp
+                                         3 );
+        StockTick tick2 = new StockTick( 2,
+                                         "ACME",
+                                         10,
+                                         100050, // 50 milliseconds after DROO
+                                         3 );
+
+        InternalFactHandle handle1 = (InternalFactHandle) wm.insert( tick1 );
+        InternalFactHandle handle2 = (InternalFactHandle) wm.insert( tick2 );
+
+        assertNotNull( handle1 );
+        assertNotNull( handle2 );
+
+        assertTrue( handle1.isEvent() );
+        assertTrue( handle2.isEvent() );
+
+        //        wm  = SerializationHelper.serializeObject(wm);
+        wm.fireAllRules();
+
+        assertEquals( 4,
+                      results.size() );
+        assertEquals( tick1,
+                      results.get( 0 ) );
+        assertEquals( tick2,
+                      results.get( 1 ) );
+        assertEquals( tick1,
+                      results.get( 2 ) );
+        assertEquals( tick2,
+                      results.get( 3 ) );
+    }
+
     // @FIXME: we need to decide on the semantics of expiration
     public void FIXME_testSimpleTimeWindow() throws Exception {
         // read in the source

Added: labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_CEP_CoincidesOperatorDates.drl
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_CEP_CoincidesOperatorDates.drl	                        (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_CEP_CoincidesOperatorDates.drl	2008-12-19 20:51:24 UTC (rev 24444)
@@ -0,0 +1,48 @@
+package org.drools;
+
+import org.drools.StockTick;
+
+global java.util.List results;
+
+declare StockTick
+    @role( event )
+    @timestamp( time )
+end
+
+rule "after operator on date"
+    salience 10
+when
+    $a : StockTick( company == "DROO" )
+    $b : StockTick( company == "ACME", dateTimestamp coincides[1s] $a.dateTimestamp )
+then
+    results.add( $a );
+end
+
+rule "after operator on long"
+    salience 5
+when
+    $a : StockTick( company == "DROO" )
+    $b : StockTick( company == "ACME", time coincides[1s] $a.time )
+then
+    results.add( $b );
+end
+
+
+rule "after operator on mixed event and date"
+    salience 3
+when
+    $a : StockTick( company == "DROO" )
+    $b : StockTick( company == "ACME", this coincides[1s] $a.time )
+then
+    results.add( $a );
+end
+
+rule "after operator on mixed date and event"
+    salience 0
+when
+    $a : StockTick( company == "DROO" )
+    $b : StockTick( company == "ACME", time coincides[1s] $a )
+then
+    results.add( $b );
+end
+

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-12-19 20:22:33 UTC (rev 24443)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/BeforeEvaluatorDefinition.java	2008-12-19 20:51:24 UTC (rev 24444)
@@ -28,8 +28,6 @@
 import org.drools.RuntimeDroolsException;
 import org.drools.base.BaseEvaluator;
 import org.drools.base.ValueType;
-import org.drools.base.evaluators.AfterEvaluatorDefinition.AfterEvaluator;
-import org.drools.base.evaluators.EvaluatorDefinition.Target;
 import org.drools.common.EventFactHandle;
 import org.drools.common.InternalFactHandle;
 import org.drools.common.InternalWorkingMemory;
@@ -159,7 +157,7 @@
         if ( this.cache == Collections.EMPTY_MAP ) {
             this.cache = new HashMap<String, BeforeEvaluator>();
         }
-        String key = isNegated + ":" + parameterText;
+        String key = left+":"+right+":"+isNegated + ":" + parameterText;
         BeforeEvaluator eval = this.cache.get( key );
         if ( eval == null ) {
             Long[] params = parser.parse( parameterText );

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-12-19 20:22:33 UTC (rev 24443)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/evaluators/CoincidesEvaluatorDefinition.java	2008-12-19 20:51:24 UTC (rev 24444)
@@ -21,6 +21,7 @@
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
 import java.util.Collections;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -30,6 +31,7 @@
 import org.drools.common.EventFactHandle;
 import org.drools.common.InternalFactHandle;
 import org.drools.common.InternalWorkingMemory;
+import org.drools.rule.VariableRestriction.LongVariableContextEntry;
 import org.drools.rule.VariableRestriction.ObjectVariableContextEntry;
 import org.drools.rule.VariableRestriction.VariableContextEntry;
 import org.drools.spi.Evaluator;
@@ -126,16 +128,16 @@
     public Evaluator getEvaluator(final ValueType type,
                                   final String operatorId,
                                   final boolean isNegated,
-                                  final String parameterText ) {
+                                  final String parameterText) {
         return this.getEvaluator( type,
                                   operatorId,
                                   isNegated,
                                   parameterText,
                                   Target.HANDLE,
                                   Target.HANDLE );
-        
+
     }
-    
+
     /**
      * @inheritDoc
      */
@@ -144,18 +146,20 @@
                                   final boolean isNegated,
                                   final String parameterText,
                                   final Target left,
-                                  final Target right ) {
+                                  final Target right) {
         if ( this.cache == Collections.EMPTY_MAP ) {
             this.cache = new HashMap<String, CoincidesEvaluator>();
         }
-        String key = isNegated + ":" + parameterText;
+        String key = left + ":" + right + ":" + isNegated + ":" + parameterText;
         CoincidesEvaluator eval = this.cache.get( key );
         if ( eval == null ) {
             Long[] params = parser.parse( parameterText );
             eval = new CoincidesEvaluator( type,
                                            isNegated,
                                            params,
-                                           parameterText );
+                                           parameterText,
+                                           left == Target.FACT,
+                                           right == Target.FACT );
             this.cache.put( key,
                             eval );
         }
@@ -201,6 +205,8 @@
         private long              startDev;
         private long              endDev;
         private String            paramText;
+        private boolean           unwrapLeft;
+        private boolean           unwrapRight;
 
         public CoincidesEvaluator() {
         }
@@ -208,10 +214,14 @@
         public CoincidesEvaluator(final ValueType type,
                                   final boolean isNegated,
                                   final Long[] parameters,
-                                  final String paramText) {
+                                  final String paramText,
+                                  final boolean unwrapLeft,
+                                  final boolean unwrapRight) {
             super( type,
                    isNegated ? COINCIDES_NOT : COINCIDES );
             this.paramText = paramText;
+            this.unwrapLeft = unwrapLeft;
+            this.unwrapRight = unwrapRight;
             this.setParameters( parameters );
         }
 
@@ -220,6 +230,8 @@
             super.readExternal( in );
             startDev = in.readLong();
             endDev = in.readLong();
+            unwrapLeft = in.readBoolean();
+            unwrapRight = in.readBoolean();
             paramText = (String) in.readObject();
         }
 
@@ -227,15 +239,22 @@
             super.writeExternal( out );
             out.writeLong( startDev );
             out.writeLong( endDev );
+            out.writeBoolean( unwrapLeft );
+            out.writeBoolean( unwrapRight );
             out.writeObject( paramText );
         }
 
         @Override
         public Object prepareLeftObject(InternalFactHandle handle) {
-            return handle;
+            return unwrapLeft ? handle.getObject() : handle;
         }
 
         @Override
+        public Object prepareRightObject(InternalFactHandle handle) {
+            return unwrapRight ? handle.getObject() : handle;
+        }
+
+        @Override
         public boolean isTemporal() {
             return true;
         }
@@ -263,8 +282,29 @@
             if ( context.rightNull ) {
                 return false;
             }
-            long distStart = Math.abs( ((EventFactHandle) ((ObjectVariableContextEntry) context).right).getStartTimestamp() - ((EventFactHandle) left).getStartTimestamp() );
-            long distEnd = Math.abs( ((EventFactHandle) ((ObjectVariableContextEntry) context).right).getEndTimestamp() - ((EventFactHandle) left).getEndTimestamp() );
+            long rightStartTS, rightEndTS;
+            long leftStartTS, leftEndTS;
+            if ( this.unwrapRight ) {
+                if ( context instanceof ObjectVariableContextEntry ) {
+                    if ( ((ObjectVariableContextEntry) context).right instanceof Date ) {
+                        rightStartTS = ((Date) ((ObjectVariableContextEntry) context).right).getTime();
+                    } else {
+                        rightStartTS = ((Number) ((ObjectVariableContextEntry) context).right).longValue();
+                    }
+                } else {
+                    rightStartTS = ((LongVariableContextEntry) context).right;
+                }
+                rightEndTS = rightStartTS;
+            } else {
+                rightStartTS = ((EventFactHandle) ((ObjectVariableContextEntry) context).right).getStartTimestamp();
+                rightEndTS = ((EventFactHandle) ((ObjectVariableContextEntry) context).right).getEndTimestamp();
+            }
+            leftStartTS = this.unwrapLeft ? context.declaration.getExtractor().getLongValue( workingMemory,
+                                                                                             left ) : ((EventFactHandle) left).getStartTimestamp();
+            leftEndTS = this.unwrapLeft ? rightStartTS : ((EventFactHandle) left).getEndTimestamp();
+
+            long distStart = Math.abs( rightStartTS - leftStartTS );
+            long distEnd = Math.abs( rightEndTS - leftEndTS );
             return this.getOperator().isNegated() ^ (distStart <= this.startDev && distEnd <= this.endDev);
         }
 
@@ -275,8 +315,32 @@
                                                 right ) ) {
                 return false;
             }
-            long distStart = Math.abs( ((EventFactHandle) right).getStartTimestamp() - ((EventFactHandle) ((ObjectVariableContextEntry) context).left).getStartTimestamp() );
-            long distEnd = Math.abs( ((EventFactHandle) right).getEndTimestamp() - ((EventFactHandle) ((ObjectVariableContextEntry) context).left).getEndTimestamp() );
+
+            long rightStartTS, rightEndTS;
+            long leftStartTS, leftEndTS;
+
+            rightStartTS = this.unwrapRight ? context.extractor.getLongValue( workingMemory,
+                                                                              right ) : ((EventFactHandle) right).getStartTimestamp();
+            rightEndTS = this.unwrapRight ? rightStartTS : ((EventFactHandle) right).getEndTimestamp();
+
+            if ( this.unwrapLeft ) {
+                if ( context instanceof ObjectVariableContextEntry ) {
+                    if ( ((ObjectVariableContextEntry) context).left instanceof Date ) {
+                        leftStartTS = ((Date) ((ObjectVariableContextEntry) context).left).getTime();
+                    } else {
+                        leftStartTS = ((Number) ((ObjectVariableContextEntry) context).left).longValue();
+                    }
+                } else {
+                    leftStartTS = ((LongVariableContextEntry) context).left;
+                }
+                leftEndTS = leftStartTS;
+            } else {
+                leftStartTS = ((EventFactHandle) ((ObjectVariableContextEntry) context).left).getStartTimestamp();
+                leftEndTS = ((EventFactHandle) ((ObjectVariableContextEntry) context).left).getEndTimestamp();
+            }
+
+            long distStart = Math.abs( rightStartTS - leftStartTS );
+            long distEnd = Math.abs( rightEndTS - leftEndTS );
             return this.getOperator().isNegated() ^ (distStart <= this.startDev && distEnd <= this.endDev);
         }
 
@@ -289,8 +353,19 @@
                                          object1 ) ) {
                 return false;
             }
-            long distStart = Math.abs( ((EventFactHandle) object1).getStartTimestamp() - ((EventFactHandle) object2).getStartTimestamp() );
-            long distEnd = Math.abs( ((EventFactHandle) object1).getEndTimestamp() - ((EventFactHandle) object2).getEndTimestamp() );
+            long rightStartTS, rightEndTS;
+            long leftStartTS, leftEndTS;
+
+            rightStartTS = this.unwrapRight ? extractor1.getLongValue( workingMemory,
+                                                                       object1 ) : ((EventFactHandle) object1).getStartTimestamp();
+            rightEndTS = this.unwrapRight ? rightStartTS : ((EventFactHandle) object1).getEndTimestamp();
+
+            leftStartTS = this.unwrapLeft ? extractor2.getLongValue( workingMemory,
+                                                                     object2 ) : ((EventFactHandle) object2).getStartTimestamp();
+            leftEndTS = this.unwrapLeft ? leftStartTS : ((EventFactHandle) object2).getEndTimestamp();
+
+            long distStart = Math.abs( rightStartTS - leftStartTS );
+            long distEnd = Math.abs( rightEndTS - leftEndTS );
             return this.getOperator().isNegated() ^ (distStart <= this.startDev && distEnd <= this.endDev);
         }
 
@@ -334,8 +409,8 @@
                 this.endDev = 0;
                 return;
             } else {
-                for( Long param : parameters ) {
-                    if( param.longValue() < 0 ) {
+                for ( Long param : parameters ) {
+                    if ( param.longValue() < 0 ) {
                         throw new RuntimeDroolsException( "[Coincides Evaluator]: negative values not allowed for temporal distance thresholds: '" + paramText + "'" );
                     }
                 }




More information about the jboss-svn-commits mailing list