1 | |
|
2 | |
|
3 | |
|
4 | |
|
5 | |
|
6 | |
|
7 | |
|
8 | |
|
9 | |
|
10 | |
|
11 | |
|
12 | |
|
13 | |
|
14 | |
|
15 | |
|
16 | |
|
17 | |
package org.kuali.rice.kew.engine.node.service.impl; |
18 | |
|
19 | |
import java.util.ArrayList; |
20 | |
import java.util.Collection; |
21 | |
import java.util.Collections; |
22 | |
import java.util.Comparator; |
23 | |
import java.util.HashMap; |
24 | |
import java.util.HashSet; |
25 | |
import java.util.Iterator; |
26 | |
import java.util.List; |
27 | |
import java.util.Map; |
28 | |
import java.util.Set; |
29 | |
|
30 | |
import org.apache.commons.collections.ComparatorUtils; |
31 | |
import org.kuali.rice.kew.doctype.bo.DocumentType; |
32 | |
import org.kuali.rice.kew.engine.RouteHelper; |
33 | |
import org.kuali.rice.kew.engine.node.Branch; |
34 | |
import org.kuali.rice.kew.engine.node.BranchState; |
35 | |
import org.kuali.rice.kew.engine.node.NodeGraphContext; |
36 | |
import org.kuali.rice.kew.engine.node.NodeGraphSearchCriteria; |
37 | |
import org.kuali.rice.kew.engine.node.NodeGraphSearchResult; |
38 | |
import org.kuali.rice.kew.engine.node.NodeMatcher; |
39 | |
import org.kuali.rice.kew.engine.node.NodeState; |
40 | |
import org.kuali.rice.kew.engine.node.Process; |
41 | |
import org.kuali.rice.kew.engine.node.RouteNode; |
42 | |
import org.kuali.rice.kew.engine.node.RouteNodeInstance; |
43 | |
import org.kuali.rice.kew.engine.node.RouteNodeUtils; |
44 | |
import org.kuali.rice.kew.engine.node.dao.RouteNodeDAO; |
45 | |
import org.kuali.rice.kew.engine.node.service.RouteNodeService; |
46 | |
import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue; |
47 | |
import org.kuali.rice.kew.service.KEWServiceLocator; |
48 | |
import org.kuali.rice.kew.util.Utilities; |
49 | |
|
50 | |
|
51 | |
|
52 | 0 | public class RouteNodeServiceImpl implements RouteNodeService { |
53 | |
|
54 | 0 | protected final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(getClass()); |
55 | |
|
56 | |
public static final String REVOKED_NODE_INSTANCES_STATE_KEY = "NodeInstances.Revoked"; |
57 | |
|
58 | 0 | private static final Comparator NODE_INSTANCE_FORWARD_SORT = new NodeInstanceIdSorter(); |
59 | 0 | private static final Comparator NODE_INSTANCE_BACKWARD_SORT = |
60 | |
ComparatorUtils.reversedComparator(NODE_INSTANCE_FORWARD_SORT); |
61 | 0 | private RouteHelper helper = new RouteHelper(); |
62 | |
private RouteNodeDAO routeNodeDAO; |
63 | |
|
64 | |
public void save(RouteNode node) { |
65 | 0 | routeNodeDAO.save(node); |
66 | 0 | } |
67 | |
|
68 | |
public void save(RouteNodeInstance nodeInstance) { |
69 | 0 | routeNodeDAO.save(nodeInstance); |
70 | 0 | } |
71 | |
|
72 | |
public void save(NodeState nodeState) { |
73 | 0 | routeNodeDAO.save(nodeState); |
74 | 0 | } |
75 | |
|
76 | |
public void save(Branch branch) { |
77 | 0 | routeNodeDAO.save(branch); |
78 | 0 | } |
79 | |
|
80 | |
public RouteNode findRouteNodeById(Long nodeId) { |
81 | 0 | return routeNodeDAO.findRouteNodeById(nodeId); |
82 | |
} |
83 | |
|
84 | |
public RouteNodeInstance findRouteNodeInstanceById(Long nodeInstanceId) { |
85 | 0 | return routeNodeDAO.findRouteNodeInstanceById(nodeInstanceId); |
86 | |
} |
87 | |
|
88 | |
public RouteNodeInstance findRouteNodeInstanceById(Long nodeInstanceId, DocumentRouteHeaderValue document) { |
89 | 0 | return RouteNodeUtils.findRouteNodeInstanceById(nodeInstanceId, document); |
90 | |
} |
91 | |
|
92 | |
public List getCurrentNodeInstances(Long documentId) { |
93 | 0 | List currentNodeInstances = getActiveNodeInstances(documentId); |
94 | 0 | if (currentNodeInstances.isEmpty()) { |
95 | 0 | currentNodeInstances = getTerminalNodeInstances(documentId); |
96 | |
} |
97 | 0 | return currentNodeInstances; |
98 | |
} |
99 | |
|
100 | |
public List<RouteNodeInstance> getActiveNodeInstances(Long documentId) { |
101 | 0 | return routeNodeDAO.getActiveNodeInstances(documentId); |
102 | |
} |
103 | |
|
104 | |
public List<RouteNodeInstance> getActiveNodeInstances(DocumentRouteHeaderValue document) { |
105 | 0 | List flattenedNodeInstances = getFlattenedNodeInstances(document, true); |
106 | 0 | List<RouteNodeInstance> activeNodeInstances = new ArrayList(); |
107 | 0 | for (Iterator iterator = flattenedNodeInstances.iterator(); iterator.hasNext();) { |
108 | 0 | RouteNodeInstance nodeInstance = (RouteNodeInstance) iterator.next(); |
109 | 0 | if (nodeInstance.isActive()) { |
110 | 0 | activeNodeInstances.add(nodeInstance); |
111 | |
} |
112 | 0 | } |
113 | 0 | return activeNodeInstances; |
114 | |
} |
115 | |
|
116 | |
public List getTerminalNodeInstances(Long documentId) { |
117 | 0 | return routeNodeDAO.getTerminalNodeInstances(documentId); |
118 | |
} |
119 | |
|
120 | |
public List getInitialNodeInstances(Long documentId) { |
121 | 0 | return routeNodeDAO.getInitialNodeInstances(documentId); |
122 | |
} |
123 | |
|
124 | |
public NodeState findNodeState(Long nodeInstanceId, String key) { |
125 | 0 | return routeNodeDAO.findNodeState(nodeInstanceId, key); |
126 | |
} |
127 | |
|
128 | |
public RouteNode findRouteNodeByName(Long documentTypeId, String name) { |
129 | 0 | return routeNodeDAO.findRouteNodeByName(documentTypeId, name); |
130 | |
} |
131 | |
|
132 | |
public List findFinalApprovalRouteNodes(Long documentTypeId) { |
133 | 0 | DocumentType documentType = KEWServiceLocator.getDocumentTypeService().findById(documentTypeId); |
134 | 0 | documentType = documentType.getRouteDefiningDocumentType(); |
135 | 0 | return routeNodeDAO.findFinalApprovalRouteNodes(documentType.getDocumentTypeId()); |
136 | |
} |
137 | |
|
138 | |
public List findNextRouteNodesInPath(RouteNodeInstance nodeInstance, String nodeName) { |
139 | 0 | List nodesInPath = new ArrayList(); |
140 | 0 | for (Iterator iterator = nodeInstance.getRouteNode().getNextNodes().iterator(); iterator.hasNext();) { |
141 | 0 | RouteNode nextNode = (RouteNode) iterator.next(); |
142 | 0 | nodesInPath.addAll(findNextRouteNodesInPath(nodeName, nextNode, new HashSet())); |
143 | 0 | } |
144 | 0 | return nodesInPath; |
145 | |
} |
146 | |
|
147 | |
private List findNextRouteNodesInPath(String nodeName, RouteNode node, Set inspected) { |
148 | 0 | List nextNodesInPath = new ArrayList(); |
149 | 0 | if (inspected.contains(node.getRouteNodeId())) { |
150 | 0 | return nextNodesInPath; |
151 | |
} |
152 | 0 | inspected.add(node.getRouteNodeId()); |
153 | 0 | if (node.getRouteNodeName().equals(nodeName)) { |
154 | 0 | nextNodesInPath.add(node); |
155 | |
} else { |
156 | 0 | if (helper.isSubProcessNode(node)) { |
157 | 0 | Process subProcess = node.getDocumentType().getNamedProcess(node.getRouteNodeName()); |
158 | 0 | RouteNode subNode = subProcess.getInitialRouteNode(); |
159 | 0 | nextNodesInPath.addAll(findNextRouteNodesInPath(nodeName, subNode, inspected)); |
160 | |
} |
161 | 0 | for (Iterator iterator = node.getNextNodes().iterator(); iterator.hasNext();) { |
162 | 0 | RouteNode nextNode = (RouteNode) iterator.next(); |
163 | 0 | nextNodesInPath.addAll(findNextRouteNodesInPath(nodeName, nextNode, inspected)); |
164 | 0 | } |
165 | |
} |
166 | 0 | return nextNodesInPath; |
167 | |
} |
168 | |
|
169 | |
public boolean isNodeInPath(DocumentRouteHeaderValue document, String nodeName) { |
170 | 0 | boolean isInPath = false; |
171 | 0 | Collection activeNodes = getActiveNodeInstances(document.getRouteHeaderId()); |
172 | 0 | for (Iterator iterator = activeNodes.iterator(); iterator.hasNext();) { |
173 | 0 | RouteNodeInstance nodeInstance = (RouteNodeInstance) iterator.next(); |
174 | 0 | List nextNodesInPath = findNextRouteNodesInPath(nodeInstance, nodeName); |
175 | 0 | isInPath = isInPath || !nextNodesInPath.isEmpty(); |
176 | 0 | } |
177 | 0 | return isInPath; |
178 | |
} |
179 | |
|
180 | |
public List findRouteNodeInstances(Long documentId) { |
181 | 0 | return this.routeNodeDAO.findRouteNodeInstances(documentId); |
182 | |
} |
183 | |
|
184 | |
public void setRouteNodeDAO(RouteNodeDAO dao) { |
185 | 0 | this.routeNodeDAO = dao; |
186 | 0 | } |
187 | |
|
188 | |
public List findProcessNodeInstances(RouteNodeInstance process) { |
189 | 0 | return this.routeNodeDAO.findProcessNodeInstances(process); |
190 | |
} |
191 | |
|
192 | |
public Set findPreviousNodeNames(Long documentId) { |
193 | 0 | List currentNodeInstances = KEWServiceLocator.getRouteNodeService().getCurrentNodeInstances(documentId); |
194 | 0 | List nodeInstances = new ArrayList(); |
195 | 0 | for (Iterator iterator = currentNodeInstances.iterator(); iterator.hasNext();) { |
196 | 0 | RouteNodeInstance nodeInstance = (RouteNodeInstance) iterator.next(); |
197 | 0 | nodeInstances.addAll(nodeInstance.getPreviousNodeInstances()); |
198 | 0 | } |
199 | 0 | Set nodeNames = new HashSet(); |
200 | 0 | while (!nodeInstances.isEmpty()) { |
201 | 0 | RouteNodeInstance nodeInstance = (RouteNodeInstance)nodeInstances.remove(0); |
202 | 0 | nodeNames.add(nodeInstance.getName()); |
203 | 0 | nodeInstances.addAll(nodeInstance.getPreviousNodeInstances()); |
204 | 0 | } |
205 | 0 | return nodeNames; |
206 | |
} |
207 | |
|
208 | |
public List<String> findFutureNodeNames(Long documentId) { |
209 | 0 | List currentNodeInstances = KEWServiceLocator.getRouteNodeService().getCurrentNodeInstances(documentId); |
210 | 0 | List nodes = new ArrayList(); |
211 | 0 | for (Iterator iterator = currentNodeInstances.iterator(); iterator.hasNext();) { |
212 | 0 | RouteNodeInstance nodeInstance = (RouteNodeInstance) iterator.next(); |
213 | 0 | nodes.addAll(nodeInstance.getRouteNode().getNextNodes()); |
214 | 0 | } |
215 | 0 | List<String> nodeNames = new ArrayList<String>(); |
216 | 0 | while (!nodes.isEmpty()) { |
217 | 0 | RouteNode node = (RouteNode)nodes.remove(0); |
218 | 0 | if (!nodeNames.contains(node.getRouteNodeName())) { |
219 | 0 | nodeNames.add(node.getRouteNodeName()); |
220 | |
} |
221 | 0 | nodes.addAll(node.getNextNodes()); |
222 | 0 | } |
223 | 0 | return nodeNames; |
224 | |
} |
225 | |
|
226 | |
public List<RouteNode> getFlattenedNodes(DocumentType documentType, boolean climbHierarchy) { |
227 | 0 | List<RouteNode> nodes = new ArrayList<RouteNode>(); |
228 | 0 | if (!documentType.isRouteInherited() || climbHierarchy) { |
229 | 0 | for (Iterator iterator = documentType.getProcesses().iterator(); iterator.hasNext();) { |
230 | 0 | Process process = (Process) iterator.next(); |
231 | 0 | nodes.addAll(getFlattenedNodes(process)); |
232 | 0 | } |
233 | |
} |
234 | 0 | Collections.sort(nodes, new RouteNodeSorter()); |
235 | 0 | return nodes; |
236 | |
} |
237 | |
|
238 | |
public List<RouteNode> getFlattenedNodes(Process process) { |
239 | 0 | Map nodesMap = new HashMap(); |
240 | 0 | if (process.getInitialRouteNode() != null) { |
241 | 0 | flattenNodeGraph(nodesMap, process.getInitialRouteNode()); |
242 | 0 | List<RouteNode> nodes = new ArrayList<RouteNode>(nodesMap.values()); |
243 | 0 | Collections.sort(nodes, new RouteNodeSorter()); |
244 | 0 | return nodes; |
245 | |
} else { |
246 | 0 | List nodes = new ArrayList(); |
247 | 0 | nodes.add(new RouteNode()); |
248 | 0 | return nodes; |
249 | |
} |
250 | |
|
251 | |
} |
252 | |
|
253 | |
|
254 | |
|
255 | |
|
256 | |
|
257 | |
private void flattenNodeGraph(Map nodes, RouteNode node) { |
258 | 0 | if (node != null) { |
259 | 0 | if (nodes.containsKey(node.getRouteNodeName())) { |
260 | 0 | return; |
261 | |
} |
262 | 0 | nodes.put(node.getRouteNodeName(), node); |
263 | 0 | for (Iterator iterator = node.getNextNodes().iterator(); iterator.hasNext();) { |
264 | 0 | RouteNode nextNode = (RouteNode) iterator.next(); |
265 | 0 | flattenNodeGraph(nodes, nextNode); |
266 | 0 | } |
267 | |
} else { |
268 | 0 | return; |
269 | |
} |
270 | 0 | } |
271 | |
|
272 | |
public List<RouteNodeInstance> getFlattenedNodeInstances(DocumentRouteHeaderValue document, boolean includeProcesses) { |
273 | 0 | List<RouteNodeInstance> nodeInstances = new ArrayList<RouteNodeInstance>(); |
274 | 0 | Set visitedNodeInstanceIds = new HashSet(); |
275 | 0 | for (Iterator iterator = document.getInitialRouteNodeInstances().iterator(); iterator.hasNext();) { |
276 | 0 | RouteNodeInstance initialNodeInstance = (RouteNodeInstance) iterator.next(); |
277 | 0 | flattenNodeInstanceGraph(nodeInstances, visitedNodeInstanceIds, initialNodeInstance, includeProcesses); |
278 | 0 | } |
279 | 0 | return nodeInstances; |
280 | |
} |
281 | |
|
282 | |
private void flattenNodeInstanceGraph(List nodeInstances, Set visitedNodeInstanceIds, RouteNodeInstance nodeInstance, boolean includeProcesses) { |
283 | |
|
284 | 0 | if (nodeInstance != null) { |
285 | 0 | if (visitedNodeInstanceIds.contains(nodeInstance.getRouteNodeInstanceId())) { |
286 | 0 | return; |
287 | |
} |
288 | 0 | if (includeProcesses && nodeInstance.getProcess() != null) { |
289 | 0 | flattenNodeInstanceGraph(nodeInstances, visitedNodeInstanceIds, nodeInstance.getProcess(), includeProcesses); |
290 | |
} |
291 | 0 | visitedNodeInstanceIds.add(nodeInstance.getRouteNodeInstanceId()); |
292 | 0 | nodeInstances.add(nodeInstance); |
293 | 0 | for (Iterator iterator = nodeInstance.getNextNodeInstances().iterator(); iterator.hasNext();) { |
294 | 0 | RouteNodeInstance nextNodeInstance = (RouteNodeInstance) iterator.next(); |
295 | 0 | flattenNodeInstanceGraph(nodeInstances, visitedNodeInstanceIds, nextNodeInstance, includeProcesses); |
296 | 0 | } |
297 | |
|
298 | |
} |
299 | |
|
300 | 0 | } |
301 | |
|
302 | |
public NodeGraphSearchResult searchNodeGraph(NodeGraphSearchCriteria criteria) { |
303 | 0 | NodeGraphContext context = new NodeGraphContext(); |
304 | 0 | if (criteria.getSearchDirection() == NodeGraphSearchCriteria.SEARCH_DIRECTION_BACKWARD) { |
305 | 0 | searchNodeGraphBackward(context, criteria.getMatcher(), null, criteria.getStartingNodeInstances()); |
306 | |
} else { |
307 | 0 | throw new UnsupportedOperationException("Search feature can only search backward currently."); |
308 | |
} |
309 | 0 | List exactPath = determineExactPath(context, criteria.getSearchDirection(), criteria.getStartingNodeInstances()); |
310 | 0 | return new NodeGraphSearchResult(context.getCurrentNodeInstance(), exactPath); |
311 | |
} |
312 | |
|
313 | |
private void searchNodeGraphBackward(NodeGraphContext context, NodeMatcher matcher, RouteNodeInstance previousNodeInstance, Collection nodeInstances) { |
314 | 0 | if (nodeInstances == null) { |
315 | 0 | return; |
316 | |
} |
317 | 0 | for (Iterator iterator = nodeInstances.iterator(); iterator.hasNext();) { |
318 | 0 | RouteNodeInstance nodeInstance = (RouteNodeInstance) iterator.next(); |
319 | 0 | context.setPreviousNodeInstance(previousNodeInstance); |
320 | 0 | context.setCurrentNodeInstance(nodeInstance); |
321 | 0 | searchNodeGraphBackward(context, matcher); |
322 | 0 | if (context.getResultNodeInstance() != null) { |
323 | |
|
324 | 0 | break; |
325 | |
} |
326 | 0 | } |
327 | 0 | } |
328 | |
|
329 | |
private void searchNodeGraphBackward(NodeGraphContext context, NodeMatcher matcher) { |
330 | 0 | RouteNodeInstance current = context.getCurrentNodeInstance(); |
331 | 0 | int numBranches = current.getNextNodeInstances().size(); |
332 | |
|
333 | 0 | if (numBranches > 1) { |
334 | |
|
335 | 0 | Integer joinCount = (Integer)context.getSplitState().get(current.getRouteNodeInstanceId()); |
336 | 0 | if (joinCount == null) { |
337 | 0 | joinCount = new Integer(0); |
338 | |
} |
339 | |
|
340 | 0 | if (context.getPreviousNodeInstance() != null) { |
341 | 0 | joinCount = new Integer(joinCount.intValue()+1); |
342 | |
} |
343 | 0 | context.getSplitState().put(current.getRouteNodeInstanceId(), joinCount); |
344 | |
|
345 | 0 | if (joinCount.intValue() != numBranches) { |
346 | 0 | return; |
347 | |
} |
348 | |
} |
349 | 0 | if (matcher.isMatch(context)) { |
350 | 0 | context.setResultNodeInstance(current); |
351 | |
} else { |
352 | 0 | context.getVisited().put(current.getRouteNodeInstanceId(), current); |
353 | 0 | searchNodeGraphBackward(context, matcher, current, current.getPreviousNodeInstances()); |
354 | |
} |
355 | 0 | } |
356 | |
|
357 | |
public List<RouteNodeInstance> getActiveNodeInstances(DocumentRouteHeaderValue document, String nodeName) { |
358 | 0 | Collection activeNodes = getActiveNodeInstances(document.getRouteHeaderId()); |
359 | 0 | List foundNodes = new ArrayList(); |
360 | 0 | for (Iterator iterator = activeNodes.iterator(); iterator.hasNext();) { |
361 | 0 | RouteNodeInstance nodeInstance = (RouteNodeInstance) iterator.next(); |
362 | 0 | if (nodeInstance.getName().equals(nodeName)) { |
363 | 0 | foundNodes.add(nodeInstance); |
364 | |
} |
365 | 0 | } |
366 | 0 | return foundNodes; |
367 | |
} |
368 | |
|
369 | |
private List determineExactPath(NodeGraphContext context, int searchDirection, Collection startingNodeInstances) { |
370 | 0 | List exactPath = new ArrayList(); |
371 | 0 | if (context.getResultNodeInstance() == null) { |
372 | 0 | exactPath.addAll(context.getVisited().values()); |
373 | |
} else { |
374 | 0 | determineExactPath(exactPath, new HashMap(), startingNodeInstances, context.getResultNodeInstance()); |
375 | |
} |
376 | 0 | if (NodeGraphSearchCriteria.SEARCH_DIRECTION_FORWARD == searchDirection) { |
377 | 0 | Collections.sort(exactPath, NODE_INSTANCE_BACKWARD_SORT); |
378 | |
} else { |
379 | 0 | Collections.sort(exactPath, NODE_INSTANCE_FORWARD_SORT); |
380 | |
} |
381 | 0 | return exactPath; |
382 | |
} |
383 | |
|
384 | |
private void determineExactPath(List exactPath, Map visited, Collection startingNodeInstances, RouteNodeInstance nodeInstance) { |
385 | 0 | if (nodeInstance == null) { |
386 | 0 | return; |
387 | |
} |
388 | 0 | if (visited.containsKey(nodeInstance.getRouteNodeInstanceId())) { |
389 | 0 | return; |
390 | |
} |
391 | 0 | visited.put(nodeInstance.getRouteNodeInstanceId(), nodeInstance); |
392 | 0 | exactPath.add(nodeInstance); |
393 | 0 | for (Iterator iterator = startingNodeInstances.iterator(); iterator.hasNext(); ) { |
394 | 0 | RouteNodeInstance startingNode = (RouteNodeInstance) iterator.next(); |
395 | 0 | if (startingNode.getRouteNodeInstanceId().equals(nodeInstance.getRouteNodeInstanceId())) { |
396 | 0 | return; |
397 | |
} |
398 | 0 | } |
399 | 0 | for (Iterator iterator = nodeInstance.getNextNodeInstances().iterator(); iterator.hasNext(); ) { |
400 | 0 | RouteNodeInstance nextNodeInstance = (RouteNodeInstance) iterator.next(); |
401 | 0 | determineExactPath(exactPath, visited, startingNodeInstances, nextNodeInstance); |
402 | 0 | } |
403 | 0 | } |
404 | |
|
405 | |
|
406 | |
|
407 | |
|
408 | |
|
409 | |
|
410 | |
|
411 | |
|
412 | 0 | private static class RouteNodeSorter implements Comparator { |
413 | |
public int compare(Object arg0, Object arg1) { |
414 | 0 | RouteNode rn1 = (RouteNode)arg0; |
415 | 0 | RouteNode rn2 = (RouteNode)arg1; |
416 | 0 | return rn1.getRouteNodeId().compareTo(rn2.getRouteNodeId()); |
417 | |
} |
418 | |
} |
419 | |
|
420 | 0 | private static class NodeInstanceIdSorter implements Comparator { |
421 | |
public int compare(Object arg0, Object arg1) { |
422 | 0 | RouteNodeInstance nodeInstance1 = (RouteNodeInstance)arg0; |
423 | 0 | RouteNodeInstance nodeInstance2 = (RouteNodeInstance)arg1; |
424 | 0 | return nodeInstance1.getRouteNodeInstanceId().compareTo(nodeInstance2.getRouteNodeInstanceId()); |
425 | |
} |
426 | |
} |
427 | |
|
428 | |
|
429 | |
public void deleteByRouteNodeInstance(RouteNodeInstance routeNodeInstance){ |
430 | |
|
431 | 0 | routeNodeDAO.deleteLinksToPreNodeInstances(routeNodeInstance); |
432 | |
|
433 | 0 | routeNodeDAO.deleteRouteNodeInstancesHereAfter(routeNodeInstance); |
434 | 0 | } |
435 | |
|
436 | |
public void deleteNodeStateById(Long nodeStateId){ |
437 | 0 | routeNodeDAO.deleteNodeStateById(nodeStateId); |
438 | 0 | } |
439 | |
|
440 | |
public void deleteNodeStates(List statesToBeDeleted){ |
441 | 0 | routeNodeDAO.deleteNodeStates(statesToBeDeleted); |
442 | 0 | } |
443 | |
|
444 | |
|
445 | |
|
446 | |
|
447 | |
public void revokeNodeInstance(DocumentRouteHeaderValue document, RouteNodeInstance nodeInstance) { |
448 | 0 | if (document == null) { |
449 | 0 | throw new IllegalArgumentException("Document must not be null."); |
450 | |
} |
451 | 0 | if (nodeInstance == null || nodeInstance.getRouteNodeInstanceId() == null) { |
452 | 0 | throw new IllegalArgumentException("In order to revoke a final approval node the node instance must be persisent and have an id."); |
453 | |
} |
454 | |
|
455 | 0 | Branch rootBranch = document.getRootBranch(); |
456 | 0 | BranchState state = null; |
457 | 0 | if (rootBranch != null) { |
458 | 0 | state = rootBranch.getBranchState(REVOKED_NODE_INSTANCES_STATE_KEY); |
459 | |
} |
460 | 0 | if (state == null) { |
461 | 0 | state = new BranchState(REVOKED_NODE_INSTANCES_STATE_KEY, ""); |
462 | 0 | rootBranch.addBranchState(state); |
463 | |
} |
464 | 0 | if (state.getValue() == null) { |
465 | 0 | state.setValue(""); |
466 | |
} |
467 | 0 | state.setValue(state.getValue() + nodeInstance.getRouteNodeInstanceId() + ","); |
468 | 0 | save(rootBranch); |
469 | 0 | } |
470 | |
|
471 | |
|
472 | |
|
473 | |
|
474 | |
|
475 | |
public List getRevokedNodeInstances(DocumentRouteHeaderValue document) { |
476 | 0 | if (document == null) { |
477 | 0 | throw new IllegalArgumentException("Document must not be null."); |
478 | |
} |
479 | 0 | List revokedNodeInstances = new ArrayList(); |
480 | |
|
481 | 0 | Branch rootBranch = document.getRootBranch(); |
482 | 0 | BranchState state = null; |
483 | 0 | if (rootBranch != null) { |
484 | 0 | state = rootBranch.getBranchState(REVOKED_NODE_INSTANCES_STATE_KEY); |
485 | |
} |
486 | 0 | if (state == null || Utilities.isEmpty(state.getValue())) { |
487 | 0 | return revokedNodeInstances; |
488 | |
} |
489 | 0 | String[] revokedNodes = state.getValue().split(","); |
490 | 0 | for (int index = 0; index < revokedNodes.length; index++) { |
491 | 0 | String revokedNodeInstanceIdValue = revokedNodes[index]; |
492 | 0 | Long revokedNodeInstanceId = Long.valueOf(revokedNodeInstanceIdValue); |
493 | 0 | RouteNodeInstance revokedNodeInstance = findRouteNodeInstanceById(revokedNodeInstanceId); |
494 | 0 | if (revokedNodeInstance == null) { |
495 | 0 | LOG.warn("Could not locate revoked RouteNodeInstance with the given id: " + revokedNodeInstanceId); |
496 | |
} else { |
497 | 0 | revokedNodeInstances.add(revokedNodeInstance); |
498 | |
} |
499 | |
} |
500 | 0 | return revokedNodeInstances; |
501 | |
} |
502 | |
|
503 | |
|
504 | |
} |