[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