[jboss-svn-commits] JBL Code SVN: r20428 - in labs/jbossrules/trunk/drools-core/src: main/java/org/drools/process/core/datatype/impl/type and 5 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Wed Jun 11 20:06:52 EDT 2008
Author: KrisVerlaenen
Date: 2008-06-11 20:06:52 -0400 (Wed, 11 Jun 2008)
New Revision: 20428
Added:
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/datatype/impl/type/ObjectDataType.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/ForEachNode.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/HumanTaskNode.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/ForEachNodeInstance.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/HumanTaskNodeInstance.java
labs/jbossrules/trunk/drools-core/src/test/java/org/drools/process/ForEachTest.java
Modified:
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/context/swimlane/SwimlaneContext.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/RuleFlowProcess.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/CompositeNode.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/impl/NodeInstanceFactoryRegistry.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/CompositeNodeInstance.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/WorkItemNodeInstance.java
Log:
JBRULES-1641: ForEach node
- initial core implementation of a for each node
JBRULES-1551: Workflow human tasks
- human task node with swimlane integration
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/context/swimlane/SwimlaneContext.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/context/swimlane/SwimlaneContext.java 2008-06-11 21:03:23 UTC (rev 20427)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/context/swimlane/SwimlaneContext.java 2008-06-12 00:06:52 UTC (rev 20428)
@@ -1,5 +1,6 @@
package org.drools.process.core.context.swimlane;
+import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@@ -12,7 +13,7 @@
public static final String SWIMLANE_SCOPE = "SwimlaneScope";
- private Map<String, Swimlane> swimlanes = new HashMap();
+ private Map<String, Swimlane> swimlanes = new HashMap<String, Swimlane>();
public String getType() {
return SWIMLANE_SCOPE;
@@ -29,6 +30,10 @@
public void removeSwimlane(String name) {
this.swimlanes.remove(name);
}
+
+ public Collection<Swimlane> getSwimlanes() {
+ return swimlanes.values();
+ }
public Context resolveContext(Object param) {
if (param instanceof String) {
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/datatype/impl/type/ObjectDataType.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/datatype/impl/type/ObjectDataType.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/core/datatype/impl/type/ObjectDataType.java 2008-06-12 00:06:52 UTC (rev 20428)
@@ -0,0 +1,62 @@
+package org.drools.process.core.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.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import org.drools.process.core.datatype.DataType;
+
+/**
+ * Representation of an object datatype.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public final class ObjectDataType implements DataType {
+
+ private static final long serialVersionUID = 4L;
+
+ private String className;
+
+ public String getClassName() {
+ return className;
+ }
+
+ public void setClassName(String className) {
+ this.className = className;
+ }
+
+ public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+ }
+
+ public void writeExternal(ObjectOutput out) throws IOException {
+ }
+
+ public boolean verifyDataType(final Object value) {
+ try {
+ Class<?> clazz = ObjectDataType.class.forName(className);
+ if (clazz.isInstance(value)) {
+ return true;
+ }
+ } catch (ClassNotFoundException e) {
+ throw new IllegalArgumentException(
+ "Could not find data type " + className);
+ }
+ return false;
+ }
+}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/RuleFlowProcess.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/RuleFlowProcess.java 2008-06-11 21:03:23 UTC (rev 20427)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/RuleFlowProcess.java 2008-06-12 00:06:52 UTC (rev 20428)
@@ -1,5 +1,6 @@
package org.drools.ruleflow.core;
+import org.drools.process.core.context.swimlane.SwimlaneContext;
import org.drools.process.core.context.variable.VariableScope;
import org.drools.workflow.core.Node;
import org.drools.workflow.core.NodeContainer;
@@ -18,11 +19,18 @@
VariableScope variableScope = new VariableScope();
addContext(variableScope);
setDefaultContext(variableScope);
+ SwimlaneContext swimLaneContext = new SwimlaneContext();
+ addContext(swimLaneContext);
+ setDefaultContext(swimLaneContext);
}
public VariableScope getVariableScope() {
return (VariableScope) getDefaultContext(VariableScope.VARIABLE_SCOPE);
}
+
+ public SwimlaneContext getSwimlaneContext() {
+ return (SwimlaneContext) getDefaultContext(SwimlaneContext.SWIMLANE_SCOPE);
+ }
protected NodeContainer createNodeContainer() {
return new WorkflowProcessNodeContainer();
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/CompositeNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/CompositeNode.java 2008-06-11 21:03:23 UTC (rev 20427)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/CompositeNode.java 2008-06-12 00:06:52 UTC (rev 20428)
@@ -67,7 +67,7 @@
}
public void linkOutgoingConnections(long outNodeId, String outNodeType, String outType) {
- inConnectionMap.put(outType, new NodeAndType(outNodeId, outNodeType));
+ outConnectionMap.put(outType, new NodeAndType(outNodeId, outNodeType));
}
public void linkOutgoingConnections(CompositeNode.NodeAndType outNode, String outType) {
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/ForEachNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/ForEachNode.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/ForEachNode.java 2008-06-12 00:06:52 UTC (rev 20428)
@@ -0,0 +1,110 @@
+package org.drools.workflow.core.node;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.drools.process.core.context.variable.Variable;
+import org.drools.process.core.context.variable.VariableScope;
+import org.drools.process.core.datatype.DataType;
+import org.drools.workflow.core.Node;
+import org.drools.workflow.core.impl.ConnectionImpl;
+
+/*
+ * 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 for each node.
+ *
+ * This node activates the contained subflow for each element of a collection.
+ * The node continues if all activated the subflow has been completed for each
+ * of the elements in the collection.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public class ForEachNode extends CompositeNode {
+
+ private static final long serialVersionUID = 4L;
+
+ private String variableName;
+ private String collectionExpression;
+
+ public ForEachNode() {
+ // Split
+ ForEachSplitNode split = new ForEachSplitNode();
+ split.setName("ForEachSplit");
+ addNode(split);
+ linkIncomingConnections(
+ Node.CONNECTION_DEFAULT_TYPE,
+ new CompositeNode.NodeAndType(split, Node.CONNECTION_DEFAULT_TYPE));
+ // Composite node
+ CompositeNode compositeNode = new CompositeNode();
+ compositeNode.setName("ForEachComposite");
+ addNode(compositeNode);
+ VariableScope variableScope = new VariableScope();
+ compositeNode.setContext(VariableScope.VARIABLE_SCOPE, variableScope);
+ // Join
+ ForEachJoinNode join = new ForEachJoinNode();
+ join.setName("ForEachJoin");
+ addNode(join);
+ linkOutgoingConnections(
+ new CompositeNode.NodeAndType(join, Node.CONNECTION_DEFAULT_TYPE),
+ Node.CONNECTION_DEFAULT_TYPE);
+ }
+
+ public String getVariableName() {
+ return variableName;
+ }
+
+ public CompositeNode getCompositeNode() {
+ return (CompositeNode) getNode(2);
+ }
+
+ public void setVariable(String variableName, DataType type) {
+ this.variableName = variableName;
+ List<Variable> variables = new ArrayList<Variable>();
+ Variable variable = new Variable();
+ variable.setName(variableName);
+ variable.setType(type);
+ variables.add(variable);
+ ((VariableScope) getCompositeNode().getContext(VariableScope.VARIABLE_SCOPE)).setVariables(variables);
+ // TODO: can only create connections after linking composite node ports
+ new ConnectionImpl(
+ getNode(1), Node.CONNECTION_DEFAULT_TYPE,
+ getCompositeNode(), Node.CONNECTION_DEFAULT_TYPE
+ );
+ new ConnectionImpl(
+ getCompositeNode(), Node.CONNECTION_DEFAULT_TYPE,
+ getNode(3), Node.CONNECTION_DEFAULT_TYPE
+ );
+ }
+
+ public String getCollectionExpression() {
+ return collectionExpression;
+ }
+
+ public void setCollectionExpression(String collectionExpression) {
+ this.collectionExpression = collectionExpression;
+ }
+
+ public class ForEachSplitNode extends SequenceNode {
+ private static final long serialVersionUID = 4L;
+ }
+
+ public class ForEachJoinNode extends SequenceNode {
+ private static final long serialVersionUID = 4L;
+ }
+
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/HumanTaskNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/HumanTaskNode.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/HumanTaskNode.java 2008-06-12 00:06:52 UTC (rev 20428)
@@ -0,0 +1,26 @@
+package org.drools.workflow.core.node;
+
+import org.drools.process.core.Work;
+import org.drools.process.core.impl.WorkImpl;
+
+public class HumanTaskNode extends WorkItemNode {
+
+ private static final long serialVersionUID = 4L;
+
+ private String swimlane;
+
+ public HumanTaskNode() {
+ Work work = new WorkImpl();
+ work.setName("Human Task");
+ setWork(work);
+ }
+
+ public String getSwimlane() {
+ return swimlane;
+ }
+
+ public void setSwimlane(String swimlane) {
+ this.swimlane = swimlane;
+ }
+
+}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/impl/NodeInstanceFactoryRegistry.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/impl/NodeInstanceFactoryRegistry.java 2008-06-11 21:03:23 UTC (rev 20427)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/impl/NodeInstanceFactoryRegistry.java 2008-06-12 00:06:52 UTC (rev 20428)
@@ -8,6 +8,8 @@
import org.drools.workflow.core.node.CompositeNode;
import org.drools.workflow.core.node.EndNode;
import org.drools.workflow.core.node.FaultNode;
+import org.drools.workflow.core.node.ForEachNode;
+import org.drools.workflow.core.node.HumanTaskNode;
import org.drools.workflow.core.node.Join;
import org.drools.workflow.core.node.MilestoneNode;
import org.drools.workflow.core.node.RuleSetNode;
@@ -22,6 +24,8 @@
import org.drools.workflow.instance.node.CompositeNodeInstance;
import org.drools.workflow.instance.node.EndNodeInstance;
import org.drools.workflow.instance.node.FaultNodeInstance;
+import org.drools.workflow.instance.node.ForEachNodeInstance;
+import org.drools.workflow.instance.node.HumanTaskNodeInstance;
import org.drools.workflow.instance.node.JoinInstance;
import org.drools.workflow.instance.node.MilestoneNodeInstance;
import org.drools.workflow.instance.node.RuleSetNodeInstance;
@@ -64,6 +68,10 @@
new CreateNewNodeFactory( FaultNodeInstance.class ) );
register( CompositeNode.class,
new CreateNewNodeFactory( CompositeNodeInstance.class ) );
+ register( HumanTaskNode.class,
+ new CreateNewNodeFactory( HumanTaskNodeInstance.class ) );
+ register( ForEachNode.class,
+ new CreateNewNodeFactory( ForEachNodeInstance.class ) );
}
public void register(Class< ? extends Node> cls,
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/CompositeNodeInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/CompositeNodeInstance.java 2008-06-11 21:03:23 UTC (rev 20427)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/CompositeNodeInstance.java 2008-06-12 00:06:52 UTC (rev 20428)
@@ -141,9 +141,6 @@
throw new IllegalArgumentException("Illegal node type: " + node.getClass());
}
NodeInstanceImpl nodeInstance = (NodeInstanceImpl) conf.getNodeInstance(node, getProcessInstance(), this);
- nodeInstance.setNodeId(node.getId());
- nodeInstance.setNodeInstanceContainer(this);
- nodeInstance.setProcessInstance(getProcessInstance());
if (nodeInstance == null) {
throw new IllegalArgumentException("Illegal node type: " + node.getClass());
}
@@ -181,7 +178,6 @@
}
public void triggerCompleted() {
- getNodeInstanceContainer().removeNodeInstance(this);
CompositeNodeInstance.this.triggerCompleted(
getCompositeNodeEnd().getOutType());
}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/ForEachNodeInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/ForEachNodeInstance.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/ForEachNodeInstance.java 2008-06-12 00:06:52 UTC (rev 20428)
@@ -0,0 +1,125 @@
+package org.drools.workflow.instance.node;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.drools.process.core.context.variable.VariableScope;
+import org.drools.process.instance.context.variable.VariableScopeInstance;
+import org.drools.workflow.core.Connection;
+import org.drools.workflow.core.Node;
+import org.drools.workflow.core.node.ForEachNode;
+import org.drools.workflow.core.node.ForEachNode.ForEachJoinNode;
+import org.drools.workflow.core.node.ForEachNode.ForEachSplitNode;
+import org.drools.workflow.instance.NodeInstance;
+import org.drools.workflow.instance.impl.NodeInstanceImpl;
+
+/*
+ * 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.
+ */
+
+/**
+ * Runtime counterpart of a for each node.
+ *
+ * @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
+ */
+public class ForEachNodeInstance extends CompositeNodeInstance {
+
+ private static final long serialVersionUID = 4L;
+
+ public ForEachNode getForEachNode() {
+ return (ForEachNode) getNode();
+ }
+
+ public NodeInstance getNodeInstance(final Node node) {
+ // TODO do this cleaner for split / join of for each?
+ if (node instanceof ForEachSplitNode) {
+ ForEachSplitNodeInstance nodeInstance = new ForEachSplitNodeInstance();
+ nodeInstance.setNodeId(node.getId());
+ nodeInstance.setNodeInstanceContainer(this);
+ nodeInstance.setProcessInstance(getProcessInstance());
+ return nodeInstance;
+ } else if (node instanceof ForEachJoinNode) {
+ ForEachJoinNodeInstance nodeInstance = (ForEachJoinNodeInstance)
+ getFirstNodeInstance(node.getId());
+ if (nodeInstance == null) {
+ nodeInstance = new ForEachJoinNodeInstance();
+ nodeInstance.setNodeId(node.getId());
+ nodeInstance.setNodeInstanceContainer(this);
+ nodeInstance.setProcessInstance(getProcessInstance());
+ }
+ return nodeInstance;
+ }
+ return super.getNodeInstance(node);
+ }
+
+ public class ForEachSplitNodeInstance extends NodeInstanceImpl {
+
+ private static final long serialVersionUID = 4L;
+
+ public ForEachSplitNode getForEachSplitNode() {
+ return (ForEachSplitNode) getNode();
+ }
+
+ public void internalTrigger(NodeInstance from, String type) {
+ String collectionExpression = getForEachNode().getCollectionExpression();
+ Collection<?> collection = evaluateCollectionExpression(collectionExpression);
+ getNodeInstanceContainer().removeNodeInstance(this);
+ List<NodeInstance> nodeInstances = new ArrayList<NodeInstance>();
+ for (Object o: collection) {
+ String variableName = getForEachNode().getVariableName();
+ CompositeNodeInstance nodeInstance = (CompositeNodeInstance)
+ getNodeInstanceContainer().getNodeInstance(getForEachSplitNode().getTo().getTo());
+ VariableScopeInstance variableScopeInstance = (VariableScopeInstance)
+ nodeInstance.resolveContextInstance(VariableScope.VARIABLE_SCOPE, variableName);
+ variableScopeInstance.setVariable(variableName, o);
+ nodeInstances.add(nodeInstance);
+ }
+ for (NodeInstance nodeInstance: nodeInstances) {
+ nodeInstance.trigger(this, getForEachSplitNode().getTo().getToType());
+ }
+ }
+
+ private Collection<?> evaluateCollectionExpression(String collectionExpression) {
+ // TODO: should evaluate this expression using MVEL
+ VariableScopeInstance variableScopeInstance = (VariableScopeInstance)
+ resolveContextInstance(VariableScope.VARIABLE_SCOPE, collectionExpression);
+ if (variableScopeInstance == null) {
+ throw new IllegalArgumentException(
+ "Could not find collection " + collectionExpression);
+ }
+ return (Collection<?>) variableScopeInstance.getVariable(collectionExpression);
+ }
+
+ }
+
+ public class ForEachJoinNodeInstance extends NodeInstanceImpl {
+
+ private static final long serialVersionUID = 4L;
+
+ public ForEachJoinNode getForEachJoinNode() {
+ return (ForEachJoinNode) getNode();
+ }
+
+ public void internalTrigger(NodeInstance from, String type) {
+ if (getNodeInstanceContainer().getNodeInstances().size() == 1) {
+ getNodeInstanceContainer().removeNodeInstance(this);
+ triggerConnection(getForEachJoinNode().getTo());
+ }
+ }
+
+ }
+
+}
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/HumanTaskNodeInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/HumanTaskNodeInstance.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/HumanTaskNodeInstance.java 2008-06-12 00:06:52 UTC (rev 20428)
@@ -0,0 +1,82 @@
+package org.drools.workflow.instance.node;
+
+import org.drools.process.core.context.swimlane.SwimlaneContext;
+import org.drools.process.instance.WorkItem;
+import org.drools.process.instance.context.swimlane.SwimlaneContextInstance;
+import org.drools.process.instance.impl.WorkItemImpl;
+import org.drools.workflow.core.node.HumanTaskNode;
+import org.drools.workflow.core.node.WorkItemNode;
+
+public class HumanTaskNodeInstance extends WorkItemNodeInstance {
+
+ private static final long serialVersionUID = 4L;
+
+ private transient SwimlaneContextInstance swimlaneContextInstance;
+
+ public HumanTaskNode getHumanTaskNode() {
+ return (HumanTaskNode) getNode();
+ }
+
+ protected WorkItem createWorkItem(WorkItemNode workItemNode) {
+ WorkItem workItem = super.createWorkItem(workItemNode);
+ String actorId = assignWorkItem();
+ if (actorId != null) {
+ ((WorkItemImpl) workItem).setParameter("ActorId", actorId);
+ }
+ return workItem;
+ }
+
+ protected String assignWorkItem() {
+ String actorId = null;
+ // if this human task node is part of a swim lane, check whether an actor
+ // has already been assigned to this swim lane
+ String swimlaneName = getHumanTaskNode().getSwimlane();
+ SwimlaneContextInstance swimlaneContextInstance = getSwimlaneContextInstance(swimlaneName);
+ if (swimlaneContextInstance != null) {
+ actorId = swimlaneContextInstance.getActorId(swimlaneName);
+ }
+ if (actorId == null) {
+ // if the actorId has not yet been assigned, check whether assigners are
+ // defined for this human task node
+ // TODO
+ }
+ if (actorId == null) {
+ // if the actorId has not yet been assigned, check whether assigners are
+ // defined for this swim lane
+ }
+ return actorId;
+ }
+
+ private SwimlaneContextInstance getSwimlaneContextInstance(String swimlaneName) {
+ if (this.swimlaneContextInstance == null) {
+ if (swimlaneName == null) {
+ return null;
+ }
+ SwimlaneContextInstance swimlaneContextInstance =
+ (SwimlaneContextInstance) resolveContextInstance(
+ SwimlaneContext.SWIMLANE_SCOPE, swimlaneName);
+ if (swimlaneContextInstance == null) {
+ throw new IllegalArgumentException(
+ "Could not find swimlane context instance");
+ }
+ this.swimlaneContextInstance = swimlaneContextInstance;
+ }
+ return this.swimlaneContextInstance;
+ }
+
+ public void triggerCompleted(WorkItem workItem) {
+ String swimlaneName = getHumanTaskNode().getSwimlane();
+ SwimlaneContextInstance swimlaneContextInstance = getSwimlaneContextInstance(swimlaneName);
+ if (swimlaneContextInstance != null) {
+ String oldActorId = swimlaneContextInstance.getActorId(swimlaneName);
+ // only assign if swimlane has not already been assigned to an actor
+ if (oldActorId == null) {
+ String newActorId = (String) workItem.getResult("ActorId");
+ if (newActorId != null) {
+ swimlaneContextInstance.setActorId(swimlaneName, newActorId);
+ }
+ }
+ }
+ super.triggerCompleted(workItem);
+ }
+}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/WorkItemNodeInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/WorkItemNodeInstance.java 2008-06-11 21:03:23 UTC (rev 20427)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/WorkItemNodeInstance.java 2008-06-12 00:06:52 UTC (rev 20428)
@@ -64,12 +64,25 @@
// "A WorkItemNode only accepts default incoming connections!");
// }
WorkItemNode workItemNode = getWorkItemNode();
+ WorkItem workItem = createWorkItem(workItemNode);
+ if (workItemNode.isWaitForCompletion()) {
+ addEventListeners();
+ }
+ getProcessInstance().getWorkingMemory().getWorkItemManager().internalExecuteWorkItem(workItem);
+ if (!workItemNode.isWaitForCompletion()) {
+ triggerCompleted();
+ } else {
+ this.workItemId = workItem.getId();
+ }
+ }
+
+ protected WorkItem createWorkItem(WorkItemNode workItemNode) {
Work work = workItemNode.getWork();
- workItem = new WorkItemImpl();
- workItem.setName(work.getName());
- workItem.setProcessInstanceId(getProcessInstance().getId());
- workItem.setParameters(new HashMap<String, Object>(work.getParameters()));
- for (Iterator<Map.Entry<String, String>> iterator = workItemNode.getInMappings().entrySet().iterator(); iterator.hasNext(); ) {
+ WorkItemImpl workItem = new WorkItemImpl();
+ workItem.setName(work.getName());
+ workItem.setProcessInstanceId(getProcessInstance().getId());
+ workItem.setParameters(new HashMap<String, Object>(work.getParameters()));
+ for (Iterator<Map.Entry<String, String>> iterator = workItemNode.getInMappings().entrySet().iterator(); iterator.hasNext(); ) {
Map.Entry<String, String> mapping = iterator.next();
VariableScopeInstance variableScopeInstance = (VariableScopeInstance)
resolveContextInstance(VariableScope.VARIABLE_SCOPE, mapping.getValue());
@@ -81,15 +94,7 @@
System.err.println("Continuing without setting parameter.");
}
}
- if (workItemNode.isWaitForCompletion()) {
- addEventListeners();
- }
- getProcessInstance().getWorkingMemory().getWorkItemManager().internalExecuteWorkItem(workItem);
- if (!workItemNode.isWaitForCompletion()) {
- triggerCompleted();
- } else {
- this.workItemId = workItem.getId();
- }
+ return workItem;
}
public void triggerCompleted(WorkItem workItem) {
Added: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/process/ForEachTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/process/ForEachTest.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/process/ForEachTest.java 2008-06-12 00:06:52 UTC (rev 20428)
@@ -0,0 +1,101 @@
+package org.drools.process;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.drools.Person;
+import org.drools.RuleBaseFactory;
+import org.drools.WorkingMemory;
+import org.drools.common.AbstractRuleBase;
+import org.drools.common.InternalWorkingMemory;
+import org.drools.process.core.context.variable.Variable;
+import org.drools.process.core.datatype.impl.type.ListDataType;
+import org.drools.process.core.datatype.impl.type.ObjectDataType;
+import org.drools.reteoo.ReteooWorkingMemory;
+import org.drools.ruleflow.core.RuleFlowProcess;
+import org.drools.spi.Action;
+import org.drools.spi.KnowledgeHelper;
+import org.drools.workflow.core.Node;
+import org.drools.workflow.core.impl.ConnectionImpl;
+import org.drools.workflow.core.node.ActionNode;
+import org.drools.workflow.core.node.EndNode;
+import org.drools.workflow.core.node.ForEachNode;
+import org.drools.workflow.core.node.StartNode;
+
+public class ForEachTest extends TestCase {
+
+ public void testForEach() {
+ RuleFlowProcess process = new RuleFlowProcess();
+ process.setId("org.drools.process.foreach");
+ process.setName("ForEach Process");
+
+ List<Variable> variables = new ArrayList<Variable>();
+ Variable variable = new Variable();
+ variable.setName("persons");
+ ListDataType listDataType = new ListDataType();
+ ObjectDataType personDataType = new ObjectDataType();
+ personDataType.setClassName("org.drools.Person");
+ listDataType.setDataType(personDataType);
+ variable.setType(listDataType);
+ variables.add(variable);
+ process.getVariableScope().setVariables(variables);
+
+ StartNode startNode = new StartNode();
+ startNode.setName("Start");
+ startNode.setId(1);
+ process.addNode(startNode);
+ EndNode endNode = new EndNode();
+ endNode.setName("EndNode");
+ endNode.setId(2);
+ process.addNode(endNode);
+ ForEachNode forEachNode = new ForEachNode();
+ forEachNode.setName("ForEach");
+ forEachNode.setId(3);
+ forEachNode.setCollectionExpression("persons");
+ personDataType = new ObjectDataType();
+ personDataType.setClassName("org.drools.Person");
+ process.addNode(forEachNode);
+ new ConnectionImpl(
+ startNode, Node.CONNECTION_DEFAULT_TYPE,
+ forEachNode, Node.CONNECTION_DEFAULT_TYPE
+ );
+ new ConnectionImpl(
+ forEachNode, Node.CONNECTION_DEFAULT_TYPE,
+ endNode, Node.CONNECTION_DEFAULT_TYPE
+ );
+
+ final List<String> myList = new ArrayList<String>();
+ ActionNode actionNode = new ActionNode();
+ actionNode.setName("Print child");
+ actionNode.setAction(new Action() {
+ public void execute(KnowledgeHelper knowledgeHelper, WorkingMemory workingMemory) throws Exception {
+ myList.add("Executed action");
+ }
+ });
+ forEachNode.getCompositeNode().addNode(actionNode);
+ forEachNode.getCompositeNode().linkIncomingConnections(
+ Node.CONNECTION_DEFAULT_TYPE,
+ actionNode.getId(), Node.CONNECTION_DEFAULT_TYPE);
+ forEachNode.getCompositeNode().linkOutgoingConnections(
+ actionNode.getId(), Node.CONNECTION_DEFAULT_TYPE,
+ Node.CONNECTION_DEFAULT_TYPE);
+ forEachNode.setVariable("child", personDataType);
+
+ AbstractRuleBase ruleBase = (AbstractRuleBase) RuleBaseFactory.newRuleBase();
+ ruleBase.addProcess(process);
+ InternalWorkingMemory workingMemory = new ReteooWorkingMemory(1, ruleBase);
+ Map<String, Object> parameters = new HashMap<String, Object>();
+ List<Person> persons = new ArrayList<Person>();
+ persons.add(new Person("John Doe", 30));
+ persons.add(new Person("Jane Doe", 20));
+ persons.add(new Person("Jack", 60));
+ parameters.put("persons", persons);
+ workingMemory.startProcess("org.drools.process.foreach", parameters);
+ assertEquals(3, myList.size());
+ }
+
+}
More information about the jboss-svn-commits
mailing list