[jboss-svn-commits] JBL Code SVN: r29630 - in labs/jbossrules/trunk: drools-compiler/src/test/java/org/drools/integrationtests and 5 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Thu Oct 15 19:14:17 EDT 2009
Author: tirelli
Date: 2009-10-15 19:14:17 -0400 (Thu, 15 Oct 2009)
New Revision: 29630
Added:
labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_ForallSlidingWindow.drl
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ForallNotNode.java
Modified:
labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/PatternBuilder.java
labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/FirstOrderLogicTest.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/impl/InputMarshaller.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/impl/OutputMarshaller.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/NodeTypeEnums.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/NotNode.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/ForallBuilder.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/GroupElementBuilder.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/GroupElement.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/GroupElementFactory.java
Log:
JBRULES-2288: fixing FORALL behavior
Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/PatternBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/PatternBuilder.java 2009-10-15 20:47:19 UTC (rev 29629)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/PatternBuilder.java 2009-10-15 23:14:17 UTC (rev 29630)
@@ -210,14 +210,22 @@
}
for ( BehaviorDescr behaviorDescr : patternDescr.getBehaviors() ) {
- if ( Behavior.BehaviorType.TIME_WINDOW.matches( behaviorDescr.getType() ) ) {
- SlidingWindowDescr swd = (SlidingWindowDescr) behaviorDescr;
- SlidingTimeWindow window = new SlidingTimeWindow( swd.getLength() );
- pattern.addBehavior( window );
- } else if ( Behavior.BehaviorType.LENGTH_WINDOW.matches( behaviorDescr.getType() ) ) {
- SlidingWindowDescr swd = (SlidingWindowDescr) behaviorDescr;
- SlidingLengthWindow window = new SlidingLengthWindow( (int) swd.getLength() );
- pattern.addBehavior( window );
+ if( pattern.getObjectType().isEvent() ) {
+ if ( Behavior.BehaviorType.TIME_WINDOW.matches( behaviorDescr.getType() ) ) {
+ SlidingWindowDescr swd = (SlidingWindowDescr) behaviorDescr;
+ SlidingTimeWindow window = new SlidingTimeWindow( swd.getLength() );
+ pattern.addBehavior( window );
+ } else if ( Behavior.BehaviorType.LENGTH_WINDOW.matches( behaviorDescr.getType() ) ) {
+ SlidingWindowDescr swd = (SlidingWindowDescr) behaviorDescr;
+ SlidingLengthWindow window = new SlidingLengthWindow( (int) swd.getLength() );
+ pattern.addBehavior( window );
+ }
+ } else {
+ // Some behaviors can only be assigned to patterns declared as events
+ context.getErrors().add( new DescrBuildError( context.getParentDescr(),
+ patternDescr,
+ null,
+ "A Sliding Window behavior can only be assigned to patterns declared with @role( event ). The pattern '" + pattern.getObjectType() + "' in the rule '" + context.getRule().getName() + "' is not declared as an Event." ) );
}
}
Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/FirstOrderLogicTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/FirstOrderLogicTest.java 2009-10-15 20:47:19 UTC (rev 29629)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/FirstOrderLogicTest.java 2009-10-15 23:14:17 UTC (rev 29630)
@@ -6,6 +6,7 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import java.util.concurrent.TimeUnit;
import junit.framework.Assert;
import junit.framework.TestCase;
@@ -13,8 +14,10 @@
import org.drools.Address;
import org.drools.Cheese;
import org.drools.Cheesery;
+import org.drools.ClockType;
import org.drools.FactHandle;
import org.drools.KnowledgeBase;
+import org.drools.KnowledgeBaseConfiguration;
import org.drools.KnowledgeBaseFactory;
import org.drools.Order;
import org.drools.OrderItem;
@@ -26,6 +29,7 @@
import org.drools.SpecialString;
import org.drools.State;
import org.drools.StatefulSession;
+import org.drools.StockTick;
import org.drools.WorkingMemory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderFactory;
@@ -33,11 +37,15 @@
import org.drools.compiler.DrlParser;
import org.drools.compiler.DroolsParserException;
import org.drools.compiler.PackageBuilder;
+import org.drools.integrationtests.eventgenerator.PseudoSessionClock;
import org.drools.io.ResourceFactory;
import org.drools.lang.descr.PackageDescr;
import org.drools.rule.Package;
import org.drools.rule.Rule;
+import org.drools.runtime.KnowledgeSessionConfiguration;
import org.drools.runtime.StatefulKnowledgeSession;
+import org.drools.runtime.conf.ClockTypeOption;
+import org.drools.time.SessionPseudoClock;
public class FirstOrderLogicTest extends TestCase {
protected RuleBase getRuleBase() throws Exception {
@@ -76,7 +84,7 @@
150 ) );
wm = SerializationHelper.getSerialisedStatefulSession( wm );
results = (List) wm.getGlobal( "results" );
-
+
wm.insert( new Cheese( "provolone",
20 ) );
wm.insert( new Person( "Bob",
@@ -90,7 +98,7 @@
wm = SerializationHelper.getSerialisedStatefulSession( wm );
results = (List) wm.getGlobal( "results" );
-
+
Assert.assertEquals( 1,
results.size() );
Assert.assertEquals( 3,
@@ -106,7 +114,7 @@
RuleBase ruleBase = getRuleBase();
ruleBase.addPackage( pkg );
- ruleBase = SerializationHelper.serializeObject(ruleBase);
+ ruleBase = SerializationHelper.serializeObject( ruleBase );
StatefulSession workingMemory = ruleBase.newStatefulSession();
List results = new ArrayList();
@@ -115,12 +123,12 @@
workingMemory = SerializationHelper.getSerialisedStatefulSession( workingMemory );
results = (List) workingMemory.getGlobal( "results" );
-
+
workingMemory.insert( new Cheese( "stilton",
10 ) );
workingMemory = SerializationHelper.getSerialisedStatefulSession( workingMemory );
results = (List) workingMemory.getGlobal( "results" );
-
+
workingMemory.insert( new Cheese( "brie",
15 ) );
@@ -128,7 +136,7 @@
workingMemory = SerializationHelper.getSerialisedStatefulSession( workingMemory );
results = (List) workingMemory.getGlobal( "results" );
-
+
assertEquals( 1,
results.size() );
@@ -178,7 +186,7 @@
cheese[index].setPrice( 9 );
wm.update( cheeseHandles[index],
cheese[index] );
-
+
wm.fireAllRules();
Assert.assertEquals( ++fireCount,
@@ -222,14 +230,14 @@
10 ) );
wm = SerializationHelper.getSerialisedStatefulSession( wm );
results = (List) wm.getGlobal( "results" );
-
+
wm.fireAllRules();
Assert.assertEquals( 1,
results.size() );
Assert.assertEquals( 1,
((Collection) results.get( 0 )).size() );
-
+
wm.insert( new Cheese( "stilton",
7 ) );
wm.insert( new Cheese( "stilton",
@@ -238,7 +246,7 @@
wm = SerializationHelper.getSerialisedStatefulSession( wm );
results = (List) wm.getGlobal( "results" );
-
+
Assert.assertEquals( 1,
results.size() );
Assert.assertEquals( 1,
@@ -254,7 +262,7 @@
RuleBase ruleBase = getRuleBase();
ruleBase.addPackage( pkg );
- ruleBase = SerializationHelper.serializeObject(ruleBase);
+ ruleBase = SerializationHelper.serializeObject( ruleBase );
final WorkingMemory workingMemory = ruleBase.newStatefulSession();
final List list = new ArrayList();
@@ -321,7 +329,7 @@
builder.getErrors().getErrors().length );
RuleBase ruleBase = getRuleBase();
ruleBase.addPackage( pkg );
- ruleBase = SerializationHelper.serializeObject(ruleBase);
+ ruleBase = SerializationHelper.serializeObject( ruleBase );
final WorkingMemory workingMemory = ruleBase.newStatefulSession();
final List list = new ArrayList();
@@ -359,7 +367,7 @@
RuleBase ruleBase = getRuleBase();
ruleBase.addPackage( pkg );
- ruleBase = SerializationHelper.serializeObject(ruleBase);
+ ruleBase = SerializationHelper.serializeObject( ruleBase );
final WorkingMemory workingMemory = ruleBase.newStatefulSession();
final List list = new ArrayList();
@@ -398,7 +406,7 @@
RuleBase ruleBase = getRuleBase();
ruleBase.addPackage( pkg );
- ruleBase = SerializationHelper.serializeObject(ruleBase);
+ ruleBase = SerializationHelper.serializeObject( ruleBase );
final WorkingMemory workingMemory = ruleBase.newStatefulSession();
final List list = new ArrayList();
@@ -442,7 +450,7 @@
RuleBase ruleBase = getRuleBase();
ruleBase.addPackage( pkg );
- ruleBase = SerializationHelper.serializeObject(ruleBase);
+ ruleBase = SerializationHelper.serializeObject( ruleBase );
final WorkingMemory workingMemory = ruleBase.newStatefulSession();
final List list = new ArrayList();
@@ -479,7 +487,7 @@
config.setRemoveIdentities( true );
RuleBase ruleBase = getRuleBase( config );
ruleBase.addPackage( pkg );
- ruleBase = SerializationHelper.serializeObject(ruleBase);
+ ruleBase = SerializationHelper.serializeObject( ruleBase );
final WorkingMemory workingMemory = ruleBase.newStatefulSession();
final List list = new ArrayList();
@@ -529,7 +537,7 @@
RuleBase ruleBase = getRuleBase();
ruleBase.addPackage( pkg );
- ruleBase = SerializationHelper.serializeObject(ruleBase);
+ ruleBase = SerializationHelper.serializeObject( ruleBase );
final WorkingMemory workingMemory = ruleBase.newStatefulSession();
final List results = new ArrayList();
@@ -646,7 +654,7 @@
// add the package to a rulebase
RuleBase ruleBase = getRuleBase();
ruleBase.addPackage( pkg );
- ruleBase = SerializationHelper.serializeObject(ruleBase);
+ ruleBase = SerializationHelper.serializeObject( ruleBase );
// load up the rulebase
return ruleBase;
}
@@ -658,7 +666,7 @@
RuleBase ruleBase = getRuleBase();
ruleBase.addPackage( pkg );
- ruleBase = SerializationHelper.serializeObject(ruleBase);
+ ruleBase = SerializationHelper.serializeObject( ruleBase );
final WorkingMemory workingMemory = ruleBase.newStatefulSession();
final List list = new ArrayList();
@@ -703,13 +711,10 @@
assertEquals( 2,
list.size() );
- // TODO: in the future, we need to fix the following test case
- // // no cheese anymore, so should not fire again
- // workingMemory.retract( stilton2 );
- // workingMemory.fireAllRules();
- // assertEquals( 2,
- // list.size() );
- //
+ workingMemory.retract( stilton2 );
+ workingMemory.fireAllRules();
+ assertEquals( 2,
+ list.size() );
}
@@ -757,7 +762,7 @@
RuleBase ruleBase = RuleBaseFactory.newRuleBase();
ruleBase.addPackage( builder.getPackage() );
- ruleBase = SerializationHelper.serializeObject(ruleBase);
+ ruleBase = SerializationHelper.serializeObject( ruleBase );
StatefulSession session = ruleBase.newStatefulSession();
List list1 = new ArrayList();
@@ -822,7 +827,7 @@
RuleBase ruleBase = getRuleBase();
ruleBase.addPackage( pkg );
- ruleBase = SerializationHelper.serializeObject(ruleBase);
+ ruleBase = SerializationHelper.serializeObject( ruleBase );
final WorkingMemory workingMemory = ruleBase.newStatefulSession();
final List list = new ArrayList();
@@ -861,7 +866,7 @@
RuleBase ruleBase = getRuleBase();
ruleBase.addPackage( pkg );
- ruleBase = SerializationHelper.serializeObject(ruleBase);
+ ruleBase = SerializationHelper.serializeObject( ruleBase );
final WorkingMemory workingMemory = ruleBase.newStatefulSession();
final List list = new ArrayList();
@@ -894,7 +899,7 @@
RuleBase ruleBase = getRuleBase();
ruleBase.addPackage( pkg );
- ruleBase = SerializationHelper.serializeObject(ruleBase);
+ ruleBase = SerializationHelper.serializeObject( ruleBase );
final WorkingMemory workingMemory = ruleBase.newStatefulSession();
final List list = new ArrayList();
@@ -952,7 +957,7 @@
RuleBase ruleBase = getRuleBase();
ruleBase.addPackage( pkg );
- ruleBase = SerializationHelper.serializeObject(ruleBase);
+ ruleBase = SerializationHelper.serializeObject( ruleBase );
final WorkingMemory workingMemory = ruleBase.newStatefulSession();
final List list = new ArrayList();
@@ -1010,24 +1015,31 @@
RuleBase ruleBase = getRuleBase();
ruleBase.addPackage( pkg );
- ruleBase = SerializationHelper.serializeObject(ruleBase);
+ ruleBase = SerializationHelper.serializeObject( ruleBase );
final WorkingMemory workingMemory = ruleBase.newStatefulSession();
final List list = new ArrayList();
workingMemory.setGlobal( "results",
list );
-
- workingMemory.insert( new Cheese( "stilton", 10 ) );
- workingMemory.insert( new Cheese( "brie", 10 ) );
- workingMemory.insert( new Cheese( "brie", 10 ) );
- workingMemory.insert( new Order( 1, "bob" ) );
- workingMemory.insert( new Person( "bob", "stilton", 10 ) );
- workingMemory.insert( new Person( "mark", "stilton" ) );
-
+
+ workingMemory.insert( new Cheese( "stilton",
+ 10 ) );
+ workingMemory.insert( new Cheese( "brie",
+ 10 ) );
+ workingMemory.insert( new Cheese( "brie",
+ 10 ) );
+ workingMemory.insert( new Order( 1,
+ "bob" ) );
+ workingMemory.insert( new Person( "bob",
+ "stilton",
+ 10 ) );
+ workingMemory.insert( new Person( "mark",
+ "stilton" ) );
+
workingMemory.fireAllRules();
-
+
//assertEquals( 1, list.size() );
-
+
}
public void testCollectResultBetaConstraint() throws Exception {
@@ -1045,22 +1057,22 @@
wm.insert( new Double( 10 ) );
wm.insert( new Integer( 2 ) );
-// ruleBase = SerializationHelper.serializeObject( ruleBase );
-// wm = serializeWorkingMemory( ruleBase,
-// wm );
-// results = (List) wm.getGlobal( "results" );
+ // ruleBase = SerializationHelper.serializeObject( ruleBase );
+ // wm = serializeWorkingMemory( ruleBase,
+ // wm );
+ // results = (List) wm.getGlobal( "results" );
wm.fireAllRules();
Assert.assertEquals( 0,
results.size() );
-
- wm.insert( new Double(15) );
+
+ wm.insert( new Double( 15 ) );
wm.fireAllRules();
-
+
Assert.assertEquals( 2,
results.size() );
-
+
Assert.assertEquals( "collect",
results.get( 0 ) );
Assert.assertEquals( "accumulate",
@@ -1071,12 +1083,12 @@
KnowledgeBuilder builder = KnowledgeBuilderFactory.newKnowledgeBuilder();
builder.add( ResourceFactory.newInputStreamResource( getClass().getResourceAsStream( "test_FromWithOr.drl" ) ),
ResourceType.DRL );
-
- if( builder.hasErrors() ) {
+
+ if ( builder.hasErrors() ) {
System.out.println( builder.getErrors() );
}
assertFalse( builder.hasErrors() );
-
+
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages( builder.getKnowledgePackages() );
@@ -1084,27 +1096,128 @@
final List<Address> results = new ArrayList<Address>();
session.setGlobal( "results",
- results );
+ results );
Address a1 = new Address();
- a1.setZipCode("12345");
+ a1.setZipCode( "12345" );
Address a2 = new Address();
- a2.setZipCode("54321");
+ a2.setZipCode( "54321" );
Address a3 = new Address();
- a3.setZipCode("99999");
-
+ a3.setZipCode( "99999" );
+
Person p = new Person();
- p.addAddress(a1);
- p.addAddress(a2);
- p.addAddress(a3);
-
- session.insert( p);
- session.fireAllRules();
-
- assertEquals( 2, results.size() );
+ p.addAddress( a1 );
+ p.addAddress( a2 );
+ p.addAddress( a3 );
+
+ session.insert( p );
+ session.fireAllRules();
+
+ assertEquals( 2,
+ results.size() );
assertTrue( results.contains( a1 ) );
assertTrue( results.contains( a2 ) );
}
+ public void testForallWithSlidingWindow() throws Exception {
+ final KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
+ kbuilder.add( ResourceFactory.newInputStreamResource( getClass().getResourceAsStream( "test_ForallSlidingWindow.drl" ) ),
+ ResourceType.DRL );
+ assertFalse( kbuilder.getErrors().toString(),
+ kbuilder.hasErrors() );
+
+ final KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
+ kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );
+
+ final KnowledgeSessionConfiguration conf = KnowledgeBaseFactory.newKnowledgeSessionConfiguration();
+ conf.setOption( ClockTypeOption.get( ClockType.PSEUDO_CLOCK.getId() ) );
+ final StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession( conf,
+ null );
+ final SessionPseudoClock clock = ksession.getSessionClock();
+ List<String> results = new ArrayList<String>();
+ ksession.setGlobal( "results",
+ results );
+
+ // advance time... no events, so forall should fire
+ clock.advanceTime( 60,
+ TimeUnit.SECONDS );
+ ksession.fireAllRules();
+ assertEquals( 1,
+ results.size() );
+
+ int seq = 1;
+ // advance time... there are matching events now, but forall still not fire
+ ksession.insert( new StockTick( seq++,
+ "RHT",
+ 10,
+ clock.getCurrentTime() ) ); // 60
+ clock.advanceTime( 5,
+ TimeUnit.SECONDS );
+ ksession.fireAllRules();
+ assertEquals( 1,
+ results.size() );
+ ksession.insert( new StockTick( seq++,
+ "RHT",
+ 10,
+ clock.getCurrentTime() ) ); // 65
+ clock.advanceTime( 5,
+ TimeUnit.SECONDS );
+ ksession.fireAllRules();
+ assertEquals( 1,
+ results.size() );
+
+ // advance time... there are non-matching events now, so forall de-activates
+ ksession.insert( new StockTick( seq++,
+ "IBM",
+ 10,
+ clock.getCurrentTime() ) ); // 70
+ clock.advanceTime( 10,
+ TimeUnit.SECONDS );
+ ksession.fireAllRules();
+ assertEquals( 1,
+ results.size() );
+
+ // advance time... there are non-matching events now, so forall is still deactivated
+ ksession.insert( new StockTick( seq++,
+ "RHT",
+ 10,
+ clock.getCurrentTime() ) ); // 80
+ clock.advanceTime( 10,
+ TimeUnit.SECONDS );
+ ksession.fireAllRules();
+ assertEquals( 1,
+ results.size() );
+
+ // advance time... non-matching event expires now, so forall should fire
+ ksession.insert( new StockTick( seq++,
+ "RHT",
+ 10,
+ clock.getCurrentTime() ) ); // 90
+ clock.advanceTime( 10,
+ TimeUnit.SECONDS );
+ ksession.fireAllRules();
+ assertEquals( 2,
+ results.size() );
+
+ // advance time... forall still matches and should not fire
+ ksession.insert( new StockTick( seq++,
+ "RHT",
+ 10,
+ clock.getCurrentTime() ) ); // 100
+ clock.advanceTime( 10,
+ TimeUnit.SECONDS );
+ ksession.fireAllRules();
+ assertEquals( 2,
+ results.size() );
+
+ // advance time... forall still matches and should not fire
+ clock.advanceTime( 60,
+ TimeUnit.SECONDS );
+ ksession.fireAllRules();
+ assertEquals( 2,
+ results.size() );
+
+ }
+
}
Added: labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_ForallSlidingWindow.drl
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_ForallSlidingWindow.drl (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_ForallSlidingWindow.drl 2009-10-15 23:14:17 UTC (rev 29630)
@@ -0,0 +1,14 @@
+package org.drools;
+
+global java.util.List results;
+
+declare StockTick
+ @role( event )
+end
+
+rule "test nested CEs"
+ when
+ forall( StockTick( company == "RHT" ) over window:time( 30s ) )
+ then
+ results.add("OK");
+end
\ No newline at end of file
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/impl/InputMarshaller.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/impl/InputMarshaller.java 2009-10-15 20:47:19 UTC (rev 29629)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/impl/InputMarshaller.java 2009-10-15 23:14:17 UTC (rev 29630)
@@ -473,7 +473,8 @@
}
break;
}
- case NodeTypeEnums.NotNode : {
+ case NodeTypeEnums.NotNode :
+ case NodeTypeEnums.ForallNotNode : {
BetaMemory memory = (BetaMemory) context.wm.getNodeMemory( (BetaNode) sink );
int type = stream.readShort();
if ( type == PersisterEnums.LEFT_TUPLE_NOT_BLOCKED ) {
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/impl/OutputMarshaller.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/impl/OutputMarshaller.java 2009-10-15 20:47:19 UTC (rev 29629)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/marshalling/impl/OutputMarshaller.java 2009-10-15 23:14:17 UTC (rev 29630)
@@ -449,7 +449,8 @@
stream.writeShort( PersisterEnums.END );
break;
}
- case NodeTypeEnums.NotNode : {
+ case NodeTypeEnums.NotNode :
+ case NodeTypeEnums.ForallNotNode : {
if ( leftTuple.getBlocker() == null ) {
// is not blocked so has children
stream.writeShort( PersisterEnums.LEFT_TUPLE_NOT_BLOCKED );
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ForallNotNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ForallNotNode.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ForallNotNode.java 2009-10-15 23:14:17 UTC (rev 29630)
@@ -0,0 +1,130 @@
+package org.drools.reteoo;
+
+/*
+ * Copyright 20059 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.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import org.drools.common.BetaConstraints;
+import org.drools.common.InternalFactHandle;
+import org.drools.common.InternalWorkingMemory;
+import org.drools.reteoo.builder.BuildContext;
+import org.drools.rule.Behavior;
+import org.drools.spi.ObjectType;
+import org.drools.spi.PropagationContext;
+
+/**
+ * A 'forall' conditional element is translated into a specific set of notes in the network. As
+ * an example, the following construction:
+ *
+ * forall( Bus( color == RED ) )
+ *
+ * Is translated into:
+ *
+ * not*( $bus : Bus( ) and not ( Bus( this == $bus, color == RED ) ) )
+ *
+ * This class implements the modified 'not' node that corresponds to the 'not*' CE above.
+ * It behaves like a not node in all aspects but for the right activations that never trigger
+ * propagations.
+ *
+ * @author <a href="mailto:tirelli at post.com">Edson Tirelli</a>
+ */
+public class ForallNotNode extends NotNode {
+ private static final long serialVersionUID = 510L;
+
+ private ObjectType baseObjectType = null;
+
+ // ------------------------------------------------------------
+ // Instance methods
+ // ------------------------------------------------------------
+ public ForallNotNode() {
+ }
+
+ /**
+ * Construct.
+ *
+ * @param leftInput
+ * The left input <code>TupleSource</code>.
+ * @param rightInput
+ * The right input <code>TupleSource</code>.
+ * @param objectType
+ */
+ public ForallNotNode(final int id,
+ final LeftTupleSource leftInput,
+ final ObjectSource rightInput,
+ final BetaConstraints joinNodeBinder,
+ final Behavior[] behaviors,
+ final BuildContext context,
+ ObjectType objectType) {
+ super( id,
+ leftInput,
+ rightInput,
+ joinNodeBinder,
+ behaviors,
+ context );
+ this.baseObjectType = objectType;
+ }
+
+ public void readExternal(ObjectInput in) throws IOException,
+ ClassNotFoundException {
+ super.readExternal( in );
+ baseObjectType = (ObjectType) in.readObject();
+ }
+
+ public void writeExternal(ObjectOutput out) throws IOException {
+ super.writeExternal( out );
+ out.writeObject( baseObjectType );
+ }
+
+ @Override
+ protected void propagateRetractLeftTuple(PropagationContext context,
+ InternalWorkingMemory workingMemory,
+ LeftTuple leftTuple) {
+ if ( !this.baseObjectType.isAssignableFrom( workingMemory.getObjectTypeConfigurationRegistry().getObjectTypeConf( context.getEntryPoint(),
+ ((InternalFactHandle) context.getFactHandle()).getObject() ).getConcreteObjectTypeNode().getObjectType() ) ) {
+ this.sink.propagateRetractLeftTuple( leftTuple,
+ context,
+ workingMemory );
+ }
+ }
+
+ @Override
+ protected void propagateAssertLeftTuple(PropagationContext context,
+ InternalWorkingMemory workingMemory,
+ LeftTuple leftTuple) {
+ if ( !this.baseObjectType.isAssignableFrom( workingMemory.getObjectTypeConfigurationRegistry().getObjectTypeConf( context.getEntryPoint(),
+ ((InternalFactHandle) context.getFactHandle()).getObject() ).getConcreteObjectTypeNode().getObjectType() ) ) {
+ this.sink.propagateAssertLeftTuple( leftTuple,
+ context,
+ workingMemory,
+ this.tupleMemoryEnabled );
+ }
+ }
+
+ public short getType() {
+ return NodeTypeEnums.ForallNotNode;
+ }
+
+ public ObjectType getBaseObjectType() {
+ return baseObjectType;
+ }
+
+ public void setBaseObjectType(ObjectType baseObjectType) {
+ this.baseObjectType = baseObjectType;
+ }
+}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/NodeTypeEnums.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/NodeTypeEnums.java 2009-10-15 20:47:19 UTC (rev 29629)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/NodeTypeEnums.java 2009-10-15 23:14:17 UTC (rev 29630)
@@ -11,4 +11,5 @@
public static final short RightInputAdaterNode = 7;
public static final short QueryTerminalNode = 8;
public static final short RuleTerminalNode = 9;
+ public static final short ForallNotNode = 10;
}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/NotNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/NotNode.java 2009-10-15 20:47:19 UTC (rev 29629)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/NotNode.java 2009-10-15 23:14:17 UTC (rev 29630)
@@ -177,9 +177,10 @@
// this is now blocked so remove from memory
memory.getLeftTupleMemory().remove( leftTuple );
- this.sink.propagateRetractLeftTuple( leftTuple,
- context,
- workingMemory );
+ // subclasses like ForallNotNode might override this propagation
+ propagateRetractLeftTuple( context,
+ workingMemory,
+ leftTuple );
}
leftTuple = temp;
@@ -189,6 +190,22 @@
}
/**
+ * This is a hook method so that subclasses (like ForallNotNode) can
+ * override the default behaviour.
+ *
+ * @param context
+ * @param workingMemory
+ * @param leftTuple
+ */
+ protected void propagateRetractLeftTuple(final PropagationContext context,
+ final InternalWorkingMemory workingMemory,
+ LeftTuple leftTuple) {
+ this.sink.propagateRetractLeftTuple( leftTuple,
+ context,
+ workingMemory );
+ }
+
+ /**
* Retract the <code>FactHandleImpl</code>. If the handle has any
* <code>ReteTuple</code> matches then those matches copied are propagated
* as new joins.
@@ -243,10 +260,10 @@
// was previous blocked and not in memory, so add
memory.getLeftTupleMemory().add( leftTuple );
- this.sink.propagateAssertLeftTuple( leftTuple,
- context,
- workingMemory,
- this.tupleMemoryEnabled );
+ // subclasses like ForallNotNode might override this propagation
+ propagateAssertLeftTuple( context,
+ workingMemory,
+ leftTuple );
}
leftTuple = temp;
@@ -255,6 +272,23 @@
}
/**
+ * This is a hook method so that subclasses (like ForallNotNode) can
+ * override the default behaviour.
+ *
+ * @param context
+ * @param workingMemory
+ * @param leftTuple
+ */
+ protected void propagateAssertLeftTuple(final PropagationContext context,
+ final InternalWorkingMemory workingMemory,
+ LeftTuple leftTuple) {
+ this.sink.propagateAssertLeftTuple( leftTuple,
+ context,
+ workingMemory,
+ this.tupleMemoryEnabled );
+ }
+
+ /**
* Retract the
* <code>ReteTuple<code>, any resulting proppagated joins are also retracted.
*
@@ -309,6 +343,6 @@
source = source.source;
}
- return "[NotNode - " + ((ObjectTypeNode) source).getObjectType() + "]";
+ return "[" + getClass().getSimpleName() + "(" + this.getId() + ") - " + ((ObjectTypeNode) source).getObjectType() + "]";
}
}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/ForallBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/ForallBuilder.java 2009-10-15 20:47:19 UTC (rev 29629)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/ForallBuilder.java 2009-10-15 23:14:17 UTC (rev 29630)
@@ -16,8 +16,17 @@
package org.drools.reteoo.builder;
+import java.util.ArrayList;
import java.util.Iterator;
+import java.util.List;
+import org.drools.common.BetaConstraints;
+import org.drools.common.TupleStartEqualsConstraint;
+import org.drools.reteoo.LeftTupleSource;
+import org.drools.reteoo.NotNode;
+import org.drools.reteoo.ObjectSource;
+import org.drools.reteoo.RightInputAdapterNode;
+import org.drools.rule.Behavior;
import org.drools.rule.Forall;
import org.drools.rule.GroupElement;
import org.drools.rule.GroupElementFactory;
@@ -48,7 +57,8 @@
final GroupElement and = GroupElementFactory.newAndInstance();
and.addChild( forall.getBasePattern() );
- final GroupElement not2 = GroupElementFactory.newNotInstance();
+ final GroupElement not2 = GroupElementFactory.newForallNotInstance();
+ not2.setForallBaseObjectType( forall.getBasePattern().getObjectType() );
if ( forall.getRemainingPatterns().size() == 1 ) {
not2.addChild( (Pattern) forall.getRemainingPatterns().get( 0 ) );
and.addChild( not2 );
@@ -71,6 +81,7 @@
builder.build( context,
utils,
not );
+
}
/**
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/GroupElementBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/GroupElementBuilder.java 2009-10-15 20:47:19 UTC (rev 29629)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/GroupElementBuilder.java 2009-10-15 23:14:17 UTC (rev 29630)
@@ -27,6 +27,7 @@
import org.drools.common.BetaConstraints;
import org.drools.common.TupleStartEqualsConstraint;
import org.drools.reteoo.ExistsNode;
+import org.drools.reteoo.ForallNotNode;
import org.drools.reteoo.JoinNode;
import org.drools.reteoo.LeftInputAdapterNode;
import org.drools.reteoo.LeftTupleSource;
@@ -36,6 +37,7 @@
import org.drools.rule.Behavior;
import org.drools.rule.GroupElement;
import org.drools.rule.RuleConditionElement;
+import org.drools.rule.GroupElement.Type;
/**
* @author etirelli
@@ -45,7 +47,7 @@
implements
ReteooComponentBuilder {
- private final Map geBuilders = new HashMap();
+ private final Map<Type, ReteooComponentBuilder> geBuilders = new HashMap<Type, ReteooComponentBuilder>();
public GroupElementBuilder() {
this.geBuilders.put( GroupElement.AND,
@@ -54,6 +56,8 @@
new OrBuilder() );
this.geBuilders.put( GroupElement.NOT,
new NotBuilder() );
+ this.geBuilders.put( GroupElement.FORALL_NOT,
+ new NotBuilder() );
this.geBuilders.put( GroupElement.EXISTS,
new ExistsBuilder() );
}
@@ -66,7 +70,7 @@
final RuleConditionElement rce) {
final GroupElement ge = (GroupElement) rce;
- final ReteooComponentBuilder builder = (ReteooComponentBuilder) this.geBuilders.get( ge.getType() );
+ final ReteooComponentBuilder builder = this.geBuilders.get( ge.getType() );
context.push( ge );
@@ -84,7 +88,7 @@
final RuleConditionElement rce) {
final GroupElement ge = (GroupElement) rce;
- final ReteooComponentBuilder builder = (ReteooComponentBuilder) this.geBuilders.get( ge.getType() );
+ final ReteooComponentBuilder builder = this.geBuilders.get( ge.getType() );
return builder.requiresLeftActivation( utils,
rce );
@@ -243,7 +247,7 @@
// create a tuple start equals constraint and set it in the context
final TupleStartEqualsConstraint constraint = TupleStartEqualsConstraint.getInstance();
- final List predicates = new ArrayList();
+ final List<TupleStartEqualsConstraint> predicates = new ArrayList<TupleStartEqualsConstraint>();
predicates.add( constraint );
context.setBetaconstraints( predicates );
@@ -257,13 +261,25 @@
// then attach the NOT node. It will work both as a simple not node
// or as subnetwork join node as the context was set appropriatelly
// in each case
+ NotNode node = null;
+ if( GroupElement.FORALL_NOT.equals( not.getType() ) ) {
+ node = new ForallNotNode( context.getNextId(),
+ context.getTupleSource(),
+ context.getObjectSource(),
+ betaConstraints,
+ behaviors,
+ context,
+ not.getForallBaseObjectType() );
+ } else {
+ node = new NotNode( context.getNextId(),
+ context.getTupleSource(),
+ context.getObjectSource(),
+ betaConstraints,
+ behaviors,
+ context );
+ }
context.setTupleSource( (LeftTupleSource) utils.attachNode( context,
- new NotNode( context.getNextId(),
- context.getTupleSource(),
- context.getObjectSource(),
- betaConstraints,
- behaviors,
- context ) ) );
+ node ) );
context.setBetaconstraints( null );
context.setObjectSource( null );
@@ -323,7 +339,7 @@
// create a tuple start equals constraint and set it in the context
final TupleStartEqualsConstraint constraint = TupleStartEqualsConstraint.getInstance();
- final List predicates = new ArrayList();
+ final List<TupleStartEqualsConstraint> predicates = new ArrayList<TupleStartEqualsConstraint>();
predicates.add( constraint );
context.setBetaconstraints( predicates );
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/GroupElement.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/GroupElement.java 2009-10-15 20:47:19 UTC (rev 29629)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/GroupElement.java 2009-10-15 23:14:17 UTC (rev 29630)
@@ -28,20 +28,23 @@
import java.util.Map;
import org.drools.RuntimeDroolsException;
+import org.drools.spi.ObjectType;
public class GroupElement extends ConditionalElement
implements
Externalizable {
- private static final long serialVersionUID = 400L;
+ private static final long serialVersionUID = 510L;
- public static final Type AND = Type.AND;
- public static final Type OR = Type.OR;
- public static final Type NOT = Type.NOT;
- public static final Type EXISTS = Type.EXISTS;
+ public static final Type AND = Type.AND;
+ public static final Type OR = Type.OR;
+ public static final Type NOT = Type.NOT;
+ public static final Type EXISTS = Type.EXISTS;
+ public static final Type FORALL_NOT = Type.FORALL_NOT;
- private Type type = null;
- private List children = new ArrayList();
+ private Type type = null;
+ private List children = new ArrayList();
+ private ObjectType forallBaseObjectType = null;
public GroupElement() {
this( Type.AND );
@@ -113,6 +116,14 @@
return (Declaration) this.type.getInnerDeclarations( this.children ).get( identifier );
}
+ public void setForallBaseObjectType(ObjectType objectType) {
+ this.forallBaseObjectType = objectType;
+ }
+
+ public ObjectType getForallBaseObjectType() {
+ return this.forallBaseObjectType;
+ }
+
/**
* Optimize the group element subtree by removing redundancies
* like an AND inside another AND, OR inside OR, single branches
@@ -301,7 +312,7 @@
}
public boolean isNot() {
- return NOT.equals( this.type );
+ return NOT.equals( this.type ) || FORALL_NOT.equals( this.type );
}
public boolean isExists() {
@@ -325,10 +336,12 @@
*/
public static enum Type {
- AND(false),
- OR(false),
- NOT(true),
- EXISTS(true);
+ AND(
+ false), OR(
+ false), NOT(
+ true), EXISTS(
+ true), FORALL_NOT(
+ true);
private final boolean scopeDelimiter;
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/GroupElementFactory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/GroupElementFactory.java 2009-10-15 20:47:19 UTC (rev 29629)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/GroupElementFactory.java 2009-10-15 23:14:17 UTC (rev 29630)
@@ -38,6 +38,10 @@
return new GroupElement( GroupElement.NOT );
}
+ public static GroupElement newForallNotInstance() {
+ return new GroupElement( GroupElement.FORALL_NOT );
+ }
+
public static GroupElement newExistsInstance() {
return new GroupElement( GroupElement.EXISTS );
}
More information about the jboss-svn-commits
mailing list