[jboss-svn-commits] JBL Code SVN: r9865 - in labs/jbossrules/trunk/drools-core/src: main/java/org/drools/common and 16 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Wed Feb 28 21:32:56 EST 2007
Author: KrisVerlaenen
Date: 2007-02-28 21:32:55 -0500 (Wed, 28 Feb 2007)
New Revision: 9865
Added:
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalRuleFlowGroup.java
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/ruleflow/
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/IProcess.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/impl/
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/impl/Process.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/IDataType.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/IDataTypeFactory.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/impl/
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/impl/InstanceDataTypeFactory.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/impl/NewInstanceDataTypeFactory.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/impl/type/
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/impl/type/BooleanDataType.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/impl/type/FloatDataType.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/impl/type/IntegerDataType.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/impl/type/ListDataType.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/impl/type/StringDataType.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/impl/type/UndefinedDataType.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/IProcessInstance.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/impl/
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/impl/ProcessInstance.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IConnection.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IConstraint.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IEndNode.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IJoin.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/INode.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IRuleFlowProcess.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IRuleFlowProcessValidationError.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IRuleFlowProcessValidator.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IRuleSetNode.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/ISplit.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IStartNode.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IVariable.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/Connection.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/Constraint.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/EndNode.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/Join.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/Node.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/RuleFlowProcess.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/RuleFlowProcessValidationError.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/RuleFlowProcessValidator.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/RuleSetNode.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/Split.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/StartNode.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/Variable.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/IRuleFlowNodeInstance.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/IRuleFlowProcessInstance.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/EndNodeInstance.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowJoinInstance.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowNodeInstance.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowProcessInstance.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowSequenceNodeInstance.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowSplitInstance.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/StartNodeInstance.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/RuleFlowGroup.java
labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/RuleFlowGroupTest.java
Removed:
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
Modified:
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/Agenda.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBase.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/SynchronizedWorkingMemory.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/WorkingMemory.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractRuleBase.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.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/reteoo/RuleTerminalNode.java
labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/AgendaTest.java
Log:
JBRULES-619: Rule Flow Core Implementation
- first implementation of ruleflow in core
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-03-01 02:19:52 UTC (rev 9864)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/Agenda.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -20,7 +20,23 @@
public AgendaGroup getAgendaGroup(String name);
public RuleFlowGroup getRuleFlowGroup(String name);
+
+ /**
+ * Activates the <code>RuleFlowGroup</code> with the given name.
+ * All activations in the given <code>RuleFlowGroup</code> are added to the agenda.
+ * As long as the <code>RuleFlowGroup</code> remains active,
+ * its activations are automatically added to the agenda.
+ */
+ public void activateRuleFlowGroup(String name);
+ /**
+ * Deactivates the <code>RuleFlowGroup</code> with the given name.
+ * All activations in the given <code>RuleFlowGroup</code> are removed from the agenda.
+ * As long as the <code>RuleFlowGroup</code> remains deactive,
+ * its activations are not added to the agenda
+ */
+ public void deactivateRuleFlowGroup(String name);
+
public AgendaGroup[] getAgendaGroups();
public AgendaGroup[] getStack();
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBase.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBase.java 2007-03-01 02:19:52 UTC (rev 9864)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBase.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -22,6 +22,7 @@
import java.util.Set;
import org.drools.rule.Package;
+import org.drools.ruleflow.common.core.IProcess;
/**
* Active collection of <code>Rule</code>s.
@@ -124,6 +125,12 @@
void removePackage(String packageName);
+ void addProcess(IProcess process);
+
+ void removeProcess(String id);
+
+ IProcess getProcess(String id);
+
void removeRule(String packageName,
String ruleName);
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/SynchronizedWorkingMemory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/SynchronizedWorkingMemory.java 2007-03-01 02:19:52 UTC (rev 9864)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/SynchronizedWorkingMemory.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -21,6 +21,7 @@
import org.drools.event.AgendaEventListener;
import org.drools.event.WorkingMemoryEventListener;
+import org.drools.ruleflow.common.instance.IProcessInstance;
import org.drools.spi.AgendaFilter;
import org.drools.spi.AgendaGroup;
import org.drools.spi.AsyncExceptionHandler;
@@ -182,4 +183,8 @@
this.workingMemory.setGlobal( name,
value );
}
+
+ public synchronized IProcessInstance startProcess(String processId) {
+ return this.workingMemory.startProcess(processId);
+ }
}
\ No newline at end of file
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/WorkingMemory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/WorkingMemory.java 2007-03-01 02:19:52 UTC (rev 9864)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/WorkingMemory.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -22,6 +22,7 @@
import org.drools.event.AgendaEventListener;
import org.drools.event.WorkingMemoryEventListener;
+import org.drools.ruleflow.common.instance.IProcessInstance;
import org.drools.spi.AgendaFilter;
import org.drools.spi.AgendaGroup;
import org.drools.spi.AsyncExceptionHandler;
@@ -298,4 +299,9 @@
*
*/
void dispose();
+
+ /**
+ * Starts a new process instance for the process with the given id.
+ */
+ IProcessInstance startProcess(String processId);
}
\ No newline at end of file
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractRuleBase.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractRuleBase.java 2007-03-01 02:19:52 UTC (rev 9864)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractRuleBase.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -43,6 +43,7 @@
import org.drools.rule.Package;
import org.drools.rule.PackageCompilationData;
import org.drools.rule.Rule;
+import org.drools.ruleflow.common.core.IProcess;
import org.drools.spi.FactHandleFactory;
/**
@@ -68,6 +69,8 @@
protected Map pkgs;
+ protected Map processes;
+
protected transient CompositePackageClassLoader packageClassLoader;
/** The fact handle factory. */
@@ -112,6 +115,7 @@
this.packageClassLoader = new CompositePackageClassLoader( Thread.currentThread().getContextClassLoader() );
this.pkgs = new HashMap();
+ this.processes = new HashMap();
this.globals = new HashMap();
this.workingMemories = new WeakHashMap();
}
@@ -216,6 +220,10 @@
return this.factHandleFactory.newInstance();
}
+ public IProcess[] getProcesses() {
+ return (IProcess[]) this.processes.values().toArray( new IProcess[this.processes.size()] );
+ }
+
public Package[] getPackages() {
return (Package[]) this.pkgs.values().toArray( new Package[this.pkgs.size()] );
}
@@ -445,7 +453,19 @@
}
protected abstract void removeRule(Rule rule);
+
+ public void addProcess(IProcess process) {
+ processes.put(process.getId(), process);
+ }
+ public void removeProcess(String id) {
+ processes.remove(id);
+ }
+
+ public IProcess getProcess(String id) {
+ return (IProcess) processes.get(id);
+ }
+
protected void addWorkingMemory(final WorkingMemory workingMemory,
final boolean keepReference) {
if ( keepReference ) {
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-03-01 02:19:52 UTC (rev 9864)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -46,6 +46,11 @@
import org.drools.event.WorkingMemoryEventListener;
import org.drools.event.WorkingMemoryEventSupport;
import org.drools.rule.Rule;
+import org.drools.ruleflow.common.core.IProcess;
+import org.drools.ruleflow.common.instance.IProcessInstance;
+import org.drools.ruleflow.core.IRuleFlowProcess;
+import org.drools.ruleflow.instance.IRuleFlowProcessInstance;
+import org.drools.ruleflow.instance.impl.RuleFlowProcessInstance;
import org.drools.spi.Activation;
import org.drools.spi.AgendaFilter;
import org.drools.spi.AgendaGroup;
@@ -1139,5 +1144,21 @@
this.activationOrigin );
}
}
+
+ public IProcessInstance startProcess(String processId) {
+ IProcess process = getRuleBase().getProcess(processId);
+ if (process == null) {
+ throw new IllegalArgumentException("Unknown process ID: " + processId);
+ }
+ if (process instanceof IRuleFlowProcess) {
+ IRuleFlowProcessInstance processInstance = new RuleFlowProcessInstance();
+ processInstance.setAgenda(agenda);
+ processInstance.setProcess(process);
+ processInstance.start();
+ return processInstance;
+ } else {
+ throw new IllegalArgumentException("Unknown process type: " + process.getClass());
+ }
+ }
}
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-03-01 02:19:52 UTC (rev 9864)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AgendaItem.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -23,7 +23,6 @@
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;
@@ -77,7 +76,7 @@
private ActivationGroupNode activationGroupNode;
- private RuleFlowGroupNode ruleFlowGroupNode;
+ private RuleFlowGroupNode ruleFlowGroupNode;
// ------------------------------------------------------------
// Constructors
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-03-01 02:19:52 UTC (rev 9864)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DefaultAgenda.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -265,7 +265,7 @@
}
public RuleFlowGroup getRuleFlowGroup(final String name) {
- RuleFlowGroupImpl ruleFlowGroup = (RuleFlowGroupImpl) this.ruleFlowGroups.get( name );
+ RuleFlowGroup ruleFlowGroup = (RuleFlowGroup) this.ruleFlowGroups.get( name );
if ( ruleFlowGroup == null ) {
ruleFlowGroup = new RuleFlowGroupImpl( name );
this.ruleFlowGroups.put( name,
@@ -273,6 +273,14 @@
}
return ruleFlowGroup;
}
+
+ public void activateRuleFlowGroup(String name) {
+ ((InternalRuleFlowGroup) getRuleFlowGroup(name)).setActive(true);
+ }
+
+ public void deactivateRuleFlowGroup(String name) {
+ ((InternalRuleFlowGroup) getRuleFlowGroup(name)).setActive(false);
+ }
/* (non-Javadoc)
* @see org.drools.common.AgendaI#focusStackSize()
@@ -371,8 +379,12 @@
item.getActivationGroupNode().getActivationGroup().removeActivation( item );
}
- eventsupport.getAgendaEventSupport().fireActivationCancelled( item,
- this.workingMemory );
+ if ( item.getRuleFlowGroupNode() != null ) {
+ final InternalRuleFlowGroup ruleFlowGroup = item.getRuleFlowGroupNode().getRuleFlowGroup();
+ ruleFlowGroup.removeActivation( item );
+ }
+
+ eventsupport.getAgendaEventSupport().fireActivationCancelled( item, this.workingMemory );
}
((AgendaGroupImpl) agendaGroup).clear();
}
@@ -401,8 +413,13 @@
if ( activation.isActivated() ) {
activation.setActivated( false );
activation.remove();
- eventsupport.getAgendaEventSupport().fireActivationCancelled( activation,
- this.workingMemory );
+
+ if ( activation.getRuleFlowGroupNode() != null ) {
+ final InternalRuleFlowGroup ruleFlowGroup = activation.getRuleFlowGroupNode().getRuleFlowGroup();
+ ruleFlowGroup.removeActivation( activation );
+ }
+
+ eventsupport.getAgendaEventSupport().fireActivationCancelled( activation, this.workingMemory );
}
}
activationGroup.clear();
@@ -473,15 +490,8 @@
}
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();
+ final InternalRuleFlowGroup 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/InternalRuleFlowGroup.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalRuleFlowGroup.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalRuleFlowGroup.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,25 @@
+package org.drools.common;
+
+import org.drools.spi.Activation;
+import org.drools.spi.RuleFlowGroup;
+
+public interface InternalRuleFlowGroup extends RuleFlowGroup {
+
+ void addActivation(Activation activation);
+
+ void removeActivation(Activation activation);
+
+ /**
+ * Activates or deactivates this <code>RuleFlowGroup</code>.
+ * When activating, all activations of this <code>RuleFlowGroup</code> are added
+ * to the agenda.
+ * As long as the <code>RuleFlowGroup</code> remains active,
+ * its activations are automatically added to the agenda.
+ * When deactivating, all activations of this <code>RuleFlowGroup</code> are removed
+ * to the agenda.
+ * As long as the <code>RuleFlowGroup</code> remains deactive,
+ * its activations are not added to the agenda.
+ */
+ void setActive(boolean active);
+
+}
Deleted: 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 2007-03-01 02:19:52 UTC (rev 9864)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/RuleFlowGroupImpl.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -1,195 +0,0 @@
-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/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-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,172 @@
+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 org.drools.ruleflow.instance.IRuleFlowNodeInstance;
+import org.drools.ruleflow.instance.impl.RuleFlowSequenceNodeInstance;
+import org.drools.spi.Activation;
+import org.drools.util.LinkedList;
+import org.drools.util.LinkedList.LinkedListIterator;
+
+/**
+ * Implementation of a <code>RuleFlowGroup</code> that collects activations
+ * of rules of this ruleflow-group.
+ * If this group is activated, all its activations are added to the agenda.
+ * As long as this group is active, its activations are added to the agenda.
+ * Deactivating the group removes all its activations from the agenda and
+ * collects them until it is activated again.
+ * By default, <code>RuleFlowGroups</code> are automatically deactivated when there are no more
+ * activations in the <code>RuleFlowGroup</code>. However, this can be configured.
+ *
+ * @author <a href="mailto:mark.proctor at jboss.com">Mark Proctor</a>
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ *
+ */
+public class RuleFlowGroupImpl extends RuleFlowSequenceNodeInstance implements InternalRuleFlowGroup {
+
+ private static final long serialVersionUID = 320L;
+
+ private final String name;
+ private boolean active = false;
+ private final LinkedList list;
+ private boolean autoDeactivate = true;
+
+ /**
+ * Construct a <code>RuleFlowGroupImpl</code> with the given name.
+ *
+ * @param name
+ * The RuleFlowGroup name.
+ */
+ public RuleFlowGroupImpl(final String name) {
+ this.name = name;
+ this.list = new LinkedList();
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public void setActive(boolean active) {
+ if (this.active == active) {
+ return;
+ }
+ this.active = active;
+ if (active) {
+ triggerActivations();
+ } else {
+ LinkedListIterator it = this.list.iterator();
+ for (RuleFlowGroupNode node = (RuleFlowGroupNode) it.next(); node != null; node = (RuleFlowGroupNode) it.next()) {
+ Activation activation = node.getActivation();
+ activation.remove();
+ if ( activation.getActivationGroupNode() != null ) {
+ activation.getActivationGroupNode().getActivationGroup().removeActivation( activation );
+ }
+ }
+ }
+ }
+
+ public boolean isActive() {
+ return active;
+ }
+
+ public boolean isAutoDeactivate() {
+ return autoDeactivate;
+ }
+
+ public void setAutoDeactivate(boolean autoDeactivate) {
+ this.autoDeactivate = autoDeactivate;
+ if (autoDeactivate && active && list.isEmpty()) {
+ active = false;
+ }
+ }
+
+ private void triggerActivations() {
+ // 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);
+ }
+ }
+
+ public void clear() {
+ LinkedListIterator it = this.list.iterator();
+ for (RuleFlowGroupNode node = (RuleFlowGroupNode) it.next(); node != null; node = (RuleFlowGroupNode) it.next()) {
+ node.getActivation().remove();
+ }
+ }
+
+ public int size() {
+ return this.list.size();
+ }
+
+ public void addActivation(final Activation activation) {
+ final RuleFlowGroupNode node = new RuleFlowGroupNode(activation, this);
+ activation.setRuleFlowGroupNode(node);
+ list.add( node );
+ if (active) {
+ ((AgendaGroupImpl) activation.getAgendaGroup()).add(activation);
+ }
+ }
+
+ public void removeActivation(final Activation activation) {
+ final RuleFlowGroupNode node = activation.getRuleFlowGroupNode();
+ list.remove(node);
+ activation.setActivationGroupNode(null);
+ if (autoDeactivate) {
+ if (list.isEmpty()) {
+ this.active = false;
+ // only trigger next node if this RuleFlowGroup was
+ // triggered from inside a process instance
+ if (getProcessInstance() != null) {
+ triggerCompleted();
+ }
+ }
+ }
+ }
+
+ public boolean isEmpty() {
+ return this.list.isEmpty();
+ }
+
+ 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();
+ }
+
+ public void trigger(IRuleFlowNodeInstance parent) {
+ setActive(true);
+ }
+}
Deleted: 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 2007-03-01 02:19:52 UTC (rev 9864)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/RuleFlowGroupNode.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -1,29 +0,0 @@
-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;
- }
-
-}
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-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,43 @@
+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 org.drools.spi.Activation;
+import org.drools.util.AbstractBaseLinkedListNode;
+
+public class RuleFlowGroupNode extends AbstractBaseLinkedListNode {
+
+ private static final long serialVersionUID = -6507208076979260126L;
+
+ private Activation activation;
+ private InternalRuleFlowGroup ruleFlowGroup;
+
+ public RuleFlowGroupNode(final Activation activation,
+ final InternalRuleFlowGroup ruleFlowGroup) {
+ super();
+ this.activation = activation;
+ this.ruleFlowGroup = ruleFlowGroup;
+ }
+
+ public Activation getActivation() {
+ return this.activation;
+ }
+
+ public InternalRuleFlowGroup getRuleFlowGroup() {
+ return this.ruleFlowGroup;
+ }
+
+}
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-03-01 02:19:52 UTC (rev 9864)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleTerminalNode.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -22,12 +22,11 @@
import org.drools.common.AgendaGroupImpl;
import org.drools.common.AgendaItem;
import org.drools.common.BaseNode;
-import org.drools.common.DefaultAgenda;
import org.drools.common.InternalAgenda;
+import org.drools.common.InternalRuleFlowGroup;
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;
@@ -225,6 +224,7 @@
memory.getActivationGroup().addActivation( item );
}
+ item.setAgendaGroup( agendaGroup );
if ( this.rule.getRuleFlowGroup() == null ) {
// No RuleFlowNode so add it directly to the Agenda
@@ -239,11 +239,9 @@
if ( memory.getRuleFlowGroup() == null ) {
memory.setRuleFlowGroup( workingMemory.getAgenda().getRuleFlowGroup( this.rule.getRuleFlowGroup() ) );
}
- memory.getRuleFlowGroup().addActivation( item );
- }
+ ((InternalRuleFlowGroup) memory.getRuleFlowGroup()).addActivation( item );
+ }
- item.setAgendaGroup( agendaGroup );
-
tuple.setActivation( item );
memory.getTupleMemory().add( tuple );
@@ -269,9 +267,14 @@
activation.remove();
if ( activation.getActivationGroupNode() != null ) {
- activation.getActivationGroupNode().getActivationGroup().removeActivation( activation );
+ activation.getActivationGroupNode().getActivationGroup().removeActivation( activation );
}
+ if ( activation.getRuleFlowGroupNode() != null ) {
+ final InternalRuleFlowGroup ruleFlowGroup = activation.getRuleFlowGroupNode().getRuleFlowGroup();
+ ruleFlowGroup.removeActivation( activation );
+ }
+
workingMemory.getAgendaEventSupport().fireActivationCancelled( activation,
workingMemory );
((InternalAgenda) workingMemory.getAgenda()).decreaseActiveActivations();
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/IProcess.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/IProcess.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/IProcess.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,76 @@
+package org.drools.ruleflow.common.core;
+/*
+ * 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.
+ */
+
+/**
+ * Represents a some process definition.
+ * A process has a name and a unique id.
+ * When a new version of a process is created, the name stays the same,
+ * but the id and the version of the process should be different.
+ * Different types of processes could be defined (like RuleFlow).
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public interface IProcess {
+
+ /**
+ * Sets the id of this process.
+ * The id should uniquely identify this process.
+ * @param id the id of the process
+ */
+ void setId(String id);
+ /**
+ * Returns the id of this process.
+ * @return the id of this process
+ */
+ String getId();
+
+ /**
+ * Sets the name of this process.
+ * @param name the name of this process
+ */
+ void setName(String name);
+ /**
+ * Returns the name of this process.
+ * If no name is specified, null is returned.
+ * @return the name of this process
+ */
+ String getName();
+
+ /**
+ * Sets the version of this process.
+ * @param version the version of this process
+ */
+ void setVersion(String version);
+ /**
+ * Returns the version of this process.
+ * If no version is specified, null is returned.
+ * @return the version of this process
+ */
+ String getVersion();
+
+ /**
+ * Sets the type of this process.
+ * @param type the type of this process
+ */
+ void setType(String type);
+ /**
+ * Returns the type of this process.
+ * @return the type of this process
+ */
+ String getType();
+
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/impl/Process.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/impl/Process.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/core/impl/Process.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,78 @@
+package org.drools.ruleflow.common.core.impl;
+/*
+ * 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.io.Serializable;
+
+import org.drools.ruleflow.common.core.IProcess;
+
+/**
+ * Default implementation of a Process
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public class Process implements IProcess, Serializable {
+ private static final long serialVersionUID = 3904955335549399096L;
+
+ private String id;
+ private String name;
+ private String version;
+ private String type;
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public boolean equals(Object o) {
+ if (o instanceof Process) {
+ return ((Process) o).getName().equals(name)
+ && ((Process) o).getVersion().equals(version);
+ }
+ return false;
+ }
+
+ public int hashCode() {
+ return name.hashCode() + 3*version.hashCode();
+ }
+}
\ No newline at end of file
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/IDataType.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/IDataType.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/IDataType.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,33 @@
+package org.drools.ruleflow.common.datatype;
+/*
+ * 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.io.Serializable;
+
+/**
+ * Abstract representation of a datatype.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public interface IDataType extends Serializable {
+
+
+ /**
+ * Returns true if the given value is a valid value of this data type.
+ */
+ boolean verifyDataType(Object value);
+
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/IDataTypeFactory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/IDataTypeFactory.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/IDataTypeFactory.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,27 @@
+package org.drools.ruleflow.common.datatype;
+/*
+ * 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.
+ */
+
+/**
+ * A factory for creating a datatype.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public interface IDataTypeFactory {
+
+ IDataType createDataType();
+
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/impl/InstanceDataTypeFactory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/impl/InstanceDataTypeFactory.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/impl/InstanceDataTypeFactory.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,48 @@
+package org.drools.ruleflow.common.datatype.impl;
+/*
+ * 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 org.drools.ruleflow.common.datatype.IDataType;
+import org.drools.ruleflow.common.datatype.IDataTypeFactory;
+
+/**
+ * A data type factory that always returns the same instance of a given class.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public class InstanceDataTypeFactory implements IDataTypeFactory {
+
+ private Class dataTypeClass;
+ private IDataType instance;
+
+ public InstanceDataTypeFactory(Class dataTypeClass) {
+ this.dataTypeClass = dataTypeClass;
+ }
+
+ public IDataType createDataType() {
+ if (instance == null) {
+ try {
+ instance = (IDataType) dataTypeClass.newInstance();
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException("Could not create data type for class " + dataTypeClass, e);
+ } catch (InstantiationException e) {
+ throw new RuntimeException("Could not create data type for class " + dataTypeClass, e);
+ }
+ }
+ return instance;
+ }
+
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/impl/NewInstanceDataTypeFactory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/impl/NewInstanceDataTypeFactory.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/impl/NewInstanceDataTypeFactory.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,44 @@
+package org.drools.ruleflow.common.datatype.impl;
+/*
+ * 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 org.drools.ruleflow.common.datatype.IDataType;
+import org.drools.ruleflow.common.datatype.IDataTypeFactory;
+
+/**
+ * A data type factory that always returns a new instance of a given class.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public class NewInstanceDataTypeFactory implements IDataTypeFactory {
+
+ private Class dataTypeClass;
+
+ public NewInstanceDataTypeFactory(Class dataTypeClass) {
+ this.dataTypeClass = dataTypeClass;
+ }
+
+ public IDataType createDataType() {
+ try {
+ return (IDataType) dataTypeClass.newInstance();
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException("Could not create data type for class " + dataTypeClass, e);
+ } catch (InstantiationException e) {
+ throw new RuntimeException("Could not create data type for class " + dataTypeClass, e);
+ }
+ }
+
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/impl/type/BooleanDataType.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/impl/type/BooleanDataType.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/impl/type/BooleanDataType.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,35 @@
+package org.drools.ruleflow.common.datatype.impl.type;
+/*
+ * 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 org.drools.ruleflow.common.datatype.IDataType;
+
+/**
+ * Representation of a boolean datatype.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public final class BooleanDataType implements IDataType {
+
+ private static final long serialVersionUID = 3617855257384989752L;
+
+ public boolean verifyDataType(Object value) {
+ if (value instanceof Boolean) {
+ return true;
+ }
+ return false;
+ }
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/impl/type/FloatDataType.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/impl/type/FloatDataType.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/impl/type/FloatDataType.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,38 @@
+package org.drools.ruleflow.common.datatype.impl.type;
+/*
+ * 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 org.drools.ruleflow.common.datatype.IDataType;
+
+/**
+ * Representation of a float datatype.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public final class FloatDataType implements IDataType {
+
+ private static final long serialVersionUID = 3257008760991069747L;
+
+ public boolean verifyDataType(Object value) {
+ if (value instanceof Float) {
+ return true;
+ } else if (value == null) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/impl/type/IntegerDataType.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/impl/type/IntegerDataType.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/impl/type/IntegerDataType.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,38 @@
+package org.drools.ruleflow.common.datatype.impl.type;
+/*
+ * 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 org.drools.ruleflow.common.datatype.IDataType;
+
+/**
+ * Representation of an integer datatype.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public class IntegerDataType implements IDataType {
+
+ private static final long serialVersionUID = 3256443611980838707L;
+
+ public boolean verifyDataType(Object value) {
+ if (value instanceof Integer) {
+ return true;
+ } else if (value == null) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/impl/type/ListDataType.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/impl/type/ListDataType.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/impl/type/ListDataType.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,58 @@
+package org.drools.ruleflow.common.datatype.impl.type;
+/*
+ * 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.io.Serializable;
+import java.util.Iterator;
+import java.util.List;
+
+import org.drools.ruleflow.common.datatype.IDataType;
+
+/**
+ * Representation of a list datatype.
+ * All elements in the list must have the same datatype.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public class ListDataType implements IDataType, Serializable {
+
+ private static final long serialVersionUID = 3689069551774415161L;
+
+ private IDataType dataType;
+
+ public void setDataType(IDataType dataType) {
+ this.dataType = dataType;
+ }
+
+ public IDataType getDataType() {
+ return dataType;
+ }
+
+ public boolean verifyDataType(Object value) {
+ if (value == null) {
+ return true;
+ }
+ if (value instanceof List) {
+ for (Iterator it = ((List) value).iterator(); it.hasNext(); ) {
+ if (!dataType.verifyDataType(it.next())) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/impl/type/StringDataType.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/impl/type/StringDataType.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/impl/type/StringDataType.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,38 @@
+package org.drools.ruleflow.common.datatype.impl.type;
+/*
+ * 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 org.drools.ruleflow.common.datatype.IDataType;
+
+/**
+ * Representation of a string datatype.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public class StringDataType implements IDataType {
+
+ private static final long serialVersionUID = 3258416135924758834L;
+
+ public boolean verifyDataType(Object value) {
+ if (value instanceof String) {
+ return true;
+ } else if (value == null) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/impl/type/UndefinedDataType.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/impl/type/UndefinedDataType.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/datatype/impl/type/UndefinedDataType.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,43 @@
+package org.drools.ruleflow.common.datatype.impl.type;
+/*
+ * 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 org.drools.ruleflow.common.datatype.IDataType;
+
+/**
+ * Representation of an undefined datatype.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public final class UndefinedDataType implements IDataType {
+
+ private static final long serialVersionUID = 3690196546763699768L;
+ private static UndefinedDataType instance;
+
+ public static UndefinedDataType getInstance() {
+ if (instance == null) {
+ instance = new UndefinedDataType();
+ }
+ return instance;
+ }
+
+ public boolean verifyDataType(Object value) {
+ if (value == null) {
+ return true;
+ }
+ return false;
+ }
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/IProcessInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/IProcessInstance.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/IProcessInstance.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,46 @@
+package org.drools.ruleflow.common.instance;
+/*
+ * 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.io.Serializable;
+
+import org.drools.ruleflow.common.core.IProcess;
+
+/**
+ * A process instance is the representation of a process during its execution.
+ * It contains all the runtime status information about the running process.
+ * A process can have multiple instances.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public interface IProcessInstance extends Serializable {
+
+ int STATE_PENDING = 0;
+ int STATE_ACTIVE = 1;
+ int STATE_COMPLETED = 2;
+ int STATE_ABORTED = 3;
+ int STATE_SUSPENDED = 4;
+
+ void setId(long id);
+ long getId();
+
+ void setProcess(IProcess process);
+ IProcess getProcess();
+
+ void setState(int state);
+ int getState();
+
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/impl/ProcessInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/impl/ProcessInstance.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/common/instance/impl/ProcessInstance.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,66 @@
+package org.drools.ruleflow.common.instance.impl;
+/*
+ * 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 org.drools.ruleflow.common.core.IProcess;
+import org.drools.ruleflow.common.instance.IProcessInstance;
+
+/**
+ * Default implementation of a process instance.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public abstract class ProcessInstance implements IProcessInstance {
+
+ private long id;
+ private IProcess process;
+ private int state = STATE_PENDING;
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setProcess(IProcess process) {
+ this.process = process;
+ }
+
+ public IProcess getProcess() {
+ return process;
+ }
+
+ public void setState(int state) {
+ this.state = state;
+ }
+
+ public int getState() {
+ return state;
+ }
+
+ public String toString() {
+ StringBuilder b = new StringBuilder("ProcessInstance ");
+ b.append(getId());
+ b.append(" [processId=");
+ b.append(process.getId());
+ b.append(",state=");
+ b.append(state);
+ b.append("]");
+ return b.toString();
+ }
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IConnection.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IConnection.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IConnection.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,57 @@
+package org.drools.ruleflow.core;
+/*
+ * 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.
+ */
+
+/**
+ * Represents a connection between two nodes in a RuleFlow.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public interface IConnection {
+
+ /**
+ * The connection type
+ */
+ int TYPE_NORMAL = 1;
+ int TYPE_ABORT = 2;
+
+ /**
+ * Returns the from node of the connection.
+ * @return the from node of the connection.
+ */
+ INode getFrom();
+
+ /**
+ * Returns the to node of the connection
+ * @return the to node of the connection
+ */
+ INode getTo();
+
+ /**
+ * Returns the connection type
+ * @return the connection type
+ */
+ int getType();
+
+ /**
+ * Destroys the connection. This method also removes the
+ * connection on the <code>to</code> and <code>from</code> nodes.
+ * Onces a connection is destroyed, all methods throw
+ * an <code>IllegalStateException</code>.
+ */
+ void terminate();
+
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IConstraint.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IConstraint.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IConstraint.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,64 @@
+package org.drools.ruleflow.core;
+/*
+ * 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.
+ */
+
+/**
+ * Represents a constraint in a RuleFlow.
+ * Can be used to specify conditions in (X)OR-splits.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public interface IConstraint {
+
+ /**
+ * Typically this method returns the constraint
+ * @return the constraint
+ */
+ String getConstraint();
+
+ /**
+ * Method for setting the constraint
+ * @param constraint the constraint
+ */
+ void setConstraint(String constraint);
+
+ /**
+ * Returns the name of the constraint
+ * @return the name of the constraint
+ */
+ String getName();
+
+ /**
+ * Sets the name of the constraint
+ * @param name the name of the constraint
+ */
+ void setName(String name);
+
+ /**
+ * Returns the priority of the constriant
+ *
+ * @return the priority of the constraint
+ */
+ int getPriority();
+
+ /**
+ * Method for setting the priority of the constraint
+ *
+ * @param priority the priority of the constraint
+ */
+ void setPriority(int priority);
+
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IEndNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IEndNode.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IEndNode.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,33 @@
+package org.drools.ruleflow.core;
+/*
+ * 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.
+ */
+
+
+/**
+ * Represents an end node in a RuleFlow.
+ * An end node has one incoming and no outgoing connections.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public interface IEndNode extends INode {
+
+ /**
+ * Convenience method for returning the incoming <code>IConnection</code>.
+ * @return the incoming <code>IConnection</code>
+ */
+ IConnection getFrom();
+
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IJoin.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IJoin.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IJoin.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,64 @@
+package org.drools.ruleflow.core;
+/*
+ * 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.
+ */
+
+/**
+ * Represents a join node in a RuleFlow.
+ * A join is a special kind of node with multiple incoming connections and
+ * one outgoing connection. The type of join decides when the outgoing
+ * connections will be triggered (based on which incoming connections have
+ * been triggered).
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public interface IJoin extends INode {
+
+ int TYPE_UNDEFINED = 0;
+ /**
+ * The outgoing connection of a join of this type is triggered
+ * when all its incoming connections have been triggered.
+ */
+ int TYPE_AND = 1;
+ /**
+ * The outgoing connection of a join of this type is triggered
+ * when one of its incoming connections has been triggered.
+ */
+ int TYPE_XOR = 2;
+
+ /**
+ * Sets the type of the join.
+ *
+ * @param type The type of the join
+ * @throws IllegalArgumentException if type is null
+ */
+ void setType(int type);
+
+ /**
+ * Returns the type of the join.
+ *
+ * @return the type of the join.
+ */
+ int getType();
+
+ /**
+ * Convenience method for returning the outgoing connection of the join
+ *
+ * @return the outgoing connection of the join
+ */
+ IConnection getTo();
+
+
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/INode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/INode.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/INode.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,68 @@
+package org.drools.ruleflow.core;
+/*
+ * 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.io.Serializable;
+import java.util.List;
+
+/**
+ * Represents a node in a RuleFlow.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public interface INode extends Serializable {
+
+ /**
+ * Returns the id of the node
+ *
+ * @return the id of the node
+ */
+ long getId();
+
+ /**
+ * Method for setting the id of the node
+ *
+ * @param id the id of the node
+ */
+ void setId(long id);
+
+ /**
+ * Returns the name of the node
+ *
+ * @return the name of the node
+ */
+ String getName();
+
+ /**
+ * Method for setting the name of the node
+ *
+ * @param name the name of the node
+ */
+ void setName(String name);
+
+ /**
+ * Returns the incoming connections
+ * @return the incoming connections
+ */
+ List getIncomingConnections();
+
+ /**
+ * Returns the outgoing connections
+ * @return the outgoing connections
+ */
+ List getOutgoingConnections();
+
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IRuleFlowProcess.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IRuleFlowProcess.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IRuleFlowProcess.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,91 @@
+package org.drools.ruleflow.core;
+/*
+ * 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.List;
+
+import org.drools.ruleflow.common.core.IProcess;
+
+/**
+ * Represents a RuleFlow process.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public interface IRuleFlowProcess extends IProcess {
+
+ /**
+ * Returns the start node of this RuleFlow process.
+ *
+ * @return the start node
+ */
+ IStartNode getStart();
+
+
+ /**
+ * Returns the nodes of this RuleFlow process.
+ *
+ * @return the nodes of this RuleFlow process
+ */
+ INode[] getNodes();
+
+ /**
+ * Returns the node with the given id
+ *
+ * @param id the node id
+ * @return the node with the given id
+ * @throws IllegalArgumentException if an unknown id is passed
+ */
+ INode getNode(long id);
+
+ /**
+ * Method for adding a node to this RuleFlow process.
+ * Note that the node will get an id unique for this process.
+ *
+ * @param node the node to be added
+ * @throws IllegalArgumentException if <code>node</code> is null
+ */
+ void addNode(INode node);
+
+ /**
+ * Method for removing a node from this RuleFlow process
+ *
+ * @param node the node to be removed
+ * @throws IllegalArgumentException if <code>node</code> is null or unknown
+ */
+ void removeNode(INode node);
+
+ /**
+ * Returns the global variables used in this RuleFlow process
+ *
+ * @return a list of variables of this RuleFlow process
+ */
+ List getVariables();
+
+ /**
+ * Sets the global variables used in this RuleFlow process
+ *
+ * @param variables the variables
+ * @throws IllegalArugmentException if <code>variables</code> is null
+ */
+ void setVariables(List variables);
+
+ /**
+ * Returns the names of the global variables used in this RuleFlow process
+ *
+ * @return the variable names of this RuleFlow process
+ */
+ String[] getVariableNames();
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IRuleFlowProcessValidationError.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IRuleFlowProcessValidationError.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IRuleFlowProcessValidationError.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,45 @@
+package org.drools.ruleflow.core;
+/*
+ * 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.
+ */
+
+/**
+ * Represents a RuleFlow validation error.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public interface IRuleFlowProcessValidationError {
+
+ String NO_PROCESS_NAME = "RuleFlow process has no name.";
+ String NO_PROCESS_ID = "RuleFlow process has no id.";
+ String NO_START_NODE = "RuleFlow process has no start node.";
+ String START_NODE_WITHOUT_OUTGOING_NODES = "Start node has no outgoing connection.";
+ String END_NODE_HAS_NO_INCOMING_CONNECTIONS = "End node has no incoming connection.";
+ String NO_END_NODE = "No end node found.";
+ String RULE_SET_NODE_WITHOUT_INCOMING_CONNECTIONS = "RuleSet node has no incoming connection.";
+ String RULE_SET_NODE_WITHOUT_OUTGOING_CONNECTIONS = "RuleSet node has no outgoing connection.";
+ String RULE_SET_NODE_WITHOUT_RULE_SET_GROUP = "RuleSet node has no ruleflow-group specified.";
+ String SPLIT_WITHOUT_TYPE = "Split node has no type.";
+ String SPLIT_WITHOUT_INCOMING_CONNECTION = "Split node has no incoming connection.";
+ String SPLIT_NOT_ENOUGH_OUTGOING_CONNECTIONS = "Split node does not have enough outgoing connections.";
+ String SPLIT_OUTGOING_CONNECTION_WITHOUT_CONSTRAINT = "An outgoing connection of a split node has no constraint.";
+ String JOIN_WITHOUT_TYPE = "Join node has no type.";
+ String JOIN_NOT_ENOUGH_INCOMING_CONNECTIONS = "Join node does not have enough incoming connections.";
+ String JOIN_WITHOUT_OUTGOING_CONNECTION = "Join node has no outgoing connection.";
+ String VARIABLE_WITHOUT_TYPE = "A variable has no type.";
+ String ALL_NODES_CONNECTED_TO_START = "A node is not connected to the start node.";
+
+ String getType();
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IRuleFlowProcessValidator.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IRuleFlowProcessValidator.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IRuleFlowProcessValidator.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,27 @@
+package org.drools.ruleflow.core;
+/*
+ * 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.
+ */
+
+/**
+ * A validator for validating a RuleFlow process.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public interface IRuleFlowProcessValidator {
+
+ IRuleFlowProcessValidationError[] validateProcess(IRuleFlowProcess process);
+
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IRuleSetNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IRuleSetNode.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IRuleSetNode.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,53 @@
+package org.drools.ruleflow.core;
+/*
+ * 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.
+ */
+
+/**
+ * Represents a node containing a set of rules in a RuleFlow.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public interface IRuleSetNode extends INode {
+
+ /**
+ * Returns the incoming connection of the RuleSetNode.
+ *
+ * @return the incoming connection of the RuleSetNode.
+ */
+ IConnection getFrom();
+
+ /**
+ * Returns the outgoing connection of the RuleSetNode.
+ *
+ * @return the outgoing connection of the RuleSetNode.
+ */
+ IConnection getTo();
+
+ /**
+ * Returns the ruleflow-group of the RuleSetNode.
+ *
+ * @return the ruleflow-group of the RuleSetNode.
+ */
+ String getRuleFlowGroup();
+
+ /**
+ * Sets the ruleflow-group of the RuleSetNode.
+ *
+ * @param ruleFlowGroup The ruleflow-group of the RuleSetNode
+ * @throws IllegalArgumentException if type is null
+ */
+ void setRuleFlowGroup(String ruleFlowGroup);
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/ISplit.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/ISplit.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/ISplit.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,113 @@
+package org.drools.ruleflow.core;
+/*
+ * 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.Map;
+
+/**
+ * Represents a split node in a RuleFlow.
+ * A split is a special kind of node with one incoming connection and
+ * multiple outgoing connections. The type of split decides which of the
+ * outgoing connections will be triggered when the incoming connection
+ * has been triggered.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public interface ISplit extends INode {
+
+ int TYPE_UNDEFINED = 0;
+ /**
+ * All outgoing connections of a split of this type are triggered
+ * when its incoming connection has been triggered. A split of this
+ * type should have no constraints linked to any of its outgoing
+ * connections.
+ */
+ int TYPE_AND = 1;
+ /**
+ * Exactly one outgoing connection of a split of this type is triggered
+ * when its incoming connection has been triggered. Which connection
+ * is based on the constraints associated with each of the connections:
+ * the connection with the highest priority whose constraint is satisfied
+ * is triggered.
+ */
+ int TYPE_XOR = 2;
+ /**
+ * One or multiple outgoing connections of a split of this type are
+ * triggered when its incoming connection has been triggered. Which
+ * connections is based on the constraints associated with each of the
+ * connections: all connections whose constraint is satisfied are
+ * triggered.
+ */
+ int TYPE_OR = 3;
+
+ /**
+ * Sets the type of the split.
+ *
+ * @param type The type of the split
+ * @throws IllegalArgumentException if type is null
+ */
+ void setType(int type);
+
+ /**
+ * Returns the type of the split.
+ *
+ * @return the type of the split.
+ */
+ int getType();
+
+ /**
+ * Returns the corresponding constraint of the given outgoing connection
+ *
+ * @param connection the outgoing connection
+ * @return the corresponding constraint of the given outgoing connection
+ * @throws IllegalArgumentException if <code>connection</code> is
+ * not a valid outgoing connection for this split
+ * @throws UnsupportedOperationException if this method is called
+ * on a split with split type of something else than XOR or OR
+ */
+ IConstraint getConstraint(IConnection connection);
+
+ /**
+ * Method for setting a constraint corresponding to the given
+ * outgoing connection
+ *
+ * @param connection the outgoing connection
+ * @param constraint the constraint
+ * @throws IllegalArgumentException if <code>connection</code> is
+ * not a valid outgoing connection for this split
+ * @throws UnsupportedOperationException if the split type is
+ * something else than XOR or OR
+ */
+ void setConstraint(IConnection connection, IConstraint constraint);
+
+ /**
+ * Returns the constraints of the split.
+ *
+ * @return a map containing for each connection the constraint associated with
+ * that connection, or null if no constraint has been specified yet for that connection
+ * @throws UnsupportedOperationException if this method is called
+ * on a split with split type of something else than XOR or OR
+ */
+ Map getConstraints();
+
+ /**
+ * Convenience method for returning the incoming connection of the split.
+ *
+ * @return the incoming connection ot the split.
+ */
+ IConnection getFrom();
+
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IStartNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IStartNode.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IStartNode.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,32 @@
+package org.drools.ruleflow.core;
+/*
+ * 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.
+ */
+
+/**
+ * Represents a start node in a RuleFlow.
+ * A start node has no incoming and one outgoing connection.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public interface IStartNode extends INode {
+
+ /**
+ * Convenience method for returning the outgoing <code>IConnection</code>.
+ * @return the outgoing <code>IConnection</code>
+ */
+ IConnection getTo();
+
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IVariable.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IVariable.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/IVariable.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,40 @@
+package org.drools.ruleflow.core;
+/*
+ * 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.io.Serializable;
+
+import org.drools.ruleflow.common.datatype.IDataType;
+
+/**
+ * Represents a global variable used in a RuleFlow.
+ * A variable has a name (should be unique for this process), a datatype
+ * and possibly an initial value.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public interface IVariable {
+
+ String getName();
+ void setName(String name);
+
+ IDataType getType();
+ void setType(IDataType type);
+
+ Serializable getValue();
+ void setValue(Serializable value);
+
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/Connection.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/Connection.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/Connection.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,107 @@
+package org.drools.ruleflow.core.impl;
+/*
+ * 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.io.Serializable;
+
+import org.drools.ruleflow.core.IConnection;
+import org.drools.ruleflow.core.INode;
+
+/**
+ * Default implementation of a connection.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public class Connection implements IConnection, Serializable {
+
+ private static final long serialVersionUID = 3256439218229424434L;
+
+ private int type;
+ private Node from;
+ private Node to;
+
+ private Connection() {
+ }
+
+ /**
+ * Creates a new connection, given a from node, a to node
+ * and a type.
+ *
+ * @param from The from node
+ * @param to The to node
+ * @param type The connection type
+ */
+ public Connection(INode from, INode to, int type) {
+ if (from == null) {
+ throw new IllegalArgumentException("From node is null!");
+ }
+ if (to == null) {
+ throw new IllegalArgumentException("To node is null!");
+ }
+ if (from.equals(to)) {
+ throw new IllegalArgumentException("To and from nodes are the same!");
+ }
+ this.from = (Node) from;
+ this.to = (Node) to;
+ this.type = type;
+ this.from.addOutgoingConnection(this);
+ this.to.addIncomingConnection(this);
+ }
+
+ public synchronized void terminate() {
+ from.removeOutgoingConnection(this);
+ to.removeIncomingConnection(this);
+ type = 0;
+ from = null;
+ to = null;
+ }
+
+ public INode getFrom() {
+ return from;
+ }
+
+ public INode getTo() {
+ return to;
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public boolean equals(Object object) {
+ if (object instanceof Connection) {
+ Connection connection = (Connection) object;
+ return type == connection.getType() && getFrom().equals(connection.getFrom())
+ && getTo().equals(connection.getTo());
+ }
+ return false;
+ }
+
+ public int hashCode() {
+ return getFrom().hashCode() + 3*getTo().hashCode() + 5*getType();
+ }
+
+ public String toString() {
+ StringBuilder sb = new StringBuilder("Connection ");
+ sb.append(getFrom());
+ sb.append(" - ");
+ sb.append(getTo());
+ sb.append(" [type=");
+ sb.append(getType());
+ sb.append("]");
+ return sb.toString();
+ }
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/Constraint.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/Constraint.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/Constraint.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,62 @@
+package org.drools.ruleflow.core.impl;
+/*
+ * 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.io.Serializable;
+
+import org.drools.ruleflow.core.IConstraint;
+
+/**
+ * Default implementation of a constraint.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public class Constraint implements IConstraint, Serializable {
+
+ private static final long serialVersionUID = 3257849861633422902L;
+
+ private String name;
+ private String constraint;
+ private int priority;
+
+ public String getConstraint() {
+ return constraint;
+ }
+
+ public void setConstraint(String constraint) {
+ this.constraint = constraint;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String toString() {
+ return name;
+ }
+
+ public int getPriority() {
+ return priority;
+ }
+
+ public void setPriority(int priority) {
+ this.priority = priority;
+ }
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/EndNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/EndNode.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/EndNode.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,54 @@
+package org.drools.ruleflow.core.impl;
+/*
+ * 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.List;
+
+import org.drools.ruleflow.core.IConnection;
+import org.drools.ruleflow.core.IEndNode;
+
+/**
+ * Default implementation of an end node.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public class EndNode extends Node implements IEndNode {
+
+ private static final long serialVersionUID = 3906930075512484153L;
+
+ public IConnection getFrom() {
+ List list = getIncomingConnections();
+ if (list.size() > 0) {
+ return (IConnection) list.get(0);
+ }
+ return null;
+ }
+
+ protected void validateAddIncomingConnection(IConnection connection) {
+ super.validateAddIncomingConnection(connection);
+ if (getIncomingConnections().size() > 0) {
+ throw new IllegalArgumentException("An end node cannot have more than one incoming connection");
+ }
+ }
+
+ protected void validateAddOutgoingConnection(IConnection connection) {
+ throw new UnsupportedOperationException("An end node does not have an outgoing connection");
+ }
+
+ protected void validateRemoveOutgoingConnection(IConnection connection) {
+ throw new UnsupportedOperationException("An end node does not have an outgoing connection");
+ }
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/Join.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/Join.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/Join.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,62 @@
+package org.drools.ruleflow.core.impl;
+/*
+ * 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 org.drools.ruleflow.core.IConnection;
+import org.drools.ruleflow.core.IJoin;
+
+/**
+ * Default implementation of a join.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public class Join extends Node implements IJoin {
+
+ private static final long serialVersionUID = 3257004367155573815L;
+
+ private int type;
+
+ public Join() {
+ this.type = TYPE_UNDEFINED;
+ }
+
+ public void setType(int type) {
+ this.type = type;
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public IConnection getTo() {
+ if (getOutgoingConnections().size() > 0) {
+ return (IConnection) getOutgoingConnections().get(0);
+ }
+ return null;
+ }
+
+ protected void validateAddOutgoingConnection(IConnection connection) {
+ super.validateAddOutgoingConnection(connection);
+ if (connection.getType() != IConnection.TYPE_NORMAL) {
+ throw new IllegalArgumentException("Unknown connection type :" + connection.getType()
+ + ", only NORMAL is allowed as outgoing connection.");
+ }
+ if (getOutgoingConnections().size() > 0) {
+ throw new IllegalArgumentException("A join cannot have more than one outgoing connection");
+ }
+ }
+
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/Node.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/Node.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/Node.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,181 @@
+package org.drools.ruleflow.core.impl;
+/*
+ * 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.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.drools.ruleflow.core.IConnection;
+import org.drools.ruleflow.core.INode;
+
+/**
+ * Default implementation of a node.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public abstract class Node implements INode, Serializable {
+
+ protected static final Node[] EMPTY_NODE_ARRAY = new Node[0];
+
+ private long id;
+ private String name;
+ private List incomingConnections;
+ private List outgoingConnections;
+
+ public Node() {
+ this.id = -1;
+ incomingConnections = new ArrayList();
+ outgoingConnections = new ArrayList();
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public List getIncomingConnections() {
+ return Collections.unmodifiableList(incomingConnections);
+ }
+
+ public List getOutgoingConnections() {
+ return Collections.unmodifiableList(outgoingConnections);
+ }
+
+ protected void addIncomingConnection(IConnection connection) {
+ validateAddIncomingConnection(connection);
+ incomingConnections.add(connection);
+ }
+
+ /**
+ * This method validates whether the given connection can be added. If the
+ * connection cannot be added, an IllegalArgumentException is thrown.
+ * <p>
+ *
+ * @param connection
+ * the incoming connection to be added
+ * @throws IllegalArgumentException
+ * is thrown if the connection is null, or if a connection is
+ * added twice. If subclasses want to change the rules for
+ * adding incoming connections the
+ * <code>validateAddIncomingConnection(IConnection connection)</code>
+ * should be overridden.
+ */
+ protected void validateAddIncomingConnection(IConnection connection) {
+ if (connection == null) {
+ throw new IllegalArgumentException("Connection cannot be null");
+ }
+ if (incomingConnections.contains(connection)) {
+ throw new IllegalArgumentException("Connection is already added");
+ }
+ }
+
+ protected void addOutgoingConnection(IConnection connection) {
+ validateAddOutgoingConnection(connection);
+ outgoingConnections.add(connection);
+ }
+
+ /**
+ * This method validates whether the given connection can be added. If the
+ * connection cannot be added, an IllegalArgumentException is thrown.
+ * <p>
+ *
+ * @param connection
+ * the outgoin connection to be added
+ * @throws IllegalArgumentException
+ * is thrown if the connection is null, or if a connection is
+ * added twice. If subclasses want to change the rules for
+ * adding outgoing connections the
+ * <code>validateAddIncomingConnection(IConnection connection)</code>
+ * should be overridden.
+ */
+ protected void validateAddOutgoingConnection(IConnection connection) {
+ if (connection == null) {
+ throw new IllegalArgumentException("Connection cannot be null");
+ }
+ if (outgoingConnections.contains(connection)) {
+ throw new IllegalArgumentException("Connection is already added");
+ }
+ }
+
+ protected void removeIncomingConnection(IConnection connection) {
+ validateRemoveIncomingConnection(connection);
+ incomingConnections.remove(connection);
+ }
+
+ /**
+ * This method validates whether the given connection can be removed
+ * <p>
+ *
+ * @param connection
+ * the incoming connection
+ * @throws IllegalArgumentException
+ * is thrown if connectin is null, or unknown. If subclasses
+ * want to change the rules for removing incoming connections
+ * the
+ * <code>validateRemoveIncomingConnection(IConnection connection)</code>
+ * should be overridden.
+ */
+ protected void validateRemoveIncomingConnection(IConnection connection) {
+ if (connection == null) {
+ throw new IllegalArgumentException("Connection is null");
+ }
+ if (!incomingConnections.contains(connection)) {
+ throw new IllegalArgumentException("Given connection <"
+ + connection + "> is not part of the incoming connections");
+ }
+ }
+
+ protected void removeOutgoingConnection(IConnection connection) {
+ validateRemoveOutgoingConnection(connection);
+ outgoingConnections.remove(connection);
+ }
+
+ /**
+ * This method validates whether the given connection can be removed
+ * <p>
+ *
+ * @param connection
+ * the outgoing connection
+ * @throws IllegalArgumentException
+ * is thrown if connectin is null, or unknown. If subclasses
+ * want to change the rules for removing outgoing connections
+ * the
+ * <code>validateRemoveOutgoingConnection(IConnection connection)</code>
+ * should be overridden.
+ */
+ protected void validateRemoveOutgoingConnection(IConnection connection) {
+ if (connection == null) {
+ throw new IllegalArgumentException("Connection is null");
+ }
+ if (!outgoingConnections.contains(connection)) {
+ throw new IllegalArgumentException("Given connection <"
+ + connection + "> is not part of the outgoing connections");
+ }
+ }
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/RuleFlowProcess.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/RuleFlowProcess.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/RuleFlowProcess.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,133 @@
+package org.drools.ruleflow.core.impl;
+/*
+ * 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.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.drools.ruleflow.common.core.impl.Process;
+import org.drools.ruleflow.core.IEndNode;
+import org.drools.ruleflow.core.INode;
+import org.drools.ruleflow.core.IRuleFlowProcess;
+import org.drools.ruleflow.core.IStartNode;
+import org.drools.ruleflow.core.IVariable;
+
+/**
+ * Default implementation of a RuleFlow process.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public class RuleFlowProcess extends Process implements IRuleFlowProcess {
+
+ public static final String RULEFLOW_TYPE = "RuleFlow";
+
+ private static final long serialVersionUID = 3257005445309609272L;
+
+ private Map nodes;
+ private List variables;
+ private long lastNodeId;
+
+ public RuleFlowProcess() {
+ super();
+ setType(RULEFLOW_TYPE);
+ nodes = new HashMap();
+ variables = new ArrayList();
+ }
+
+ public IStartNode getStart() {
+ for (Iterator it = nodes.values().iterator(); it.hasNext(); ) {
+ INode node = (INode) it.next();
+ if (node instanceof IStartNode) {
+ return (IStartNode) node;
+ }
+ }
+ return null;
+ }
+
+ public INode[] getNodes() {
+ return (INode[]) nodes.values().toArray(new INode[nodes.size()]);
+ }
+
+ public INode getNode(long id) {
+ Long idLong = new Long(id);
+ if (!nodes.containsKey(idLong)) {
+ throw new IllegalArgumentException("Unknown node id: " + id);
+ }
+ return (INode) nodes.get(idLong);
+ }
+
+
+ private IEndNode getEnd() {
+ for (Iterator it = nodes.values().iterator(); it.hasNext(); ) {
+ INode node = (INode) it.next();
+ if (node instanceof IEndNode) {
+ return (IEndNode) node;
+ }
+ }
+ return null;
+ }
+
+ public void removeNode(INode node) {
+ if (node == null) {
+ throw new IllegalArgumentException("Node is null");
+ }
+ INode n = (INode) nodes.remove(new Long(node.getId()));
+ if (n == null) {
+ throw new IllegalArgumentException("Unknown node: " + node);
+ }
+ }
+
+ public List getVariables() {
+ return variables;
+ }
+
+ public void setVariables(List variables) {
+ if (variables == null) {
+ throw new IllegalArgumentException("Variables is null");
+ }
+ this.variables = variables;
+ }
+
+ public String[] getVariableNames() {
+ String[] result = new String[variables.size()];
+ for (int i = 0; i < variables.size(); i++) {
+ result[i] = ((IVariable) variables.get(i)).getName();
+ }
+ return result;
+ }
+
+ public void addNode(INode node) {
+ validateAddNode(node);
+ if (!nodes.containsValue(node)) {
+ node.setId(++lastNodeId);
+ nodes.put(new Long(node.getId()), node);
+ }
+ }
+
+ private void validateAddNode(INode node) {
+ if ((node instanceof IStartNode) && (getStart() != null)) {
+ throw new IllegalArgumentException(
+ "A ruleflow process cannot have more than one start node!");
+ }
+ if ((node instanceof IEndNode) && (getEnd() != null)) {
+ throw new IllegalArgumentException(
+ "A ruleflow process cannot have more than one end node!");
+ }
+ }
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/RuleFlowProcessValidationError.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/RuleFlowProcessValidationError.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/RuleFlowProcessValidationError.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,41 @@
+package org.drools.ruleflow.core.impl;
+/*
+ * 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 org.drools.ruleflow.core.IRuleFlowProcessValidationError;
+
+/**
+ * Default implementation of a RuleFlow validation error.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public class RuleFlowProcessValidationError implements
+ IRuleFlowProcessValidationError {
+
+ private String type;
+
+ public RuleFlowProcessValidationError(String type) {
+ this.type = type;
+ }
+
+ public String toString() {
+ return type;
+ }
+
+ public String getType() {
+ return type;
+ }
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/RuleFlowProcessValidator.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/RuleFlowProcessValidator.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/RuleFlowProcessValidator.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,207 @@
+package org.drools.ruleflow.core.impl;
+/*
+ * 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.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.drools.ruleflow.core.IConnection;
+import org.drools.ruleflow.core.IEndNode;
+import org.drools.ruleflow.core.IJoin;
+import org.drools.ruleflow.core.INode;
+import org.drools.ruleflow.core.IRuleSetNode;
+import org.drools.ruleflow.core.ISplit;
+import org.drools.ruleflow.core.IStartNode;
+import org.drools.ruleflow.core.IVariable;
+import org.drools.ruleflow.core.IRuleFlowProcess;
+import org.drools.ruleflow.core.IRuleFlowProcessValidationError;
+import org.drools.ruleflow.core.IRuleFlowProcessValidator;
+
+/**
+ * Default implementation of a RuleFlow validator.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public class RuleFlowProcessValidator implements IRuleFlowProcessValidator {
+
+ private static RuleFlowProcessValidator instance;
+
+ private RuleFlowProcessValidator() {
+ }
+
+ public static RuleFlowProcessValidator getInstance() {
+ if (instance == null) {
+ instance = new RuleFlowProcessValidator();
+ }
+ return instance;
+ }
+
+ public IRuleFlowProcessValidationError[] validateProcess(IRuleFlowProcess process) {
+ List errors = new ArrayList();
+
+ if (process.getName() == null) {
+ errors.add(new RuleFlowProcessValidationError(
+ IRuleFlowProcessValidationError.NO_PROCESS_NAME));
+ }
+
+ if (process.getId() == null || "".equals(process.getId())) {
+ errors.add(new RuleFlowProcessValidationError(
+ IRuleFlowProcessValidationError.NO_PROCESS_ID));
+ }
+
+ // check start node of process
+ if (process.getStart() == null) {
+ errors.add(new RuleFlowProcessValidationError(
+ IRuleFlowProcessValidationError.NO_START_NODE));
+ }
+
+ boolean startNodeFound = false;
+ boolean endNodeFound = false;
+ INode[] nodes = process.getNodes();
+ for (int i = 0; i < nodes.length; i++) {
+ INode node = nodes[i];
+ if (node instanceof IStartNode) {
+ IStartNode startNode = (IStartNode) node;
+ startNodeFound = true;
+ if (startNode.getTo() == null) {
+ errors.add(new RuleFlowProcessValidationError(
+ IRuleFlowProcessValidationError.START_NODE_WITHOUT_OUTGOING_NODES));
+ }
+ } else if (node instanceof IEndNode) {
+ IEndNode endNode = (IEndNode) node;
+ endNodeFound = true;
+ if (endNode.getFrom() == null) {
+ errors.add(new RuleFlowProcessValidationError(
+ IRuleFlowProcessValidationError.END_NODE_HAS_NO_INCOMING_CONNECTIONS));
+ }
+ } else if (node instanceof IRuleSetNode) {
+ IRuleSetNode ruleSetNode = (IRuleSetNode) node;
+ if (ruleSetNode.getFrom() == null) {
+ errors.add(new RuleFlowProcessValidationError(
+ IRuleFlowProcessValidationError.RULE_SET_NODE_WITHOUT_INCOMING_CONNECTIONS));
+ }
+
+ if (ruleSetNode.getTo() == null) {
+ errors.add(new RuleFlowProcessValidationError(
+ IRuleFlowProcessValidationError.RULE_SET_NODE_WITHOUT_OUTGOING_CONNECTIONS));
+ }
+ String ruleFlowGroup = ruleSetNode.getRuleFlowGroup();
+ if (ruleFlowGroup == null || "".equals(ruleFlowGroup)) {
+ errors.add(new RuleFlowProcessValidationError(
+ IRuleFlowProcessValidationError.RULE_SET_NODE_WITHOUT_RULE_SET_GROUP));
+ }
+ } else if (node instanceof ISplit) {
+ ISplit split = (ISplit) node;
+ if (split.getType() == ISplit.TYPE_UNDEFINED) {
+ errors.add(new RuleFlowProcessValidationError(
+ IRuleFlowProcessValidationError.SPLIT_WITHOUT_TYPE));
+ }
+ if (split.getFrom() == null) {
+ errors.add(new RuleFlowProcessValidationError(
+ IRuleFlowProcessValidationError.SPLIT_WITHOUT_INCOMING_CONNECTION));
+ }
+ if (split.getOutgoingConnections().size() < 2) {
+ errors.add(new RuleFlowProcessValidationError(
+ IRuleFlowProcessValidationError.SPLIT_NOT_ENOUGH_OUTGOING_CONNECTIONS));
+ }
+ if (split.getType() == ISplit.TYPE_XOR || split.getType() == ISplit.TYPE_OR) {
+ for (Iterator it = split.getOutgoingConnections().iterator(); it.hasNext(); ) {
+ IConnection connection = (IConnection) it.next();
+ if (split.getConstraint(connection) == null) {
+ errors.add(new RuleFlowProcessValidationError(
+ IRuleFlowProcessValidationError.SPLIT_OUTGOING_CONNECTION_WITHOUT_CONSTRAINT));
+ }
+ }
+ }
+ } else if (node instanceof IJoin) {
+ IJoin join = (IJoin) node;
+ if (join.getType() == IJoin.TYPE_UNDEFINED) {
+ errors.add(new RuleFlowProcessValidationError(
+ IRuleFlowProcessValidationError.JOIN_WITHOUT_TYPE));
+ }
+ if (join.getIncomingConnections().size() < 2) {
+ errors.add(new RuleFlowProcessValidationError(
+ IRuleFlowProcessValidationError.JOIN_NOT_ENOUGH_INCOMING_CONNECTIONS));
+ }
+ if (join.getTo() == null) {
+ errors.add(new RuleFlowProcessValidationError(
+ IRuleFlowProcessValidationError.JOIN_WITHOUT_OUTGOING_CONNECTION));
+ }
+ }
+ }
+ if (!startNodeFound) {
+ errors.add(new RuleFlowProcessValidationError(
+ IRuleFlowProcessValidationError.NO_START_NODE));
+ }
+ if (!endNodeFound) {
+ errors.add(new RuleFlowProcessValidationError(
+ IRuleFlowProcessValidationError.NO_END_NODE));
+ }
+ for (Iterator it = process.getVariables().iterator(); it.hasNext(); ) {
+ IVariable variable = (IVariable) it.next();
+ if (variable.getType() == null) {
+ errors.add(new RuleFlowProcessValidationError(
+ IRuleFlowProcessValidationError.VARIABLE_WITHOUT_TYPE));
+ }
+ }
+
+ checkAllNodesConnectedToStart(process, errors);
+
+ return (IRuleFlowProcessValidationError[]) errors.toArray(new IRuleFlowProcessValidationError[errors.size()]);
+ }
+
+ private void checkAllNodesConnectedToStart(
+ IRuleFlowProcess process,
+ List errors) {
+ Map processNodes = new HashMap();
+ INode[] nodes = process.getNodes();
+ for (int i = 0; i < nodes.length; i++) {
+ INode node = nodes[i];
+ processNodes.put(node, Boolean.FALSE);
+ }
+
+ INode start = process.getStart();
+ if (start != null) {
+ processNode(start, processNodes);
+ }
+
+ for (Iterator it = processNodes.keySet().iterator(); it.hasNext(); ) {
+ INode node = (INode) it.next();
+ if (Boolean.FALSE.equals(processNodes.get(node))) {
+ errors.add(new RuleFlowProcessValidationError(
+ IRuleFlowProcessValidationError.ALL_NODES_CONNECTED_TO_START));
+ }
+ }
+ }
+
+ private void processNode(INode node, Map nodes) {
+ if (!nodes.containsKey(node)) {
+ throw new IllegalStateException("A process node is connected with "
+ + "a node that does not belong to the process.");
+ }
+ Boolean prevValue = (Boolean) nodes.put(node, Boolean.TRUE);
+ if (prevValue == Boolean.FALSE) {
+ for (Iterator it = node.getOutgoingConnections().iterator(); it.hasNext(); ) {
+ IConnection connection = (IConnection) it.next();
+ processNode(connection.getTo(), nodes);
+ }
+ }
+ }
+
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/RuleSetNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/RuleSetNode.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/RuleSetNode.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,78 @@
+package org.drools.ruleflow.core.impl;
+/*
+ * 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.Iterator;
+import java.util.List;
+
+import org.drools.ruleflow.core.IConnection;
+import org.drools.ruleflow.core.IRuleSetNode;
+
+/**
+ * Default implementation of a RuleSet node.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public class RuleSetNode extends Node implements IRuleSetNode {
+
+ private static final long serialVersionUID = 3257285846544691769L;
+
+ private String ruleFlowGroup;
+
+ public void setRuleFlowGroup(String ruleFlowGroup) {
+ this.ruleFlowGroup = ruleFlowGroup;
+ }
+
+ public String getRuleFlowGroup() {
+ return ruleFlowGroup;
+ }
+
+ public IConnection getFrom() {
+ List list = getIncomingConnections();
+ if (list.size() > 0) {
+ return (IConnection) list.get(0);
+ }
+ return null;
+ }
+
+ public IConnection getTo() {
+ List list = getOutgoingConnections();
+ if (list.size() > 0) {
+ return (IConnection) list.get(0);
+ }
+ return null;
+ }
+
+ protected void validateAddIncomingConnection(IConnection connection) {
+ super.validateAddIncomingConnection(connection);
+ if (getIncomingConnections().size() > 0) {
+ throw new IllegalArgumentException(
+ "A RuleSetNode cannot have more than one incoming node");
+ }
+ }
+
+ protected void validateAddOutgoingConnection(IConnection connection) {
+ super.validateAddOutgoingConnection(connection);
+ for (Iterator it = getOutgoingConnections().iterator(); it.hasNext(); ) {
+ IConnection conn = (IConnection) it.next();
+ if (conn.getType() == connection.getType()) {
+ throw new IllegalArgumentException(
+ "A RuleSetNode can have at most one outgoing node");
+ }
+ }
+ }
+
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/Split.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/Split.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/Split.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,131 @@
+package org.drools.ruleflow.core.impl;
+/*
+ * 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.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.drools.ruleflow.core.IConnection;
+import org.drools.ruleflow.core.IConstraint;
+import org.drools.ruleflow.core.ISplit;
+
+/**
+ * Default implementation of a split node.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public class Split extends Node implements ISplit {
+
+ private static final long serialVersionUID = 3258413949669159736L;
+
+ private int type;
+ private Map constraints;
+
+ public Split() {
+ type = TYPE_UNDEFINED;
+ constraints = new HashMap();
+ }
+
+ public Split(int type) {
+ this.type = type;
+ constraints = new HashMap();
+ }
+
+ public void setType(int type) {
+ this.type = type;
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public IConstraint getConstraint(IConnection connection) {
+ if (connection == null) {
+ throw new IllegalArgumentException("connection is null");
+ }
+
+ // dirty hack because keys were entered wrong
+ // probably caused by xstreams
+ HashMap newMap = new HashMap();
+ for (Iterator it = constraints.entrySet().iterator(); it.hasNext(); ) {
+ Entry entry = (Entry) it.next();
+ newMap.put(entry.getKey(), entry.getValue());
+ }
+ constraints = newMap;
+
+ if (type == TYPE_OR || type == TYPE_XOR) {
+ return (IConstraint) constraints.get(connection);
+ }
+ throw new UnsupportedOperationException("Constraints are "
+ + "only supported with XOR or OR split types, not with: "
+ + getType());
+ }
+
+ public void setConstraint(IConnection connection, IConstraint constraint) {
+ if (type == TYPE_OR || type == TYPE_XOR) {
+ if (connection == null) {
+ throw new IllegalArgumentException("connection is null");
+ }
+ if (!getOutgoingConnections().contains(connection)) {
+ throw new IllegalArgumentException("connection is unknown:" + connection);
+ }
+ constraints.put(connection, constraint);
+ } else {
+ throw new UnsupportedOperationException("Constraints are "
+ + "only supported with XOR or OR split types, not with type:"
+ + getType());
+ }
+ }
+
+ public Map getConstraints() {
+ if (type == TYPE_OR || type == TYPE_XOR) {
+ return Collections.unmodifiableMap(constraints);
+ }
+ throw new UnsupportedOperationException("Constraints are "
+ + "only supported with XOR or OR split types, not with: "
+ + getType());
+ }
+
+ public IConnection getFrom() {
+ if (getIncomingConnections().size() > 0) {
+ return (IConnection) getIncomingConnections().get(0);
+ }
+ return null;
+ }
+
+ protected void validateAddIncomingConnection(IConnection connection) {
+ super.validateAddIncomingConnection(connection);
+ if (getIncomingConnections().size() > 0) {
+ throw new IllegalArgumentException("A split cannot have more than one incoming connection");
+ }
+ }
+
+ protected void validateAddOutgoingConnection(IConnection connection) {
+ super.validateAddOutgoingConnection(connection);
+ if (connection.getType() != IConnection.TYPE_NORMAL) {
+ throw new IllegalArgumentException("Unknown connection type :" + connection.getType()
+ + ", only NORMAL is allowed as outgoing connection.");
+ }
+ }
+
+ public void removeOutgoingConnection(IConnection connection) {
+ super.removeOutgoingConnection(connection);
+ constraints.remove(connection);
+ }
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/StartNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/StartNode.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/StartNode.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,59 @@
+package org.drools.ruleflow.core.impl;
+/*
+ * 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.List;
+
+import org.drools.ruleflow.core.IConnection;
+import org.drools.ruleflow.core.IStartNode;
+
+/**
+ * Default implementation of a start node.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public class StartNode extends Node implements IStartNode {
+
+ private static final long serialVersionUID = 3257564005806782517L;
+
+ public IConnection getTo() {
+ List list = getOutgoingConnections();
+ if (list.size() > 0) {
+ return (IConnection) list.get(0);
+ }
+ return null;
+ }
+
+ protected void validateAddOutgoingConnection(IConnection connection) {
+ super.validateAddOutgoingConnection(connection);
+ if (getOutgoingConnections().size() > 0) {
+ throw new IllegalArgumentException(
+ "A start node cannot have more than one outgoing connection");
+ }
+ }
+
+
+ protected void validateAddIncomingConnection(IConnection connection) {
+ throw new UnsupportedOperationException(
+ "A start node does not have an incoming connection");
+ }
+
+ protected void validateRemoveIncomingConnection(IConnection connection) {
+ throw new UnsupportedOperationException(
+ "A start node does not have an incoming connection");
+ }
+
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/Variable.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/Variable.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/impl/Variable.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,80 @@
+package org.drools.ruleflow.core.impl;
+/*
+ * 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.io.Serializable;
+
+import org.drools.ruleflow.common.datatype.IDataType;
+import org.drools.ruleflow.common.datatype.impl.type.UndefinedDataType;
+import org.drools.ruleflow.core.IVariable;
+
+/**
+ * Default implementation of a variable.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public class Variable implements IVariable, Serializable {
+
+ private static final long serialVersionUID = 3256441400072353336L;
+
+ private String name;
+ private IDataType type;
+ private Serializable value;
+
+ public Variable() {
+ type = UndefinedDataType.getInstance();
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public IDataType getType() {
+ return type;
+ }
+
+ public void setType(IDataType type) {
+ if (type == null) {
+ throw new IllegalArgumentException("type is null");
+ }
+ this.type = type;
+ }
+
+ public Serializable getValue() {
+ return value;
+ }
+
+ public void setValue(Serializable value) {
+ if (this.type.verifyDataType(value)) {
+ this.value = value;
+ } else {
+ StringBuilder sb = new StringBuilder();
+ sb.append("Value <");
+ sb.append(value);
+ sb.append("> is not valid for datatype: ");
+ sb.append(type);
+ throw new IllegalArgumentException(sb.toString());
+ }
+ }
+
+ public String toString() {
+ return name;
+ }
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/IRuleFlowNodeInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/IRuleFlowNodeInstance.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/IRuleFlowNodeInstance.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,44 @@
+package org.drools.ruleflow.instance;
+/*
+ * 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.
+ */
+
+/**
+ * Represents a node instance in a RuleFlow. This is the runtime counterpart
+ * of a node, containing all runtime state. Node instance classes also
+ * contain the logic on what to do when it is being triggered (start
+ * executing) or completed (end of execution).
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public interface IRuleFlowNodeInstance {
+
+ void setId(long id);
+
+ long getId();
+
+ void setNodeId(long nodeId);
+
+ long getNodeId();
+
+ void setProcessInstance(IRuleFlowProcessInstance processInstance);
+
+ IRuleFlowProcessInstance getProcessInstance();
+
+ void trigger(IRuleFlowNodeInstance from);
+
+ void triggerCompleted();
+
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/IRuleFlowProcessInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/IRuleFlowProcessInstance.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/IRuleFlowProcessInstance.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,52 @@
+package org.drools.ruleflow.instance;
+/*
+ * 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.Collection;
+
+import org.drools.Agenda;
+import org.drools.ruleflow.common.instance.IProcessInstance;
+import org.drools.ruleflow.core.INode;
+import org.drools.ruleflow.core.IRuleFlowProcess;
+
+/**
+ * A process instance for a RuleFlow process.
+ * Contains a reference to all its node instances, and the agenda that
+ * is controlling the RuleFlow process.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public interface IRuleFlowProcessInstance extends IProcessInstance {
+
+ IRuleFlowProcess getRuleFlowProcess();
+
+ void addNodeInstance(IRuleFlowNodeInstance nodeInstance);
+
+ void removeNodeInstance(IRuleFlowNodeInstance nodeInstance);
+
+ Collection getNodeInstances();
+
+ IRuleFlowNodeInstance getFirstNodeInstance(long nodeId);
+
+ void setAgenda(Agenda agenda);
+
+ Agenda getAgenda();
+
+ IRuleFlowNodeInstance getNodeInstance(INode node);
+
+ void start();
+
+}
\ No newline at end of file
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/EndNodeInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/EndNodeInstance.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/EndNodeInstance.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,36 @@
+package org.drools.ruleflow.instance.impl;
+/*
+ * 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 org.drools.ruleflow.common.instance.IProcessInstance;
+import org.drools.ruleflow.instance.IRuleFlowNodeInstance;
+
+/**
+ * Runtime counterpart of an end node.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public class EndNodeInstance extends RuleFlowNodeInstance {
+
+ public void trigger(IRuleFlowNodeInstance from) {
+ getProcessInstance().setState(IProcessInstance.STATE_COMPLETED);
+ }
+
+ public void triggerCompleted() {
+ // this should never occur
+ throw new IllegalArgumentException("End nodes cannot be completed.");
+ }
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowJoinInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowJoinInstance.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowJoinInstance.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,87 @@
+package org.drools.ruleflow.instance.impl;
+/*
+ * 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.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.drools.ruleflow.core.IConnection;
+import org.drools.ruleflow.core.IJoin;
+import org.drools.ruleflow.core.INode;
+import org.drools.ruleflow.instance.IRuleFlowNodeInstance;
+
+/**
+ * Runtime counterpart of a join node.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public class RuleFlowJoinInstance extends RuleFlowNodeInstance implements IRuleFlowNodeInstance {
+
+ private Map triggers = new HashMap();
+
+ protected IJoin getJoinNode() {
+ return (IJoin) getNode();
+ }
+
+ public void trigger(IRuleFlowNodeInstance from) {
+ IJoin join = getJoinNode();
+ switch (join.getType()) {
+ case IJoin.TYPE_XOR:
+ triggerCompleted();
+ break;
+ case IJoin.TYPE_AND:
+ INode node = getProcessInstance().getRuleFlowProcess().getNode(from.getNodeId());
+ Integer count = (Integer) triggers.get(node);
+ if (count == null) {
+ triggers.put(node, new Integer(1));
+ } else {
+ triggers.put(node, new Integer(count.intValue() + 1));
+ }
+ checkActivation();
+ break;
+ default:
+ throw new IllegalArgumentException("Illegal join type " + join.getType());
+ }
+ }
+
+ private void checkActivation() {
+ // check whether all parent nodes have been triggered
+ for (Iterator it = getJoinNode().getIncomingConnections().iterator(); it.hasNext(); ) {
+ IConnection connection = (IConnection) it.next();
+ if (triggers.get(connection.getFrom()) == null) {
+ return;
+ }
+ }
+ // if true, decrease trigger count for all parents and trigger children
+ for (Iterator it = getJoinNode().getIncomingConnections().iterator(); it.hasNext(); ) {
+ IConnection connection = (IConnection) it.next();
+ Integer count = (Integer) triggers.get(connection.getFrom());
+ if (count.intValue() == 1) {
+ triggers.remove(connection.getFrom());
+ } else {
+ triggers.put(connection.getFrom(), new Integer(count.intValue() - 1));
+ }
+ }
+ triggerCompleted();
+ }
+
+ public void triggerCompleted() {
+ getProcessInstance().getNodeInstance(
+ getJoinNode().getTo().getTo()).trigger(this);
+ }
+
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowNodeInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowNodeInstance.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowNodeInstance.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,60 @@
+package org.drools.ruleflow.instance.impl;
+/*
+ * 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 org.drools.ruleflow.core.INode;
+import org.drools.ruleflow.instance.IRuleFlowNodeInstance;
+import org.drools.ruleflow.instance.IRuleFlowProcessInstance;
+
+/**
+ * Default implementation of a RuleFlow node instance.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public abstract class RuleFlowNodeInstance implements IRuleFlowNodeInstance {
+
+ private long id;
+ private long nodeId;
+ private IRuleFlowProcessInstance processInstance;
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setNodeId(long nodeId) {
+ this.nodeId = nodeId;
+ }
+
+ public long getNodeId() {
+ return nodeId;
+ }
+
+ public void setProcessInstance(IRuleFlowProcessInstance processInstance) {
+ this.processInstance = processInstance;
+ }
+
+ public IRuleFlowProcessInstance getProcessInstance() {
+ return processInstance;
+ }
+
+ protected INode getNode() {
+ return processInstance.getRuleFlowProcess().getNode(nodeId);
+ }
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowProcessInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowProcessInstance.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowProcessInstance.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,140 @@
+package org.drools.ruleflow.instance.impl;
+/*
+ * 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.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.drools.Agenda;
+import org.drools.ruleflow.common.instance.IProcessInstance;
+import org.drools.ruleflow.common.instance.impl.ProcessInstance;
+import org.drools.ruleflow.core.IEndNode;
+import org.drools.ruleflow.core.IJoin;
+import org.drools.ruleflow.core.INode;
+import org.drools.ruleflow.core.IRuleFlowProcess;
+import org.drools.ruleflow.core.IRuleSetNode;
+import org.drools.ruleflow.core.ISplit;
+import org.drools.ruleflow.core.IStartNode;
+import org.drools.ruleflow.instance.IRuleFlowNodeInstance;
+import org.drools.ruleflow.instance.IRuleFlowProcessInstance;
+
+/**
+ * Default implementation of a RuleFlow process instance.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public class RuleFlowProcessInstance extends ProcessInstance implements IRuleFlowProcessInstance {
+
+ private static final long serialVersionUID = -6760756665603399413L;
+
+ private Agenda agenda;
+ private List nodeInstances = new ArrayList();
+
+ public IRuleFlowProcess getRuleFlowProcess() {
+ return (IRuleFlowProcess) getProcess();
+ }
+
+ public void addNodeInstance(IRuleFlowNodeInstance nodeInstance) {
+ nodeInstances.add(nodeInstance);
+ nodeInstance.setProcessInstance(this);
+ }
+
+ public void removeNodeInstance(IRuleFlowNodeInstance nodeInstance) {
+ nodeInstances.remove(nodeInstance);
+ }
+
+ public Collection getNodeInstances() {
+ return Collections.unmodifiableCollection(nodeInstances);
+ }
+
+ public IRuleFlowNodeInstance getFirstNodeInstance(long nodeId) {
+ for (Iterator iterator = nodeInstances.iterator(); iterator.hasNext(); ) {
+ IRuleFlowNodeInstance nodeInstance = (IRuleFlowNodeInstance) iterator.next();
+ if (nodeInstance.getNodeId() == nodeId) {
+ return nodeInstance;
+ }
+ }
+ return null;
+ }
+
+ public Agenda getAgenda() {
+ return agenda;
+ }
+
+ public void setAgenda(Agenda agenda) {
+ this.agenda = agenda;
+ }
+
+ public IRuleFlowNodeInstance getNodeInstance(INode node) {
+ if (node instanceof IRuleSetNode) {
+ IRuleFlowNodeInstance result = (IRuleFlowNodeInstance)
+ agenda.getRuleFlowGroup(((IRuleSetNode) node).getRuleFlowGroup());
+ result.setNodeId(node.getId());
+ addNodeInstance(result);
+ return result;
+ } else if (node instanceof ISplit) {
+ IRuleFlowNodeInstance result = getFirstNodeInstance(node.getId());
+ if (result == null) {
+ result = new RuleFlowSplitInstance();
+ result.setNodeId(node.getId());
+ addNodeInstance(result);
+ return result;
+ }
+ } else if (node instanceof IJoin) {
+ IRuleFlowNodeInstance result = getFirstNodeInstance(node.getId());
+ if (result == null) {
+ result = new RuleFlowJoinInstance();
+ result.setNodeId(node.getId());
+ addNodeInstance(result);
+ }
+ return result;
+ } else if (node instanceof IStartNode) {
+ IRuleFlowNodeInstance result = new StartNodeInstance();
+ result.setNodeId(node.getId());
+ addNodeInstance(result);
+ return result;
+ } else if (node instanceof IEndNode) {
+ IRuleFlowNodeInstance result = new EndNodeInstance();
+ result.setNodeId(node.getId());
+ addNodeInstance(result);
+ return result;
+ }
+ throw new IllegalArgumentException("Illegal node type: " + node.getClass());
+ }
+
+ public void start() {
+ if (getState() != IProcessInstance.STATE_PENDING) {
+ throw new IllegalArgumentException(
+ "A process instance can only be started once");
+ }
+ setState(IProcessInstance.STATE_ACTIVE);
+ getNodeInstance(getRuleFlowProcess().getStart()).trigger(null);
+ }
+
+ public String toString() {
+ StringBuilder sb = new StringBuilder("RuleFlowProcessInstance");
+ sb.append(getId());
+ sb.append(" [processId=");
+ sb.append(getProcess().getId());
+ sb.append(",state=");
+ sb.append(getState());
+ sb.append("]");
+ return sb.toString();
+ }
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowSequenceNodeInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowSequenceNodeInstance.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowSequenceNodeInstance.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,41 @@
+package org.drools.ruleflow.instance.impl;
+/*
+ * 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 org.drools.ruleflow.core.IRuleSetNode;
+import org.drools.ruleflow.instance.IRuleFlowNodeInstance;
+
+/**
+ * Runtime counterpart of a ruleset node.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public class RuleFlowSequenceNodeInstance extends RuleFlowNodeInstance {
+
+ protected IRuleSetNode getRuleSetNode() {
+ return (IRuleSetNode) getNode();
+ }
+
+ public void trigger(IRuleFlowNodeInstance from) {
+ getProcessInstance().getAgenda()
+ .activateRuleFlowGroup(getRuleSetNode().getRuleFlowGroup());
+ }
+
+ public void triggerCompleted() {
+ getProcessInstance().getNodeInstance(getRuleSetNode().getTo().getTo()).trigger(this);
+ }
+
+}
\ No newline at end of file
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowSplitInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowSplitInstance.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/RuleFlowSplitInstance.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,56 @@
+package org.drools.ruleflow.instance.impl;
+/*
+ * 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.Iterator;
+import java.util.List;
+
+import org.drools.ruleflow.core.IConnection;
+import org.drools.ruleflow.core.ISplit;
+import org.drools.ruleflow.instance.IRuleFlowNodeInstance;
+
+/**
+ * Runtime counterpart of a split node.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public class RuleFlowSplitInstance extends RuleFlowNodeInstance implements IRuleFlowNodeInstance {
+
+ protected ISplit getSplitNode() {
+ return (ISplit) getNode();
+ }
+
+ public void trigger(IRuleFlowNodeInstance from) {
+ ISplit split = getSplitNode();
+ switch (split.getType()) {
+ case ISplit.TYPE_AND:
+ List outgoing = split.getOutgoingConnections();
+ for (Iterator iterator = outgoing.iterator(); iterator.hasNext(); ) {
+ IConnection connection = (IConnection) iterator.next();
+ getProcessInstance().getNodeInstance(connection.getTo()).trigger(this);
+ }
+ break;
+ default:
+ throw new IllegalArgumentException("Illegal split type " + split.getType());
+ }
+ }
+
+ public void triggerCompleted() {
+ // TODO Auto-generated method stub
+
+ }
+
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/StartNodeInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/StartNodeInstance.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/instance/impl/StartNodeInstance.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,39 @@
+package org.drools.ruleflow.instance.impl;
+/*
+ * 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 org.drools.ruleflow.core.IStartNode;
+import org.drools.ruleflow.instance.IRuleFlowNodeInstance;
+
+/**
+ * Runtime counterpart of a start node.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public class StartNodeInstance extends RuleFlowNodeInstance {
+
+ public void trigger(IRuleFlowNodeInstance from) {
+ triggerCompleted();
+ }
+
+ public IStartNode getStartNode() {
+ return (IStartNode) getNode();
+ }
+
+ public void triggerCompleted() {
+ getProcessInstance().getNodeInstance(getStartNode().getTo().getTo()).trigger(this);
+ }
+}
Deleted: 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 2007-03-01 02:19:52 UTC (rev 9864)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/RuleFlowGroup.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -1,31 +0,0 @@
-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
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-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,41 @@
+package org.drools.spi;
+/*
+ * 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.Iterator;
+
+public interface RuleFlowGroup {
+
+ String getName();
+
+ public Iterator iterator();
+
+ boolean isEmpty();
+
+ int size();
+
+ boolean isActive();
+
+ boolean isAutoDeactivate();
+
+ /**
+ * Sets the auto-deactivate status of this RuleFlowGroup.
+ * If this is set to true, an active RuleFlowGroup automatically
+ * deactivates if it has no more activations. If it had no
+ * activations when it was activated, it will be deactivated immediately.
+ */
+ void setAutoDeactivate(boolean autoDeactivate);
+}
\ 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-03-01 02:19:52 UTC (rev 9864)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/AgendaTest.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -676,6 +676,12 @@
}
+ /**
+ * Basic RuleFlowGroup test where there are three rules, each in their own
+ * RuleFlowGroup. First only rule-flow-group-0 is activated and rule0 is
+ * executed. When the two remaining groups are activated, the rule with the
+ * highest priority is executed first.
+ */
public void testRuleFlowGroup() {
final RuleBase ruleBase = RuleBaseFactory.newRuleBase();
@@ -736,9 +742,6 @@
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,
@@ -774,7 +777,7 @@
agenda.agendaSize() );
// Activate the RuleFlowGroup, the nodes stay in the group, but should now also be in the Agenda
- ruleFlowGroup0.activate();
+ agenda.activateRuleFlowGroup("rule-flow-group-0");
assertEquals( 2,
ruleFlowGroup0.size() );
assertEquals( 2,
@@ -787,17 +790,23 @@
assertEquals( 1,
agenda.agendaSize() );
- // on firing the last activation the child rule flow groups should
- // activate and thus repopulate the agenda
+ // After firing all activations of RuleFlowGroup 0, the agenda is empty
agenda.fireNextItem( null );
assertEquals( 0,
ruleFlowGroup0.size() );
+ assertEquals( 0,
+ agenda.agendaSize() );
+
+ // Now we activate two RuleFlowGroups together
+ // All their activations should be added to the agenda.
+ agenda.activateRuleFlowGroup("rule-flow-group-1");
+ agenda.activateRuleFlowGroup("rule-flow-group-2");
assertEquals( 1,
- ruleFlowGroup1.size() );
+ ruleFlowGroup1.size() );
assertEquals( 1,
- ruleFlowGroup2.size() );
+ ruleFlowGroup2.size() );
assertEquals( 2,
- agenda.agendaSize() );
+ agenda.agendaSize() );
// we set the salience higher on rule2, so it sould fire first and empty ruleFlowGroup2
agenda.fireNextItem( null );
@@ -808,7 +817,7 @@
assertEquals( 1,
agenda.agendaSize() );
- // this is the last activation, so everything shoud be empty after this
+ // this is the last activation, so everything should be empty after this
agenda.fireNextItem( null );
assertEquals( 0,
ruleFlowGroup0.size() );
@@ -819,4 +828,383 @@
assertEquals( 0,
agenda.agendaSize() );
}
+
+ /**
+ * RuleFlowGroup test that makes sure that, if new activations are created
+ * for an active RuleFlowGroup, those activations get added to the agenda
+ * directly as well.
+ */
+ public void testRuleFlowGroup1() {
+ final RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+
+ final ReteooWorkingMemory workingMemory = (ReteooWorkingMemory) ruleBase.newWorkingMemory();
+
+ final InternalAgenda agenda = (InternalAgenda) workingMemory.getAgenda();
+
+ // create rule1
+ final Consequence consequence1 = new Consequence() {
+ private static final long serialVersionUID = -2596133893109870505L;
+ public void evaluate(KnowledgeHelper knowledgeHelper,
+ WorkingMemory workingMemory) {
+ // do nothing
+ }
+ };
+
+ final Rule rule1 = new Rule( "test-rule1" );
+ rule1.setRuleFlowGroup( "rule-flow-group-0" );
+ rule1.setConsequence( consequence1 );
+
+ final RuleTerminalNode node1 = new RuleTerminalNode( 4,
+ new MockTupleSource( 2 ),
+ rule1,
+ rule1.getLhs() );
+
+ // create context
+ final PropagationContext context0 = new PropagationContextImpl( 0,
+ PropagationContext.ASSERTION,
+ rule1,
+ null );
+
+ // create rule0
+ final Consequence consequence0 = new Consequence() {
+ private static final long serialVersionUID = -2596133893109870505L;
+ public void evaluate(KnowledgeHelper knowledgeHelper,
+ WorkingMemory w) {
+ // activate rule1
+ final ReteTuple tuple1 = new ReteTuple( new DefaultFactHandle( 1, "cheese" ) );
+ node1.assertTuple( tuple1,
+ context0,
+ workingMemory );
+ }
+ };
+
+ final Rule rule0 = new Rule( "test-rule0" );
+ rule0.setRuleFlowGroup( "rule-flow-group-0" );
+ rule0.setConsequence( consequence0 );
+
+ final RuleTerminalNode node0 = new RuleTerminalNode( 3,
+ new MockTupleSource( 2 ),
+ rule0,
+ rule0.getLhs() );
+
+ final RuleFlowGroup ruleFlowGroup0 = agenda.getRuleFlowGroup( "rule-flow-group-0" );
+
+ // Create one activation for rule0 only
+ final ReteTuple tuple0 = new ReteTuple( new DefaultFactHandle( 1, "cheese" ) );
+ node0.assertTuple( tuple0,
+ context0,
+ workingMemory );
+
+ // RuleFlowGroup should be populated, but the agenda shouldn't be
+ assertEquals( 1,
+ ruleFlowGroup0.size() );
+ assertEquals( 0,
+ agenda.agendaSize() );
+
+ // Activate the RuleFlowGroup, the activation stays in the group, but should now also be in the Agenda
+ agenda.activateRuleFlowGroup("rule-flow-group-0");
+ assertEquals( 1,
+ ruleFlowGroup0.size() );
+ assertEquals( 1,
+ agenda.agendaSize() );
+
+ // As we fire the rule, an new activation is created for rule1, and it should be added to group AND the agenda.
+ agenda.fireNextItem( null );
+ assertEquals( 1,
+ ruleFlowGroup0.size() );
+ assertEquals( 1,
+ agenda.agendaSize() );
+
+ // After firing all activations of RuleFlowGroup 0, the agenda is empty
+ agenda.fireNextItem( null );
+ assertEquals( 0,
+ ruleFlowGroup0.size() );
+ assertEquals( 0,
+ agenda.agendaSize() );
+ }
+
+ /**
+ * RuleFlowGroup test that makes sure that, if an activation in an active
+ * RuleFlowGroup gets deactivated, the activation is no longer executed.
+ */
+ public void testRuleFlowGroup2() {
+ final RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+
+ final ReteooWorkingMemory workingMemory = (ReteooWorkingMemory) ruleBase.newWorkingMemory();
+
+ final InternalAgenda agenda = (InternalAgenda) workingMemory.getAgenda();
+
+ // create rule1
+ final Consequence consequence1 = new Consequence() {
+ private static final long serialVersionUID = -2596133893109870505L;
+ public void evaluate(KnowledgeHelper knowledgeHelper,
+ WorkingMemory workingMemory) {
+ // do nothing
+ }
+ };
+
+ final Rule rule1 = new Rule( "test-rule1" );
+ rule1.setRuleFlowGroup( "rule-flow-group-0" );
+ rule1.setConsequence( consequence1 );
+
+ final RuleTerminalNode node1 = new RuleTerminalNode( 4,
+ new MockTupleSource( 2 ),
+ rule1,
+ rule1.getLhs() );
+
+ // create context
+ final PropagationContext context0 = new PropagationContextImpl( 0,
+ PropagationContext.ASSERTION,
+ rule1,
+ null );
+
+ final ReteTuple tuple1 = new ReteTuple( new DefaultFactHandle( 1, "cheese" ) );
+
+ // create rule0
+ final Consequence consequence0 = new Consequence() {
+ private static final long serialVersionUID = -2596133893109870505L;
+ public void evaluate(KnowledgeHelper knowledgeHelper,
+ WorkingMemory w) {
+ // deactivate rule1
+ node1.retractTuple( tuple1,
+ context0,
+ workingMemory );
+ }
+ };
+
+ final Rule rule0 = new Rule( "test-rule0" );
+ rule0.setRuleFlowGroup( "rule-flow-group-0" );
+ rule0.setConsequence( consequence0 );
+ rule0.setSalience(10);
+
+ final RuleTerminalNode node0 = new RuleTerminalNode( 3,
+ new MockTupleSource( 2 ),
+ rule0,
+ rule0.getLhs() );
+
+ final RuleFlowGroup ruleFlowGroup0 = agenda.getRuleFlowGroup( "rule-flow-group-0" );
+
+ // Create an activation for both rules
+ final ReteTuple tuple0 = new ReteTuple( new DefaultFactHandle( 1, "cheese" ) );
+ node0.assertTuple( tuple0,
+ context0,
+ workingMemory );
+
+ node1.assertTuple( tuple1,
+ context0,
+ workingMemory );
+
+ // RuleFlowGroup should be populated, but the agenda shouldn't be
+ assertEquals( 2,
+ ruleFlowGroup0.size() );
+ assertEquals( 0,
+ agenda.agendaSize() );
+
+ // Activate the RuleFlowGroup, the activations stay in the group, but should now also be in the Agenda
+ agenda.activateRuleFlowGroup("rule-flow-group-0");
+ assertEquals( 2,
+ ruleFlowGroup0.size() );
+ assertEquals( 2,
+ agenda.agendaSize() );
+
+ // As we fire the rule, rule0 should execute first, as it has higher salience.
+ // Rule0 should deactivate rule1 as well, so the everything should be empty
+ agenda.fireNextItem( null );
+ assertEquals( 0,
+ ruleFlowGroup0.size() );
+ assertEquals( 0,
+ agenda.agendaSize() );
+
+ }
+
+ /**
+ * RuleFlowGroup test that makes sure that, when deactivating a RuleFlowGroup,
+ * all activations for that group are no longer on the agenda. When
+ * reactivating the RuleFlowGroup however, they get added to the agenda again.
+ */
+ public void testRuleFlowGroup3() {
+ final RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+
+ final ReteooWorkingMemory workingMemory = (ReteooWorkingMemory) ruleBase.newWorkingMemory();
+
+ final InternalAgenda agenda = (InternalAgenda) workingMemory.getAgenda();
+
+ // create rule0
+ final Consequence consequence0 = new Consequence() {
+ private static final long serialVersionUID = -2596133893109870505L;
+ public void evaluate(KnowledgeHelper knowledgeHelper,
+ WorkingMemory w) {
+ // do nothing
+ }
+ };
+
+ final Rule rule0 = new Rule( "test-rule0" );
+ rule0.setRuleFlowGroup( "rule-flow-group-0" );
+ rule0.setConsequence( consequence0 );
+
+ final RuleTerminalNode node0 = new RuleTerminalNode( 1,
+ new MockTupleSource( 2 ),
+ rule0,
+ rule0.getLhs() );
+
+ final RuleFlowGroup ruleFlowGroup0 = agenda.getRuleFlowGroup( "rule-flow-group-0" );
+
+ // create context
+ final PropagationContext context0 = new PropagationContextImpl( 0,
+ PropagationContext.ASSERTION,
+ rule0,
+ null );
+
+ // Create two activation for this rule
+ 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 );
+
+ // RuleFlowGroup should be populated, but the agenda shouldn't be
+ assertEquals( 2,
+ ruleFlowGroup0.size() );
+ assertEquals( 0,
+ agenda.agendaSize() );
+
+ // Activate the RuleFlowGroup, the activations stay in the group, but
+ // should now also be in the Agenda
+ agenda.activateRuleFlowGroup("rule-flow-group-0");
+ assertEquals( 2,
+ ruleFlowGroup0.size() );
+ assertEquals( 2,
+ agenda.agendaSize() );
+
+ // Reactivate an already active RuleFlowGroup should not have any effect
+ agenda.activateRuleFlowGroup("rule-flow-group-0");
+ assertEquals( 2,
+ ruleFlowGroup0.size() );
+ assertEquals( 2,
+ agenda.agendaSize() );
+
+ // Deactivate the RuleFlowGroup, the activations should be removed from
+ // the agenda but still in the RuleFlowGroup
+ agenda.deactivateRuleFlowGroup("rule-flow-group-0");
+ assertEquals( 2,
+ ruleFlowGroup0.size() );
+ assertEquals( 0,
+ agenda.agendaSize() );
+
+ // Reactivate the RuleFlowGroup, the activations stay in the group, but
+ // should now also be in the Agenda again
+ agenda.activateRuleFlowGroup("rule-flow-group-0");
+ assertEquals( 2,
+ ruleFlowGroup0.size() );
+ assertEquals( 2,
+ agenda.agendaSize() );
+
+ }
+
+ /**
+ * Test auto-deactivation of RuleFlowGroup.
+ */
+ public void testRuleFlowGroup4() {
+ final RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+
+ final ReteooWorkingMemory workingMemory = (ReteooWorkingMemory) ruleBase.newWorkingMemory();
+
+ final InternalAgenda agenda = (InternalAgenda) workingMemory.getAgenda();
+
+ // create rule0
+ final Consequence consequence0 = new Consequence() {
+ private static final long serialVersionUID = -2596133893109870505L;
+ public void evaluate(KnowledgeHelper knowledgeHelper,
+ WorkingMemory w) {
+ // do nothing
+ }
+ };
+
+ final Rule rule0 = new Rule( "test-rule0" );
+ rule0.setRuleFlowGroup( "rule-flow-group-0" );
+ rule0.setConsequence( consequence0 );
+
+ final RuleTerminalNode node0 = new RuleTerminalNode( 1,
+ new MockTupleSource( 2 ),
+ rule0,
+ rule0.getLhs() );
+
+ final RuleFlowGroup ruleFlowGroup0 = agenda.getRuleFlowGroup( "rule-flow-group-0" );
+ assertTrue( ruleFlowGroup0.isAutoDeactivate() );
+ ruleFlowGroup0.setAutoDeactivate(false);
+ assertFalse( ruleFlowGroup0.isAutoDeactivate() );
+
+ // create context
+ final PropagationContext context0 = new PropagationContextImpl( 0,
+ PropagationContext.ASSERTION,
+ rule0,
+ null );
+
+ // Create an activation for this rule
+ final ReteTuple tuple0 = new ReteTuple( new DefaultFactHandle( 1, "cheese" ) );
+ node0.assertTuple( tuple0,
+ context0,
+ workingMemory );
+
+ // RuleFlowGroup should be populated, but the agenda shouldn't be
+ assertEquals( 1,
+ ruleFlowGroup0.size() );
+ assertEquals( 0,
+ agenda.agendaSize() );
+
+ // Activate the RuleFlowGroup, the activations stay in the group, but
+ // should now also be in the Agenda
+ agenda.activateRuleFlowGroup("rule-flow-group-0");
+ assertEquals( 1,
+ ruleFlowGroup0.size() );
+ assertEquals( 1,
+ agenda.agendaSize() );
+
+ // Execute activation
+ agenda.fireNextItem( null );
+ assertEquals( 0,
+ ruleFlowGroup0.size() );
+ assertEquals( 0,
+ agenda.agendaSize() );
+ assertTrue( ruleFlowGroup0.isActive() );
+
+ // Set auto-deactivation status to true
+ ruleFlowGroup0.setAutoDeactivate(true);
+ assertTrue( ruleFlowGroup0.isAutoDeactivate() );
+ assertFalse( ruleFlowGroup0.isActive() );
+
+ // Add another activation and activate RuleFlowGroup again
+ final ReteTuple tuple1 = new ReteTuple( new DefaultFactHandle( 1, "cheese" ) );
+ node0.assertTuple( tuple1,
+ context0,
+ workingMemory );
+ agenda.activateRuleFlowGroup("rule-flow-group-0");
+ assertEquals( 1,
+ ruleFlowGroup0.size() );
+ assertEquals( 1,
+ agenda.agendaSize() );
+ assertTrue( ruleFlowGroup0.isActive() );
+
+ // Execute the activation, the RuleFlowGroup should automatically deactivate
+ agenda.fireNextItem( null );
+ assertEquals( 0,
+ ruleFlowGroup0.size() );
+ assertEquals( 0,
+ agenda.agendaSize() );
+ assertFalse( ruleFlowGroup0.isActive() );
+
+ // A new activation should now be added to the RuleFlowGroup but not to the agenda
+ final ReteTuple tuple2 = new ReteTuple( new DefaultFactHandle( 1, "cheese" ) );
+ node0.assertTuple( tuple2,
+ context0,
+ workingMemory );
+ assertEquals( 1,
+ ruleFlowGroup0.size() );
+ assertEquals( 0,
+ agenda.agendaSize() );
+ }
+
}
Added: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/RuleFlowGroupTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/RuleFlowGroupTest.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/RuleFlowGroupTest.java 2007-03-01 02:32:55 UTC (rev 9865)
@@ -0,0 +1,279 @@
+package org.drools.reteoo;
+
+/*
+ * 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.List;
+
+import org.drools.DroolsTestCase;
+import org.drools.RuleBase;
+import org.drools.RuleBaseFactory;
+import org.drools.WorkingMemory;
+import org.drools.common.DefaultFactHandle;
+import org.drools.common.InternalAgenda;
+import org.drools.common.PropagationContextImpl;
+import org.drools.common.RuleFlowGroupImpl;
+import org.drools.rule.Rule;
+import org.drools.ruleflow.common.instance.IProcessInstance;
+import org.drools.ruleflow.core.IConnection;
+import org.drools.ruleflow.core.IEndNode;
+import org.drools.ruleflow.core.IJoin;
+import org.drools.ruleflow.core.IRuleFlowProcess;
+import org.drools.ruleflow.core.IRuleSetNode;
+import org.drools.ruleflow.core.ISplit;
+import org.drools.ruleflow.core.IStartNode;
+import org.drools.ruleflow.core.impl.Connection;
+import org.drools.ruleflow.core.impl.EndNode;
+import org.drools.ruleflow.core.impl.Join;
+import org.drools.ruleflow.core.impl.RuleFlowProcess;
+import org.drools.ruleflow.core.impl.RuleSetNode;
+import org.drools.ruleflow.core.impl.Split;
+import org.drools.ruleflow.core.impl.StartNode;
+import org.drools.ruleflow.instance.IRuleFlowProcessInstance;
+import org.drools.ruleflow.instance.impl.RuleFlowProcessInstance;
+import org.drools.spi.Consequence;
+import org.drools.spi.KnowledgeHelper;
+import org.drools.spi.PropagationContext;
+
+/**
+ * @author mproctor
+ */
+
+public class RuleFlowGroupTest extends DroolsTestCase {
+
+ 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 Rule rule3 = new Rule( "test-rule3" );
+ rule3.setRuleFlowGroup( "rule-flow-group-3" );
+ rule3.setConsequence( consequence );
+
+ final RuleTerminalNode node3 = new RuleTerminalNode( 6,
+ new MockTupleSource( 2 ),
+ rule3,
+ rule3.getLhs() );
+
+ final PropagationContext context0 = new PropagationContextImpl( 0,
+ PropagationContext.ASSERTION,
+ rule0,
+ null );
+
+ // nodes
+ IStartNode start = new StartNode();
+ IRuleSetNode ruleSet0 = new RuleSetNode();
+ ruleSet0.setRuleFlowGroup("rule-flow-group-0");
+ IRuleSetNode ruleSet1 = new RuleSetNode();
+ ruleSet1.setRuleFlowGroup("rule-flow-group-1");
+ IRuleSetNode ruleSet2 = new RuleSetNode();
+ ruleSet2.setRuleFlowGroup("rule-flow-group-2");
+ IRuleSetNode ruleSet3 = new RuleSetNode();
+ ruleSet3.setRuleFlowGroup("rule-flow-group-3");
+ ISplit split = new Split();
+ split.setType(ISplit.TYPE_AND);
+ IJoin join = new Join();
+ join.setType(IJoin.TYPE_AND);
+ IEndNode end = new EndNode();
+ // connections
+ new Connection(start, ruleSet0, IConnection.TYPE_NORMAL);
+ new Connection(ruleSet0, split, IConnection.TYPE_NORMAL);
+ new Connection(split, ruleSet1, IConnection.TYPE_NORMAL);
+ new Connection(split, ruleSet2, IConnection.TYPE_NORMAL);
+ new Connection(ruleSet1, join, IConnection.TYPE_NORMAL);
+ new Connection(ruleSet2, join, IConnection.TYPE_NORMAL);
+ new Connection(join, ruleSet3, IConnection.TYPE_NORMAL);
+ new Connection(ruleSet3, end, IConnection.TYPE_NORMAL);
+
+ // process
+ IRuleFlowProcess process = new RuleFlowProcess();
+ process.addNode(start);
+ process.addNode(ruleSet0);
+ process.addNode(ruleSet1);
+ process.addNode(ruleSet2);
+ process.addNode(ruleSet3);
+ process.addNode(split);
+ process.addNode(join);
+ process.addNode(end);
+
+ // proces instance
+ IRuleFlowProcessInstance processInstance = new RuleFlowProcessInstance();
+ processInstance.setAgenda(agenda);
+ processInstance.setProcess(process);
+ assertEquals( IProcessInstance.STATE_PENDING,
+ processInstance.getState() );
+
+ final RuleFlowGroupImpl ruleFlowGroup0 = (RuleFlowGroupImpl) agenda.getRuleFlowGroup( "rule-flow-group-0" );
+ final RuleFlowGroupImpl ruleFlowGroup1 = (RuleFlowGroupImpl) agenda.getRuleFlowGroup( "rule-flow-group-1" );
+ final RuleFlowGroupImpl ruleFlowGroup2 = (RuleFlowGroupImpl) agenda.getRuleFlowGroup( "rule-flow-group-2" );
+ final RuleFlowGroupImpl ruleFlowGroup3 = (RuleFlowGroupImpl) agenda.getRuleFlowGroup( "rule-flow-group-3" );
+
+ 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 );
+
+ final ReteTuple tuple4 = new ReteTuple( new DefaultFactHandle( 1,
+ "cheese" ) );
+ node3.assertTuple( tuple4,
+ context0,
+ workingMemory );
+
+ // RuleFlowGroups should be populated, but the agenda shouldn't
+ assertEquals( 2,
+ ruleFlowGroup0.size() );
+ assertEquals( 1,
+ ruleFlowGroup1.size() );
+ assertEquals( 1,
+ ruleFlowGroup2.size() );
+ assertEquals( 1,
+ ruleFlowGroup3.size() );
+ assertEquals( 0,
+ agenda.agendaSize() );
+
+ // Activate process instance, the activations stay in the group,
+ // but should now also be in the Agenda
+ processInstance.start();
+ assertEquals( IProcessInstance.STATE_ACTIVE,
+ processInstance.getState() );
+ 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() );
+
+ // executing rule1, which should activate AND-join and thus group 3
+ agenda.fireNextItem( null );
+ assertEquals( 0,
+ ruleFlowGroup0.size() );
+ assertEquals( 0,
+ ruleFlowGroup1.size() );
+ assertEquals( 0,
+ ruleFlowGroup2.size() );
+ assertEquals( 1,
+ ruleFlowGroup3.size() );
+ assertEquals( 1,
+ agenda.agendaSize() );
+
+ // executing rule3, and finishing execution
+ agenda.fireNextItem( null );
+ assertEquals( 0,
+ ruleFlowGroup0.size() );
+ assertEquals( 0,
+ ruleFlowGroup1.size() );
+ assertEquals( 0,
+ ruleFlowGroup2.size() );
+ assertEquals( 0,
+ ruleFlowGroup3.size() );
+ assertEquals( 0,
+ agenda.agendaSize() );
+ assertEquals( IProcessInstance.STATE_COMPLETED,
+ processInstance.getState() );
+ }
+}
More information about the jboss-svn-commits
mailing list