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