/machinelearning/5.0.x/drools-core/src/main/java/org/drools/workflow/instance/node/ForEachNodeInstance.java

https://github.com/etirelli/droolsjbpm-contributed-experiments · Java · 146 lines · 105 code · 19 blank · 22 comment · 18 complexity · 7d15594108457b3dce7728b6f12114a5 MD5 · raw file

  1. package org.drools.workflow.instance.node;
  2. import java.util.ArrayList;
  3. import java.util.Collection;
  4. import java.util.Collections;
  5. import java.util.List;
  6. import org.drools.definition.process.Node;
  7. import org.drools.process.core.context.variable.VariableScope;
  8. import org.drools.process.instance.context.variable.VariableScopeInstance;
  9. import org.drools.workflow.core.node.ForEachNode;
  10. import org.drools.workflow.core.node.ForEachNode.ForEachJoinNode;
  11. import org.drools.workflow.core.node.ForEachNode.ForEachSplitNode;
  12. import org.drools.workflow.instance.NodeInstance;
  13. import org.drools.workflow.instance.NodeInstanceContainer;
  14. import org.drools.workflow.instance.impl.NodeInstanceImpl;
  15. /*
  16. * Copyright 2005 JBoss Inc
  17. *
  18. * Licensed under the Apache License, Version 2.0 (the "License");
  19. * you may not use this file except in compliance with the License.
  20. * You may obtain a copy of the License at
  21. *
  22. * http://www.apache.org/licenses/LICENSE-2.0
  23. *
  24. * Unless required by applicable law or agreed to in writing, software
  25. * distributed under the License is distributed on an "AS IS" BASIS,
  26. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  27. * See the License for the specific language governing permissions and
  28. * limitations under the License.
  29. */
  30. /**
  31. * Runtime counterpart of a for each node.
  32. *
  33. * @author <a href="mailto:kris_verlaenen@hotmail.com">Kris Verlaenen</a>
  34. */
  35. public class ForEachNodeInstance extends CompositeNodeInstance {
  36. private static final long serialVersionUID = 4L;
  37. public ForEachNode getForEachNode() {
  38. return (ForEachNode) getNode();
  39. }
  40. public NodeInstance getNodeInstance(final Node node) {
  41. // TODO do this cleaner for split / join of for each?
  42. if (node instanceof ForEachSplitNode) {
  43. ForEachSplitNodeInstance nodeInstance = new ForEachSplitNodeInstance();
  44. nodeInstance.setNodeId(node.getId());
  45. nodeInstance.setNodeInstanceContainer(this);
  46. nodeInstance.setProcessInstance(getProcessInstance());
  47. return nodeInstance;
  48. } else if (node instanceof ForEachJoinNode) {
  49. ForEachJoinNodeInstance nodeInstance = (ForEachJoinNodeInstance)
  50. getFirstNodeInstance(node.getId());
  51. if (nodeInstance == null) {
  52. nodeInstance = new ForEachJoinNodeInstance();
  53. nodeInstance.setNodeId(node.getId());
  54. nodeInstance.setNodeInstanceContainer(this);
  55. nodeInstance.setProcessInstance(getProcessInstance());
  56. }
  57. return nodeInstance;
  58. }
  59. return super.getNodeInstance(node);
  60. }
  61. public class ForEachSplitNodeInstance extends NodeInstanceImpl {
  62. private static final long serialVersionUID = 4L;
  63. public ForEachSplitNode getForEachSplitNode() {
  64. return (ForEachSplitNode) getNode();
  65. }
  66. public void internalTrigger(org.drools.runtime.process.NodeInstance from, String type) {
  67. String collectionExpression = getForEachNode().getCollectionExpression();
  68. Collection<?> collection = evaluateCollectionExpression(collectionExpression);
  69. ((NodeInstanceContainer) getNodeInstanceContainer()).removeNodeInstance(this);
  70. List<NodeInstance> nodeInstances = new ArrayList<NodeInstance>();
  71. for (Object o: collection) {
  72. String variableName = getForEachNode().getVariableName();
  73. CompositeNodeInstance nodeInstance = (CompositeNodeInstance)
  74. ((NodeInstanceContainer) getNodeInstanceContainer()).getNodeInstance(getForEachSplitNode().getTo().getTo());
  75. VariableScopeInstance variableScopeInstance = (VariableScopeInstance)
  76. nodeInstance.resolveContextInstance(VariableScope.VARIABLE_SCOPE, variableName);
  77. variableScopeInstance.setVariable(variableName, o);
  78. nodeInstances.add(nodeInstance);
  79. }
  80. for (NodeInstance nodeInstance: nodeInstances) {
  81. ((org.drools.workflow.instance.NodeInstance) nodeInstance).trigger(this, getForEachSplitNode().getTo().getToType());
  82. }
  83. if (!getForEachNode().isWaitForCompletion()) {
  84. ForEachNodeInstance.this.triggerCompleted(org.drools.workflow.core.Node.CONNECTION_DEFAULT_TYPE, false);
  85. }
  86. }
  87. private Collection<?> evaluateCollectionExpression(String collectionExpression) {
  88. // TODO: should evaluate this expression using MVEL
  89. VariableScopeInstance variableScopeInstance = (VariableScopeInstance)
  90. resolveContextInstance(VariableScope.VARIABLE_SCOPE, collectionExpression);
  91. if (variableScopeInstance == null) {
  92. throw new IllegalArgumentException(
  93. "Could not find collection " + collectionExpression);
  94. }
  95. Object collection = variableScopeInstance.getVariable(collectionExpression);
  96. if (collection == null) {
  97. return Collections.EMPTY_LIST;
  98. }
  99. if (collection instanceof Collection<?>) {
  100. return (Collection<?>) collection;
  101. }
  102. if (collection.getClass().isArray() ) {
  103. List<Object> list = new ArrayList<Object>();
  104. for (Object o: (Object[]) collection) {
  105. list.add(o);
  106. }
  107. return list;
  108. }
  109. throw new IllegalArgumentException(
  110. "Unexpected collection type: " + collection.getClass());
  111. }
  112. }
  113. public class ForEachJoinNodeInstance extends NodeInstanceImpl {
  114. private static final long serialVersionUID = 4L;
  115. public ForEachJoinNode getForEachJoinNode() {
  116. return (ForEachJoinNode) getNode();
  117. }
  118. public void internalTrigger(org.drools.runtime.process.NodeInstance from, String type) {
  119. if (getNodeInstanceContainer().getNodeInstances().size() == 1) {
  120. ((NodeInstanceContainer) getNodeInstanceContainer()).removeNodeInstance(this);
  121. if (getForEachNode().isWaitForCompletion()) {
  122. triggerConnection(getForEachJoinNode().getTo());
  123. }
  124. }
  125. }
  126. }
  127. }