001 /* 002 * Copyright 2005-2007 The Kuali Foundation 003 * 004 * 005 * Licensed under the Educational Community License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.opensource.org/licenses/ecl2.php 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.kuali.rice.kew.actions; 018 019 import java.util.ArrayList; 020 import java.util.List; 021 022 import org.apache.log4j.MDC; 023 import org.kuali.rice.kew.actionrequest.ActionRequestFactory; 024 import org.kuali.rice.kew.actionrequest.ActionRequestValue; 025 import org.kuali.rice.kew.actionrequest.KimPrincipalRecipient; 026 import org.kuali.rice.kew.actiontaken.ActionTakenValue; 027 import org.kuali.rice.kew.doctype.bo.DocumentType; 028 import org.kuali.rice.kew.exception.InvalidActionTakenException; 029 import org.kuali.rice.kew.exception.WorkflowException; 030 import org.kuali.rice.kew.exception.WorkflowServiceErrorException; 031 import org.kuali.rice.kew.exception.WorkflowServiceErrorImpl; 032 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue; 033 import org.kuali.rice.kew.service.KEWServiceLocator; 034 import org.kuali.rice.kew.util.KEWConstants; 035 import org.kuali.rice.kew.util.Utilities; 036 import org.kuali.rice.kim.bo.entity.KimPrincipal; 037 038 039 /** 040 * Super user Approves a single action request. 041 * 042 * @author Kuali Rice Team (rice.collab@kuali.org) 043 */ 044 public class SuperUserActionRequestApproveEvent extends SuperUserActionTakenEvent { 045 /** 046 * This is the only action which is polymorphic...the action taken code is dynamically determined 047 * based on action requested. All other actions' action taken code is immutable, so the field could otherwise 048 * be set to final and initialized in the constructor...however it would not be advisable to perform in the 049 * constructor the work required by this class to determine the action taken. So for now the class initializes 050 * the action taken to null (this would be the behavior anyway if the constructor did not enforce an action taken code 051 * to be supplied). An alternative would be to do away with the stored superclass field and simply delegate to a subclass 052 * getActionTakenCode implementation when necessary. It is also not clear that this would be a good choice as it may be 053 * called multiple times in arbitrary contexts. 054 */ 055 private static final String UNDEFINED_ACTION_TAKEN_CODE = null; 056 057 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(SuperUserActionRequestApproveEvent.class); 058 private Long actionRequestId; 059 060 public SuperUserActionRequestApproveEvent(DocumentRouteHeaderValue routeHeader, KimPrincipal principal) { 061 super(UNDEFINED_ACTION_TAKEN_CODE, routeHeader, principal); 062 this.superUserAction = KEWConstants.SUPER_USER_ACTION_REQUEST_APPROVE; 063 } 064 065 public SuperUserActionRequestApproveEvent(DocumentRouteHeaderValue routeHeader, KimPrincipal principal, Long actionRequestId, String annotation, boolean runPostProcessor) { 066 super(UNDEFINED_ACTION_TAKEN_CODE, routeHeader, principal, annotation, runPostProcessor); 067 this.superUserAction = KEWConstants.SUPER_USER_ACTION_REQUEST_APPROVE; 068 this.actionRequestId = actionRequestId; 069 } 070 071 public void setActionTaken() { 072 String actionRequestCode = ""; 073 074 ActionRequestValue actionRequest = getActionRequestService().findByActionRequestId(actionRequestId); 075 076 setActionRequest(actionRequest); 077 078 actionRequestCode = actionRequest.getActionRequested(); 079 //This has been set up for all of the actions, but this class only does approvals 080 if (KEWConstants.ACTION_REQUEST_APPROVE_REQ.equals(actionRequestCode)) { 081 this.setActionTakenCode(KEWConstants.ACTION_TAKEN_SU_ACTION_REQUEST_APPROVED_CD); 082 } else if (KEWConstants.ACTION_REQUEST_COMPLETE_REQ.equals(actionRequestCode)) { 083 this.setActionTakenCode(KEWConstants.ACTION_TAKEN_SU_ACTION_REQUEST_COMPLETED_CD); 084 } else if (KEWConstants.ACTION_REQUEST_FYI_REQ.equals(actionRequestCode)) { 085 this.setActionTakenCode(KEWConstants.ACTION_TAKEN_SU_ACTION_REQUEST_FYI_CD); 086 } else if (KEWConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ.equals(actionRequestCode)) { 087 this.setActionTakenCode(KEWConstants.ACTION_TAKEN_SU_ACTION_REQUEST_ACKNOWLEDGED_CD); 088 } else { 089 //TODO this should be checked 090 LOG.error("Invalid SU delegation action request code: " + actionRequestCode); 091 throw new RuntimeException("Invalid SU delegation action request code: " + actionRequestCode); 092 } 093 } 094 095 protected void processActionRequests() throws InvalidActionTakenException { 096 //this method has been written to process all of the actions though only approvals are currently processed 097 098 DocumentType docType = getRouteHeader().getDocumentType(); 099 // 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 }