[jboss-svn-commits] JBL Code SVN: r21160 - in labs/jbossrules/trunk/drools-core/src: main/java/org/drools/spi and 6 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Tue Jul 22 08:30:50 EDT 2008


Author: KrisVerlaenen
Date: 2008-07-22 08:30:50 -0400 (Tue, 22 Jul 2008)
New Revision: 21160

Added:
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/CompositeContextNodeInstance.java
Modified:
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/validation/RuleFlowProcessValidator.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/ActionContext.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/NodeContainer.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/impl/NodeContainerImpl.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/impl/WorkflowProcessImpl.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/core/node/ForEachNode.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/impl/NodeInstanceImpl.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/ForEachNodeInstance.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/process/ForEachTest.java
Log:
JBRULES-1690: IDE support for ForEach
 - extended for each in core


Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/validation/RuleFlowProcessValidator.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/validation/RuleFlowProcessValidator.java	2008-07-22 12:21:06 UTC (rev 21159)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/ruleflow/core/validation/RuleFlowProcessValidator.java	2008-07-22 12:30:50 UTC (rev 21160)
@@ -35,6 +35,7 @@
 import org.drools.workflow.core.node.ActionNode;
 import org.drools.workflow.core.node.CompositeNode;
 import org.drools.workflow.core.node.EndNode;
+import org.drools.workflow.core.node.ForEachNode;
 import org.drools.workflow.core.node.Join;
 import org.drools.workflow.core.node.MilestoneNode;
 import org.drools.workflow.core.node.RuleSetNode;
@@ -280,6 +281,35 @@
                             "WorkItem node '" + node.getName() + "' [" + node.getId() + "] has no work name."));
                     }
                 }
+            } else if (node instanceof ForEachNode) {
+                final ForEachNode forEachNode = (ForEachNode) node;
+                String variableName = forEachNode.getVariableName();
+                if (variableName == null || "".equals(variableName)) {
+                    errors.add(new ProcessValidationErrorImpl(process,
+                        "ForEach node '" + node.getName() + "' [" + node.getId() + "] has no variable name"));
+                }
+                String collectionExpression = forEachNode.getCollectionExpression();
+                if (collectionExpression == null || "".equals(collectionExpression)) {
+                    errors.add(new ProcessValidationErrorImpl(process,
+                        "ForEach node '" + node.getName() + "' [" + node.getId() + "] has no collection expression"));
+                }
+                if (forEachNode.getIncomingConnections(Node.CONNECTION_DEFAULT_TYPE).size() == 0) {
+                    errors.add(new ProcessValidationErrorImpl(process,
+                        "ForEach node '" + node.getName() + "' [" + node.getId() + "] has no incoming connection"));
+                }
+                if (forEachNode.getOutgoingConnections(Node.CONNECTION_DEFAULT_TYPE).size() == 0) {
+                    errors.add(new ProcessValidationErrorImpl(process,
+                        "ForEach node '" + node.getName() + "' [" + node.getId() + "] has no outgoing connection"));
+                }
+                if (forEachNode.getLinkedIncomingNode(Node.CONNECTION_DEFAULT_TYPE) == null) {
+                    errors.add(new ProcessValidationErrorImpl(process,
+                        "ForEach node '" + node.getName() + "' [" + node.getId() + "] has no linked start node"));
+                }
+                if (forEachNode.getLinkedOutgoingNode(Node.CONNECTION_DEFAULT_TYPE) == null) {
+                    errors.add(new ProcessValidationErrorImpl(process,
+                        "ForEach node '" + node.getName() + "' [" + node.getId() + "] has no linked end node"));
+                }
+                validateNodes(forEachNode.getNodes(), errors, process);
             } else if (node instanceof CompositeNode) {
                 final CompositeNode compositeNode = (CompositeNode) node;
                 for (String inType: compositeNode.getLinkedIncomingNodes().keySet()) {

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/ActionContext.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/ActionContext.java	2008-07-22 12:21:06 UTC (rev 21159)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/ActionContext.java	2008-07-22 12:30:50 UTC (rev 21160)
@@ -1,5 +1,7 @@
 package org.drools.spi;
 
+import org.drools.process.core.context.variable.VariableScope;
+import org.drools.process.instance.context.variable.VariableScopeInstance;
 import org.drools.workflow.instance.NodeInstance;
 
 public class ActionContext {
@@ -14,4 +16,12 @@
         this.nodeInstance = nodeInstance;
     }
     
+    public Object getVariable(String variableName) {
+    	VariableScopeInstance variableScope = (VariableScopeInstance) nodeInstance.resolveContextInstance(VariableScope.VARIABLE_SCOPE, variableName);
+    	if (variableScope == null) {
+    		return null;
+    	}
+    	return variableScope.getVariable(variableName);
+    }
+    
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/NodeContainer.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/NodeContainer.java	2008-07-22 12:21:06 UTC (rev 21159)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/NodeContainer.java	2008-07-22 12:30:50 UTC (rev 21160)
@@ -46,4 +46,6 @@
     
     Context resolveContext(String contextId, Object param);
     
+    Node internalGetNode(long id);
+    
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/impl/NodeContainerImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/impl/NodeContainerImpl.java	2008-07-22 12:21:06 UTC (rev 21159)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/impl/NodeContainerImpl.java	2008-07-22 12:30:50 UTC (rev 21160)
@@ -47,6 +47,10 @@
         }
         return node; 
     }
