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 public class RequestActivationNode extends RequestActivationNodeBase {
45
46 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(RequestActivationNode.class);
47 private static long generatedRequestPriority = 0;
48
49 @Override
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,
59 nodeInstance)) {
60 return new SimpleResult(true);
61 } else {
62 return new SimpleResult(false);
63 }
64 }
65
66
67
68
69
70
71
72
73
74
75
76
77 protected boolean shouldTransition(DocumentRouteHeaderValue document, RouteNodeInstance nodeInstance) {
78 List<ActionRequestValue> requests =
79 KEWServiceLocator.getActionRequestService().findPendingRootRequestsByDocIdAtRouteNode(
80 document.getDocumentId(), nodeInstance.getRouteNodeInstanceId());
81 boolean shouldTransition = true;
82 for (ActionRequestValue request : requests) {
83 if (request.isApproveOrCompleteRequest()) {
84 shouldTransition = false;
85 break;
86 }
87 }
88 return shouldTransition;
89 }
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109 public boolean activateRequests(RouteContext context, DocumentRouteHeaderValue document,
110 RouteNodeInstance nodeInstance) throws WorkflowException {
111 MDC.put("docId", document.getDocumentId());
112 PerformanceLogger performanceLogger = new PerformanceLogger(document.getDocumentId());
113 List<ActionItem> generatedActionItems = new ArrayList<ActionItem>();
114 List<ActionRequestValue> requests = new ArrayList<ActionRequestValue>();
115 if (context.isSimulation()) {
116 for (ActionRequestValue ar : context.getDocument().getActionRequests()) {
117
118 if (ar.getCurrentIndicator()
119 && (ActionRequestStatus.INITIALIZED.getCode().equals(ar.getStatus())
120 || ActionRequestStatus.ACTIVATED.getCode().equals(ar.getStatus()))
121 && ar.getNodeInstance().getRouteNodeInstanceId().equals(nodeInstance.getRouteNodeInstanceId())
122 && ar.getParentActionRequest() == null) {
123 requests.add(ar);
124 }
125 }
126 requests.addAll(context.getEngineState().getGeneratedRequests());
127 } else {
128 requests = KEWServiceLocator.getActionRequestService().findPendingRootRequestsByDocIdAtRouteNode(
129 document.getDocumentId(), nodeInstance.getRouteNodeInstanceId());
130 }
131 if (LOG.isDebugEnabled()) {
132 LOG.debug("Pending Root Requests " + requests.size());
133 }
134 boolean activatedApproveRequest = activateRequestsCustom(context, requests, generatedActionItems, document,
135 nodeInstance);
136
137
138
139 notify(context, generatedActionItems, nodeInstance);
140
141 performanceLogger.log("Time to activate requests.");
142 return activatedApproveRequest;
143 }
144
145 protected boolean activateRequestsCustom(RouteContext context, List<ActionRequestValue> requests,
146 List<ActionItem> generatedActionItems, DocumentRouteHeaderValue document,
147 RouteNodeInstance nodeInstance) throws WorkflowException {
148
149 requests = new ArrayList<ActionRequestValue>(requests);
150 Collections.sort(requests, new Utilities.PrioritySorter());
151 String activationType = nodeInstance.getRouteNode().getActivationType();
152 if (StringUtils.isBlank(activationType)) {
153
154 activationType = KewApiConstants.ROUTE_LEVEL_SEQUENCE;
155 }
156 boolean isParallel = KewApiConstants.ROUTE_LEVEL_PARALLEL.equals(activationType);
157 boolean isPriorityParallel = KewApiConstants.ROUTE_LEVEL_PRIORITY_PARALLEL.equals(activationType);
158 boolean isSequential = KewApiConstants.ROUTE_LEVEL_SEQUENCE.equals(activationType);
159
160 boolean activatedApproveRequest = false;
161 if (CollectionUtils.isNotEmpty(requests)) {
162
163 int currentPriority = requests.get(0).getPriority();
164 for (ActionRequestValue request : requests) {
165 if (request.getParentActionRequest() != null || request.getNodeInstance() == null) {
166
167
168 continue;
169 }
170 if (activatedApproveRequest && (!context.isSimulation() || !context.getActivationContext()
171 .isActivateRequests())) {
172 if (isSequential || (isPriorityParallel && request.getPriority() != currentPriority)) {
173 break;
174 }
175 }
176 currentPriority = request.getPriority();
177 if (request.isActive()) {
178 activatedApproveRequest = activatedApproveRequest || request.isApproveOrCompleteRequest();
179 continue;
180 }
181 logProcessingMessage(request);
182 if (LOG.isDebugEnabled()) {
183 LOG.debug("Activating request: " + request);
184 }
185 activatedApproveRequest = activateRequest(context, request, nodeInstance, generatedActionItems)
186 || activatedApproveRequest;
187 }
188 }
189 return activatedApproveRequest;
190 }
191
192 protected boolean activateRequest(RouteContext context, ActionRequestValue actionRequest,
193 RouteNodeInstance nodeInstance, List<ActionItem> generatedActionItems) {
194 if (actionRequest.isRoleRequest()) {
195 List<ActionRequestValue> actionRequests =
196 KEWServiceLocator.getActionRequestService().findPendingRootRequestsByDocIdAtRouteNode(
197 actionRequest.getDocumentId(), nodeInstance.getRouteNodeInstanceId());
198 for (ActionRequestValue siblingRequest : actionRequests) {
199 if (actionRequest.getRoleName().equals(siblingRequest.getRoleName())) {
200 KEWServiceLocator.getActionRequestService().activateRequestNoNotification(siblingRequest,
201 context.getActivationContext());
202
203 generatedActionItems.addAll(context.getActivationContext().getGeneratedActionItems());
204 }
205 }
206 }
207 actionRequest = KEWServiceLocator.getActionRequestService().activateRequestNoNotification(actionRequest,
208 context.getActivationContext());
209
210 generatedActionItems.addAll(context.getActivationContext().getGeneratedActionItems());
211 return actionRequest.isApproveOrCompleteRequest() && !actionRequest.isDone();
212 }
213
214 protected ActionRequestValue saveActionRequest(RouteContext context, ActionRequestValue actionRequest) {
215 if (!context.isSimulation()) {
216 return KEWServiceLocator.getActionRequestService().saveActionRequest(actionRequest);
217 } else {
218 actionRequest.setActionRequestId(String.valueOf(generatedRequestPriority++));
219 context.getEngineState().getGeneratedRequests().add(actionRequest);
220 return actionRequest;
221 }
222
223 }
224
225 protected DocumentRouteHeaderValue saveDocument(RouteContext context, DocumentRouteHeaderValue document) {
226 if (!context.isSimulation()) {
227 document = KEWServiceLocator.getRouteHeaderService().saveRouteHeader(document);
228 context.setDocument(document);
229 }
230 return document;
231 }
232
233 protected void logProcessingMessage(ActionRequestValue request) {
234 if (LOG.isDebugEnabled()) {
235 RouteNodeInstance nodeInstance = request.getNodeInstance();
236 StringBuffer buffer = new StringBuffer();
237 buffer.append("Processing AR: ").append(request.getActionRequestId()).append("\n");
238 buffer.append("AR Node Name: ").append(nodeInstance != null ? nodeInstance.getName() : "null").append("\n");
239 buffer.append("AR RouteLevel: ").append(request.getRouteLevel()).append("\n");
240 buffer.append("AR Request Code: ").append(request.getActionRequested()).append("\n");
241 buffer.append("AR Request priority: ").append(request.getPriority()).append("\n");
242 LOG.debug(buffer);
243 }
244 }
245
246 }