1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kew.engine.transition;
17
18 import org.kuali.rice.kew.engine.RouteContext;
19 import org.kuali.rice.kew.engine.node.*;
20 import org.kuali.rice.kew.exception.RouteManagerException;
21
22 import java.util.HashSet;
23 import java.util.Iterator;
24 import java.util.List;
25 import java.util.Set;
26
27
28
29
30
31
32
33
34
35
36 public class DynamicTransitionEngine extends TransitionEngine {
37
38
39
40
41
42 public RouteNodeInstance transitionTo(RouteNodeInstance dynamicNodeInstance, RouteContext context) throws Exception {
43 dynamicNodeInstance.setInitial(false);
44 dynamicNodeInstance.setActive(false);
45 DynamicNode dynamicNode = (DynamicNode) getNode(dynamicNodeInstance.getRouteNode(), DynamicNode.class);
46 DynamicResult result = dynamicNode.transitioningInto(context, dynamicNodeInstance, getRouteHelper());
47 RouteNodeInstance nextNodeInstance = result.getNextNodeInstance();
48 RouteNodeInstance finalNodeInstance = null;
49 if (result.isComplete()) {
50 dynamicNodeInstance.setComplete(true);
51 finalNodeInstance = getFinalNodeInstance(dynamicNodeInstance, context);
52 if (nextNodeInstance == null) {
53 nextNodeInstance = finalNodeInstance;
54 }
55 }
56
57 if (nextNodeInstance !=null) {
58 initializeNodeGraph(context, dynamicNodeInstance, nextNodeInstance, new HashSet<RouteNodeInstance>(), finalNodeInstance);
59 }
60 return nextNodeInstance;
61 }
62
63 public ProcessResult isComplete(RouteContext context) throws Exception {
64 throw new UnsupportedOperationException("isComplete() should not be invoked on a Dynamic node!");
65 }
66
67 public Transition transitionFrom(RouteContext context, ProcessResult processResult) throws Exception {
68
69 Transition transition = new Transition();
70 RouteNodeInstance dynamicNodeInstance = context.getNodeInstance().getProcess();
71 DynamicNode dynamicNode = (DynamicNode) getNode(dynamicNodeInstance.getRouteNode(), DynamicNode.class);
72 DynamicResult result = dynamicNode.transitioningOutOf(context, getRouteHelper());
73 if (result.getNextNodeInstance() == null && result.getNextNodeInstances().isEmpty() && result.isComplete()) {
74 dynamicNodeInstance.setComplete(true);
75 RouteNodeInstance finalNodeInstance = getFinalNodeInstance(dynamicNodeInstance, context);
76 if (finalNodeInstance != null) {
77 transition.getNextNodeInstances().add(finalNodeInstance);
78 }
79 } else {
80 if (result.getNextNodeInstance() != null) {
81 result.getNextNodeInstance().setProcess(dynamicNodeInstance);
82 transition.getNextNodeInstances().add(result.getNextNodeInstance());
83 }
84 for (Iterator iter = result.getNextNodeInstances().iterator(); iter.hasNext();) {
85 RouteNodeInstance nextNodeInstance = (RouteNodeInstance) iter.next();
86 nextNodeInstance.setProcess(dynamicNodeInstance);
87 }
88 transition.getNextNodeInstances().addAll(result.getNextNodeInstances());
89 }
90 return transition;
91 }
92
93
94
95
96
97
98 private void initializeNodeGraph(RouteContext context, RouteNodeInstance dynamicNodeInstance, RouteNodeInstance nodeInstance, Set<RouteNodeInstance> nodeInstances, RouteNodeInstance finalNodeInstance) throws Exception {
99 if (nodeInstances.contains(nodeInstance)) {
100 throw new RouteManagerException("A cycle was detected in the node graph returned from the dynamic node.", context);
101 }
102 nodeInstances.add(nodeInstance);
103 nodeInstance.setProcess(dynamicNodeInstance);
104 List<RouteNodeInstance> nextNodeInstances = nodeInstance.getNextNodeInstances();
105
106 if (nextNodeInstances.size() > 1) {
107
108
109 }
110 for (RouteNodeInstance nextNodeInstance : nextNodeInstances)
111 {
112 initializeNodeGraph(context, dynamicNodeInstance, nextNodeInstance, nodeInstances, finalNodeInstance);
113 }
114 if (nextNodeInstances.isEmpty() && finalNodeInstance != null) {
115 nodeInstance.addNextNodeInstance(finalNodeInstance);
116 }
117 }
118
119 private RouteNodeInstance getFinalNodeInstance(RouteNodeInstance dynamicNodeInstance, RouteContext context) throws Exception {
120 List<RouteNode> nextNodes = dynamicNodeInstance.getRouteNode().getNextNodes();
121 if (nextNodes.size() > 1) {
122 throw new RouteManagerException("There should only be 1 next node following a dynamic node, there were " + nextNodes.size(), context);
123 }
124 RouteNodeInstance finalNodeInstance = null;
125 if (!nextNodes.isEmpty()) {
126 finalNodeInstance = getRouteHelper().getNodeFactory().createRouteNodeInstance(context.getDocument().getDocumentId(), (RouteNode) nextNodes.get(0));
127 finalNodeInstance.setBranch(dynamicNodeInstance.getBranch());
128 finalNodeInstance.setProcess(dynamicNodeInstance.getProcess());
129 }
130 return finalNodeInstance;
131 }
132 }