[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