[jboss-svn-commits] JBL Code SVN: r8701 - in labs/jbossrules/trunk/drools-core/src: main/java/org/drools main/java/org/drools/common test/java/org/drools/reteoo
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Fri Jan 5 05:38:08 EST 2007
Author: michael.neale at jboss.com
Date: 2007-01-05 05:38:02 -0500 (Fri, 05 Jan 2007)
New Revision: 8701
Added:
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/Otherwise.java
labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/OtherwiseTest.java
Modified:
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java
Log:
JBRULES-600 Otherwise first cut.
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/Otherwise.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/Otherwise.java 2007-01-05 02:44:18 UTC (rev 8700)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/Otherwise.java 2007-01-05 10:38:02 UTC (rev 8701)
@@ -0,0 +1,12 @@
+package org.drools;
+
+/**
+ * This class is essentually a named fact that will be asserted when the engine
+ * has not matched any rules.
+ *
+ * @author Michael Neale
+ *
+ */
+public class Otherwise {
+
+}
Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/Otherwise.java
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java 2007-01-05 02:44:18 UTC (rev 8700)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java 2007-01-05 10:38:02 UTC (rev 8701)
@@ -33,6 +33,7 @@
import org.drools.FactHandle;
import org.drools.NoSuchFactHandleException;
import org.drools.NoSuchFactObjectException;
+import org.drools.Otherwise;
import org.drools.QueryResults;
import org.drools.RuleBase;
import org.drools.RuleBaseConfiguration;
@@ -342,21 +343,73 @@
if ( !this.factQueue.isEmpty() ) {
propagateQueuedActions();
}
+
+ boolean noneFired = true;
if ( !this.firing ) {
try {
this.firing = true;
-
+
while ( this.agenda.fireNextItem( agendaFilter ) ) {
- ;
+ noneFired = false;
}
} finally {
this.firing = false;
+ if (noneFired) {
+ doOtherwise(agendaFilter);
+ }
+
}
}
}
/**
+ * This does the "otherwise" phase of processing.
+ * If no items are fired, then it will assert a temporary "Otherwise"
+ * fact and allow any rules to fire to handle "otherwise" cases.
+ */
+ private void doOtherwise(AgendaFilter agendaFilter) {
+ FactHandle handle = this.assertObject( new Otherwise() );
+ if ( !this.factQueue.isEmpty() ) {
+ propagateQueuedActions();
+ }
+
+ while ( this.agenda.fireNextItem( agendaFilter ) ) {
+ ;
+ }
+
+ this.retractObject( handle );
+ }
+
+
+//
+// MN: The following is the traditional fireAllRules (without otherwise).
+// Purely kept here as this implementation of otherwise is still experimental.
+//
+// public synchronized void fireAllRules(final AgendaFilter agendaFilter) throws FactException {
+// // If we're already firing a rule, then it'll pick up
+// // the firing for any other assertObject(..) that get
+// // nested inside, avoiding concurrent-modification
+// // exceptions, depending on code paths of the actions.
+//
+// if ( !this.factQueue.isEmpty() ) {
+// propagateQueuedActions();
+// }
+//
+// if ( !this.firing ) {
+// try {
+// this.firing = true;
+//
+// while ( this.agenda.fireNextItem( agendaFilter ) ) {
+// ;
+// }
+// } finally {
+// this.firing = false;
+// }
+// }
+// }
+
+ /**
* Returns the fact Object for the given <code>FactHandle</code>. It
* actually attemps to return the value from the handle, before retrieving
* it from objects map.
Added: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/OtherwiseTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/OtherwiseTest.java 2007-01-05 02:44:18 UTC (rev 8700)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/OtherwiseTest.java 2007-01-05 10:38:02 UTC (rev 8701)
@@ -0,0 +1,162 @@
+package org.drools.reteoo;
+
+import java.util.Map;
+
+import org.drools.Otherwise;
+import org.drools.RuleBase;
+import org.drools.RuleBaseFactory;
+import org.drools.WorkingMemory;
+import org.drools.base.ClassObjectType;
+import org.drools.base.ShadowProxyFactory;
+import org.drools.base.TestBean;
+import org.drools.examples.manners.Context;
+import org.drools.rule.Column;
+import org.drools.rule.Package;
+import org.drools.rule.Rule;
+import org.drools.rule.RuleConditionElement;
+import org.drools.spi.Consequence;
+import org.drools.spi.KnowledgeHelper;
+
+import junit.framework.TestCase;
+
+/**
+ * This tests the "otherwise" feature.
+ * @author Michael Neale
+ */
+public class OtherwiseTest extends TestCase {
+
+ public void testOneRuleFiringNoOtherwise() throws Exception {
+ final RuleBase ruleBase = RuleBaseFactory.newRuleBase( RuleBase.RETEOO );
+
+ Package pkg = new Package( "Miss Manners" );
+ Rule rule1 = getRule("rule1");
+ pkg.addRule( rule1 );
+
+ Rule ruleOtherwise = getOtherwise("rule2");
+ pkg.addRule( ruleOtherwise );
+
+ ruleBase.addPackage( pkg );
+
+ final WorkingMemory workingMemory = ruleBase.newWorkingMemory();
+ workingMemory.assertObject( new TestBean() );
+ workingMemory.fireAllRules();
+
+
+ assertTrue(((MockConsequence) rule1.getConsequence()).fired);
+ assertFalse(((MockConsequence) ruleOtherwise.getConsequence()).fired);
+
+ }
+
+ public void testTwoRulesFiringNoOtherwise() throws Exception {
+ final RuleBase ruleBase = RuleBaseFactory.newRuleBase( RuleBase.RETEOO );
+
+ Package pkg = new Package( "Miss Manners" );
+ Rule rule1 = getRule("rule1");
+ pkg.addRule( rule1 );
+ Rule rule2 = getRule("rule2");
+ pkg.addRule( rule2 );
+
+ Rule ruleOtherwise = getOtherwise("ruleOtherwise");
+ pkg.addRule( ruleOtherwise );
+
+ ruleBase.addPackage( pkg );
+
+ final WorkingMemory workingMemory = ruleBase.newWorkingMemory();
+ workingMemory.assertObject( new TestBean() );
+ workingMemory.fireAllRules();
+
+ assertFalse(((MockConsequence) ruleOtherwise.getConsequence()).fired);
+ assertTrue(((MockConsequence) rule1.getConsequence()).fired);
+ assertTrue(((MockConsequence) rule2.getConsequence()).fired);
+
+ }
+
+ public void testOtherwiseFiringWithOneRule() throws Exception {
+ final RuleBase ruleBase = RuleBaseFactory.newRuleBase( RuleBase.RETEOO );
+
+ Package pkg = new Package( "Miss Manners" );
+ Rule rule1 = getRule("rule1");
+ pkg.addRule( rule1 );
+
+ Rule ruleOtherwise = getOtherwise("rule2");
+ pkg.addRule( ruleOtherwise );
+
+ ruleBase.addPackage( pkg );
+
+ final WorkingMemory workingMemory = ruleBase.newWorkingMemory();
+
+ workingMemory.fireAllRules();
+
+
+ assertFalse(((MockConsequence) rule1.getConsequence()).fired);
+ assertTrue(((MockConsequence) ruleOtherwise.getConsequence()).fired);
+
+ }
+
+ public void testOtherwiseFiringMultipleRules() throws Exception {
+ final RuleBase ruleBase = RuleBaseFactory.newRuleBase( RuleBase.RETEOO );
+
+ Package pkg = new Package( "Miss Manners" );
+ Rule rule1 = getRule("rule1");
+ pkg.addRule( rule1 );
+ Rule rule2 = getRule("rule2");
+ pkg.addRule( rule2 );
+
+ Rule ruleOtherwise1 = getOtherwise("other1");
+ pkg.addRule( ruleOtherwise1 );
+ Rule ruleOtherwise2 = getOtherwise("other2");
+ pkg.addRule( ruleOtherwise2 );
+
+
+
+ ruleBase.addPackage( pkg );
+
+ final WorkingMemory workingMemory = ruleBase.newWorkingMemory();
+
+ workingMemory.fireAllRules();
+
+
+ assertFalse(((MockConsequence) rule1.getConsequence()).fired);
+ assertFalse(((MockConsequence) rule2.getConsequence()).fired);
+ assertTrue(((MockConsequence) ruleOtherwise1.getConsequence()).fired);
+ assertTrue(((MockConsequence) ruleOtherwise2.getConsequence()).fired);
+
+ }
+
+
+
+ private Rule getOtherwise(String name) {
+ Rule rule = new Rule( name );
+ final Column pat = new Column( 0,
+ new ClassObjectType( Otherwise.class,
+ ShadowProxyFactory.getProxy( Otherwise.class ) ) );
+ rule.addPattern( pat );
+ rule.setConsequence( new MockConsequence() );
+ return rule;
+ }
+
+ private Rule getRule(String name) {
+ Rule rule = new Rule( name );
+
+ final Column pat = new Column( 0,
+ new ClassObjectType( TestBean.class,
+ ShadowProxyFactory.getProxy( TestBean.class ) ) );
+
+ rule.addPattern( pat );
+ rule.setConsequence(new MockConsequence());
+
+ return rule;
+ }
+
+ static class MockConsequence implements Consequence {
+
+ public boolean fired = false;
+
+ public void evaluate(KnowledgeHelper knowledgeHelper,
+ WorkingMemory workingMemory) throws Exception {
+ fired = true;
+ }
+
+ }
+
+}
Property changes on: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/OtherwiseTest.java
___________________________________________________________________
Name: svn:eol-style
+ native
More information about the jboss-svn-commits
mailing list