1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.kuali.rice.kew.engine.simulation;
18
19 import org.apache.log4j.MDC;
20 import org.kuali.rice.kew.actionitem.ActionItem;
21 import org.kuali.rice.kew.actionrequest.ActionRequestValue;
22 import org.kuali.rice.kew.actionrequest.KimGroupRecipient;
23 import org.kuali.rice.kew.actionrequest.KimPrincipalRecipient;
24 import org.kuali.rice.kew.actionrequest.Recipient;
25 import org.kuali.rice.kew.actionrequest.service.ActionRequestService;
26 import org.kuali.rice.kew.actiontaken.ActionTakenValue;
27 import org.kuali.rice.kew.doctype.bo.DocumentType;
28 import org.kuali.rice.kew.engine.ActivationContext;
29 import org.kuali.rice.kew.engine.EngineState;
30 import org.kuali.rice.kew.engine.ProcessContext;
31 import org.kuali.rice.kew.engine.RouteContext;
32 import org.kuali.rice.kew.engine.StandardWorkflowEngine;
33 import org.kuali.rice.kew.engine.node.Branch;
34 import org.kuali.rice.kew.engine.node.NoOpNode;
35 import org.kuali.rice.kew.engine.node.NodeJotter;
36 import org.kuali.rice.kew.engine.node.NodeType;
37 import org.kuali.rice.kew.engine.node.Process;
38 import org.kuali.rice.kew.engine.node.RequestsNode;
39 import org.kuali.rice.kew.engine.node.RouteNode;
40 import org.kuali.rice.kew.engine.node.RouteNodeInstance;
41 import org.kuali.rice.kew.engine.node.SimpleNode;
42 import org.kuali.rice.kew.exception.DocumentSimulatedRouteException;
43 import org.kuali.rice.kew.exception.InvalidActionTakenException;
44 import org.kuali.rice.kew.exception.ResourceUnavailableException;
45 import org.kuali.rice.kew.exception.WorkflowRuntimeException;
46 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
47 import org.kuali.rice.kew.service.KEWServiceLocator;
48 import org.kuali.rice.kew.util.KEWConstants;
49 import org.kuali.rice.kew.util.PerformanceLogger;
50 import org.kuali.rice.kew.util.Utilities;
51 import org.kuali.rice.kim.api.group.Group;
52 import org.kuali.rice.kim.bo.Person;
53
54 import java.io.ByteArrayInputStream;
55 import java.io.ByteArrayOutputStream;
56 import java.io.IOException;
57 import java.io.ObjectInputStream;
58 import java.io.ObjectOutputStream;
59 import java.io.Serializable;
60 import java.sql.Timestamp;
61 import java.util.ArrayList;
62 import java.util.Collections;
63 import java.util.HashSet;
64 import java.util.Iterator;
65 import java.util.List;
66 import java.util.Set;
67
68
69
70
71
72
73
74
75 public class SimulationEngine extends StandardWorkflowEngine implements SimulationWorkflowEngine {
76
77 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(SimulationEngine.class);
78
79 private SimulationCriteria criteria;
80 private SimulationResults results;
81
82 @Override
83 public SimulationResults runSimulation(SimulationCriteria criteria) throws Exception {
84 try {
85 this.criteria = criteria;
86 this.results = new SimulationResults();
87 validateCriteria(criteria);
88 process(criteria.getDocumentId(), null);
89 return results;
90 } finally {
91
92 this.criteria = null;
93 this.results = null;
94 }
95 }
96
97 @Override
98 public void process(String documentId, Long nodeInstanceId) throws InvalidActionTakenException, DocumentSimulatedRouteException {
99 RouteContext context = RouteContext.createNewRouteContext();
100 try {
101 ActivationContext activationContext = new ActivationContext(ActivationContext.CONTEXT_IS_SIMULATION);
102 if (criteria.isActivateRequests() == null) {
103 activationContext.setActivateRequests(!criteria.getActionsToTake().isEmpty());
104 } else {
105 activationContext.setActivateRequests(criteria.isActivateRequests().booleanValue());
106 }
107 context.setActivationContext(activationContext);
108 context.setEngineState(new EngineState());
109
110 RequestsNode.setSupressPolicyErrors(context);
111 DocumentRouteHeaderValue document = createSimulationDocument(documentId, criteria, context);
112 if ( (criteria.isDocumentSimulation()) && ( (document.isProcessed()) || (document.isFinal()) ) ) {
113 results.setDocument(document);
114 return;
115 }
116 routeDocumentIfNecessary(document, criteria, context);
117 results.setDocument(document);
118 documentId = document.getDocumentId();
119
120
121 boolean mdcHadDocId = MDC.get("docId") != null;
122 if (!mdcHadDocId) { MDC.put("docId", documentId); }
123
124 PerformanceLogger perfLog = new PerformanceLogger(documentId);
125 try {
126 if ( LOG.isInfoEnabled() ) {
127 LOG.info("Processing document for Simulation: " + documentId);
128 }
129 List<RouteNodeInstance> activeNodeInstances = getRouteNodeService().getActiveNodeInstances(document);
130 List<RouteNodeInstance> nodeInstancesToProcess = determineNodeInstancesToProcess(activeNodeInstances, criteria.getDestinationNodeName());
131
132 context.setDocument(document);
133
134 context.setEngineState(new EngineState());
135 ProcessContext processContext = new ProcessContext(true, nodeInstancesToProcess);
136 while (! nodeInstancesToProcess.isEmpty()) {
137 RouteNodeInstance nodeInstance = (RouteNodeInstance)nodeInstancesToProcess.remove(0);
138 if ( !nodeInstance.isActive() ) {
139 continue;
140 }
141 NodeJotter.jotNodeInstance(context.getDocument(), nodeInstance);
142 context.setNodeInstance(nodeInstance);
143 processContext = processNodeInstance(context, helper);
144 if (!hasReachedCompletion(processContext, context.getEngineState().getGeneratedRequests(), nodeInstance, criteria)) {
145 if (processContext.isComplete()) {
146 if (!processContext.getNextNodeInstances().isEmpty()) {
147 nodeInstancesToProcess.addAll(processContext.getNextNodeInstances());
148 }
149 context.getActivationContext().getSimulatedActionsTaken().addAll(processPotentialActionsTaken(context, document, nodeInstance, criteria));
150 }
151 } else {
152 context.getActivationContext().getSimulatedActionsTaken().addAll(processPotentialActionsTaken(context, document, nodeInstance, criteria));
153 }
154 }
155 List simulatedActionRequests = context.getEngineState().getGeneratedRequests();
156 Collections.sort(simulatedActionRequests, new Utilities.RouteLogActionRequestSorter());
157 results.setSimulatedActionRequests(simulatedActionRequests);
158 results.setSimulatedActionsTaken(context.getActivationContext().getSimulatedActionsTaken());
159 } catch (InvalidActionTakenException e) {
160 throw e;
161 } catch (Exception e) {
162 String errorMsg = "Error running simulation for document " + ((criteria.isDocumentSimulation()) ? "id " + documentId.toString() : "type " + criteria.getDocumentTypeName());
163 LOG.error(errorMsg,e);
164 throw new DocumentSimulatedRouteException(errorMsg, e);
165 } finally {
166 perfLog.log("Time to run simulation.");
167 RouteContext.clearCurrentRouteContext();
168
169 if (!mdcHadDocId) { MDC.remove("docID"); }
170 }
171 } finally {
172 RouteContext.releaseCurrentRouteContext();
173 }
174 }
175
176
177
178
179
180
181
182 private List<RouteNodeInstance> determineNodeInstancesToProcess(List<RouteNodeInstance> activeNodeInstances, String nodeName) throws InvalidActionTakenException {
183 if (org.apache.commons.lang.StringUtils.isEmpty(nodeName)) {
184 return activeNodeInstances;
185 }
186 List<RouteNodeInstance> nodeInstancesToProcess = new ArrayList<RouteNodeInstance>();
187 for (RouteNodeInstance nodeInstance : activeNodeInstances) {
188 if (nodeName.equals(nodeInstance.getName())) {
189
190 return new ArrayList<RouteNodeInstance>();
191 } else {
192 if (isNodeNameInPath(nodeName, nodeInstance)) {
193 nodeInstancesToProcess.add(nodeInstance);
194 }
195 }
196 }
197 if (nodeInstancesToProcess.size() == 0) {
198 throw new InvalidActionTakenException("Could not locate a node with the given name in the blanket approval path '" + nodeName + "'. " +
199 "The document is probably already passed the specified node or does not contain the node.");
200 }
201 return nodeInstancesToProcess;
202 }
203
204 private boolean isNodeNameInPath(String nodeName, RouteNodeInstance nodeInstance) {
205 boolean isInPath = false;
206 for (Iterator<RouteNode> iterator = nodeInstance.getRouteNode().getNextNodes().iterator(); iterator.hasNext();) {
207 RouteNode nextNode = (RouteNode) iterator.next();
208 isInPath = isInPath || isNodeNameInPath(nodeName, nextNode, new HashSet<Long>());
209 }
210 return isInPath;
211 }
212
213 private boolean isNodeNameInPath(String nodeName, RouteNode node, Set<Long> inspected) {
214 boolean isInPath = !inspected.contains(node.getRouteNodeId()) && node.getRouteNodeName().equals(nodeName);
215 inspected.add(node.getRouteNodeId());
216 if (helper.isSubProcessNode(node)) {
217 Process subProcess = node.getDocumentType().getNamedProcess(node.getRouteNodeName());
218 RouteNode subNode = subProcess.getInitialRouteNode();
219 isInPath = isInPath || isNodeNameInPath(nodeName, subNode, inspected);
220 }
221 for (Iterator<RouteNode> iterator = node.getNextNodes().iterator(); iterator.hasNext();) {
222 RouteNode nextNode = (RouteNode) iterator.next();
223 isInPath = isInPath || isNodeNameInPath(nodeName, nextNode, inspected);
224 }
225 return isInPath;
226 }
227
228 private boolean hasReachedCompletion(ProcessContext processContext, List actionRequests, RouteNodeInstance nodeInstance, SimulationCriteria criteria) {
229 if (!criteria.getDestinationRecipients().isEmpty()) {
230 for (Iterator iterator = actionRequests.iterator(); iterator.hasNext();) {
231 ActionRequestValue request = (ActionRequestValue) iterator.next();
232 for (Iterator<Recipient> userIt = criteria.getDestinationRecipients().iterator(); userIt.hasNext();) {
233 Recipient recipient = (Recipient) userIt.next();
234 if (request.isRecipientRoutedRequest(recipient)) {
235 if ( (org.apache.commons.lang.StringUtils.isEmpty(criteria.getDestinationNodeName())) || (criteria.getDestinationNodeName().equals(request.getNodeInstance().getName())) ) {
236 return true;
237 }
238 }
239 }
240 }
241 }
242 return (org.apache.commons.lang.StringUtils.isEmpty(criteria.getDestinationNodeName()) && processContext.isComplete() && processContext.getNextNodeInstances().isEmpty())
243 || nodeInstance.getRouteNode().getRouteNodeName().equals(criteria.getDestinationNodeName());
244 }
245
246 private List<ActionTakenValue> processPotentialActionsTaken(RouteContext routeContext, DocumentRouteHeaderValue routeHeader, RouteNodeInstance justProcessedNode, SimulationCriteria criteria) {
247 List<ActionTakenValue> actionsTaken = new ArrayList<ActionTakenValue>();
248 List requestsToCheck = new ArrayList();
249 requestsToCheck.addAll(routeContext.getEngineState().getGeneratedRequests());
250 requestsToCheck.addAll(routeHeader.getActionRequests());
251 List<ActionRequestValue> pendingActionRequestValues = getCriteriaActionsToDoByNodeName(requestsToCheck, justProcessedNode.getName());
252 List<ActionTakenValue> actionsToTakeForNode = generateActionsToTakeForNode(justProcessedNode.getName(), routeHeader, criteria, pendingActionRequestValues);
253
254 for (ActionTakenValue actionTaken : actionsToTakeForNode)
255 {
256 KEWServiceLocator.getActionRequestService().deactivateRequests(actionTaken, pendingActionRequestValues, routeContext.getActivationContext());
257 actionsTaken.add(actionTaken);
258
259 }
260 return actionsTaken;
261 }
262
263 private List<ActionTakenValue> generateActionsToTakeForNode(String nodeName, DocumentRouteHeaderValue routeHeader, SimulationCriteria criteria, List<ActionRequestValue> pendingActionRequests) {
264 List<ActionTakenValue> actions = new ArrayList<ActionTakenValue>();
265 if ( (criteria.getActionsToTake() != null) && (!criteria.getActionsToTake().isEmpty()) ) {
266 for (SimulationActionToTake simAction : criteria.getActionsToTake()) {
267 if (nodeName.equals(simAction.getNodeName())) {
268 actions.add(createDummyActionTaken(routeHeader, simAction.getUser(), simAction.getActionToPerform(), findDelegatorForActionRequests(pendingActionRequests)));
269 }
270 }
271 }
272 return actions;
273 }
274
275 private List<ActionRequestValue> getCriteriaActionsToDoByNodeName(List generatedRequests, String nodeName) {
276 List<ActionRequestValue> requests = new ArrayList<ActionRequestValue>();
277 for (Iterator iterator = generatedRequests.iterator(); iterator.hasNext();) {
278 ActionRequestValue request = (ActionRequestValue) iterator.next();
279 if ( (request.isPending()) && request.getNodeInstance() != null && nodeName.equals(request.getNodeInstance().getName())) {
280 requests.add(request);
281 }
282 }
283 return requests;
284 }
285
286 private void validateCriteria(SimulationCriteria criteria) {
287 if (criteria.getDocumentId() == null && org.apache.commons.lang.StringUtils.isEmpty(criteria.getDocumentTypeName())) {
288 throw new IllegalArgumentException("No document type name or document id given, cannot simulate a document without a document type name or a document id.");
289 }
290 if (criteria.getXmlContent() == null) {
291 criteria.setXmlContent("");
292 }
293 }
294
295
296
297
298
299
300
301
302 private DocumentRouteHeaderValue createSimulationDocument(String documentId, SimulationCriteria criteria, RouteContext context) {
303 DocumentRouteHeaderValue document = null;
304 if (criteria.isDocumentSimulation()) {
305 document = getDocumentForSimulation(documentId);
306 if (!org.apache.commons.lang.StringUtils.isEmpty(criteria.getXmlContent())) {
307 document.setDocContent(criteria.getXmlContent());
308 }
309 } else if (criteria.isDocumentTypeSimulation()) {
310 DocumentType documentType = KEWServiceLocator.getDocumentTypeService().findByName(criteria.getDocumentTypeName());
311 if (documentType == null) {
312 throw new IllegalArgumentException("Specified document type could not be found for name '"+criteria.getDocumentTypeName()+"'");
313 }
314 documentId = context.getEngineState().getNextSimulationId().toString();
315 document = new DocumentRouteHeaderValue();
316 context.setDocument(document);
317 document.setDocumentId(documentId);
318 document.setCreateDate(new Timestamp(System.currentTimeMillis()));
319 document.setDocContent(criteria.getXmlContent());
320 document.setDocRouteLevel(new Integer(0));
321 document.setDocumentTypeId(documentType.getDocumentTypeId());
322 document.setDocRouteStatus(KEWConstants.ROUTE_HEADER_INITIATED_CD);
323 initializeDocument(document);
324 }
325 if (document == null) {
326 throw new IllegalArgumentException("Workflow simulation engine could not locate document with id "+documentId);
327 }
328 for (ActionRequestValue actionRequest : document.getActionRequests()) {
329 actionRequest = (ActionRequestValue) deepCopy(actionRequest);
330 document.getSimulatedActionRequests().add(actionRequest);
331 for (ActionItem actionItem : actionRequest.getActionItems()) {
332 actionRequest.getSimulatedActionItems().add((ActionItem) deepCopy(actionItem));
333 }
334 }
335 context.setDocument(document);
336 installSimulationNodeInstances(context, criteria);
337 return document;
338 }
339
340 private DocumentRouteHeaderValue getDocumentForSimulation(String documentId) {
341 DocumentRouteHeaderValue document = getRouteHeaderService().getRouteHeader(documentId);
342 return (DocumentRouteHeaderValue)deepCopy(document);
343 }
344
345 private Serializable deepCopy(Serializable src) {
346 Serializable obj = null;
347 if (src != null) {
348 ObjectOutputStream oos = null;
349 ObjectInputStream ois = null;
350 try {
351 ByteArrayOutputStream serializer = new ByteArrayOutputStream();
352 oos = new ObjectOutputStream(serializer);
353 oos.writeObject(src);
354
355 ByteArrayInputStream deserializer = new ByteArrayInputStream(serializer.toByteArray());
356 ois = new ObjectInputStream(deserializer);
357 obj = (Serializable) ois.readObject();
358 }
359 catch (IOException e) {
360 throw new RuntimeException("unable to complete deepCopy from src '" + src.toString() + "'", e);
361 }
362 catch (ClassNotFoundException e) {
363 throw new RuntimeException("unable to complete deepCopy from src '" + src.toString() + "'", e);
364 }
365 finally {
366 try {
367 if (oos != null) {
368 oos.close();
369 }
370 if (ois != null) {
371 ois.close();
372 }
373 }
374 catch (IOException e) {
375
376 }
377 }
378 }
379 return obj;
380 }
381
382 private void routeDocumentIfNecessary(DocumentRouteHeaderValue document, SimulationCriteria criteria, RouteContext routeContext) throws InvalidActionTakenException {
383 if (criteria.getRoutingUser() != null) {
384 ActionTakenValue action = createDummyActionTaken(document, criteria.getRoutingUser(), KEWConstants.ACTION_TAKEN_ROUTED_CD, null);
385 routeContext.getActivationContext().getSimulatedActionsTaken().add(action);
386 simulateDocumentRoute(action, document, criteria.getRoutingUser(), routeContext);
387 }
388 }
389
390
391
392
393
394
395 private void installSimulationNodeInstances(RouteContext context, SimulationCriteria criteria) {
396 DocumentRouteHeaderValue document = context.getDocument();
397 List<RouteNode> simulationNodes = new ArrayList<RouteNode>();
398 if (!criteria.getNodeNames().isEmpty()) {
399 for (String nodeName : criteria.getNodeNames()) {
400 if ( LOG.isDebugEnabled() ) {
401 LOG.debug("Installing simulation starting node '"+nodeName+"'");
402 }
403 List<RouteNode> nodes = KEWServiceLocator.getRouteNodeService().getFlattenedNodes(document.getDocumentType(), true);
404 boolean foundNode = false;
405 for (RouteNode node : nodes) {
406 if (node.getRouteNodeName().equals(nodeName)) {
407 simulationNodes.add(node);
408 foundNode = true;
409 break;
410 }
411 }
412 if (!foundNode) {
413 throw new IllegalArgumentException("Could not find node on the document type for the given name '"+nodeName+"'");
414 }
415 }
416 } else if (!criteria.getRuleTemplateNames().isEmpty()) {
417 List<RouteNode> nodes = KEWServiceLocator.getRouteNodeService().getFlattenedNodes(document.getDocumentType(), true);
418 for (String ruleTemplateName : criteria.getRuleTemplateNames()) {
419 boolean foundNode = false;
420 for (RouteNode node : nodes) {
421 String routeMethodName = node.getRouteMethodName();
422 if (node.isFlexRM() && ruleTemplateName.equals(routeMethodName)) {
423 simulationNodes.add(node);
424 foundNode = true;
425 break;
426 }
427 }
428 if (!foundNode) {
429 throw new IllegalArgumentException("Could not find node on the document type with the given rule template name '"+ruleTemplateName+"'");
430 }
431 }
432 } else if (criteria.isFlattenNodes()) {
433
434 List<RouteNode> nodes = KEWServiceLocator.getRouteNodeService().getFlattenedNodes(document.getDocumentType(), true);
435 for ( RouteNode node : nodes ) {
436 try {
437 if ( NodeType.fromNode( node ).isTypeOf( SimpleNode.class )
438 && !NodeType.fromNode( node ).isTypeOf( NoOpNode.class ) ) {
439 simulationNodes.add(node);
440 }
441 } catch (ResourceUnavailableException ex) {
442 LOG.warn( "Unable to determine node type in simulator: " + ex.getMessage() );
443 }
444 }
445 } else {
446
447 return;
448 }
449
450
451 Branch defaultBranch = document.getInitialRouteNodeInstances().get(0).getBranch();
452
453 document.getInitialRouteNodeInstances().clear();
454
455 RouteNodeInstance currentNodeInstance = null;
456 for (RouteNode simulationNode : simulationNodes) {
457 RouteNodeInstance nodeInstance = helper.getNodeFactory().createRouteNodeInstance(document.getDocumentId(), simulationNode);
458 nodeInstance.setBranch(defaultBranch);
459 if (currentNodeInstance == null) {
460 document.getInitialRouteNodeInstances().add(nodeInstance);
461 nodeInstance.setActive(true);
462 saveNode(context, nodeInstance);
463 } else {
464 currentNodeInstance.addNextNodeInstance(nodeInstance);
465 saveNode(context, currentNodeInstance);
466 }
467 currentNodeInstance = nodeInstance;
468 }
469 installSimulationTerminationNode(context, document.getDocumentType(), currentNodeInstance);
470 }
471
472 private void installSimulationTerminationNode(RouteContext context, DocumentType documentType, RouteNodeInstance lastNodeInstance) {
473 RouteNode terminationNode = new RouteNode();
474 terminationNode.setDocumentType(documentType);
475 terminationNode.setDocumentTypeId(documentType.getDocumentTypeId());
476 terminationNode.setNodeType(NoOpNode.class.getName());
477 terminationNode.setRouteNodeName("SIMULATION_TERMINATION_NODE");
478 RouteNodeInstance terminationNodeInstance = helper.getNodeFactory().createRouteNodeInstance(lastNodeInstance.getDocumentId(), terminationNode);
479 terminationNodeInstance.setBranch(lastNodeInstance.getBranch());
480 lastNodeInstance.addNextNodeInstance(terminationNodeInstance);
481 saveNode(context, lastNodeInstance);
482 }
483
484
485 private void simulateDocumentRoute(ActionTakenValue actionTaken, DocumentRouteHeaderValue document, Person user, RouteContext routeContext) throws InvalidActionTakenException {
486 if (document.isRouted()) {
487 throw new WorkflowRuntimeException("Document can not simulate a route if it has already been routed");
488 }
489 ActionRequestService actionRequestService = KEWServiceLocator.getActionRequestService();
490
491 List<ActionRequestValue> actionRequests = new ArrayList<ActionRequestValue>();
492 for (Iterator iter = actionRequestService.findPendingByDoc(document.getDocumentId()).iterator(); iter.hasNext();) {
493 ActionRequestValue arv = (ActionRequestValue) deepCopy( (ActionRequestValue) iter.next() );
494 for (ActionItem actionItem : arv.getActionItems()) {
495 arv.getSimulatedActionItems().add((ActionItem) deepCopy(actionItem));
496 }
497 actionRequests.add(arv);
498 }
499
500 LOG.debug("Simulate Deactivating all pending action requests");
501
502 for (Iterator<ActionRequestValue> iter = actionRequests.iterator(); iter.hasNext();) {
503 ActionRequestValue actionRequest = (ActionRequestValue) iter.next();
504
505 if ( (user.getPrincipalId().equals(actionRequest.getPrincipalId())) && (actionRequest.isActive()) ) {
506 actionRequestService.deactivateRequest(actionTaken, actionRequest, routeContext.getActivationContext());
507 }
508
509 else if (KEWConstants.SAVED_REQUEST_RESPONSIBILITY_ID.equals(actionRequest.getResponsibilityId())) {
510 actionRequestService.deactivateRequest(actionTaken, actionRequest, routeContext.getActivationContext());
511 }
512 }
513
514
515 document.markDocumentEnroute();
516
517
518
519 }
520
521 private ActionTakenValue createDummyActionTaken(DocumentRouteHeaderValue routeHeader, Person userToPerformAction, String actionToPerform, Recipient delegator) {
522 ActionTakenValue val = new ActionTakenValue();
523 val.setActionTaken(actionToPerform);
524 if (KEWConstants.ACTION_TAKEN_ROUTED_CD.equals(actionToPerform)) {
525 val.setActionTaken(KEWConstants.ACTION_TAKEN_COMPLETED_CD);
526 }
527 val.setAnnotation("");
528 val.setDocVersion(routeHeader.getDocVersion());
529 val.setDocumentId(routeHeader.getDocumentId());
530 val.setPrincipalId(userToPerformAction.getPrincipalId());
531
532 if (delegator != null) {
533 if (delegator instanceof KimPrincipalRecipient) {
534 val.setDelegatorPrincipalId(((KimPrincipalRecipient) delegator).getPrincipalId());
535 } else if (delegator instanceof KimGroupRecipient) {
536 Group group = ((KimGroupRecipient) delegator).getGroup();
537 val.setDelegatorGroupId(group.getId());
538 } else{
539 throw new IllegalArgumentException("Invalid Recipient type received: " + delegator.getClass().getName());
540 }
541 }
542
543
544 val.setCurrentIndicator(Boolean.TRUE);
545 return val;
546 }
547
548
549
550
551
552
553 private Recipient findDelegatorForActionRequests(List<ActionRequestValue> actionRequests) {
554 return KEWServiceLocator.getActionRequestService().findDelegator(actionRequests);
555 }
556
557
558
559
560
561
562
563 @Override
564 protected void saveNode(RouteContext context, RouteNodeInstance nodeInstance) {
565
566
567 if (nodeInstance.getRouteNodeInstanceId() == null) {
568 nodeInstance.setRouteNodeInstanceId(context.getEngineState().getNextSimulationId());
569 }
570
571
572
573 for (Iterator<RouteNodeInstance> iterator = nodeInstance.getNextNodeInstances().iterator(); iterator.hasNext();) {
574 RouteNodeInstance routeNodeInstance = (RouteNodeInstance) iterator.next();
575 if (routeNodeInstance.getRouteNodeInstanceId() == null) {
576 routeNodeInstance.setRouteNodeInstanceId(context.getEngineState().getNextSimulationId());
577 }
578 }
579 if (nodeInstance.getProcess() != null && nodeInstance.getProcess().getRouteNodeInstanceId() == null) {
580 nodeInstance.getProcess().setRouteNodeInstanceId(context.getEngineState().getNextSimulationId());
581 }
582 if (nodeInstance.getBranch() != null && nodeInstance.getBranch().getBranchId() == null) {
583 nodeInstance.getBranch().setBranchId(context.getEngineState().getNextSimulationId());
584 }
585 }
586
587 }