[jboss-svn-commits] JBL Code SVN: r8987 - in labs/jbossrules/trunk/drools-core: src/main/java/org and 7 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Mon Jan 22 23:30:53 EST 2007
Author: mark.proctor at jboss.com
Date: 2007-01-22 23:30:53 -0500 (Mon, 22 Jan 2007)
New Revision: 8987
Added:
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/RuleFlowGroupImpl.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/RuleFlowGroupNode.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/RuleFlowGroup.java
Removed:
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/RuleFlowNode.java
labs/jbossrules/trunk/drools-core/src/main/java/org/mvel/
Modified:
labs/jbossrules/trunk/drools-core/.classpath
labs/jbossrules/trunk/drools-core/.project
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/Agenda.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/dataproviders/MVELDataProvider.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AgendaItem.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DefaultAgenda.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/ScheduledAgendaItem.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleTerminalNode.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Rule.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/Activation.java
labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/AgendaTest.java
Log:
JBRULES-619 Rule Flow Core Implementation
Modified: labs/jbossrules/trunk/drools-core/.classpath
===================================================================
--- labs/jbossrules/trunk/drools-core/.classpath 2007-01-23 00:39:35 UTC (rev 8986)
+++ labs/jbossrules/trunk/drools-core/.classpath 2007-01-23 04:30:53 UTC (rev 8987)
@@ -5,9 +5,12 @@
<classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
<classpathentry kind="src" output="target/test-classes" path="src/test/resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="var" path="M2_REPO/antlr/antlr/2.7.7/antlr-2.7.7.jar"/>
+ <classpathentry kind="var" path="M2_REPO/antlr/stringtemplate/3.0/stringtemplate-3.0.jar"/>
<classpathentry kind="var" path="M2_REPO/xpp3/xpp3/1.1.3.4.O/xpp3-1.1.3.4.O.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/antlr/antlr/3.0b5/antlr-3.0b5.jar"/>
<classpathentry kind="var" path="M2_REPO/junit/junit/3.8.1/junit-3.8.1.jar"/>
<classpathentry kind="var" path="M2_REPO/xstream/xstream/1.1.3/xstream-1.1.3.jar"/>
- <classpathentry kind="var" path="M2_REPO/org/antlr/antlr/3.0b5/antlr-3.0b5.jar"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/mvel"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>
Modified: labs/jbossrules/trunk/drools-core/.project
===================================================================
--- labs/jbossrules/trunk/drools-core/.project 2007-01-23 00:39:35 UTC (rev 8986)
+++ labs/jbossrules/trunk/drools-core/.project 2007-01-23 04:30:53 UTC (rev 8987)
@@ -1,28 +1,14 @@
<projectDescription>
<name>drools-core</name>
- <comment/>
+ <comment>A rule production system</comment>
<projects/>
<buildSpec>
<buildCommand>
- <name>org.eclipse.wst.common.modulecore.ComponentStructuralBuilder</name>
- <arguments/>
- </buildCommand>
- <buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments/>
</buildCommand>
- <buildCommand>
- <name>org.eclipse.wst.validation.validationbuilder</name>
- <arguments/>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.wst.common.modulecore.ComponentStructuralBuilderDependencyResolver</name>
- <arguments/>
- </buildCommand>
</buildSpec>
<natures>
- <nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
- <nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
</natures>
</projectDescription>
\ No newline at end of file
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/Agenda.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/Agenda.java 2007-01-23 00:39:35 UTC (rev 8986)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/Agenda.java 2007-01-23 04:30:53 UTC (rev 8987)
@@ -3,6 +3,7 @@
import org.drools.spi.Activation;
import org.drools.spi.ActivationGroup;
import org.drools.spi.AgendaGroup;
+import org.drools.spi.RuleFlowGroup;
public interface Agenda {
@@ -17,6 +18,8 @@
public AgendaGroup getFocus();
public AgendaGroup getAgendaGroup(String name);
+
+ public RuleFlowGroup getRuleFlowGroup(String name);
public AgendaGroup[] getAgendaGroups();
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/dataproviders/MVELDataProvider.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/dataproviders/MVELDataProvider.java 2007-01-23 00:39:35 UTC (rev 8986)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/dataproviders/MVELDataProvider.java 2007-01-23 04:30:53 UTC (rev 8987)
@@ -1,5 +1,6 @@
package org.drools.base.dataproviders;
+import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
@@ -18,10 +19,10 @@
implements
DataProvider {
//private final Expr expression;
- private final CompiledExpression expression;
+ private final Serializable expression;
private final DroolsMVELFactory factory;
- public MVELDataProvider(final CompiledExpression expression,
+ public MVELDataProvider(final Serializable expression,
final DroolsMVELFactory factory) {
this.expression = expression;
this.factory = factory;
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AgendaItem.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AgendaItem.java 2007-01-23 00:39:35 UTC (rev 8986)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AgendaItem.java 2007-01-23 04:30:53 UTC (rev 8987)
@@ -21,7 +21,9 @@
import org.drools.rule.GroupElement;
import org.drools.rule.Rule;
import org.drools.spi.Activation;
+import org.drools.spi.AgendaGroup;
import org.drools.spi.PropagationContext;
+import org.drools.spi.RuleFlowGroup;
import org.drools.spi.Tuple;
import org.drools.util.LinkedList;
import org.drools.util.Queue;
@@ -52,7 +54,7 @@
/** The rule. */
private final Rule rule;
-
+
/** The subrule */
private final GroupElement subrule;
@@ -71,8 +73,12 @@
private boolean activated;
+ private AgendaGroupImpl agendaGroup;
+
private ActivationGroupNode activationGroupNode;
+ private RuleFlowGroupNode ruleFlowGroupNode;
+
// ------------------------------------------------------------
// Constructors
// ------------------------------------------------------------
@@ -89,7 +95,7 @@
final Tuple tuple,
final PropagationContext context,
final Rule rule,
- final GroupElement subrule ) {
+ final GroupElement subrule) {
this.tuple = tuple;
this.context = context;
this.rule = rule;
@@ -206,6 +212,22 @@
this.activationGroupNode = activationNode;
}
+ public AgendaGroup getAgendaGroup() {
+ return agendaGroup;
+ }
+
+ public void setAgendaGroup(AgendaGroupImpl agendaGroup) {
+ this.agendaGroup = agendaGroup;
+ }
+
+ public RuleFlowGroupNode getRuleFlowGroupNode() {
+ return ruleFlowGroupNode;
+ }
+
+ public void setRuleFlowGroupNode(RuleFlowGroupNode ruleFlowGroupNode) {
+ this.ruleFlowGroupNode = ruleFlowGroupNode;
+ }
+
public GroupElement getSubRule() {
return this.subrule;
}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DefaultAgenda.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DefaultAgenda.java 2007-01-23 00:39:35 UTC (rev 8986)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DefaultAgenda.java 2007-01-23 04:30:53 UTC (rev 8987)
@@ -32,6 +32,7 @@
import org.drools.spi.AgendaFilter;
import org.drools.spi.AgendaGroup;
import org.drools.spi.ConsequenceException;
+import org.drools.spi.RuleFlowGroup;
import org.drools.util.LinkedListNode;
import org.drools.util.Queueable;
@@ -63,7 +64,7 @@
/**
*
*/
- private static final long serialVersionUID = -9112292414291983688L;
+ private static final long serialVersionUID = 320L;
/** Working memory of this Agenda. */
private final WorkingMemory workingMemory;
@@ -75,6 +76,8 @@
private final Map agendaGroups;
private final Map activationGroups;
+
+ private final Map ruleFlowGroups;
private final LinkedList focusStack;
@@ -101,6 +104,7 @@
this.knowledgeHelper = new DefaultKnowledgeHelper( this.workingMemory );
this.agendaGroups = new HashMap();
this.activationGroups = new HashMap();
+ this.ruleFlowGroups = new HashMap();
this.focusStack = new LinkedList();
// MAIN should always be the first AgendaGroup and can never be removed
@@ -256,6 +260,16 @@
}
return activationGroup;
}
+
+ public RuleFlowGroup getRuleFlowGroup(final String name) {
+ RuleFlowGroupImpl ruleFlowGroup = (RuleFlowGroupImpl) this.ruleFlowGroups.get( name );
+ if ( ruleFlowGroup == null ) {
+ ruleFlowGroup = new RuleFlowGroupImpl( name );
+ this.ruleFlowGroups.put( name,
+ ruleFlowGroup );
+ }
+ return ruleFlowGroup;
+ }
/* (non-Javadoc)
* @see org.drools.common.AgendaI#focusStackSize()
@@ -429,11 +443,13 @@
eventsupport.getAgendaEventSupport().fireBeforeActivationFired( activation, this.workingMemory );
if ( activation.getActivationGroupNode() != null ) {
+ // We know that this rule will cancel all other activatiosn in the group
+ // so lets remove the information now, before the consequence fires
final ActivationGroup activationGroup = activation.getActivationGroupNode().getActivationGroup();
activationGroup.removeActivation( activation );
clearActivationGroup( activationGroup );
}
- activation.setActivated( false );
+ activation.setActivated( false );
try {
this.knowledgeHelper.setActivation( activation );
@@ -444,6 +460,18 @@
throw new ConsequenceException( e,
activation.getRule() );
}
+
+ if ( activation.getRuleFlowGroupNode() != null ) {
+ // Now the rule has fired, remove it and check if the rule flow group is empty
+ // if its empty, activate the child groups. We do this after the consequence
+ // fired as we don't want to populate the Agenda prior to the rule actually firing.
+ final RuleFlowGroup ruleFlowGroup = activation.getRuleFlowGroupNode().getRuleFlowGroup();
+ ruleFlowGroup.removeActivation( activation );
+
+ if ( ruleFlowGroup.isEmpty() ) {
+ ruleFlowGroup.activateChildren();
+ }
+ }
eventsupport.getAgendaEventSupport().fireAfterActivationFired( activation );
}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/RuleFlowGroupImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/RuleFlowGroupImpl.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/RuleFlowGroupImpl.java 2007-01-23 04:30:53 UTC (rev 8987)
@@ -0,0 +1,195 @@
+package org.drools.common;
+
+/*
+ * 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.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.drools.conflict.DepthConflictResolver;
+import org.drools.spi.Activation;
+import org.drools.spi.AgendaGroup;
+import org.drools.spi.RuleFlowGroup;
+import org.drools.util.BinaryHeapQueue;
+import org.drools.util.Iterator;
+import org.drools.util.LinkedList;
+import org.drools.util.ObjectHashMap;
+import org.drools.util.Queueable;
+import org.drools.util.LinkedList.LinkedListIterator;
+
+/**
+ * <code>AgendaGroup</code> implementation that uses a <code>PriorityQueue</code> to prioritise the evaluation of added
+ * <code>ActivationQueue</code>s. The <code>AgendaGroup</code> also maintains a <code>Map</code> of <code>ActivationQueues</code>
+ * for requested salience values.
+ *
+ * @see PriorityQueue
+ * @see ActivationQueue
+ *
+ * @author <a href="mailto:mark.proctor at jboss.com">Mark Proctor</a>
+ * @author <a href="mailto:bob at werken.com">Bob McWhirter</a>
+ *
+ */
+public class RuleFlowGroupImpl
+ implements
+ RuleFlowGroup {
+
+ private static final long serialVersionUID = 320L;
+
+ private final String name;
+
+ private final LinkedList list;
+
+ private List childNodes = Collections.EMPTY_LIST;
+
+ /**
+ * Construct an <code>AgendaGroup</code> with the given name.
+ *
+ * @param name
+ * The <AgendaGroup> name.
+ */
+ public RuleFlowGroupImpl(final String name) {
+ this.name = name;
+ this.list = new LinkedList();
+ }
+
+ /* (non-Javadoc)
+ * @see org.drools.spi.AgendaGroup#getName()
+ */
+ /* (non-Javadoc)
+ * @see org.drools.common.RuleFlowGroup#getName()
+ */
+ public String getName() {
+ return this.name;
+ }
+
+ /* (non-Javadoc)
+ * @see org.drools.common.RuleFlowGroup#addChild(org.drools.common.RuleFlowGroup)
+ */
+ public void addChild(final RuleFlowGroup child) {
+ if ( this.childNodes == Collections.EMPTY_LIST ) {
+ this.childNodes = new ArrayList( 1 );
+ }
+ this.childNodes.add( child );
+ }
+
+ /* (non-Javadoc)
+ * @see org.drools.common.RuleFlowGroup#removeChild(org.drools.common.RuleFlowGroup)
+ */
+ public boolean removeChild(final RuleFlowGroup child) {
+ return this.childNodes.remove( child );
+ }
+
+ /* (non-Javadoc)
+ * @see org.drools.common.RuleFlowGroup#activate()
+ */
+ public void activate() {
+ // iterate all activations adding them to their AgendaGroups
+ LinkedListIterator it = this.list.iterator();
+ for ( RuleFlowGroupNode node = (RuleFlowGroupNode) it.next(); node != null; node = (RuleFlowGroupNode) it.next() ) {
+ Activation activation = node.getActivation();
+ ( (AgendaGroupImpl) activation.getAgendaGroup() ).add( activation );
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.drools.common.RuleFlowGroup#activateChildren()
+ */
+ public void activateChildren() {
+ // do we have any children still to fire, if so remove them from the AgendaGroups
+ if ( !this.list.isEmpty() ) {
+ clear();
+ }
+
+ // iterate all children calling activate
+ for ( java.util.Iterator it = this.childNodes.iterator(); it.hasNext(); ) {
+ ((RuleFlowGroup) it.next() ).activate();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.drools.common.RuleFlowGroup#clear()
+ */
+ public void clear() {
+ LinkedListIterator it = this.list.iterator();
+ for ( RuleFlowGroupNode node = (RuleFlowGroupNode) it.next(); node != null; node = (RuleFlowGroupNode) it.next() ) {
+ Activation activation = node.getActivation();
+ activation.remove();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.drools.spi.AgendaGroup#size()
+ */
+ /* (non-Javadoc)
+ * @see org.drools.common.RuleFlowGroup#size()
+ */
+ public int size() {
+ return this.list.size();
+ }
+
+ public void addActivation(final Activation activation) {
+ final RuleFlowGroupNode node = new RuleFlowGroupNode( activation,
+ this );
+ activation.setRuleFlowGroupNode( node );
+ this.list.add( node );
+ }
+
+ public void removeActivation(final Activation activation) {
+ final RuleFlowGroupNode node = activation.getRuleFlowGroupNode();
+ this.list.remove( node );
+ activation.setActivationGroupNode( null );
+ }
+
+ /* (non-Javadoc)
+ * @see org.drools.common.RuleFlowGroup#isEmpty()
+ */
+ public boolean isEmpty() {
+ return this.list.isEmpty();
+ }
+
+ /* (non-Javadoc)
+ * @see org.drools.common.RuleFlowGroup#getActivations()
+ */
+ public Activation[] getActivations() {
+ //return (Activation[]) this.activations.toArray( new AgendaItem[this.queue.size()] );
+ return null;
+ }
+
+ public java.util.Iterator iterator() {
+ return this.list.javaUtilIterator();
+ }
+
+ public String toString() {
+ return "RuleFlowGroup '" + this.name + "'";
+ }
+
+ public boolean equal(final Object object) {
+ if ( (object == null) || !(object instanceof RuleFlowGroupImpl) ) {
+ return false;
+ }
+
+ if ( ((RuleFlowGroupImpl) object).name.equals( this.name ) ) {
+ return true;
+ }
+
+ return false;
+ }
+
+ public int hashCode() {
+ return this.name.hashCode();
+ }
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/RuleFlowGroupNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/RuleFlowGroupNode.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/RuleFlowGroupNode.java 2007-01-23 04:30:53 UTC (rev 8987)
@@ -0,0 +1,29 @@
+package org.drools.common;
+
+import org.drools.spi.Activation;
+import org.drools.spi.ActivationGroup;
+import org.drools.spi.RuleFlowGroup;
+import org.drools.util.AbstractBaseLinkedListNode;
+
+public class RuleFlowGroupNode extends AbstractBaseLinkedListNode {
+
+ private Activation activation;
+
+ private RuleFlowGroup ruleFlowGroup;
+
+ public RuleFlowGroupNode(final Activation activation,
+ final RuleFlowGroup ruleFlowGroup) {
+ super();
+ this.activation = activation;
+ this.ruleFlowGroup = ruleFlowGroup;
+ }
+
+ public Activation getActivation() {
+ return this.activation;
+ }
+
+ public RuleFlowGroup getRuleFlowGroup() {
+ return this.ruleFlowGroup;
+ }
+
+}
Deleted: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/RuleFlowNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/RuleFlowNode.java 2007-01-23 00:39:35 UTC (rev 8986)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/RuleFlowNode.java 2007-01-23 04:30:53 UTC (rev 8987)
@@ -1,176 +0,0 @@
-package org.drools.common;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import org.drools.conflict.DepthConflictResolver;
-import org.drools.spi.Activation;
-import org.drools.spi.AgendaGroup;
-import org.drools.util.BinaryHeapQueue;
-import org.drools.util.Queueable;
-
-public class RuleFlowNode
- implements
- AgendaGroup {
-
- private static final long serialVersionUID = 320L;
-
- private final String name;
-
- private final InternalAgenda agenda;
-
- /** @todo Maybe this should just be a LinkedList and we sort on use? */
- private final BinaryHeapQueue queue;
-
- private List childNodes = Collections.EMPTY_LIST;
-
- private final Object lock;
-
- /**
- * Construct an <code>RuleFlowNode</code> with the given name.
- *
- * @param name
- * The <RuleFlowNode> name.
- */
- public RuleFlowNode(final String name,
- final InternalAgenda agenda) {
- this.name = name;
- this.agenda = agenda;
- this.queue = new BinaryHeapQueue( DepthConflictResolver.getInstance() );
- this.lock = new Object();
- }
-
- /* (non-Javadoc)
- * @see org.drools.spi.RuleFlowNode#getName()
- */
- public String getName() {
- return this.name;
- }
-
- public void addChildNode(final RuleFlowNode child) {
- if ( this.childNodes == Collections.EMPTY_LIST ) {
- this.childNodes = new ArrayList( 1 );
- }
- this.childNodes.add( child );
- }
-
- public boolean removeChildNode(final RuleFlowNode child) {
- return this.childNodes.remove( child );
- }
-
- public void clear() {
- synchronized ( this.lock ) {
- this.queue.clear();
- }
- }
-
- /* (non-Javadoc)
- * @see org.drools.spi.RuleFlowNode#size()
- */
- public int size() {
- synchronized ( this.lock ) {
- return this.queue.size();
- }
- }
-
- public void add(final Activation activation) {
- synchronized ( this.lock ) {
- this.queue.enqueue( (Queueable) activation );
- }
- }
-
- public Activation getNext() {
- synchronized ( this.lock ) {
- return (Activation) this.queue.dequeue();
- }
- }
-
- /**
- * Iterates a PriorityQueue removing empty entries until it finds a populated entry and return true,
- * otherwise it returns false;
- *
- * @param priorityQueue
- * @return
- */
- public boolean isEmpty() {
- synchronized ( this.lock ) {
- return this.queue.isEmpty();
- }
- }
-
- public Activation[] getActivations() {
- synchronized ( this.lock ) {
- return (Activation[]) this.queue.toArray( new AgendaItem[this.queue.size()] );
- }
- }
-
- public Queueable[] getQueueable() {
- return this.queue.getQueueable();
- }
-
- public void activate() {
- Activation[] activations = null;
- int i = 0;
- // We need to make a sorted copy of the queue as an array
- synchronized ( this.lock ) {
- activations = new Activation[this.queue.size()];
- while ( !this.queue.isEmpty() ) {
- activations[i++] = (Activation) this.queue.dequeue();
- }
- }
-
- // Make a runnable execution so we can fire all the activations
- final ExecuteRuleFlowNode execute = new ExecuteRuleFlowNode( this.agenda,
- (RuleFlowNode[]) this.childNodes.toArray( new RuleFlowNode[this.childNodes.size()] ),
- activations );
- final Thread thread = new Thread( execute );
- thread.start();
- }
-
- public String toString() {
- return "RuleFlowNode '" + this.name + "'";
- }
-
- public boolean equal(final Object object) {
- if ( (object == null) || !(object instanceof RuleFlowNode) ) {
- return false;
- }
-
- if ( ((RuleFlowNode) object).name.equals( this.name ) ) {
- return true;
- }
-
- return false;
- }
-
- public int hashCode() {
- return this.name.hashCode();
- }
-
- public static class ExecuteRuleFlowNode
- implements
- Runnable {
- private final InternalAgenda agenda;
- private final RuleFlowNode[] nodes;
- private final Activation[] activations;
-
- public ExecuteRuleFlowNode(final InternalAgenda agenda,
- final RuleFlowNode[] nodes,
- final Activation[] activations) {
- this.agenda = agenda;
- this.nodes = nodes;
- this.activations = activations;
- }
-
- public void run() {
- for ( int i = 0, length = this.activations.length; i < length; i++ ) {
- this.agenda.fireActivation( this.activations[i] );
- }
-
- for ( int i = 0, length = this.nodes.length; i < length; i++ ) {
- this.nodes[i].activate();
- }
- }
- }
-}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/ScheduledAgendaItem.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/ScheduledAgendaItem.java 2007-01-23 00:39:35 UTC (rev 8986)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/ScheduledAgendaItem.java 2007-01-23 04:30:53 UTC (rev 8987)
@@ -22,6 +22,7 @@
import org.drools.rule.GroupElement;
import org.drools.rule.Rule;
import org.drools.spi.Activation;
+import org.drools.spi.AgendaGroup;
import org.drools.spi.PropagationContext;
import org.drools.spi.Tuple;
import org.drools.util.LinkedList;
@@ -69,7 +70,7 @@
private boolean activated;
- private ActivationGroupNode activationGroupNode;
+ private ActivationGroupNode activationGroupNode;
// ------------------------------------------------------------
// Constructors
@@ -185,7 +186,19 @@
public void setActivationGroupNode(final ActivationGroupNode activationGroupNode) {
this.activationGroupNode = activationGroupNode;
}
+
+ public RuleFlowGroupNode getRuleFlowGroupNode() {
+ throw new UnsupportedOperationException( "Scheduled activations cannot be in a Rule Flow Group" );
+ }
+ public void setRuleFlowGroupNode(RuleFlowGroupNode ruleFlowGroupNode) {
+ throw new UnsupportedOperationException( "Scheduled activations cannot be in a Rule Flow Group" );
+ }
+
+ public AgendaGroup getAgendaGroup() {
+ throw new UnsupportedOperationException( "Scheduled activations cannot be in an Agenda Group");
+ }
+
/*
* (non-Javadoc)
*
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleTerminalNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleTerminalNode.java 2007-01-23 00:39:35 UTC (rev 8986)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleTerminalNode.java 2007-01-23 04:30:53 UTC (rev 8987)
@@ -26,6 +26,7 @@
import org.drools.common.InternalWorkingMemory;
import org.drools.common.NodeMemory;
import org.drools.common.PropagationContextImpl;
+import org.drools.common.RuleFlowGroupImpl;
import org.drools.common.ScheduledAgendaItem;
import org.drools.rule.GroupElement;
import org.drools.rule.Rule;
@@ -34,6 +35,7 @@
import org.drools.spi.AgendaGroup;
import org.drools.spi.Duration;
import org.drools.spi.PropagationContext;
+import org.drools.spi.RuleFlowGroup;
import org.drools.util.Iterator;
import org.drools.util.TupleHashTable;
@@ -221,11 +223,26 @@
}
memory.getActivationGroup().addActivation( item );
}
+
+ if ( this.rule.getRuleFlowGroup() == null ) {
+ // No RuleFlowNode so add it directly to the Agenda
+
+ // Makes sure the Lifo is added to the AgendaGroup priority queue
+ // If the AgendaGroup is already in the priority queue it just
+ // returns.
+ agendaGroup.add( item );
+ } else {
+ //There is a RuleFlowNode so add it there, instead of the Agenda
+
+ // Lazy cache ruleFlowGroup
+ if ( memory.getRuleFlowGroup() == null ) {
+ memory.setRuleFlowGroup( workingMemory.getAgenda().getRuleFlowGroup( this.rule.getRuleFlowGroup() ) );
+ }
+ memory.getRuleFlowGroup().addActivation( item );
+ }
+
+ item.setAgendaGroup( agendaGroup );
- // Makes sure the Lifo is added to the AgendaGroup priority queue
- // If the AgendaGroup is already in the priority queue it just
- // returns.
- agendaGroup.add( item );
tuple.setActivation( item );
memory.getTupleMemory().add( tuple );
@@ -384,6 +401,8 @@
private AgendaGroupImpl agendaGroup;
private ActivationGroup activationGroup;
+
+ private RuleFlowGroup ruleFlowGroup;
private TupleHashTable tupleMemory;
@@ -410,5 +429,13 @@
public TupleHashTable getTupleMemory() {
return this.tupleMemory;
}
+
+ public RuleFlowGroup getRuleFlowGroup() {
+ return ruleFlowGroup;
+ }
+
+ public void setRuleFlowGroup(RuleFlowGroup ruleFlowGroup) {
+ this.ruleFlowGroup = ruleFlowGroup;
+ }
}
}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Rule.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Rule.java 2007-01-23 00:39:35 UTC (rev 8986)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Rule.java 2007-01-23 04:30:53 UTC (rev 8987)
@@ -83,7 +83,9 @@
/** makes the rule's much the current focus */
private boolean autoFocus;
- private String ActivationGroup;
+ private String activationGroup;
+
+ private String ruleFlowGroup;
/** indicates that the rule is semantically correct. */
private boolean semanticallyValid = true;
@@ -278,14 +280,24 @@
}
public String getActivationGroup() {
- return this.ActivationGroup;
+ return this.activationGroup;
}
- public void setXorGroup(final String activationGroup) {
- this.ActivationGroup = activationGroup;
+ public void setActivationGroup(final String activationGroup) {
+ this.activationGroup = activationGroup;
}
+
+
- /**
+ public String getRuleFlowGroup() {
+ return ruleFlowGroup;
+ }
+
+ public void setRuleFlowGroup(String ruleFlowGroup) {
+ this.ruleFlowGroup = ruleFlowGroup;
+ }
+
+ /**
* Retrieve a parameter <code>Declaration</code> by identifier.
*
* @param identifier
@@ -435,7 +447,7 @@
final Rule other = (Rule) object;
return (this.name.equals( other.name ) && this.agendaGroup.equals( other.agendaGroup )
- && ((this.ActivationGroup == null && other.ActivationGroup == null) || (this.ActivationGroup != null && this.ActivationGroup.equals( other.ActivationGroup ))) && this.salience == other.salience && this.noLoop == other.noLoop);
+ && ((this.activationGroup == null && other.activationGroup == null) || (this.activationGroup != null && this.activationGroup.equals( other.activationGroup ))) && this.salience == other.salience && this.noLoop == other.noLoop);
}
public int hashCode() {
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/Activation.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/Activation.java 2007-01-23 00:39:35 UTC (rev 8986)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/Activation.java 2007-01-23 04:30:53 UTC (rev 8987)
@@ -20,6 +20,7 @@
import org.drools.common.ActivationGroupNode;
import org.drools.common.LogicalDependency;
+import org.drools.common.RuleFlowGroupNode;
import org.drools.rule.GroupElement;
import org.drools.rule.Rule;
import org.drools.util.LinkedList;
@@ -81,8 +82,14 @@
public boolean isActivated();
public void setActivated(boolean activated);
+
+ public AgendaGroup getAgendaGroup();
public ActivationGroupNode getActivationGroupNode();
public void setActivationGroupNode(ActivationGroupNode activationGroupNode);
+
+ public RuleFlowGroupNode getRuleFlowGroupNode();
+
+ public void setRuleFlowGroupNode(RuleFlowGroupNode ruleFlowGroupNode);
}
\ No newline at end of file
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/RuleFlowGroup.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/RuleFlowGroup.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/RuleFlowGroup.java 2007-01-23 04:30:53 UTC (rev 8987)
@@ -0,0 +1,31 @@
+package org.drools.spi;
+
+import java.util.Iterator;
+
+
+public interface RuleFlowGroup {
+ public String getName();
+
+ public void addActivation(Activation activation);
+
+ public void removeActivation(Activation activation);
+
+ public Iterator iterator();
+
+ public boolean isEmpty();
+
+ public int size();
+
+ public void clear();
+
+ public abstract void addChild(final RuleFlowGroup child);
+
+ public abstract boolean removeChild(final RuleFlowGroup child);
+
+ public abstract void activate();
+
+ public abstract void activateChildren();
+
+ public abstract Activation[] getActivations();
+
+}
\ No newline at end of file
Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/AgendaTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/AgendaTest.java 2007-01-23 00:39:35 UTC (rev 8986)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/AgendaTest.java 2007-01-23 04:30:53 UTC (rev 8987)
@@ -39,6 +39,7 @@
import org.drools.spi.ConsequenceException;
import org.drools.spi.KnowledgeHelper;
import org.drools.spi.PropagationContext;
+import org.drools.spi.RuleFlowGroup;
/**
* @author mproctor
@@ -55,9 +56,9 @@
final Rule rule1 = new Rule( "test-rule1" );
final RuleTerminalNode node1 = new RuleTerminalNode( 3,
- new MockTupleSource( 2 ),
- rule1,
- rule1.getLhs());
+ new MockTupleSource( 2 ),
+ rule1,
+ rule1.getLhs() );
final ReteTuple tuple = new ReteTuple( new DefaultFactHandle( 1,
"cheese" ) );
@@ -107,9 +108,9 @@
final Rule rule = new Rule( "test-rule" );
final RuleTerminalNode node = new RuleTerminalNode( 3,
- new MockTupleSource( 2 ),
- rule,
- rule.getLhs() );
+ new MockTupleSource( 2 ),
+ rule,
+ rule.getLhs() );
final Map results = new HashMap();
// add consequence
@@ -230,9 +231,9 @@
// create a rule for each agendaGroup
final Rule rule0 = new Rule( "test-rule0" );
final RuleTerminalNode node0 = new RuleTerminalNode( 3,
- new MockTupleSource( 2 ),
- rule0,
- rule0.getLhs() );
+ new MockTupleSource( 2 ),
+ rule0,
+ rule0.getLhs() );
rule0.setConsequence( consequence );
final PropagationContext context0 = new PropagationContextImpl( 0,
PropagationContext.ASSERTION,
@@ -242,9 +243,9 @@
final Rule rule1 = new Rule( "test-rule1",
"agendaGroup1" );
final RuleTerminalNode node1 = new RuleTerminalNode( 5,
- new MockTupleSource( 4 ),
- rule1,
- rule1.getLhs() );
+ new MockTupleSource( 4 ),
+ rule1,
+ rule1.getLhs() );
rule1.setConsequence( consequence );
final PropagationContext context1 = new PropagationContextImpl( 0,
PropagationContext.ASSERTION,
@@ -254,9 +255,9 @@
final Rule rule2 = new Rule( "test-rule2",
"agendaGroup2" );
final RuleTerminalNode node2 = new RuleTerminalNode( 7,
- new MockTupleSource( 6 ),
- rule2,
- rule2.getLhs() );
+ new MockTupleSource( 6 ),
+ rule2,
+ rule2.getLhs() );
rule2.setConsequence( consequence );
final PropagationContext context2 = new PropagationContextImpl( 0,
PropagationContext.ASSERTION,
@@ -266,9 +267,9 @@
final Rule rule3 = new Rule( "test-rule3",
"agendaGroup3" );
final RuleTerminalNode node3 = new RuleTerminalNode( 9,
- new MockTupleSource( 8 ),
- rule3,
- rule3.getLhs() );
+ new MockTupleSource( 8 ),
+ rule3,
+ rule3.getLhs() );
rule3.setConsequence( consequence );
final PropagationContext context3 = new PropagationContextImpl( 0,
PropagationContext.ASSERTION,
@@ -447,9 +448,9 @@
final Rule rule = new Rule( "test-rule",
"agendaGroup" );
final RuleTerminalNode node = new RuleTerminalNode( 2,
- new MockTupleSource( 2 ),
- rule,
- rule.getLhs() );
+ new MockTupleSource( 2 ),
+ rule,
+ rule.getLhs() );
rule.setConsequence( consequence );
final PropagationContext context = new PropagationContextImpl( 0,
PropagationContext.ASSERTION,
@@ -495,7 +496,7 @@
// queue.size() );
}
- public void testXorGroup() {
+ public void testActivationGroup() {
final RuleBase ruleBase = RuleBaseFactory.newRuleBase();
final ReteooWorkingMemory workingMemory = (ReteooWorkingMemory) ruleBase.newWorkingMemory();
@@ -522,11 +523,11 @@
// create a rule for each agendaGroup
final Rule rule0 = new Rule( "test-rule0" );
- rule0.setXorGroup( "activation-group-0" );
+ rule0.setActivationGroup( "activation-group-0" );
final RuleTerminalNode node0 = new RuleTerminalNode( 3,
- new MockTupleSource( 2 ),
- rule0,
- rule0.getLhs() );
+ new MockTupleSource( 2 ),
+ rule0,
+ rule0.getLhs() );
rule0.setConsequence( consequence );
final PropagationContext context0 = new PropagationContextImpl( 0,
PropagationContext.ASSERTION,
@@ -534,11 +535,11 @@
null );
final Rule rule1 = new Rule( "test-rule1" );
- rule1.setXorGroup( "activation-group-0" );
+ rule1.setActivationGroup( "activation-group-0" );
final RuleTerminalNode node1 = new RuleTerminalNode( 5,
- new MockTupleSource( 4 ),
- rule1,
- rule1.getLhs() );
+ new MockTupleSource( 4 ),
+ rule1,
+ rule1.getLhs() );
rule1.setConsequence( consequence );
final PropagationContext context1 = new PropagationContextImpl( 0,
PropagationContext.ASSERTION,
@@ -547,9 +548,9 @@
final Rule rule2 = new Rule( "test-rule2" );
final RuleTerminalNode node2 = new RuleTerminalNode( 7,
- new MockTupleSource( 6 ),
- rule2,
- rule2.getLhs() );
+ new MockTupleSource( 6 ),
+ rule2,
+ rule2.getLhs() );
rule2.setConsequence( consequence );
final PropagationContext context2 = new PropagationContextImpl( 0,
PropagationContext.ASSERTION,
@@ -558,11 +559,11 @@
final Rule rule3 = new Rule( "test-rule3",
"agendaGroup3" );
- rule3.setXorGroup( "activation-group-3" );
+ rule3.setActivationGroup( "activation-group-3" );
final RuleTerminalNode node3 = new RuleTerminalNode( 9,
- new MockTupleSource( 8 ),
- rule3,
- rule3.getLhs() );
+ new MockTupleSource( 8 ),
+ rule3,
+ rule3.getLhs() );
rule3.setConsequence( consequence );
final PropagationContext context3 = new PropagationContextImpl( 0,
PropagationContext.ASSERTION,
@@ -661,4 +662,147 @@
}
+ public void testRuleFlowGroup() {
+ final RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+
+ final ReteooWorkingMemory workingMemory = (ReteooWorkingMemory) ruleBase.newWorkingMemory();
+
+ final InternalAgenda agenda = (InternalAgenda) workingMemory.getAgenda();
+
+ final List list = new ArrayList();
+
+ // create the consequence
+ final Consequence consequence = new Consequence() {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2596133893109870505L;
+
+ public void evaluate(KnowledgeHelper knowledgeHelper,
+ WorkingMemory workingMemory) {
+ list.add( knowledgeHelper.getRule() );
+ }
+ };
+
+ // create a rule for each rule flow groups
+ final Rule rule0 = new Rule( "test-rule0" );
+ rule0.setRuleFlowGroup( "rule-flow-group-0" );
+ rule0.setConsequence( consequence );
+
+ final RuleTerminalNode node0 = new RuleTerminalNode( 3,
+ new MockTupleSource( 2 ),
+ rule0,
+ rule0.getLhs() );
+
+ final Rule rule1 = new Rule( "test-rule1" );
+ rule1.setRuleFlowGroup( "rule-flow-group-1" );
+ rule1.setConsequence( consequence );
+
+ final RuleTerminalNode node1 = new RuleTerminalNode( 4,
+ new MockTupleSource( 2 ),
+ rule1,
+ rule1.getLhs() );
+
+ final Rule rule2 = new Rule( "test-rule2" );
+ rule2.setRuleFlowGroup( "rule-flow-group-2" );
+ rule2.setConsequence( consequence );
+ rule2.setSalience( 10 );
+
+ final RuleTerminalNode node2 = new RuleTerminalNode( 5,
+ new MockTupleSource( 2 ),
+ rule2,
+ rule2.getLhs() );
+
+ final PropagationContext context0 = new PropagationContextImpl( 0,
+ PropagationContext.ASSERTION,
+ rule0,
+ null );
+
+ final RuleFlowGroup ruleFlowGroup0 = agenda.getRuleFlowGroup( "rule-flow-group-0" );
+ final RuleFlowGroup ruleFlowGroup1 = agenda.getRuleFlowGroup( "rule-flow-group-1" );
+ final RuleFlowGroup ruleFlowGroup2 = agenda.getRuleFlowGroup( "rule-flow-group-2" );
+
+ ruleFlowGroup0.addChild( ruleFlowGroup1 );
+ ruleFlowGroup0.addChild( ruleFlowGroup2 );
+
+ final ReteTuple tuple0 = new ReteTuple( new DefaultFactHandle( 1,
+ "cheese" ) );
+ node0.assertTuple( tuple0,
+ context0,
+ workingMemory );
+
+ final ReteTuple tuple1 = new ReteTuple( new DefaultFactHandle( 1,
+ "cheese" ) );
+ node0.assertTuple( tuple1,
+ context0,
+ workingMemory );
+
+ final ReteTuple tuple2 = new ReteTuple( new DefaultFactHandle( 1,
+ "cheese" ) );
+ node1.assertTuple( tuple2,
+ context0,
+ workingMemory );
+
+ final ReteTuple tuple3 = new ReteTuple( new DefaultFactHandle( 1,
+ "cheese" ) );
+ node2.assertTuple( tuple3,
+ context0,
+ workingMemory );
+
+ // RuleFlowGroups should be populated, but the agenda shouldn't be
+ assertEquals( 2,
+ ruleFlowGroup0.size() );
+ assertEquals( 1,
+ ruleFlowGroup1.size() );
+ assertEquals( 1,
+ ruleFlowGroup2.size() );
+ assertEquals( 0,
+ agenda.agendaSize() );
+
+ // Activate the RuleFlowGroup, the nodes stay in the group, but should now also be in the Agenda
+ ruleFlowGroup0.activate();
+ assertEquals( 2,
+ ruleFlowGroup0.size() );
+ assertEquals( 2,
+ agenda.agendaSize() );
+
+ // As we fire each rule they are removed from both the Agenda and the RuleFlowGroup
+ agenda.fireNextItem( null );
+ assertEquals( 1,
+ ruleFlowGroup0.size() );
+ assertEquals( 1,
+ agenda.agendaSize() );
+
+ // on firing the last activation the child rule flow groups should
+ // activate and thus repopulate the agenda
+ agenda.fireNextItem( null );
+ assertEquals( 0,
+ ruleFlowGroup0.size() );
+ assertEquals( 1,
+ ruleFlowGroup1.size() );
+ assertEquals( 1,
+ ruleFlowGroup2.size() );
+ assertEquals( 2,
+ agenda.agendaSize() );
+
+ // we set the salience higher on rule2, so it sould fire first and empty ruleFlowGroup2
+ agenda.fireNextItem( null );
+ assertEquals( 1,
+ ruleFlowGroup1.size() );
+ assertEquals( 0,
+ ruleFlowGroup2.size() );
+ assertEquals( 1,
+ agenda.agendaSize() );
+
+ // this is the last activation, so everything shoud be empty after this
+ agenda.fireNextItem( null );
+ assertEquals( 0,
+ ruleFlowGroup0.size() );
+ assertEquals( 0,
+ ruleFlowGroup1.size() );
+ assertEquals( 0,
+ ruleFlowGroup2.size() );
+ assertEquals( 0,
+ agenda.agendaSize() );
+ }
}
More information about the jboss-svn-commits
mailing list