View Javadoc

1   /**
2    * Copyright 2005-2012 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.apache.log4j.MDC;
19  import org.kuali.rice.kew.actionrequest.ActionRequestFactory;
20  import org.kuali.rice.kew.actionrequest.ActionRequestValue;
21  import org.kuali.rice.kew.actionrequest.KimPrincipalRecipient;
22  import org.kuali.rice.kew.actiontaken.ActionTakenValue;
23  import org.kuali.rice.kew.api.exception.WorkflowException;
24  import org.kuali.rice.kew.doctype.bo.DocumentType;
25  import org.kuali.rice.kew.api.exception.InvalidActionTakenException;
26  import org.kuali.rice.kew.exception.WorkflowServiceErrorException;
27  import org.kuali.rice.kew.exception.WorkflowServiceErrorImpl;
28  import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
29  import org.kuali.rice.kew.service.KEWServiceLocator;
30  import org.kuali.rice.kew.api.KewApiConstants;
31  import org.kuali.rice.kim.api.identity.principal.PrincipalContract;
32  
33  
34  import java.util.ArrayList;
35  import java.util.List;
36  
37  
38  /**
39   * Super user Approves a single action request.
40   *
41   * @author Kuali Rice Team (rice.collab@kuali.org)
42   */
43  public class SuperUserActionRequestApproveEvent extends SuperUserActionTakenEvent {
44      /**
45       * This is the only action which is polymorphic...the action taken code is dynamically determined
46       * based on action requested.  All other actions' action taken code is immutable, so the field could otherwise
47       * be set to final and initialized in the constructor...however it would not be advisable to perform in the
48       * constructor the work required by this class to determine the action taken.  So for now the class initializes
49       * the action taken to null (this would be the behavior anyway if the constructor did not enforce an action taken code
50       * to be supplied).  An alternative would be to do away with the stored superclass field and simply delegate to a subclass
51       * getActionTakenCode implementation when necessary.  It is also not clear that this would be a good choice as it may be
52       * called multiple times in arbitrary contexts.
53       */
54      private static final String UNDEFINED_ACTION_TAKEN_CODE = null;
55  
56      private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(SuperUserActionRequestApproveEvent.class);
57      private String actionRequestId;
58  
59      public SuperUserActionRequestApproveEvent(DocumentRouteHeaderValue routeHeader, PrincipalContract principal) {
60          super(UNDEFINED_ACTION_TAKEN_CODE, routeHeader, principal);
61          this.superUserAction = KewApiConstants.SUPER_USER_ACTION_REQUEST_APPROVE;
62      }
63  
64      public SuperUserActionRequestApproveEvent(DocumentRouteHeaderValue routeHeader, PrincipalContract principal, String actionRequestId, String annotation, boolean runPostProcessor) {
65          super(UNDEFINED_ACTION_TAKEN_CODE, routeHeader, principal, annotation, runPostProcessor);
66          this.superUserAction = KewApiConstants.SUPER_USER_ACTION_REQUEST_APPROVE;
67          this.actionRequestId = actionRequestId;
68      }
69  
70      public void setActionTaken() {
71          String actionRequestCode = "";
72  
73          ActionRequestValue actionRequest = getActionRequestService().findByActionRequestId(actionRequestId);
74  
75          setActionRequest(actionRequest);
76  
77          actionRequestCode = actionRequest.getActionRequested();
78          //This has been set up for all of the actions, but this class only does approvals
79          if (KewApiConstants.ACTION_REQUEST_APPROVE_REQ.equals(actionRequestCode)) {
80              this.setActionTakenCode(KewApiConstants.ACTION_TAKEN_SU_ACTION_REQUEST_APPROVED_CD);
81          } else if (KewApiConstants.ACTION_REQUEST_COMPLETE_REQ.equals(actionRequestCode)) {
82              this.setActionTakenCode(KewApiConstants.ACTION_TAKEN_SU_ACTION_REQUEST_COMPLETED_CD);
83          } else if (KewApiConstants.ACTION_REQUEST_FYI_REQ.equals(actionRequestCode)) {
84              this.setActionTakenCode(KewApiConstants.ACTION_TAKEN_SU_ACTION_REQUEST_FYI_CD);
85          } else if (KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ.equals(actionRequestCode)) {
86              this.setActionTakenCode(KewApiConstants.ACTION_TAKEN_SU_ACTION_REQUEST_ACKNOWLEDGED_CD);
87          } else {
88              //TODO this should be checked
89              LOG.error("Invalid SU delegation action request code: " + actionRequestCode);
90              throw new RuntimeException("Invalid SU delegation action request code: " + actionRequestCode);
91          }
92      }
93  
94      protected void processActionRequests() throws InvalidActionTakenException {
95          //this method has been written to process all of the actions though only approvals are currently processed
96  
97          DocumentType docType = getRouteHeader().getDocumentType();
98  //        boolean userAuthorized = getDocumentTypeService().verifySUAuthority(docType, getUser());
99  
100         String errorMessage = super.validateActionRules();
101         if (!org.apache.commons.lang.StringUtils.isEmpty(errorMessage)) {
102             LOG.info("User not authorized");
103             List<WorkflowServiceErrorImpl> errors = new ArrayList<WorkflowServiceErrorImpl>();
104             errors.add(new WorkflowServiceErrorImpl(errorMessage, SuperUserActionTakenEvent.AUTHORIZATION));
105             throw new WorkflowServiceErrorException(errorMessage, errors);
106         }
107 //        if (!docType.isSuperUser(getUser())) {
108 //            List errors = new ArrayList();
109 //            errors.add(new WorkflowServiceErrorImpl("User not authorized for super user action", SuperUserActionTakenEvent.AUTHORIZATION));
110 //            throw new WorkflowServiceErrorException("Super User Authorization Error", errors);
111 //        }
112 
113         this.setActionTaken();
114 
115         MDC.put("docId", getRouteHeader().getDocumentId());
116 
117         LOG.debug("Super User Delegation Action on action request: " + annotation);
118         KimPrincipalRecipient superUserRecipient = null;
119         if (getActionRequest().getPrincipal() != null) {
120         	superUserRecipient = new KimPrincipalRecipient(getActionRequest().getPrincipal());
121         }
122         
123         ActionTakenValue actionTaken = this.saveActionTaken(superUserRecipient);
124 
125         LOG.debug("Deactivate this action request");
126 
127         ActionRequestValue request = getActionRequest();
128         getActionRequestService().deactivateRequest(actionTaken, request);
129         if (docType.getSuperUserApproveNotificationPolicy().getPolicyValue() && request.isApproveOrCompleteRequest()) {
130         	KEWServiceLocator.getActionRequestService().activateRequest(
131         	new ActionRequestFactory(this.getRouteHeader()).createNotificationRequest(KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ, request.getPrincipal(), this.getActionTakenCode(), getPrincipal(), null));
132         }
133         notifyActionTaken(actionTaken);
134 
135         if (!(KewApiConstants.ACTION_TAKEN_SU_ACTION_REQUEST_FYI_CD.equals(this.getActionTakenCode()) && KewApiConstants.ACTION_TAKEN_SU_ACTION_REQUEST_ACKNOWLEDGED_CD.equals(this.getActionTakenCode()))) {
136             if (getRouteHeader().isInException()) {
137                 LOG.debug("Moving document back to Enroute from Exception");
138 
139                 String oldStatus = getRouteHeader().getDocRouteStatus();
140                 this.getRouteHeader().markDocumentEnroute();
141 
142                 String newStatus = getRouteHeader().getDocRouteStatus();
143                 this.notifyStatusChange(newStatus, oldStatus);
144                 KEWServiceLocator.getRouteHeaderService().saveRouteHeader(getRouteHeader());
145             }
146             else if (getRouteHeader().isStateSaved()) {
147         	if (KewApiConstants.SAVED_REQUEST_RESPONSIBILITY_ID.equals(request.getResponsibilityId())) {
148                     LOG.debug("Moving document to Enroute from Saved because action request was request generated by save action");
149             	
150                     String oldStatus = getRouteHeader().getDocRouteStatus();
151                     this.getRouteHeader().markDocumentEnroute();
152                     String newStatus = getRouteHeader().getDocRouteStatus();
153                     this.notifyStatusChange(newStatus, oldStatus);
154                     KEWServiceLocator.getRouteHeaderService().saveRouteHeader(getRouteHeader());
155         	}
156             }
157         }
158     }
159 
160     public void recordAction() throws InvalidActionTakenException {
161         this.processActionRequests();
162         this.queueDocumentProcessing();
163     }
164 
165     protected void markDocument() throws WorkflowException {
166     }
167 }