1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kew.engine.node;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.kuali.rice.core.exception.RiceRuntimeException;
20 import org.kuali.rice.kew.doctype.bo.DocumentType;
21 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
22 import org.kuali.rice.kew.rule.xmlrouting.XPathHelper;
23 import org.w3c.dom.Document;
24 import org.xml.sax.InputSource;
25
26 import javax.xml.parsers.DocumentBuilder;
27 import javax.xml.parsers.DocumentBuilderFactory;
28 import java.io.StringReader;
29 import java.util.*;
30
31
32
33
34
35
36
37
38 public class RouteNodeUtils {
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59 public static String getValueOfCustomProperty(RouteNode routeNode, String propertyName) {
60 String contentFragment = routeNode.getContentFragment();
61 String elementValue = null;
62 if (!StringUtils.isBlank(contentFragment)) {
63 try {
64 DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
65 Document document = db.parse(new InputSource(new StringReader(contentFragment)));
66 elementValue = XPathHelper.newXPath().evaluate("//" + propertyName, document);
67 } catch (Exception e) {
68 throw new RiceRuntimeException("Error when attempting to parse Document Type content fragment for property name: " + propertyName, e);
69 }
70 }
71 return elementValue;
72 }
73
74 public static List<RouteNodeInstance> getFlattenedNodeInstances(DocumentRouteHeaderValue document, boolean includeProcesses) {
75 List<RouteNodeInstance> nodeInstances = new ArrayList<RouteNodeInstance>();
76 Set<Long> visitedNodeInstanceIds = new HashSet<Long>();
77 for (RouteNodeInstance initialNodeInstance : document.getInitialRouteNodeInstances())
78 {
79 flattenNodeInstanceGraph(nodeInstances, visitedNodeInstanceIds, initialNodeInstance, includeProcesses);
80 }
81 return nodeInstances;
82 }
83
84 private static void flattenNodeInstanceGraph(List<RouteNodeInstance> nodeInstances, Set<Long> visitedNodeInstanceIds, RouteNodeInstance nodeInstance, boolean includeProcesses) {
85 if (visitedNodeInstanceIds.contains(nodeInstance.getRouteNodeInstanceId())) {
86 return;
87 }
88 if (includeProcesses && nodeInstance.getProcess() != null) {
89 flattenNodeInstanceGraph(nodeInstances, visitedNodeInstanceIds, nodeInstance.getProcess(), includeProcesses);
90 }
91 visitedNodeInstanceIds.add(nodeInstance.getRouteNodeInstanceId());
92 nodeInstances.add(nodeInstance);
93 for (RouteNodeInstance nextNodeInstance : nodeInstance.getNextNodeInstances())
94 {
95 flattenNodeInstanceGraph(nodeInstances, visitedNodeInstanceIds, nextNodeInstance, includeProcesses);
96 }
97 }
98
99 public static List<RouteNode> getFlattenedNodes(DocumentType documentType, boolean climbHierarchy) {
100 List<RouteNode> nodes = new ArrayList<RouteNode>();
101 if (!documentType.isRouteInherited() || climbHierarchy) {
102 for (Object o : documentType.getProcesses())
103 {
104 Process process = (Process) o;
105 nodes.addAll(getFlattenedNodes(process));
106 }
107 }
108 Collections.sort(nodes, new RouteNodeSorter());
109 return nodes;
110 }
111
112 public static List<RouteNode> getFlattenedNodes(Process process) {
113 Map<String, RouteNode> nodesMap = new HashMap<String, RouteNode>();
114 if (process.getInitialRouteNode() != null) {
115 flattenNodeGraph(nodesMap, process.getInitialRouteNode());
116 List<RouteNode> nodes = new ArrayList<RouteNode>(nodesMap.values());
117 Collections.sort(nodes, new RouteNodeSorter());
118 return nodes;
119 } else {
120 List<RouteNode> nodes = new ArrayList<RouteNode>();
121 nodes.add(new RouteNode());
122 return nodes;
123 }
124
125 }
126
127
128
129
130
131
132
133 private static void flattenNodeGraph(Map<String, RouteNode> nodes, RouteNode node) {
134 if (node != null) {
135 if (nodes.containsKey(node.getRouteNodeName())) {
136 return;
137 }
138 nodes.put(node.getRouteNodeName(), node);
139 for (RouteNode nextNode : node.getNextNodes())
140 {
141 flattenNodeGraph(nodes, nextNode);
142 }
143 } else {
144 return;
145 }
146 }
147
148
149
150
151
152
153
154 private static class RouteNodeSorter implements Comparator {
155 public int compare(Object arg0, Object arg1) {
156 RouteNode rn1 = (RouteNode)arg0;
157 RouteNode rn2 = (RouteNode)arg1;
158 return rn1.getRouteNodeId().compareTo(rn2.getRouteNodeId());
159 }
160 }
161
162 public static List<RouteNodeInstance> getActiveNodeInstances(DocumentRouteHeaderValue document) {
163 List<RouteNodeInstance> flattenedNodeInstances = getFlattenedNodeInstances(document, true);
164 List<RouteNodeInstance> activeNodeInstances = new ArrayList<RouteNodeInstance>();
165 for (RouteNodeInstance nodeInstance : flattenedNodeInstances)
166 {
167 if (nodeInstance.isActive())
168 {
169 activeNodeInstances.add(nodeInstance);
170 }
171 }
172 return activeNodeInstances;
173 }
174
175 public static RouteNodeInstance findRouteNodeInstanceById(Long nodeInstanceId, DocumentRouteHeaderValue document) {
176 List<RouteNodeInstance> flattenedNodeInstances = getFlattenedNodeInstances(document, true);
177 RouteNodeInstance niRet = null;
178 for (RouteNodeInstance nodeInstance : flattenedNodeInstances)
179 {
180 if (nodeInstanceId.equals(nodeInstance.getRouteNodeInstanceId()))
181 {
182 niRet = nodeInstance;
183 break;
184 }
185 }
186 return niRet;
187 }
188
189
190
191 }