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 java.util.ArrayList;
19 import java.util.Collections;
20 import java.util.Iterator;
21 import java.util.List;
22
23 import org.apache.commons.collections.CollectionUtils;
24 import org.apache.commons.lang.StringUtils;
25 import org.apache.log4j.MDC;
26 import org.kuali.rice.kew.actionitem.ActionItem;
27 import org.kuali.rice.kew.actionrequest.ActionRequestValue;
28 import org.kuali.rice.kew.api.action.ActionRequestStatus;
29 import org.kuali.rice.kew.api.exception.WorkflowException;
30 import org.kuali.rice.kew.engine.RouteContext;
31 import org.kuali.rice.kew.engine.RouteHelper;
32 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
33 import org.kuali.rice.kew.service.KEWServiceLocator;
34 import org.kuali.rice.kew.api.KewApiConstants;
35 import org.kuali.rice.kew.util.PerformanceLogger;
36 import org.kuali.rice.kew.util.Utilities;
37
38
39
40
41
42
43
44
45 public class RequestActivationNode extends RequestActivationNodeBase {
46
47 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger( RequestActivationNode.class );
48 private static long generatedRequestPriority = 0;
49
50 public SimpleResult process(RouteContext routeContext, RouteHelper routeHelper) throws Exception {
51 DocumentRouteHeaderValue document = routeContext.getDocument();
52 RouteNodeInstance nodeInstance = routeContext.getNodeInstance();
53 if (routeContext.isSimulation()) {
54 if (routeContext.getActivationContext().isActivateRequests()) {
55 activateRequests(routeContext, document, nodeInstance);
56 }
57 return new SimpleResult(true);
58 } else if (!activateRequests(routeContext, document, nodeInstance) && shouldTransition(document, nodeInstance)) {
59 return new SimpleResult(true);
60 } else {
61 return new SimpleResult(false);
62 }
63 }
64
65 public boolean shouldTransition(DocumentRouteHeaderValue document, RouteNodeInstance nodeInstance) {
66 List requests = KEWServiceLocator.getActionRequestService().findPendingRootRequestsByDocIdAtRouteNode(document.getDocumentId(), nodeInstance.getRouteNodeInstanceId());
67 boolean shouldTransition = true;
68 for (Iterator iterator = requests.iterator(); iterator.hasNext();) {
69 ActionRequestValue request = (ActionRequestValue) iterator.next();
70 if (request.isApproveOrCompleteRequest()) {
71 shouldTransition = false;
72 break;
73 }
74 }
75 return shouldTransition;
76 }
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92 public boolean activateRequests(RouteContext context, DocumentRouteHeaderValue document, RouteNodeInstance nodeInstance) throws WorkflowException {
93 MDC.put("docId", document.getDocumentId());
94 PerformanceLogger performanceLogger = new PerformanceLogger(document.getDocumentId());
95 List<ActionItem> generatedActionItems = new ArrayList<ActionItem>();
96 List<ActionRequestValue> requests = new ArrayList<ActionRequestValue>();
97 if (context.isSimulation()) {
98 for (ActionRequestValue ar : context.getDocument().getActionRequests()) {
99
100 if (ar.getCurrentIndicator()
101 && (ActionRequestStatus.INITIALIZED.getCode().equals(ar.getStatus()) || ActionRequestStatus.ACTIVATED.getCode().equals(ar.getStatus()))
102 && ar.getNodeInstance().getRouteNodeInstanceId().equals(nodeInstance.getRouteNodeInstanceId())
103 && ar.getParentActionRequest() == null) {
104 requests.add(ar);
105 }
106 }
107 requests.addAll(context.getEngineState().getGeneratedRequests());
108 } else {
109 requests = KEWServiceLocator.getActionRequestService().findPendingRootRequestsByDocIdAtRouteNode(document.getDocumentId(), nodeInstance.getRouteNodeInstanceId());
110 }
111 if ( LOG.isDebugEnabled() ) {
112 LOG.debug("Pending Root Requests " + requests.size());
113 }
114 boolean activatedApproveRequest = activateRequestsCustom( context, requests, generatedActionItems, document, nodeInstance );
115
116
117
118 notify(context, generatedActionItems, nodeInstance);
119
120 performanceLogger.log("Time to activate requests.");
121 return activatedApproveRequest;
122 }
123
124 protected boolean activateRequestsCustom( RouteContext context, List<ActionRequestValue> requests, List<ActionItem> generatedActionItems,
125 DocumentRouteHeaderValue document, RouteNodeInstance nodeInstance) throws WorkflowException {
126 Collections.sort(requests, new Utilities.PrioritySorter());
127 String activationType = nodeInstance.getRouteNode().getActivationType();
128 if (StringUtils.isBlank(activationType)) {
129
130 activationType = KewApiConstants.ROUTE_LEVEL_SEQUENCE;
131 }
132 boolean isParallel = KewApiConstants.ROUTE_LEVEL_PARALLEL.equals(activationType);
133 boolean isPriorityParallel = KewApiConstants.ROUTE_LEVEL_PRIORITY_PARALLEL.equals(activationType);
134 boolean isSequential = KewApiConstants.ROUTE_LEVEL_SEQUENCE.equals(activationType);
135
136 boolean activatedApproveRequest = false;
137 if (CollectionUtils.isNotEmpty(requests)) {
138
139 int currentPriority = requests.get(0).getPriority();
140 for (ActionRequestValue request : requests ) {
141 if (request.getParentActionRequest() != null || request.getNodeInstance() == null) {
142
143
144 continue;
145 }
146 if (activatedApproveRequest && (!context.isSimulation() || !context.getActivationContext().isActivateRequests())) {
147 if (isSequential || (isPriorityParallel && request.getPriority() != currentPriority)) {
148 break;
149 }
150 }
151 currentPriority = request.getPriority();
152 if (request.isActive()) {
153 activatedApproveRequest = activatedApproveRequest || request.isApproveOrCompleteRequest();
154 continue;
155 }
156 logProcessingMessage(request);
157 if ( LOG.isDebugEnabled() ) {
158 LOG.debug("Activating request: " + request);
159 }
160 activatedApproveRequest = activateRequest(context, request, nodeInstance, generatedActionItems) || activatedApproveRequest;
161 }
162 }
163 return activatedApproveRequest;
164 }
165
166 protected boolean activateRequest(RouteContext context, ActionRequestValue actionRequest, RouteNodeInstance nodeInstance, List generatedActionItems) {
167 if (actionRequest.isRoleRequest()) {
168 List actionRequests = KEWServiceLocator.getActionRequestService().findPendingRootRequestsByDocIdAtRouteNode(actionRequest.getDocumentId(), nodeInstance.getRouteNodeInstanceId());
169 for (Iterator iterator = actionRequests.iterator(); iterator.hasNext();) {
170 ActionRequestValue siblingRequest = (ActionRequestValue) iterator.next();
171 if (actionRequest.getRoleName().equals(siblingRequest.getRoleName())) {
172 generatedActionItems.addAll(KEWServiceLocator.getActionRequestService().activateRequestNoNotification(siblingRequest, context.getActivationContext()));
173 }
174 }
175 }
176 generatedActionItems.addAll(KEWServiceLocator.getActionRequestService().activateRequestNoNotification(actionRequest, context.getActivationContext()));
177 return actionRequest.isApproveOrCompleteRequest() && ! actionRequest.isDone();
178 }
179
180 protected void saveActionRequest(RouteContext context, ActionRequestValue actionRequest) {
181 if (!context.isSimulation()) {
182 KEWServiceLocator.getActionRequestService().saveActionRequest(actionRequest);
183 } else {
184 actionRequest.setActionRequestId(String.valueOf(generatedRequestPriority++));
185 context.getEngineState().getGeneratedRequests().add(actionRequest);
186 }
187
188 }
189
190 protected void saveDocument(RouteContext context, DocumentRouteHeaderValue document) {
191 if (!context.isSimulation()) {
192 KEWServiceLocator.getRouteHeaderService().saveRouteHeader(document);
193 }
194 }
195
196 protected void logProcessingMessage(ActionRequestValue request) {
197 if (LOG.isDebugEnabled()) {
198 RouteNodeInstance nodeInstance = request.getNodeInstance();
199 StringBuffer buffer = new StringBuffer();
200 buffer.append("Processing AR: ").append(request.getActionRequestId()).append("\n");
201 buffer.append("AR Node Name: ").append(nodeInstance != null ? nodeInstance.getName() : "null").append("\n");
202 buffer.append("AR RouteLevel: ").append(request.getRouteLevel()).append("\n");
203 buffer.append("AR Request Code: ").append(request.getActionRequested()).append("\n");
204 buffer.append("AR Request priority: ").append(request.getPriority()).append("\n");
205 LOG.debug(buffer);
206 }
207 }
208
209 }