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 }