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 }