/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/ForEachNode.java

https://github.com/mariofusco/jbpm · Java · 303 lines · 228 code · 48 blank · 27 comment · 18 complexity · 7cd9c3b5b06e721fde7aa143003e24ff MD5 · raw file

  1. /**
  2. * Copyright 2005 JBoss Inc
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.jbpm.workflow.core.node;
  17. import java.util.ArrayList;
  18. import java.util.List;
  19. import org.kie.api.definition.process.Node;
  20. import org.drools.core.process.core.datatype.DataType;
  21. import org.jbpm.process.core.Context;
  22. import org.jbpm.process.core.context.AbstractContext;
  23. import org.jbpm.process.core.context.variable.Variable;
  24. import org.jbpm.process.core.context.variable.VariableScope;
  25. import org.jbpm.workflow.core.impl.ConnectionImpl;
  26. import org.jbpm.workflow.core.impl.ExtendedNodeImpl;
  27. /**
  28. * A for each node.
  29. *
  30. * This node activates the contained subflow for each element of a collection.
  31. * The node continues if all activated the subflow has been completed for each
  32. * of the elements in the collection.
  33. *
  34. * @author <a href="mailto:kris_verlaenen@hotmail.com">Kris Verlaenen</a>
  35. */
  36. public class ForEachNode extends CompositeContextNode {
  37. private static final long serialVersionUID = 510l;
  38. private String variableName;
  39. private String outputVariableName;
  40. private String collectionExpression;
  41. private String outputCollectionExpression;
  42. private String completionConditionExpression;
  43. private boolean waitForCompletion = true;
  44. public ForEachNode() {
  45. // Split
  46. ForEachSplitNode split = new ForEachSplitNode();
  47. split.setName("ForEachSplit");
  48. split.setMetaData("hidden", true);
  49. split.setMetaData("UniqueId", getMetaData("Uniqueid") + ":foreach:split");
  50. super.addNode(split);
  51. super.linkIncomingConnections(
  52. org.jbpm.workflow.core.Node.CONNECTION_DEFAULT_TYPE,
  53. new CompositeNode.NodeAndType(split, org.jbpm.workflow.core.Node.CONNECTION_DEFAULT_TYPE));
  54. // Composite node
  55. CompositeContextNode compositeNode = new CompositeContextNode();
  56. compositeNode.setName("ForEachComposite");
  57. compositeNode.setMetaData("hidden", true);
  58. compositeNode.setMetaData("UniqueId", getMetaData("Uniqueid") + ":foreach:composite");
  59. super.addNode(compositeNode);
  60. VariableScope variableScope = new VariableScope();
  61. compositeNode.addContext(variableScope);
  62. compositeNode.setDefaultContext(variableScope);
  63. // Join
  64. ForEachJoinNode join = new ForEachJoinNode();
  65. join.setName("ForEachJoin");
  66. join.setMetaData("hidden", true);
  67. join.setMetaData("UniqueId", getMetaData("Uniqueid") + ":foreach:join");
  68. super.addNode(join);
  69. super.linkOutgoingConnections(
  70. new CompositeNode.NodeAndType(join, org.jbpm.workflow.core.Node.CONNECTION_DEFAULT_TYPE),
  71. org.jbpm.workflow.core.Node.CONNECTION_DEFAULT_TYPE);
  72. new ConnectionImpl(
  73. super.getNode(1), org.jbpm.workflow.core.Node.CONNECTION_DEFAULT_TYPE,
  74. getCompositeNode(), org.jbpm.workflow.core.Node.CONNECTION_DEFAULT_TYPE
  75. );
  76. new ConnectionImpl(
  77. getCompositeNode(), org.jbpm.workflow.core.Node.CONNECTION_DEFAULT_TYPE,
  78. super.getNode(3), org.jbpm.workflow.core.Node.CONNECTION_DEFAULT_TYPE
  79. );
  80. }
  81. public String getVariableName() {
  82. return variableName;
  83. }
  84. public DataType getVariableType() {
  85. if (variableName == null) {
  86. return null;
  87. }
  88. for (Variable variable: ((VariableScope) getCompositeNode().getDefaultContext(VariableScope.VARIABLE_SCOPE)).getVariables()) {
  89. if (variableName.equals(variable.getName())) {
  90. return variable.getType();
  91. }
  92. }
  93. return null;
  94. }
  95. public String getOutputVariableName() {
  96. return outputVariableName;
  97. }
  98. public DataType getOutputVariableType() {
  99. if (outputVariableName == null) {
  100. return null;
  101. }
  102. for (Variable variable: ((VariableScope) getCompositeNode().getDefaultContext(VariableScope.VARIABLE_SCOPE)).getVariables()) {
  103. if (outputVariableName.equals(variable.getName())) {
  104. return variable.getType();
  105. }
  106. }
  107. return null;
  108. }
  109. public CompositeContextNode getCompositeNode() {
  110. return (CompositeContextNode) super.getNode(2);
  111. }
  112. public ForEachSplitNode getForEachSplitNode() {
  113. return (ForEachSplitNode) super.getNode(1);
  114. }
  115. public ForEachJoinNode getForEachJoinNode() {
  116. return (ForEachJoinNode) super.getNode(3);
  117. }
  118. public void addNode(Node node) {
  119. getCompositeNode().addNode(node);
  120. }
  121. protected void internalAddNode(Node node) {
  122. super.addNode(node);
  123. }
  124. public Node getNode(long id) {
  125. return getCompositeNode().getNode(id);
  126. }
  127. public Node internalGetNode(long id) {
  128. return super.getNode(id);
  129. }
  130. public Node[] getNodes() {
  131. return getCompositeNode().getNodes();
  132. }
  133. public Node[] internalGetNodes() {
  134. return super.getNodes();
  135. }
  136. public void removeNode(Node node) {
  137. getCompositeNode().removeNode(node);
  138. }
  139. protected void internalRemoveNode(Node node) {
  140. super.removeNode(node);
  141. }
  142. public void linkIncomingConnections(String inType, long inNodeId, String inNodeType) {
  143. getCompositeNode().linkIncomingConnections(inType, inNodeId, inNodeType);
  144. }
  145. public void linkOutgoingConnections(long outNodeId, String outNodeType, String outType) {
  146. getCompositeNode().linkOutgoingConnections(outNodeId, outNodeType, outType);
  147. }
  148. public CompositeNode.NodeAndType getLinkedIncomingNode(String inType) {
  149. return getCompositeNode().getLinkedIncomingNode(inType);
  150. }
  151. public CompositeNode.NodeAndType internalGetLinkedIncomingNode(String inType) {
  152. return super.getLinkedIncomingNode(inType);
  153. }
  154. public CompositeNode.NodeAndType getLinkedOutgoingNode(String inType) {
  155. return getCompositeNode().getLinkedOutgoingNode(inType);
  156. }
  157. public CompositeNode.NodeAndType internalGetLinkedOutgoingNode(String inType) {
  158. return super.getLinkedOutgoingNode(inType);
  159. }
  160. public void setVariable(String variableName, DataType type) {
  161. this.variableName = variableName;
  162. VariableScope variableScope = (VariableScope) getCompositeNode().getDefaultContext(VariableScope.VARIABLE_SCOPE);
  163. List<Variable> variables = variableScope.getVariables();
  164. if (variables == null) {
  165. variables = new ArrayList<Variable>();
  166. variableScope.setVariables(variables);
  167. }
  168. Variable variable = new Variable();
  169. variable.setName(variableName);
  170. variable.setType(type);
  171. variables.add(variable);
  172. }
  173. public void setOutputVariable(String variableName, DataType type) {
  174. this.outputVariableName = variableName;
  175. VariableScope variableScope = (VariableScope) getCompositeNode().getDefaultContext(VariableScope.VARIABLE_SCOPE);
  176. List<Variable> variables = variableScope.getVariables();
  177. if (variables == null) {
  178. variables = new ArrayList<Variable>();
  179. variableScope.setVariables(variables);
  180. }
  181. Variable variable = new Variable();
  182. variable.setName(variableName);
  183. variable.setType(type);
  184. variables.add(variable);
  185. Variable tmpvariable = new Variable();
  186. tmpvariable.setName("foreach_output");
  187. tmpvariable.setType(type);
  188. variables.add(tmpvariable);
  189. }
  190. public String getCollectionExpression() {
  191. return collectionExpression;
  192. }
  193. public void setCollectionExpression(String collectionExpression) {
  194. this.collectionExpression = collectionExpression;
  195. }
  196. public String getOutputCollectionExpression() {
  197. return outputCollectionExpression;
  198. }
  199. public void setOutputCollectionExpression(String collectionExpression) {
  200. this.outputCollectionExpression = collectionExpression;
  201. }
  202. public boolean isWaitForCompletion() {
  203. return waitForCompletion;
  204. }
  205. public void setWaitForCompletion(boolean waitForCompletion) {
  206. this.waitForCompletion = waitForCompletion;
  207. }
  208. public class ForEachSplitNode extends ExtendedNodeImpl {
  209. private static final long serialVersionUID = 510l;
  210. }
  211. public class ForEachJoinNode extends ExtendedNodeImpl {
  212. private static final long serialVersionUID = 510l;
  213. }
  214. @Override
  215. public Context getContext(String contextType) {
  216. Context context = getCompositeNode().getDefaultContext(contextType);
  217. if (context != null) {
  218. return context;
  219. }
  220. return super.getContext(contextType);
  221. }
  222. @Override
  223. public void addContext(Context context) {
  224. getCompositeNode().addContext(context);
  225. ((AbstractContext) context).setContextContainer(getCompositeNode());
  226. }
  227. @Override
  228. public void setDefaultContext(Context context) {
  229. getCompositeNode().setDefaultContext(context);
  230. ((AbstractContext) context).setContextContainer(getCompositeNode());
  231. }
  232. @Override
  233. public List<Context> getContexts(String contextType) {
  234. List<Context> contexts = super.getContexts(contextType);
  235. if (contexts == null) {
  236. contexts = getCompositeNode().getContexts(contextType);
  237. }
  238. return contexts;
  239. }
  240. @Override
  241. public Context getContext(String contextType, long id) {
  242. Context ctx = super.getContext(contextType, id);
  243. if (ctx == null) {
  244. ctx = getCompositeNode().getContext(contextType, id);
  245. }
  246. return ctx;
  247. }
  248. public String getCompletionConditionExpression() {
  249. return completionConditionExpression;
  250. }
  251. public void setCompletionConditionExpression(
  252. String completionConditionExpression) {
  253. this.completionConditionExpression = completionConditionExpression;
  254. }
  255. }