[jboss-svn-commits] JBL Code SVN: r20258 - in labs/jbossrules/trunk/drools-process/drools-osworkflow/src: main/java/org/drools/osworkflow/core and 4 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Mon Jun 2 18:42:18 EDT 2008
Author: KrisVerlaenen
Date: 2008-06-02 18:42:17 -0400 (Mon, 02 Jun 2008)
New Revision: 20258
Added:
labs/jbossrules/trunk/drools-process/drools-osworkflow/src/main/java/org/drools/osworkflow/core/OSWorkflowConnection.java
Modified:
labs/jbossrules/trunk/drools-process/drools-osworkflow/src/main/java/org/drools/osworkflow/DroolsWorkflow.java
labs/jbossrules/trunk/drools-process/drools-osworkflow/src/main/java/org/drools/osworkflow/OSWorkflowParser.java
labs/jbossrules/trunk/drools-process/drools-osworkflow/src/main/java/org/drools/osworkflow/core/OSWorkflowProcess.java
labs/jbossrules/trunk/drools-process/drools-osworkflow/src/main/java/org/drools/osworkflow/core/node/StepNode.java
labs/jbossrules/trunk/drools-process/drools-osworkflow/src/main/java/org/drools/osworkflow/instance/OSWorkflowProcessInstance.java
labs/jbossrules/trunk/drools-process/drools-osworkflow/src/main/java/org/drools/osworkflow/instance/node/StepNodeInstance.java
labs/jbossrules/trunk/drools-process/drools-osworkflow/src/test/java/org/drools/Simple2ProcessTest.java
labs/jbossrules/trunk/drools-process/drools-osworkflow/src/test/java/org/drools/SimpleProcessTest.java
Log:
OSWorkflow implementation
Modified: labs/jbossrules/trunk/drools-process/drools-osworkflow/src/main/java/org/drools/osworkflow/DroolsWorkflow.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-osworkflow/src/main/java/org/drools/osworkflow/DroolsWorkflow.java 2008-06-02 17:25:55 UTC (rev 20257)
+++ labs/jbossrules/trunk/drools-process/drools-osworkflow/src/main/java/org/drools/osworkflow/DroolsWorkflow.java 2008-06-02 22:42:17 UTC (rev 20258)
@@ -1,14 +1,17 @@
package org.drools.osworkflow;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.drools.RuleBase;
import org.drools.RuleBaseFactory;
import org.drools.WorkingMemory;
+import org.drools.osworkflow.core.OSWorkflowProcess;
import org.drools.osworkflow.instance.OSWorkflowProcessInstance;
import org.drools.osworkflow.instance.node.StepNodeInstance;
+import org.drools.process.instance.ProcessInstance;
import org.drools.rule.Package;
import org.drools.workflow.instance.NodeInstance;
@@ -25,18 +28,21 @@
import com.opensymphony.workflow.loader.WorkflowDescriptor;
import com.opensymphony.workflow.query.WorkflowExpressionQuery;
import com.opensymphony.workflow.query.WorkflowQuery;
+import com.opensymphony.workflow.spi.Step;
+import com.opensymphony.workflow.spi.WorkflowEntry;
public class DroolsWorkflow implements Workflow {
private OSWorkflowParser parser = new OSWorkflowParser();
private WorkingMemory workingMemory;
private Configuration configuration;
+ private Map<Long, OSWorkflowProcessInstance> processInstances = new HashMap<Long, OSWorkflowProcessInstance>();
public long initialize(String workflowName, int initialAction, Map inputs)
throws InvalidRoleException, InvalidInputException,
WorkflowException, InvalidEntryStateException,
InvalidActionException {
- RuleBase ruleBase = workingMemory.getRuleBase();
+ RuleBase ruleBase = getWorkingMemory().getRuleBase();
Package p = ruleBase.getPackage("org.drools.osworkflow");
if (p.getRuleFlows().get(workflowName) == null) {
WorkflowDescriptor descriptor = getConfiguration().getWorkflow(workflowName);
@@ -45,31 +51,27 @@
"Could not find process with name " + workflowName);
}
Package newPackage = new Package("org.drools.osworkflow");
- newPackage.addRuleFlow(parser.parseOSWorkflow(descriptor));
+ if (descriptor.getName() == null) {
+ descriptor.setName(workflowName);
+ }
+ OSWorkflowProcess process = parser.parseOSWorkflow(descriptor);
+ newPackage.addProcess(process);
ruleBase.addPackage(newPackage);
}
- // TODO initialAction
OSWorkflowProcessInstance processInstance = (OSWorkflowProcessInstance)
- workingMemory.startProcess(workflowName);
+ getWorkingMemory().startProcess(workflowName);
processInstance.doInitialAction(initialAction, inputs);
+ processInstances.put(processInstance.getId(), processInstance);
return processInstance.getId();
}
public void doAction(long id, int actionId, Map inputs)
throws InvalidInputException, WorkflowException {
- OSWorkflowProcessInstance processInstance = findProcessInstance(id);
- for (NodeInstance nodeInstance: processInstance.getNodeInstances()) {
- StepNodeInstance stepNodeInstance = (StepNodeInstance) nodeInstance;
- if (stepNodeInstance.isAvailableAction(actionId)) {
- stepNodeInstance.doAction(actionId, inputs);
- break;
- }
- }
+ findProcessInstance(id).doAction(actionId, inputs);
}
private OSWorkflowProcessInstance findProcessInstance(long id) {
- OSWorkflowProcessInstance processInstance = (OSWorkflowProcessInstance)
- workingMemory.getProcessInstance(id);
+ OSWorkflowProcessInstance processInstance = processInstances.get(id);
if (processInstance == null) {
throw new IllegalArgumentException(
"Could not find process instance with id " + id);
@@ -120,25 +122,31 @@
// TODO
}
- public List getCurrentSteps(long id) {
- List<StepNodeInstance> result = new ArrayList<StepNodeInstance>();
- OSWorkflowProcessInstance processInstance = findProcessInstance(id);
- for (NodeInstance nodeInstance: processInstance.getNodeInstances()) {
- if (nodeInstance instanceof StepNodeInstance) {
- result.add((StepNodeInstance) nodeInstance);
- }
- }
- return result;
+ public List<Step> getCurrentSteps(long id) {
+ return findProcessInstance(id).getCurrentSteps();
}
public int getEntryState(long id) {
- // TODO
- return 0;
+ int state = findProcessInstance(id).getState();
+ switch (state) {
+ case ProcessInstance.STATE_PENDING:
+ return WorkflowEntry.CREATED;
+ case ProcessInstance.STATE_ACTIVE:
+ return WorkflowEntry.ACTIVATED;
+ case ProcessInstance.STATE_COMPLETED:
+ return WorkflowEntry.COMPLETED;
+ case ProcessInstance.STATE_ABORTED:
+ return WorkflowEntry.KILLED;
+ case ProcessInstance.STATE_SUSPENDED:
+ return WorkflowEntry.SUSPENDED;
+ default:
+ return WorkflowEntry.UNKNOWN;
+ }
}
public List getHistorySteps(long id) {
- // TODO
- return null;
+ OSWorkflowProcessInstance processInstance = findProcessInstance(id);
+ return processInstance.getHistorySteps();
}
public PropertySet getPropertySet(long id) {
@@ -192,13 +200,19 @@
// TODO
return false;
}
+
+ protected WorkingMemory getWorkingMemory() {
+ if (workingMemory == null) {
+ RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+ Package p = new Package("org.drools.osworkflow");
+ ruleBase.addPackage(p);
+ workingMemory = ruleBase.newStatefulSession();
+ }
+ return workingMemory;
+ }
public void setConfiguration(Configuration configuration) {
this.configuration = configuration;
- RuleBase ruleBase = RuleBaseFactory.newRuleBase();
- Package p = new Package("org.drools.osworkflow");
- ruleBase.addPackage(p);
- workingMemory = ruleBase.newStatefulSession();
}
private Configuration getConfiguration() {
Modified: labs/jbossrules/trunk/drools-process/drools-osworkflow/src/main/java/org/drools/osworkflow/OSWorkflowParser.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-osworkflow/src/main/java/org/drools/osworkflow/OSWorkflowParser.java 2008-06-02 17:25:55 UTC (rev 20257)
+++ labs/jbossrules/trunk/drools-process/drools-osworkflow/src/main/java/org/drools/osworkflow/OSWorkflowParser.java 2008-06-02 22:42:17 UTC (rev 20258)
@@ -1,12 +1,12 @@
package org.drools.osworkflow;
+import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.drools.osworkflow.core.OSWorkflowProcess;
import org.drools.osworkflow.core.node.StepNode;
-import org.drools.process.core.Process;
import org.drools.workflow.core.Node;
import org.drools.workflow.core.impl.ConnectionImpl;
import org.drools.workflow.core.node.Join;
@@ -27,7 +27,7 @@
private Map<Integer, Split> splitsMap;
private Map<Integer, Join> joinsMap;
- public Process parseOSWorkflow(WorkflowDescriptor descriptor) {
+ public OSWorkflowProcess parseOSWorkflow(WorkflowDescriptor descriptor) {
process = new OSWorkflowProcess();
process.setName(descriptor.getName());
process.setId(descriptor.getName());
@@ -35,13 +35,14 @@
process.setInitialActions(descriptor.getInitialActions());
stepsMap = new HashMap<Integer, StepNode>();
- int nodeCounter = 0;
List<StepDescriptor> steps = descriptor.getSteps();
for (StepDescriptor step: steps) {
StepNode stepNode = new StepNode();
- stepNode.setId(++nodeCounter);
+ stepNode.setId(step.getId());
stepNode.setName(step.getName());
stepNode.setActions(step.getActions());
+ stepNode.setPreFunctions(step.getPreFunctions());
+ stepNode.setPostFunctions(step.getPostFunctions());
process.addNode(stepNode);
stepsMap.put(step.getId(), stepNode);
}
@@ -49,7 +50,8 @@
List<SplitDescriptor> splits = descriptor.getSplits();
for (SplitDescriptor split: splits) {
Split splitNode = new Split();
- splitNode.setId(++nodeCounter);
+ // TODO: this is not fail safe
+ splitNode.setId(split.getId() + 1000);
splitNode.setName("split");
splitNode.setType(Split.TYPE_AND);
process.addNode(splitNode);
@@ -63,7 +65,8 @@
List<JoinDescriptor> joins = descriptor.getJoins();
for (JoinDescriptor join: joins) {
Join joinNode = new Join();
- joinNode.setId(++nodeCounter);
+ // TODO: this is not fail safe
+ joinNode.setId(join.getId() + 2000);
joinNode.setName("join");
// TODO conditions
List<ConditionDescriptor> conditions = join.getConditions();
@@ -73,6 +76,7 @@
ResultDescriptor result = join.getResult();
createConnection(joinNode, Node.CONNECTION_DEFAULT_TYPE, result);
}
+ postProcessActions(process.getInitialActions());
steps = descriptor.getSteps();
for (StepDescriptor step: steps) {
@@ -81,6 +85,7 @@
ResultDescriptor result = action.getUnconditionalResult();
createConnection(stepsMap.get(step.getId()), action.getId() + "", result);
}
+ postProcessActions(actions);
}
return process;
}
@@ -98,10 +103,33 @@
new ConnectionImpl(
node,
type,
- process.getNode(result.getStep()),
+ stepsMap.get(result.getStep()),
result.getStatus()
);
}
}
+
+ private void postProcessActions(Collection<ActionDescriptor> actions) {
+ if (actions != null) {
+ for (ActionDescriptor action: actions) {
+ postProcessResult(action.getUnconditionalResult());
+ List<ResultDescriptor> conditionalResults =
+ action.getConditionalResults();
+ if (conditionalResults != null) {
+ for (ResultDescriptor result: conditionalResults) {
+ postProcessResult(result);
+ }
+ }
+ }
+ }
+ }
+
+ private void postProcessResult(ResultDescriptor result) {
+ if (result.getSplit() != 0) {
+ result.setSplit(1000 + result.getSplit());
+ } else if (result.getJoin() != 0) {
+ result.setJoin(2000 + result.getJoin());
+ }
+ }
}
Added: labs/jbossrules/trunk/drools-process/drools-osworkflow/src/main/java/org/drools/osworkflow/core/OSWorkflowConnection.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-osworkflow/src/main/java/org/drools/osworkflow/core/OSWorkflowConnection.java (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-osworkflow/src/main/java/org/drools/osworkflow/core/OSWorkflowConnection.java 2008-06-02 22:42:17 UTC (rev 20258)
@@ -0,0 +1,37 @@
+package org.drools.osworkflow.core;
+
+import java.util.List;
+
+import org.drools.workflow.core.Node;
+import org.drools.workflow.core.impl.ConnectionImpl;
+
+import com.opensymphony.workflow.loader.FunctionDescriptor;
+
+public class OSWorkflowConnection extends ConnectionImpl {
+
+ private static final long serialVersionUID = 1L;
+
+ private List<FunctionDescriptor> preFunctions;
+ private List<FunctionDescriptor> postFunctions;
+
+ public OSWorkflowConnection(Node from, String fromType, Node to, String toType) {
+ super(from, fromType, to, toType);
+ }
+
+ public List<FunctionDescriptor> getPreFunctions() {
+ return preFunctions;
+ }
+
+ public void setPreFunctions(List<FunctionDescriptor> preFunctions) {
+ this.preFunctions = preFunctions;
+ }
+
+ public List<FunctionDescriptor> getPostFunctions() {
+ return postFunctions;
+ }
+
+ public void setPostFunctions(List<FunctionDescriptor> postFunctions) {
+ this.postFunctions = postFunctions;
+ }
+
+}
Modified: labs/jbossrules/trunk/drools-process/drools-osworkflow/src/main/java/org/drools/osworkflow/core/OSWorkflowProcess.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-osworkflow/src/main/java/org/drools/osworkflow/core/OSWorkflowProcess.java 2008-06-02 17:25:55 UTC (rev 20257)
+++ labs/jbossrules/trunk/drools-process/drools-osworkflow/src/main/java/org/drools/osworkflow/core/OSWorkflowProcess.java 2008-06-02 22:42:17 UTC (rev 20258)
@@ -5,6 +5,7 @@
import java.util.List;
import java.util.Map;
+import org.drools.process.core.context.variable.VariableScope;
import org.drools.workflow.core.impl.WorkflowProcessImpl;
import com.opensymphony.workflow.loader.ActionDescriptor;
@@ -20,6 +21,9 @@
public OSWorkflowProcess() {
setType(OSWORKFLOW_TYPE);
+ VariableScope variableScope = new VariableScope();
+ addContext(variableScope);
+ setDefaultContext(variableScope);
}
public void addInitialAction(ActionDescriptor action) {
Modified: labs/jbossrules/trunk/drools-process/drools-osworkflow/src/main/java/org/drools/osworkflow/core/node/StepNode.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-osworkflow/src/main/java/org/drools/osworkflow/core/node/StepNode.java 2008-06-02 17:25:55 UTC (rev 20257)
+++ labs/jbossrules/trunk/drools-process/drools-osworkflow/src/main/java/org/drools/osworkflow/core/node/StepNode.java 2008-06-02 22:42:17 UTC (rev 20258)
@@ -8,11 +8,14 @@
import org.drools.workflow.core.impl.NodeImpl;
import com.opensymphony.workflow.loader.ActionDescriptor;
+import com.opensymphony.workflow.loader.FunctionDescriptor;
public class StepNode extends NodeImpl {
- public Map<Integer, ActionDescriptor> actions =
+ private Map<Integer, ActionDescriptor> actions =
new HashMap<Integer, ActionDescriptor>();
+ private List<FunctionDescriptor> preFunctions;
+ private List<FunctionDescriptor> postFunctions;
private static final long serialVersionUID = 1L;
@@ -34,4 +37,20 @@
return actions.get(id);
}
+ public List<FunctionDescriptor> getPreFunctions() {
+ return preFunctions;
+ }
+
+ public void setPreFunctions(List<FunctionDescriptor> preFunctions) {
+ this.preFunctions = preFunctions;
+ }
+
+ public List<FunctionDescriptor> getPostFunctions() {
+ return postFunctions;
+ }
+
+ public void setPostFunctions(List<FunctionDescriptor> postFunctions) {
+ this.postFunctions = postFunctions;
+ }
+
}
Modified: labs/jbossrules/trunk/drools-process/drools-osworkflow/src/main/java/org/drools/osworkflow/instance/OSWorkflowProcessInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-osworkflow/src/main/java/org/drools/osworkflow/instance/OSWorkflowProcessInstance.java 2008-06-02 17:25:55 UTC (rev 20257)
+++ labs/jbossrules/trunk/drools-process/drools-osworkflow/src/main/java/org/drools/osworkflow/instance/OSWorkflowProcessInstance.java 2008-06-02 22:42:17 UTC (rev 20258)
@@ -1,51 +1,370 @@
package org.drools.osworkflow.instance;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import org.drools.osworkflow.core.OSWorkflowProcess;
-import org.drools.osworkflow.core.node.StepNode;
import org.drools.osworkflow.instance.node.StepNodeInstance;
+import org.drools.process.core.context.variable.VariableScope;
+import org.drools.process.instance.ProcessInstance;
+import org.drools.process.instance.context.variable.VariableScopeInstance;
+import org.drools.workflow.core.Node;
+import org.drools.workflow.instance.NodeInstance;
import org.drools.workflow.instance.impl.WorkflowProcessInstanceImpl;
+import com.opensymphony.module.propertyset.PropertySet;
+import com.opensymphony.module.propertyset.map.MapPropertySet;
+import com.opensymphony.workflow.Condition;
+import com.opensymphony.workflow.FunctionProvider;
+import com.opensymphony.workflow.StoreException;
+import com.opensymphony.workflow.TypeResolver;
+import com.opensymphony.workflow.WorkflowContext;
+import com.opensymphony.workflow.WorkflowException;
+import com.opensymphony.workflow.basic.BasicWorkflowContext;
+import com.opensymphony.workflow.loader.AbstractDescriptor;
import com.opensymphony.workflow.loader.ActionDescriptor;
+import com.opensymphony.workflow.loader.ConditionDescriptor;
+import com.opensymphony.workflow.loader.ConditionalResultDescriptor;
+import com.opensymphony.workflow.loader.ConditionsDescriptor;
+import com.opensymphony.workflow.loader.FunctionDescriptor;
import com.opensymphony.workflow.loader.ResultDescriptor;
+import com.opensymphony.workflow.query.WorkflowExpressionQuery;
+import com.opensymphony.workflow.query.WorkflowQuery;
+import com.opensymphony.workflow.spi.Step;
+import com.opensymphony.workflow.spi.WorkflowEntry;
+import com.opensymphony.workflow.spi.WorkflowStore;
-public class OSWorkflowProcessInstance extends WorkflowProcessInstanceImpl {
+public class OSWorkflowProcessInstance extends WorkflowProcessInstanceImpl implements WorkflowEntry {
private static final long serialVersionUID = 1L;
+
+ private List<Step> history = new ArrayList<Step>();
public OSWorkflowProcess getOSWorkflowProcess() {
return (OSWorkflowProcess) getProcess();
}
protected void internalStart() {
+ Map<String, Object> transientVars = new HashMap<String, Object>();
for (ActionDescriptor action: getOSWorkflowProcess().getInitialActions()) {
if (action.getAutoExecute()) {
- executeAction(action);
+ executeAction(action, 0, transientVars);
}
}
}
public void doInitialAction(int actionId, Map inputs) {
+ Map<String, Object> transientVars = new HashMap<String, Object>();
+ transientVars.put("context", new DummyWorkflowContext());
ActionDescriptor initialAction = getOSWorkflowProcess().getInitialAction(actionId);
if (initialAction == null) {
throw new IllegalArgumentException(
"Unknown initial action id " + actionId);
}
- executeAction(initialAction);
+ executeAction(initialAction, 0, transientVars);
}
- protected void executeAction(ActionDescriptor action) {
- // TODO check conditional results first
- ResultDescriptor result = action.getUnconditionalResult();
- int step = result.getStep();
- String status = result.getStatus();
- StepNode stepNode = (StepNode) getNodeContainer().getNode(step);
- if (stepNode == null) {
+ public void doAction(int actionId, Map inputs) {
+ for (NodeInstance nodeInstance: getNodeInstances()) {
+ StepNodeInstance stepNodeInstance = (StepNodeInstance) nodeInstance;
+ if (stepNodeInstance.isAvailableAction(actionId)) {
+ stepNodeInstance.doAction(actionId, inputs);
+ break;
+ }
+ }
+ checkImplicitFinish();
+ }
+
+ protected void executeAction(ActionDescriptor action, int currentStepId, Map<String, Object> transientVars) {
+ List<FunctionDescriptor> preFunctions = action.getPreFunctions();
+ if (preFunctions != null) {
+ for (FunctionDescriptor preFunction: preFunctions) {
+ executeFunction(preFunction, transientVars);
+ }
+ }
+ boolean executed = false;
+ List<ConditionalResultDescriptor> conditionalResults = action.getConditionalResults();
+ if (conditionalResults != null) {
+ for (ConditionalResultDescriptor conditionalResult: conditionalResults) {
+ if (passesConditions(null, conditionalResult.getConditions(), currentStepId)) {
+ executeResult(conditionalResult, transientVars);
+ }
+ }
+ }
+ if (!executed) {
+ executeResult(action.getUnconditionalResult(), transientVars);
+ }
+ List<FunctionDescriptor> postFunctions = action.getPostFunctions();
+ if (postFunctions != null) {
+ for (FunctionDescriptor postFunction: postFunctions) {
+ executeFunction(postFunction, transientVars);
+ }
+ }
+ if (action.isFinish()) {
+ setState(ProcessInstance.STATE_COMPLETED);
+ }
+ }
+
+ protected void executeResult(ResultDescriptor result, Map<String, Object> transientVars) {
+ List<FunctionDescriptor> preFunctions = result.getPreFunctions();
+ if (preFunctions != null) {
+ for (FunctionDescriptor preFunction: preFunctions) {
+ executeFunction(preFunction, transientVars);
+ }
+ }
+ int nodeId = 0;
+ String type = null;
+ if (result.getSplit() != 0) {
+ nodeId = result.getSplit();
+ type = Node.CONNECTION_DEFAULT_TYPE;
+ } else if (result.getJoin() != 0) {
+ nodeId = result.getJoin();
+ type = Node.CONNECTION_DEFAULT_TYPE;
+ } else {
+ nodeId = result.getStep();
+ type = result.getStatus();
+ }
+ Node node = getNodeContainer().getNode(nodeId);
+ if (node == null) {
throw new IllegalArgumentException(
- "Unknown step id " + step);
+ "Unknown node id " + nodeId);
}
- StepNodeInstance stepNodeInstance = (StepNodeInstance) getNodeInstance(stepNode);
- stepNodeInstance.trigger(null, status);
+ NodeInstance nodeInstance = getNodeInstance(node);
+ if (result.getOwner() != null && nodeInstance instanceof StepNodeInstance) {
+ ((StepNodeInstance) nodeInstance).setOwner(result.getOwner());
+ }
+ nodeInstance.trigger(null, type);
+ List<FunctionDescriptor> postFunctions = result.getPostFunctions();
+ if (postFunctions != null) {
+ for (FunctionDescriptor postFunction: postFunctions) {
+ executeFunction(postFunction, transientVars);
+ }
+ }
}
+
+ public void executeFunction(FunctionDescriptor function, Map<String, Object> transientVars) {
+ Map<String, Object> params = createParams(function.getArgs());
+ try {
+ FunctionProvider provider = TypeResolver.getResolver().getFunction(function.getType(), params);
+ if (provider == null) {
+ throw new WorkflowException("Could not load FunctionProvider class");
+ }
+ MapPropertySet ps = new MapPropertySet();
+ ps.setMap(new HashMap());
+ provider.execute(transientVars, params, ps);
+ } catch (WorkflowException e) {
+ throw new RuntimeException("WorkflowException when executing function", e);
+ }
+
+ }
+
+ protected boolean passesCondition(ConditionDescriptor conditionDesc, int currentStepId) {
+ try {
+ String type = conditionDesc.getType();
+ Map<String, Object> params = createParams(conditionDesc.getArgs());
+ if (currentStepId != -1) {
+ Object stepId = params.get("stepId");
+ if ((stepId != null) && stepId.equals("-1")) {
+ params.put("stepId", String.valueOf(currentStepId));
+ }
+ }
+ Condition condition = TypeResolver.getResolver().getCondition(type, params);
+ if (condition == null) {
+ throw new WorkflowException("Could not load condition");
+ }
+ try {
+ Map<String, Object> transientVars = new HashMap<String, Object>();
+ transientVars.put("entry", this);
+ transientVars.put("context", new DummyWorkflowContext());
+ transientVars.put("store", new DummyWorkflowStore());
+ PropertySet ps = new MapPropertySet();
+ boolean passed = condition.passesCondition(transientVars, params, ps);
+ if (conditionDesc.isNegate()) {
+ passed = !passed;
+ }
+ return passed;
+ } catch (Exception e) {
+ if (e instanceof WorkflowException) {
+ throw (WorkflowException) e;
+ }
+ throw new WorkflowException("Unknown exception encountered when checking condition " + condition, e);
+ }
+ } catch (WorkflowException e) {
+ throw new RuntimeException("WorkflowException when checking conditions", e);
+ }
+ }
+
+ public boolean passesConditions(String conditionType, List<AbstractDescriptor> conditions, int currentStepId) {
+ if ((conditions == null) || (conditions.size() == 0)) {
+ return true;
+ }
+ boolean and = "AND".equals(conditionType);
+ boolean or = !and;
+ for (AbstractDescriptor descriptor: conditions) {
+ boolean result;
+ if (descriptor instanceof ConditionsDescriptor) {
+ ConditionsDescriptor conditionsDescriptor = (ConditionsDescriptor) descriptor;
+ result = passesConditions(conditionsDescriptor.getType(), conditionsDescriptor.getConditions(), currentStepId);
+ } else {
+ result = passesCondition((ConditionDescriptor) descriptor, currentStepId);
+ }
+ if (and && !result) {
+ return false;
+ } else if (or && result) {
+ return true;
+ }
+ }
+ if (and) {
+ return true;
+ } else if (or) {
+ return false;
+ } else {
+ return false;
+ }
+ }
+
+ protected Map<String, Object> createParams(Map<String, Object> params) {
+ Map<String, Object> result = new HashMap<String, Object>(params);
+ for (String paramName : result.keySet()) {
+ VariableScopeInstance variableScopeInstance = (VariableScopeInstance)
+ getContextInstance(VariableScope.VARIABLE_SCOPE);
+ Object value = variableScopeInstance.getVariable(paramName);
+ if (value != null) {
+ result.put(paramName, value);
+ }
+ }
+ return result;
+ }
+
+ public List<Step> getCurrentSteps() {
+ List<Step> result = new ArrayList<Step>();
+ for (NodeInstance nodeInstance: getNodeInstances()) {
+ if (nodeInstance instanceof StepNodeInstance) {
+ result.add((StepNodeInstance) nodeInstance);
+ }
+ }
+ return result;
+ }
+
+ public void removeNodeInstance(final NodeInstance nodeInstance) {
+ super.removeNodeInstance(nodeInstance);
+ if (nodeInstance instanceof StepNodeInstance) {
+ history.add(0, (StepNodeInstance) nodeInstance);
+ }
+ }
+
+ private void checkImplicitFinish() {
+ boolean finished = true;
+ for (NodeInstance nodeInstance: getNodeInstances()) {
+ if (nodeInstance instanceof StepNodeInstance) {
+ if (!((StepNodeInstance) nodeInstance).getAvailableActions().isEmpty()) {
+ finished = false;
+ break;
+ }
+ }
+ }
+ if (finished) {
+ setState(ProcessInstance.STATE_COMPLETED);
+ }
+ }
+
+ public List<Step> getHistorySteps() {
+ return history;
+ }
+
+ public String getWorkflowName() {
+ return getProcess().getName();
+ }
+
+ public boolean isInitialized() {
+ return true;
+ }
+
+ public class DummyWorkflowStore implements WorkflowStore {
+
+ public Step createCurrentStep(long entryId, int stepId, String owner,
+ Date startDate, Date dueDate, String status, long[] previousIds)
+ throws StoreException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public WorkflowEntry createEntry(String workflowName)
+ throws StoreException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public List findCurrentSteps(long entryId) throws StoreException {
+ if (entryId == getId()) {
+ return getCurrentSteps();
+ }
+ return null;
+ }
+
+ public WorkflowEntry findEntry(long entryId) throws StoreException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public List findHistorySteps(long entryId) throws StoreException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public PropertySet getPropertySet(long entryId) throws StoreException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void init(Map props) throws StoreException {
+ // TODO Auto-generated method stub
+
+ }
+
+ public Step markFinished(Step step, int actionId, Date finishDate,
+ String status, String caller) throws StoreException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void moveToHistory(Step step) throws StoreException {
+ // TODO Auto-generated method stub
+
+ }
+
+ public List query(WorkflowQuery query) throws StoreException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public List query(WorkflowExpressionQuery query) throws StoreException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void setEntryState(long entryId, int state)
+ throws StoreException {
+ // TODO Auto-generated method stub
+
+ }
+
+ }
+
+ public class DummyWorkflowContext implements WorkflowContext {
+
+ public String getCaller() {
+ // TODO
+ return "caller";
+ }
+
+ public void setRollbackOnly() {
+ // TODO
+ }
+
+ }
+
}
Modified: labs/jbossrules/trunk/drools-process/drools-osworkflow/src/main/java/org/drools/osworkflow/instance/node/StepNodeInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-osworkflow/src/main/java/org/drools/osworkflow/instance/node/StepNodeInstance.java 2008-06-02 17:25:55 UTC (rev 20257)
+++ labs/jbossrules/trunk/drools-process/drools-osworkflow/src/main/java/org/drools/osworkflow/instance/node/StepNodeInstance.java 2008-06-02 22:42:17 UTC (rev 20258)
@@ -1,56 +1,148 @@
package org.drools.osworkflow.instance.node;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Date;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import org.drools.osworkflow.core.OSWorkflowConnection;
import org.drools.osworkflow.core.node.StepNode;
+import org.drools.osworkflow.instance.OSWorkflowProcessInstance;
+import org.drools.process.instance.ProcessInstance;
+import org.drools.workflow.core.Connection;
import org.drools.workflow.instance.NodeInstance;
import org.drools.workflow.instance.impl.NodeInstanceImpl;
+import com.opensymphony.module.propertyset.map.MapPropertySet;
+import com.opensymphony.workflow.basic.BasicWorkflowContext;
import com.opensymphony.workflow.loader.ActionDescriptor;
-import com.opensymphony.workflow.loader.ConditionDescriptor;
+import com.opensymphony.workflow.loader.ConditionalResultDescriptor;
import com.opensymphony.workflow.loader.ConditionsDescriptor;
+import com.opensymphony.workflow.loader.FunctionDescriptor;
import com.opensymphony.workflow.loader.RestrictionDescriptor;
import com.opensymphony.workflow.loader.ResultDescriptor;
import com.opensymphony.workflow.spi.Step;
-import com.opensymphony.workflow.util.StatusCondition;
+import com.opensymphony.workflow.util.DefaultVariableResolver;
public class StepNodeInstance extends NodeInstanceImpl implements Step {
private static final long serialVersionUID = 1L;
private String status;
+ private String owner;
public StepNode getStepNode() {
return (StepNode) getNode();
}
+ public OSWorkflowProcessInstance getOSWorkflowProcessInstance() {
+ return (OSWorkflowProcessInstance) getProcessInstance();
+ }
+
public int getStepId() {
return (int) getNodeId();
}
public void internalTrigger(NodeInstance from, String type) {
+ Map<String, Object> transientVars = new HashMap<String, Object>();
+ transientVars.put("context", new BasicWorkflowContext("caller"));
+ List<FunctionDescriptor> preFunctions = getStepNode().getPreFunctions();
+ if (preFunctions != null) {
+ for (FunctionDescriptor preFunction: preFunctions) {
+ getOSWorkflowProcessInstance().executeFunction(preFunction, transientVars);
+ }
+ }
setStatus(type);
+ Collection<ActionDescriptor> actions = getStepNode().getActions();
+ for (ActionDescriptor action: actions) {
+ if (action.getAutoExecute() && isAvailableAction(action)) {
+ doAction(action.getId(), null);
+ break;
+ }
+ }
}
public void doAction(int actionId, Map inputs) {
+ Map<String, Object> transientVars = new HashMap<String, Object>();
+ transientVars.put("context", new BasicWorkflowContext("caller"));
ActionDescriptor action = getStepNode().getAction(actionId);
if (action == null) {
throw new IllegalArgumentException(
"Unknown action id " + actionId);
}
- ResultDescriptor result = action.getUnconditionalResult();
- // TODO check stuff
+ List<FunctionDescriptor> preFunctions = action.getPreFunctions();
+ if (preFunctions != null) {
+ for (FunctionDescriptor preFunction: preFunctions) {
+ getOSWorkflowProcessInstance().executeFunction(preFunction, transientVars);
+ }
+ }
+ boolean executed = false;
+ List<ConditionalResultDescriptor> conditionalResults = action.getConditionalResults();
+ if (conditionalResults != null) {
+ for (ConditionalResultDescriptor conditionalResult: conditionalResults) {
+ if (getOSWorkflowProcessInstance().passesConditions(null, conditionalResult.getConditions(), (int) getNodeId())) {
+ executeResult(conditionalResult, actionId, transientVars);
+ }
+ }
+ }
+ if (!executed) {
+ executeResult(action.getUnconditionalResult(), actionId, transientVars);
+ }
+ List<FunctionDescriptor> postFunctions = action.getPostFunctions();
+ if (postFunctions != null) {
+ for (FunctionDescriptor postFunction: postFunctions) {
+ getOSWorkflowProcessInstance().executeFunction(postFunction, transientVars);
+ }
+ }
+ if (action.isFinish()) {
+ getProcessInstance().setState(ProcessInstance.STATE_COMPLETED);
+ }
+ }
+
+ protected void executeResult(ResultDescriptor result, int actionId, Map<String, Object> transientVars) {
+ List<FunctionDescriptor> preFunctions = result.getPreFunctions();
+ if (preFunctions != null) {
+ for (FunctionDescriptor preFunction: preFunctions) {
+ getOSWorkflowProcessInstance().executeFunction(preFunction, transientVars);
+ }
+ }
+ String owner = null;
+ if (result.getOwner() != null) {
+ MapPropertySet ps = new MapPropertySet();
+ ps.setMap(new HashMap());
+ Object o = new DefaultVariableResolver().translateVariables(result.getOwner(), transientVars, ps);
+ owner = (o != null) ? o.toString() : null;
+ }
if (result.getStep() == -1 || result.getStep() == getNodeId()) {
+ setOwner(owner);
setStatus(result.getStatus());
} else {
setStatus(result.getOldStatus());
- triggerCompleted(actionId + "", true);
+ List<FunctionDescriptor> postFunctions = getStepNode().getPostFunctions();
+ if (postFunctions != null) {
+ for (FunctionDescriptor postFunction: postFunctions) {
+ getOSWorkflowProcessInstance().executeFunction(postFunction, transientVars);
+ }
+ }
+ getNodeInstanceContainer().removeNodeInstance(this);
+ for (Connection connection: getNode().getOutgoingConnections(actionId + "")) {
+ NodeInstance nodeInstance = getNodeInstanceContainer().getNodeInstance(connection.getTo());
+ if (nodeInstance instanceof StepNodeInstance) {
+ ((StepNodeInstance) nodeInstance).setOwner(owner);
+ }
+ nodeInstance.trigger(this, connection.getToType());
+ }
}
+ List<FunctionDescriptor> postFunctions = result.getPostFunctions();
+ if (postFunctions != null) {
+ for (FunctionDescriptor postFunction: postFunctions) {
+ getOSWorkflowProcessInstance().executeFunction(postFunction, transientVars);
+ }
+ }
}
-
+
public String getStatus() {
return status;
}
@@ -71,14 +163,8 @@
if (restriction != null) {
ConditionsDescriptor conditions = restriction.getConditionsDescriptor();
if (conditions != null) {
- List<ConditionDescriptor> conditionList = conditions.getConditions();
- for (ConditionDescriptor condition: conditionList) {
- String className = (String) condition.getArgs().get("class.name");
- if (StatusCondition.class.getName().equals(className.trim())) {
- String status = (String) condition.getArgs().get("status");
- return status.equals(this.status);
- }
- }
+ return getOSWorkflowProcessInstance().passesConditions(
+ conditions.getType(), conditions.getConditions(), (int) getNodeId());
}
}
return true;
@@ -94,6 +180,28 @@
return ids;
}
+ protected void triggerConnection(Connection connection) {
+ Map<String, Object> transientVars = new HashMap<String, Object>();
+ if (connection instanceof OSWorkflowConnection) {
+ List<FunctionDescriptor> functions =
+ ((OSWorkflowConnection) connection).getPreFunctions();
+ if (functions != null) {
+ for (FunctionDescriptor function: functions) {
+ getOSWorkflowProcessInstance().executeFunction(function, transientVars);
+ }
+ }
+ super.triggerConnection(connection);
+ functions = ((OSWorkflowConnection) connection).getPostFunctions();
+ if (functions != null) {
+ for (FunctionDescriptor function: functions) {
+ getOSWorkflowProcessInstance().executeFunction(function, transientVars);
+ }
+ }
+ } else {
+ super.triggerConnection(connection);
+ }
+ }
+
public int getActionId() {
// TODO
return 0;
@@ -118,10 +226,13 @@
// TODO
return null;
}
+
+ public void setOwner(String owner) {
+ this.owner = owner;
+ }
public String getOwner() {
- // TODO
- return null;
+ return owner;
}
public long[] getPreviousStepIds() {
Modified: labs/jbossrules/trunk/drools-process/drools-osworkflow/src/test/java/org/drools/Simple2ProcessTest.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-osworkflow/src/test/java/org/drools/Simple2ProcessTest.java 2008-06-02 17:25:55 UTC (rev 20257)
+++ labs/jbossrules/trunk/drools-process/drools-osworkflow/src/test/java/org/drools/Simple2ProcessTest.java 2008-06-02 22:42:17 UTC (rev 20258)
@@ -9,9 +9,12 @@
import org.drools.osworkflow.DroolsWorkflow;
+import com.opensymphony.workflow.InvalidInputException;
import com.opensymphony.workflow.Workflow;
+import com.opensymphony.workflow.WorkflowException;
import com.opensymphony.workflow.config.DefaultConfiguration;
import com.opensymphony.workflow.spi.Step;
+import com.opensymphony.workflow.spi.WorkflowEntry;
public class Simple2ProcessTest extends TestCase {
@@ -77,20 +80,22 @@
workflow.doAction(workflowId, 4, null);
currentSteps = workflow.getCurrentSteps(workflowId);
- //verify we only have one current step
- assertEquals("Unexpected number of current steps", 1, currentSteps.size());
- //verify it's step 4
- currentStep = currentSteps.iterator().next();
- assertEquals("Unexpected current step", 4, currentStep.getStepId());
+ //verify we only have no more current steps
+ assertEquals("Unexpected number of current steps", 0, currentSteps.size());
+ //verify process completed
+ assertEquals("Unexpected state", WorkflowEntry.COMPLETED, workflow.getEntryState(workflowId));
availableActions = workflow.getAvailableActions(workflowId, Collections.EMPTY_MAP);
- //verify we only have one available action
- assertEquals("Unexpected number of available actions", 0, availableActions.length);
+ //verify we only have no available action
+ assertEquals("Unexpected number of available actions", 0, availableActions.length);
- } catch (Throwable t) {
- t.printStackTrace();
- fail();
- }
+ } catch (InvalidInputException e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ } catch (WorkflowException e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
}
}
Modified: labs/jbossrules/trunk/drools-process/drools-osworkflow/src/test/java/org/drools/SimpleProcessTest.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-osworkflow/src/test/java/org/drools/SimpleProcessTest.java 2008-06-02 17:25:55 UTC (rev 20257)
+++ labs/jbossrules/trunk/drools-process/drools-osworkflow/src/test/java/org/drools/SimpleProcessTest.java 2008-06-02 22:42:17 UTC (rev 20258)
@@ -6,11 +6,13 @@
import junit.framework.TestCase;
import org.drools.osworkflow.DroolsWorkflow;
-import org.drools.osworkflow.instance.node.StepNodeInstance;
+import com.opensymphony.workflow.InvalidInputException;
import com.opensymphony.workflow.Workflow;
+import com.opensymphony.workflow.WorkflowException;
import com.opensymphony.workflow.config.DefaultConfiguration;
import com.opensymphony.workflow.spi.Step;
+import com.opensymphony.workflow.spi.WorkflowEntry;
public class SimpleProcessTest extends TestCase {
@@ -50,19 +52,21 @@
workflow.doAction(workflowId, 3, null);
currentSteps = workflow.getCurrentSteps(workflowId);
- //verify we only have one current step
- assertEquals("Unexpected number of current steps", 1, currentSteps.size());
- //verify it's step 2
- currentStep = currentSteps.iterator().next();
- assertEquals("Unexpected current step", 2, currentStep.getStepId());
+ //verify we only have no more current steps
+ assertEquals("Unexpected number of current steps", 0, currentSteps.size());
+ //verify process completed
+ assertEquals("Unexpected state", WorkflowEntry.COMPLETED, workflow.getEntryState(workflowId));
availableActions = workflow.getAvailableActions(workflowId, Collections.EMPTY_MAP);
//verify we only have no available action
assertEquals("Unexpected number of available actions", 0, availableActions.length);
- } catch (Throwable t) {
- t.printStackTrace();
- fail(t.getMessage());
- }
+ } catch (InvalidInputException e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ } catch (WorkflowException e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
}
}
More information about the jboss-svn-commits
mailing list