View Javadoc
1   /**
2    * Copyright 2005-2016 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.kew.actions;
17  
18  import org.kuali.rice.kew.actionrequest.ActionRequestValue;
19  import org.kuali.rice.kew.actiontaken.ActionTakenValue;
20  import org.kuali.rice.kew.api.KewApiConstants;
21  import org.kuali.rice.kew.api.KewApiServiceLocator;
22  import org.kuali.rice.kew.api.exception.InvalidActionTakenException;
23  import org.kuali.rice.kew.doctype.bo.DocumentType;
24  import org.kuali.rice.kew.api.exception.WorkflowException;
25  import org.kuali.rice.kew.exception.WorkflowServiceErrorException;
26  import org.kuali.rice.kew.exception.WorkflowServiceErrorImpl;
27  import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
28  import org.kuali.rice.kew.service.KEWServiceLocator;
29  import org.kuali.rice.kim.api.identity.principal.PrincipalContract;
30  import org.kuali.rice.kew.engine.node.RouteNodeInstance;
31  
32  import java.util.ArrayList;
33  import java.util.List;
34  
35  
36  /**
37   * Super class for all super user action takens.
38   *
39   * @author Kuali Rice Team (rice.collab@kuali.org)
40   */
41  abstract class SuperUserActionTakenEvent extends ActionTakenEvent {
42  
43      private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(SuperUserActionTakenEvent.class);
44  
45      protected final String superUserAction;
46      //protected DocumentRouteStatusChange event;
47      private ActionRequestValue actionRequest;
48      public static String AUTHORIZATION = "general.routing.superuser.notAuthorized";
49  
50      protected SuperUserActionTakenEvent(String actionTakenCode, String superUserAction, DocumentRouteHeaderValue routeHeader, PrincipalContract principal) {
51          super(actionTakenCode, routeHeader, principal);
52          this.superUserAction = superUserAction;
53      }
54  
55      protected SuperUserActionTakenEvent(String actionTakenCode, String superUserAction, DocumentRouteHeaderValue routeHeader, PrincipalContract principal, String annotation, boolean runPostProcessor) {
56          super(actionTakenCode, routeHeader, principal, annotation, runPostProcessor);
57          this.superUserAction = superUserAction;
58      }
59  
60      /* (non-Javadoc)
61       * @see org.kuali.rice.kew.actions.ActionTakenEvent#validateActionRules()
62       */
63      @Override
64      public String validateActionRules() {
65          DocumentType docType = getRouteHeader().getDocumentType();
66          String principalId =   getPrincipal().getPrincipalId();
67          String docId =  getRouteHeader().getDocumentId();
68          List<RouteNodeInstance> currentNodeInstances = KEWServiceLocator.getRouteNodeService().getCurrentNodeInstances(docId);
69          String documentStatus =  KewApiServiceLocator.getWorkflowDocumentService().getDocumentStatus(docId).getCode();
70  
71          boolean canAdministerRouting = KEWServiceLocator.getDocumentTypePermissionService().canAdministerRouting(principalId, docType);
72          boolean canSuperUserApproveSingleActionRequest = ((KEWServiceLocator.getDocumentTypePermissionService().canSuperUserApproveSingleActionRequest
73                  (principalId, docType, currentNodeInstances, documentStatus)) && ((KewApiConstants.SUPER_USER_ACTION_REQUEST_APPROVE).equals(getSuperUserAction())));
74          boolean canSuperUserApproveDocument = ((KEWServiceLocator.getDocumentTypePermissionService().canSuperUserApproveDocument
75                  (principalId, docType, currentNodeInstances, documentStatus)) && ((KewApiConstants.SUPER_USER_APPROVE).equals(getSuperUserAction())));
76          boolean canSuperUserDisapproveDocument = ((KEWServiceLocator.getDocumentTypePermissionService().canSuperUserDisapproveDocument
77                  (principalId, docType, currentNodeInstances, documentStatus)) && ((KewApiConstants.SUPER_USER_DISAPPROVE).equals(getSuperUserAction())));
78  
79          String s = this.superUserAction;
80          if (!(canAdministerRouting ||
81                canSuperUserApproveSingleActionRequest ||
82                canSuperUserApproveDocument ||
83                canSuperUserDisapproveDocument )) {
84                return "User not authorized to take super user action " + getSuperUserAction() + " on document " + docId;
85          }
86          return "";
87      }
88  
89      @Override
90      public String validateActionRules(List<ActionRequestValue> actionRequests) {
91      	return validateActionRules();
92      }
93  
94      public void recordAction() throws InvalidActionTakenException {
95  
96          String errorMessage = validateActionRules();
97          if (!org.apache.commons.lang.StringUtils.isEmpty(errorMessage)) {
98              LOG.info("User not authorized: " + errorMessage);
99              List<WorkflowServiceErrorImpl> errors = new ArrayList<WorkflowServiceErrorImpl>();
100             errors.add(new WorkflowServiceErrorImpl(errorMessage, AUTHORIZATION));
101             throw new WorkflowServiceErrorException(errorMessage, errors);
102         }
103 
104         ActionTakenValue actionTaken = processActionRequests();
105 
106         try {
107         	String oldStatus = getRouteHeader().getDocRouteStatus();
108         	//if the document is initiated then set it enroute so we can transition to any other status
109         	if (getRouteHeader().isStateInitiated()) {
110         		getRouteHeader().markDocumentEnroute();
111         		notifyStatusChange(getRouteHeader().getDocRouteStatus(), oldStatus);
112         	}
113             markDocument();
114             String newStatus = getRouteHeader().getDocRouteStatus();
115             notifyStatusChange(newStatus, oldStatus);
116         } catch (Exception ex) {
117             LOG.error("Caught Exception talking to post processor", ex);
118             throw new RuntimeException("Caught Exception talking to post processor: " + this + " / Doc ID: " + getDocumentId(), ex);
119         }
120         
121         processActionTaken(actionTaken);
122     }
123 
124     protected abstract void markDocument() throws WorkflowException;
125 
126     protected ActionTakenValue processActionRequests() throws InvalidActionTakenException {
127         LOG.debug("Processing pending action requests");
128 
129         ActionTakenValue actionTaken = saveActionTaken();
130 
131         List<ActionRequestValue> actionRequests = getActionRequestService().findPendingByDoc(getDocumentId());
132 
133         for (ActionRequestValue actionRequest : actionRequests)
134         {
135             getActionRequestService().deactivateRequest(actionTaken, actionRequest);
136         }
137 
138         notifyActionTaken(actionTaken);
139 
140         return actionTaken;
141     }
142 
143     /**
144      * Allows subclasses to perform any post-processing after the action has been taken
145      */
146     protected void processActionTaken(ActionTakenValue actionTaken) {
147         // no default impl
148     }
149 
150     public ActionRequestValue getActionRequest() {
151         return actionRequest;
152     }
153 
154     public void setActionRequest(ActionRequestValue actionRequest) {
155         this.actionRequest = actionRequest;
156     }
157 
158     public String getSuperUserAction() {
159         return superUserAction;
160     }
161 }