001: /*
002: * Copyright 2005-2006 The Kuali Foundation.
003: *
004: *
005: * Licensed under the Educational Community License, Version 1.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/ecl1.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 edu.iu.uis.eden.actions;
018:
019: import java.util.Iterator;
020: import java.util.List;
021:
022: import org.apache.log4j.MDC;
023:
024: import edu.iu.uis.eden.EdenConstants;
025: import edu.iu.uis.eden.actionrequests.ActionRequestValue;
026: import edu.iu.uis.eden.exception.EdenUserNotFoundException;
027: import edu.iu.uis.eden.exception.InvalidActionTakenException;
028: import edu.iu.uis.eden.exception.ResourceUnavailableException;
029: import edu.iu.uis.eden.routeheader.DocumentRouteHeaderValue;
030: import edu.iu.uis.eden.user.Recipient;
031: import edu.iu.uis.eden.user.WorkflowUser;
032: import edu.iu.uis.eden.util.Utilities;
033:
034: /**
035: * The ApproveAction records and processes an approve action.
036: *
037: * The routeheader is first checked to make sure the action is valid for the document.
038: * Next the user is checked to make sure he/she has not taken a previous action on this
039: * document at the actions responsibility or below. The action is recorded.
040: * Any requests related to this user are deactivated.
041: *
042: * @author rkirkend
043: * @author ewestfal
044: * @author seiffert
045: */
046: public class ApproveAction extends ActionTakenEvent {
047: private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger
048: .getLogger(ApproveAction.class);
049:
050: /**
051: * @param routeHeader
052: * RouteHeader for the document upon which the action is taken.
053: * @param user
054: * User taking the action.
055: */
056: public ApproveAction(DocumentRouteHeaderValue routeHeader,
057: WorkflowUser user) {
058: super (routeHeader, user);
059: setActionTakenCode(EdenConstants.ACTION_TAKEN_APPROVED_CD);
060: }
061:
062: /**
063: * @param routeHeader
064: * RouteHeader for the document upon which the action is taken.
065: * @param user
066: * User taking the action.
067: * @param annotation
068: * User comment on the action taken
069: */
070: public ApproveAction(DocumentRouteHeaderValue routeHeader,
071: WorkflowUser user, String annotation) {
072: super (routeHeader, user, annotation);
073: setActionTakenCode(EdenConstants.ACTION_TAKEN_APPROVED_CD);
074: }
075:
076: /* (non-Javadoc)
077: * @see edu.iu.uis.eden.actions.ActionTakenEvent#isActionCompatibleRequest(java.util.List)
078: */
079: @Override
080: public String validateActionRules()
081: throws EdenUserNotFoundException {
082: return validateActionRules(getActionRequestService()
083: .findAllValidRequests(getUser(),
084: routeHeader.getRouteHeaderId(),
085: EdenConstants.ACTION_REQUEST_APPROVE_REQ));
086: }
087:
088: private String validateActionRules(List actionRequests)
089: throws EdenUserNotFoundException {
090: String super Error = super .validateActionTakenRules();
091: if (!Utilities.isEmpty(super Error)) {
092: return super Error;
093: }
094: if (!getRouteHeader().isValidActionToTake(
095: getActionPerformedCode())) {
096: return "Document is not in a state to be approved";
097: }
098: if (!isActionCompatibleRequest(actionRequests)) {
099: return "No request for the user is compatible "
100: + "with the APPROVE action";
101: }
102: return "";
103: }
104:
105: /* (non-Javadoc)
106: * @see edu.iu.uis.eden.actions.ActionTakenEvent#isActionCompatibleRequest(java.util.List)
107: */
108: @Override
109: public boolean isActionCompatibleRequest(List requests)
110: throws EdenUserNotFoundException {
111: // we allow pre-approval
112: if (requests.isEmpty()) {
113: return true;
114: }
115:
116: // can always cancel saved or initiated document
117: if (routeHeader.isStateInitiated()
118: || routeHeader.isStateSaved()) {
119: return true;
120: }
121:
122: boolean actionCompatible = false;
123: Iterator ars = requests.iterator();
124: ActionRequestValue actionRequest = null;
125:
126: while (ars.hasNext()) {
127: actionRequest = (ActionRequestValue) ars.next();
128: String request = actionRequest.getActionRequested();
129:
130: // Approve action matches Complete, Approve, FYI, and ACK requests
131: if ((EdenConstants.ACTION_REQUEST_FYI_REQ.equals(request))
132: || (EdenConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ
133: .equals(request))
134: || (EdenConstants.ACTION_REQUEST_APPROVE_REQ
135: .equals(request))
136: || (EdenConstants.ACTION_REQUEST_COMPLETE_REQ
137: .equals(request))) {
138: actionCompatible = true;
139: break;
140: }
141: }
142: return actionCompatible;
143: }
144:
145: /**
146: * Records the approve action.
147: * - Checks to make sure the document status allows the action.
148: * - Checks that the user has not taken a previous action.
149: * - Deactivates the pending requests for this user
150: * - Records the action
151: *
152: * @throws InvalidActionTakenException
153: * @throws ResourceUnavailableException
154: */
155: public void recordAction() throws InvalidActionTakenException,
156: EdenUserNotFoundException {
157: MDC.put("docId", getRouteHeader().getRouteHeaderId());
158: checkLocking();
159: updateSearchableAttributesIfPossible();
160: LOG.debug("Approving document : " + annotation);
161:
162: List actionRequests = getActionRequestService()
163: .findAllValidRequests(getUser(), getRouteHeaderId(),
164: EdenConstants.ACTION_REQUEST_APPROVE_REQ);
165: String errorMessage = validateActionRules(actionRequests);
166: if (!Utilities.isEmpty(errorMessage)) {
167: throw new InvalidActionTakenException(errorMessage);
168: }
169:
170: // if (! routeHeader.isValidActionToTake(getActionTakenCode())) {
171: // LOG.warn("Document not in state to be approved.");
172: // throw new InvalidActionTakenException("Document is not in a state to be approved");
173: // }
174: // List actionRequests = getActionRequestService().findAllValidRequests(getUser(), getRouteHeaderId(), EdenConstants.ACTION_REQUEST_APPROVE_REQ);
175: // if (!isActionCompatibleRequest(actionRequests, getActionTakenCode())) {
176: // throw new InvalidActionTakenException("No request for the user is compatible " + "with the APPROVE action");
177: // }
178:
179: Recipient delegator = findDelegatorForActionRequests(actionRequests);
180:
181: LOG.debug("Record the approve action");
182: saveActionTaken(delegator);
183:
184: LOG.debug("Deactivate all pending action requests");
185: getActionRequestService().deactivateRequests(actionTaken,
186: actionRequests);
187: notifyActionTaken(this .actionTaken);
188:
189: boolean isException = getRouteHeader().isInException();
190: boolean isSaved = getRouteHeader().isStateSaved();
191: if (isException || isSaved) {
192: String oldStatus = getRouteHeader().getDocRouteStatus();
193: LOG.debug("Moving document back to Enroute from "
194: + EdenConstants.DOCUMENT_STATUSES.get(oldStatus));
195: getRouteHeader().markDocumentEnroute();
196: String newStatus = getRouteHeader().getDocRouteStatus();
197: notifyStatusChange(newStatus, oldStatus);
198: this.getRouteHeaderService().saveRouteHeader(
199: getRouteHeader());
200: }
201: }
202: }
|