+    
+    public Node internalGetNode(long id) {
+    	return getNode(id);
+    }
 
     public void removeNode(final Node node) {
         validateRemoveNode(node);

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/impl/WorkflowProcessImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/impl/WorkflowProcessImpl.java	2008-07-22 12:21:06 UTC (rev 21159)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/impl/WorkflowProcessImpl.java	2008-07-22 12:30:50 UTC (rev 21160)
@@ -54,6 +54,10 @@
     public Node getNode(final long id) {
         return nodeContainer.getNode(id);
     }
+    
+    public Node internalGetNode(long id) {
+    	return getNode(id);
+    }
 
     public void removeNode(final Node node) {
         nodeContainer.removeNode(node);

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-07-22 12:21:06 UTC (rev 21159)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/CompositeNode.java	2008-07-22 12:30:50 UTC (rev 21160)
@@ -1,5 +1,6 @@
 package org.drools.workflow.core.node;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
@@ -31,9 +32,20 @@
     public Node getNode(long id) {
         return nodeContainer.getNode(id);
     }
+    
+    public Node internalGetNode(long id) {
+    	return getNode(id);
+    }
 
     public Node[] getNodes() {
-        return nodeContainer.getNodes();
+    	List<Node> subNodes = new ArrayList<Node>();
+    	for (Node node: nodeContainer.getNodes()) {
+    		if (!(node instanceof CompositeNode.CompositeNodeStart) &&
+    				!(node instanceof CompositeNode.CompositeNodeEnd)) {
+    			subNodes.add(node);
+    		}
+    	}
+    	return subNodes.toArray(new Node[subNodes.size()]);
     }
 
     public void addNode(Node node) {
@@ -53,35 +65,83 @@
         node.setNodeContainer(this);
     }
     
+    protected void internalAddNode(Node node) {
+    	addNode(node);
+    }
+    
     public void removeNode(Node node) {
         nodeContainer.removeNode(node);
         node.setNodeContainer(null);
     }
     
     public void linkIncomingConnections(String inType, long inNodeId, String inNodeType) {
-        inConnectionMap.put(inType, new NodeAndType(inNodeId, inNodeType));
+        linkIncomingConnections(inType, new NodeAndType(inNodeId, inNodeType));
     }
     
     public void linkIncomingConnections(String inType, CompositeNode.NodeAndType inNode) {
+        CompositeNode.NodeAndType oldNodeAndType = inConnectionMap.get(inType);
+        if (oldNodeAndType != null) {
+        	if (oldNodeAndType.equals(inNode)) {
+        		return;
+        	} else {
+        		// TODO remove old composite start nodes and connections 
+        	}
+        }
         inConnectionMap.put(inType, inNode);
+        if (inNode != null) {
+	        List<Connection> connections = getIncomingConnections(inType);
+	        for (Connection connection: connections) {
+	        	CompositeNodeStart start = new CompositeNodeStart(connection.getFrom(), inType);
+		        internalAddNode(start);
+		        new ConnectionImpl(
+		            start, Node.CONNECTION_DEFAULT_TYPE, 
+		            inNode.getNode(), inNode.getType());
+	        }
+        }
     }
     
     public void linkOutgoingConnections(long outNodeId, String outNodeType, String outType) {
-        outConnectionMap.put(outType, new NodeAndType(outNodeId, outNodeType));
+        linkOutgoingConnections(new NodeAndType(outNodeId, outNodeType), outType);
     }
     
     public void linkOutgoingConnections(CompositeNode.NodeAndType outNode, String outType) {
+        CompositeNode.NodeAndType oldNodeAndType = outConnectionMap.get(outType);
+        if (oldNodeAndType != null) {
+        	if (oldNodeAndType.equals(outNode)) {
+        		return;
+        	} else {
+        		// TODO remove old composite start nodes and connections 
+        	}
+        }
         outConnectionMap.put(outType, outNode);
+        if (outNode != null) {
+	        List<Connection> connections = getOutgoingConnections(outType);
+	        for (Connection connection: connections) {
+		        CompositeNodeEnd end = new CompositeNodeEnd(connection.getTo(), outType);
+		        internalAddNode(end);
+		        new ConnectionImpl(
+		            outNode.getNode(), outNode.getType(), 
+		            end, Node.CONNECTION_DEFAULT_TYPE);
+	        }
+        }
     }
 
     public CompositeNode.NodeAndType getLinkedIncomingNode(String inType) {
         return inConnectionMap.get(inType);
     }
 
+    public CompositeNode.NodeAndType internalGetLinkedIncomingNode(String inType) {
+        return inConnectionMap.get(inType);
+    }
+
     public CompositeNode.NodeAndType getLinkedOutgoingNode(String outType) {
         return outConnectionMap.get(outType);
     }
     
+    public CompositeNode.NodeAndType internalGetLinkedOutgoingNode(String inType) {
+        return inConnectionMap.get(inType);
+    }
+
     public Map<String, CompositeNode.NodeAndType> getLinkedIncomingNodes() {
         return inConnectionMap;
     }
@@ -91,51 +151,71 @@
     }
     
     public void validateAddIncomingConnection(final String type, final Connection connection) {
-        CompositeNode.NodeAndType nodeAndType = getLinkedIncomingNode(type);
-        if (nodeAndType == null) {
-            throw new IllegalArgumentException(
-                "Cannot add incoming connections to a composite node until these connections can be mapped correctly to a subnode!");
-        }
-        ((NodeImpl) nodeAndType.getNode()).validateAddIncomingConnection(nodeAndType.getType(), connection);
+    	CompositeNode.NodeAndType nodeAndType = internalGetLinkedIncomingNode(type);
+    	if (connection.getFrom().getNodeContainer() == this) {
+    		if (nodeAndType != null) {
+    			throw new IllegalArgumentException("Cannot link incoming connection type more than once: " + type);
+    		}
+    	} else {
+	        if (nodeAndType != null) {
+	        	((NodeImpl) nodeAndType.getNode()).validateAddIncomingConnection(nodeAndType.getType(), connection);
+	        }
+    	}
     }
     
     public void addIncomingConnection(String type, Connection connection) {
-        super.addIncomingConnection(type, connection);
-        CompositeNodeStart start = new CompositeNodeStart(connection.getFrom(), type);
-        addNode(start);
-        CompositeNode.NodeAndType inNode = getLinkedIncomingNode(type);
-        new ConnectionImpl(
-            start, Node.CONNECTION_DEFAULT_TYPE, 
-            inNode.getNode(), inNode.getType());
+    	if (connection.getFrom().getNodeContainer() == this) {
+    		linkOutgoingConnections(connection.getFrom().getId(), connection.getFromType(), Node.CONNECTION_DEFAULT_TYPE);
+    	} else {
+	        super.addIncomingConnection(type, connection);
+	        CompositeNode.NodeAndType inNode = internalGetLinkedIncomingNode(type);
+	        if (inNode != null) {
+		        CompositeNodeStart start = new CompositeNodeStart(connection.getFrom(), type);
+		        internalAddNode(start);
+		        new ConnectionImpl(
+		            start, Node.CONNECTION_DEFAULT_TYPE, 
+		            inNode.getNode(), inNode.getType());
+	        }
+    	}
     }
     
     public void validateAddOutgoingConnection(final String type, final Connection connection) {
-        CompositeNode.NodeAndType nodeAndType = getLinkedOutgoingNode(type);
-        if (nodeAndType == null) {
-            throw new IllegalArgumentException(
-                "Cannot add outgoing connections to a composite node until these connections can be mapped correctly to a subnode!");
-        }
-        ((NodeImpl) nodeAndType.getNode()).validateAddOutgoingConnection(nodeAndType.getType(), connection);
-    }
+        CompositeNode.NodeAndType nodeAndType = internalGetLinkedOutgoingNode(type);
+        if (connection.getTo().getNodeContainer() == this) {
+    		if (nodeAndType != null) {
+    			throw new IllegalArgumentException("Cannot link outgoing connection type more than once: " + type);
+    		}
+    	} else {
+    		if (nodeAndType != null) {
+	        	((NodeImpl) nodeAndType.getNode()).validateAddOutgoingConnection(nodeAndType.getType(), connection);
+	        }
+    	}
+	}
     
     public void addOutgoingConnection(String type, Connection connection) {
-        super.addOutgoingConnection(type, connection);
-        CompositeNodeEnd end = new CompositeNodeEnd(connection.getTo(), type);
-        addNode(end);
-        CompositeNode.NodeAndType outNode = getLinkedOutgoingNode(type);
-        new ConnectionImpl(
-            outNode.getNode(), outNode.getType(), 
-            end, Node.CONNECTION_DEFAULT_TYPE);
+    	if (connection.getTo().getNodeContainer() == this) {
+    		linkIncomingConnections(Node.CONNECTION_DEFAULT_TYPE, connection.getTo().getId(), connection.getToType());    		
+    	} else {
+	        super.addOutgoingConnection(type, connection);
+	        CompositeNode.NodeAndType outNode = internalGetLinkedOutgoingNode(type);
+	        if (outNode != null) {
+		        CompositeNodeEnd end = new CompositeNodeEnd(connection.getTo(), type);
+		        internalAddNode(end);
+		        new ConnectionImpl(
+		            outNode.getNode(), outNode.getType(), 
+		            end, Node.CONNECTION_DEFAULT_TYPE);
+	        }
+    	}
     }
     
     public void validateRemoveIncomingConnection(final String type, final Connection connection) {
-        CompositeNode.NodeAndType nodeAndType = getLinkedIncomingNode(type);
+        CompositeNode.NodeAndType nodeAndType = internalGetLinkedIncomingNode(type);
         ((NodeImpl) nodeAndType.getNode()).validateRemoveIncomingConnection(nodeAndType.getType(), connection);
     }
     
     public void removeIncomingConnection(String type, Connection connection) {
         super.removeIncomingConnection(type, connection);
-        CompositeNode.NodeAndType inNode = getLinkedIncomingNode(type);
+        CompositeNode.NodeAndType inNode = internalGetLinkedIncomingNode(type);
         List<Connection> connections = inNode.getNode().getIncomingConnections(inNode.getType());
         for (Iterator<Connection> iterator = connections.iterator(); iterator.hasNext(); ) {
             Connection internalConnection = iterator.next();
@@ -147,13 +227,13 @@
     }
     
     public void validateRemoveOutgoingConnection(final String type, final Connection connection) {
-        CompositeNode.NodeAndType nodeAndType = getLinkedOutgoingNode(type);
+        CompositeNode.NodeAndType nodeAndType = internalGetLinkedOutgoingNode(type);
         ((NodeImpl) nodeAndType.getNode()).validateRemoveOutgoingConnection(nodeAndType.getType(), connection);
     }
     
     public void removeOutgoingConnection(String type, Connection connection) {
         super.removeOutgoingConnection(type, connection);
-        CompositeNode.NodeAndType outNode = getLinkedOutgoingNode(type);
+        CompositeNode.NodeAndType outNode = internalGetLinkedOutgoingNode(type);
         List<Connection> connections = outNode.getNode().getOutgoingConnections(outNode.getType());
         for (Iterator<Connection> iterator = connections.iterator(); iterator.hasNext(); ) {
             Connection internalConnection = iterator.next();

Modified: 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	2008-07-22 12:21:06 UTC (rev 21159)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/core/node/ForEachNode.java	2008-07-22 12:30:50 UTC (rev 21160)
@@ -40,28 +40,38 @@
     
     private String variableName;
     private String collectionExpression;
+    private boolean waitForCompletion = true;
 
     public ForEachNode() {
         // Split
         ForEachSplitNode split = new ForEachSplitNode();
         split.setName("ForEachSplit");
-        addNode(split);
-        linkIncomingConnections(
+        super.addNode(split);
+        super.linkIncomingConnections(
             Node.CONNECTION_DEFAULT_TYPE, 
             new CompositeNode.NodeAndType(split, Node.CONNECTION_DEFAULT_TYPE));
         // Composite node
-        CompositeNode compositeNode = new CompositeNode();
+        CompositeContextNode compositeNode = new CompositeContextNode();
         compositeNode.setName("ForEachComposite");
-        addNode(compositeNode);
+        super.addNode(compositeNode);
         VariableScope variableScope = new VariableScope();
         compositeNode.setContext(VariableScope.VARIABLE_SCOPE, variableScope);
+        compositeNode.setDefaultContext(variableScope);
         // Join
         ForEachJoinNode join = new ForEachJoinNode();
         join.setName("ForEachJoin");
-        addNode(join);
-        linkOutgoingConnections(
+        super.addNode(join);
+        super.linkOutgoingConnections(
             new CompositeNode.NodeAndType(join, Node.CONNECTION_DEFAULT_TYPE),
             Node.CONNECTION_DEFAULT_TYPE);
+        new ConnectionImpl(
+            super.getNode(1), Node.CONNECTION_DEFAULT_TYPE,
+            getCompositeNode(), Node.CONNECTION_DEFAULT_TYPE
+        );
+        new ConnectionImpl(
+            getCompositeNode(), Node.CONNECTION_DEFAULT_TYPE,
+            super.getNode(3), Node.CONNECTION_DEFAULT_TYPE
+        );
     }
     
     public String getVariableName() {
@@ -69,9 +79,53 @@
     }
     
     public CompositeNode getCompositeNode() {
-        return (CompositeNode) getNode(2); 
+        return (CompositeNode) super.getNode(2); 
     }
+    
+    public void addNode(Node node) {
+    	getCompositeNode().addNode(node);
+    }
+    
+    protected void internalAddNode(Node node) {
+    	super.addNode(node);
+    }
+    
+    public Node getNode(long id) {
+    	return getCompositeNode().getNode(id);
+    }
+    
+    public Node internalGetNode(long id) {
+    	return super.getNode(id);
+    }
+    
+    public Node[] getNodes() {
+    	return getCompositeNode().getNodes();
+    }
+    
+    public void linkIncomingConnections(String inType, long inNodeId, String inNodeType) {
+    	getCompositeNode().linkIncomingConnections(inType, inNodeId, inNodeType);
+    }
 
+    public void linkOutgoingConnections(long outNodeId, String outNodeType, String outType) {
+    	getCompositeNode().linkOutgoingConnections(outNodeId, outNodeType, outType);
+	}
+    
+    public CompositeNode.NodeAndType getLinkedIncomingNode(String inType) {
+    	return getCompositeNode().getLinkedIncomingNode(inType);
+    }
+
+    public CompositeNode.NodeAndType internalGetLinkedIncomingNode(String inType) {
+        return super.getLinkedIncomingNode(inType);
+    }
+    
+    public CompositeNode.NodeAndType getLinkedOutgoingNode(String inType) {
+    	return getCompositeNode().getLinkedOutgoingNode(inType);
+    }
+
+    public CompositeNode.NodeAndType internalGetLinkedOutgoingNode(String inType) {
+        return super.getLinkedOutgoingNode(inType);
+    }
+    
     public void setVariable(String variableName, DataType type) {
         this.variableName = variableName;
         List<Variable> variables = new ArrayList<Variable>();
@@ -80,15 +134,6 @@
         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() {
@@ -99,7 +144,15 @@
         this.collectionExpression = collectionExpression;
     }
 
-    public class ForEachSplitNode extends SequenceNode {
+    public boolean isWaitForCompletion() {
+        return waitForCompletion;
+    }
+
+    public void setWaitForCompletion(boolean waitForCompletion) {
+        this.waitForCompletion = waitForCompletion;
+    }
+
+   public class ForEachSplitNode extends SequenceNode {
         private static final long serialVersionUID = 4L;
     }
 

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-07-22 12:21:06 UTC (rev 21159)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/impl/NodeInstanceFactoryRegistry.java	2008-07-22 12:30:50 UTC (rev 21160)
@@ -5,6 +5,7 @@
 
 import org.drools.workflow.core.Node;
 import org.drools.workflow.core.node.ActionNode;
+import org.drools.workflow.core.node.CompositeContextNode;
 import org.drools.workflow.core.node.CompositeNode;
 import org.drools.workflow.core.node.EndNode;
 import org.drools.workflow.core.node.FaultNode;
@@ -21,6 +22,7 @@
 import org.drools.workflow.instance.impl.factory.CreateNewNodeFactory;
 import org.drools.workflow.instance.impl.factory.ReuseNodeFactory;
 import org.drools.workflow.instance.node.ActionNodeInstance;
+import org.drools.workflow.instance.node.CompositeContextNodeInstance;
 import org.drools.workflow.instance.node.CompositeNodeInstance;
 import org.drools.workflow.instance.node.EndNodeInstance;
 import org.drools.workflow.instance.node.FaultNodeInstance;
@@ -68,6 +70,8 @@
                   new CreateNewNodeFactory( FaultNodeInstance.class ) );
         register( CompositeNode.class,
                   new CreateNewNodeFactory( CompositeNodeInstance.class ) );
+        register( CompositeContextNode.class,
+                  new CreateNewNodeFactory( CompositeContextNodeInstance.class ) );
         register( HumanTaskNode.class,
                   new CreateNewNodeFactory( HumanTaskNodeInstance.class ) );
         register( ForEachNode.class,

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/impl/NodeInstanceImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/impl/NodeInstanceImpl.java	2008-07-22 12:21:06 UTC (rev 21159)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/impl/NodeInstanceImpl.java	2008-07-22 12:30:50 UTC (rev 21160)
@@ -78,7 +78,7 @@
     }
 
     public Node getNode() {
-        return this.nodeInstanceContainer.getNodeContainer().getNode( this.nodeId );
+        return this.nodeInstanceContainer.getNodeContainer().internalGetNode( this.nodeId );
     }
     
     public boolean isInversionOfControl() {
@@ -122,7 +122,24 @@
         }
         // TODO: find right context instance container and get context instance
         // TODO: currently, only the process instance acts as a context instance container
-        ContextInstanceContainer contextInstanceContainer = getProcessInstance();
+        ContextInstanceContainer contextInstanceContainer = null;
+        if (this instanceof ContextInstanceContainer) {
+        	contextInstanceContainer = (ContextInstanceContainer) this; 
+        } else {
+        	NodeInstanceContainer nodeInstanceContainer = this.getNodeInstanceContainer();
+        	while (contextInstanceContainer == null) {
+        		if (nodeInstanceContainer instanceof ContextInstanceContainer) {
+        			contextInstanceContainer = (ContextInstanceContainer) nodeInstanceContainer;
+        		} else if (nodeInstanceContainer instanceof NodeInstance) {
+        			nodeInstanceContainer = ((NodeInstance) nodeInstanceContainer).getNodeInstanceContainer();
+        		} else {
+        			break;
+        		}
+        	}
+        }
+        if (contextInstanceContainer == null) {
+        	contextInstanceContainer = getProcessInstance();
+        }
         return contextInstanceContainer.getContextInstance(context);
     }
     

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/CompositeContextNodeInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/CompositeContextNodeInstance.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/CompositeContextNodeInstance.java	2008-07-22 12:30:50 UTC (rev 21160)
@@ -0,0 +1,89 @@
+package org.drools.workflow.instance.node;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.drools.common.InternalRuleBase;
+import org.drools.process.core.Context;
+import org.drools.process.core.ContextContainer;
+import org.drools.process.instance.ContextInstance;
+import org.drools.process.instance.ContextInstanceContainer;
+import org.drools.process.instance.impl.ContextInstanceFactory;
+import org.drools.process.instance.impl.ContextInstanceFactoryRegistry;
+import org.drools.workflow.core.node.CompositeContextNode;
+
+public class CompositeContextNodeInstance extends CompositeNodeInstance implements ContextInstanceContainer {
+
+	private static final long serialVersionUID = 4L;
+	
+	private Map<String, ContextInstance> contextInstances = new HashMap<String, ContextInstance>();
+    private Map<String, List<ContextInstance>> subContextInstances = new HashMap<String, List<ContextInstance>>();
+
+    protected CompositeContextNode getCompositeContextNode() {
+        return (CompositeContextNode) getNode();
+    }
+    
+    public ContextContainer getContextContainer() {
+        return getCompositeContextNode();
+    }
+    
+    public void setContextInstance(String contextId, ContextInstance contextInstance) {
+        this.contextInstances.put(contextId, contextInstance);
+    }
+    
+    public ContextInstance getContextInstance(String contextId) {
+        ContextInstance contextInstance = this.contextInstances.get(contextId);
+        if (contextInstance != null) {
+            return contextInstance;
+        }
+        Context context = getCompositeContextNode().getDefaultContext(contextId);
+        if (context != null) {
+            contextInstance = getContextInstance(context);
+            return contextInstance;
+        }
+        return null;
+    }
+    
+    public List<ContextInstance> getContextInstances(String contextId) {
+        return this.subContextInstances.get(contextId);
+    }
+    
+    public void addContextInstance(String contextId, ContextInstance contextInstance) {
+        List<ContextInstance> list = this.subContextInstances.get(contextId);
+        if (list == null) {
+            list = new ArrayList<ContextInstance>();
+            this.subContextInstances.put(contextId, list);
+        }
+        list.add(contextInstance);
+    }
+
+    public ContextInstance getContextInstance(String contextId, long id) {
+        List<ContextInstance> contextInstances = subContextInstances.get(contextId);
+        if (contextInstances != null) {
+            for (ContextInstance contextInstance: contextInstances) {
+                if (contextInstance.getContextId() == id) {
+                    return contextInstance;
+                }
+            }
+        }
+        return null;
+    }
+
+    public ContextInstance getContextInstance(final Context context) {
+        ContextInstanceFactoryRegistry contextRegistry =
+            ((InternalRuleBase) getProcessInstance().getWorkingMemory().getRuleBase())
+                .getConfiguration().getProcessContextInstanceFactoryRegistry();
+        ContextInstanceFactory conf = contextRegistry.getContextInstanceFactory(context);
+        if (conf == null) {
+            throw new IllegalArgumentException("Illegal context type (registry not found): " + context.getClass());
+        }
+        ContextInstance contextInstance = (ContextInstance) conf.getContextInstance(context, this);
+        if (contextInstance == null) {
+            throw new IllegalArgumentException("Illegal context type (instance not found): " + context.getClass());
+        }
+        return contextInstance;
+    }
+
+}

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-07-22 12:21:06 UTC (rev 21159)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/CompositeNodeInstance.java	2008-07-22 12:30:50 UTC (rev 21160)
@@ -54,7 +54,7 @@
     }
     
     public void internalTrigger(final NodeInstance from, String type) {
-        CompositeNode.NodeAndType nodeAndType = getCompositeNode().getLinkedIncomingNode(type);
+        CompositeNode.NodeAndType nodeAndType = getCompositeNode().internalGetLinkedIncomingNode(type);
         List<Connection> connections = nodeAndType.getNode().getIncomingConnections(nodeAndType.getType());
         for (Iterator<Connection> iterator = connections.iterator(); iterator.hasNext(); ) {
             Connection connection = iterator.next();

Modified: 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	2008-07-22 12:21:06 UTC (rev 21159)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/workflow/instance/node/ForEachNodeInstance.java	2008-07-22 12:30:50 UTC (rev 21160)
@@ -6,7 +6,6 @@
 
 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;
@@ -90,6 +89,9 @@
             for (NodeInstance nodeInstance: nodeInstances) {
                 nodeInstance.trigger(this, getForEachSplitNode().getTo().getToType());
             }
+            if (!getForEachNode().isWaitForCompletion()) {
+            	ForEachNodeInstance.this.triggerCompleted(Node.CONNECTION_DEFAULT_TYPE, false);
+            }
         }
         
         private Collection<?> evaluateCollectionExpression(String collectionExpression) {
@@ -116,7 +118,9 @@
         public void internalTrigger(NodeInstance from, String type) {
             if (getNodeInstanceContainer().getNodeInstances().size() == 1) {
                 getNodeInstanceContainer().removeNodeInstance(this);
-                triggerConnection(getForEachJoinNode().getTo());
+                if (getForEachNode().isWaitForCompletion()) {
+                	triggerConnection(getForEachJoinNode().getTo());
+                }
             }
         }
         

Modified: 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	2008-07-22 12:21:06 UTC (rev 21159)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/process/ForEachTest.java	2008-07-22 12:30:50 UTC (rev 21160)
@@ -77,15 +77,16 @@
         DroolsAction action = new DroolsConsequenceAction("java", null);
         action.setMetaData("Action", new Action() {
             public void execute(KnowledgeHelper knowledgeHelper, WorkingMemory workingMemory, ActionContext context) throws Exception {
+            	System.out.println("Executed action for child " + ((Person) context.getVariable("child")).getName());
                 myList.add("Executed action");
             }
         });
         actionNode.setAction(action);
-        forEachNode.getCompositeNode().addNode(actionNode);
-        forEachNode.getCompositeNode().linkIncomingConnections(
+        forEachNode.addNode(actionNode);
+        forEachNode.linkIncomingConnections(
             Node.CONNECTION_DEFAULT_TYPE,
             actionNode.getId(), Node.CONNECTION_DEFAULT_TYPE);
-        forEachNode.getCompositeNode().linkOutgoingConnections(
+        forEachNode.linkOutgoingConnections(
             actionNode.getId(), Node.CONNECTION_DEFAULT_TYPE,
             Node.CONNECTION_DEFAULT_TYPE);
         forEachNode.setVariable("child", personDataType);




More information about the jboss-svn-commits mailing list