View Javadoc

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