View Javadoc

1   /**
2    * Copyright 2005-2013 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.ActionRequestValue;
20  import org.kuali.rice.kew.actionrequest.Recipient;
21  import org.kuali.rice.kew.actiontaken.ActionTakenValue;
22  import org.kuali.rice.kew.api.exception.InvalidActionTakenException;
23  import org.kuali.rice.kew.doctype.DocumentTypePolicy;
24  import org.kuali.rice.kew.api.exception.ResourceUnavailableException;
25  import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
26  import org.kuali.rice.kew.api.KewApiConstants;
27  import org.kuali.rice.kim.api.identity.principal.PrincipalContract;
28  
29  
30  import java.util.Iterator;
31  import java.util.List;
32  
33  /**
34   * <p>
35   * AcknowledegeAction records the users acknowledgement of a document
36   * </p>
37   * The routeheader is first checked to make sure the action is valid for the document.
38   * Next the user is checked to make sure he/she has not taken a previous action on this
39   * document at the actions responsibility or below. The action is recorded. Any requests
40   * related to this user are deactivated.
41   * </p>
42   *
43   * @author Kuali Rice Team (rice.collab@kuali.org)
44   */
45  public class AcknowledgeAction extends ActionTakenEvent {
46      private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(AcknowledgeAction.class);
47  
48      /**
49       * @param rh
50       *            RouteHeader for the document upon which the action is taken.
51       * @param principal
52       *            User taking the action.
53       */
54      public AcknowledgeAction(DocumentRouteHeaderValue rh, PrincipalContract principal) {
55          super(KewApiConstants.ACTION_TAKEN_ACKNOWLEDGED_CD, rh, principal);
56      }
57  
58      /**
59       * @param rh
60       *            RouteHeader for the document upon which the action is taken.
61       * @param principal
62       *            User taking the action.
63       * @param annotation
64       *            User comment on the action taken
65       */
66      public AcknowledgeAction(DocumentRouteHeaderValue rh, PrincipalContract principal, String annotation) {
67          super(KewApiConstants.ACTION_TAKEN_ACKNOWLEDGED_CD, rh, principal, annotation);
68      }
69      
70      /**
71       * Method to check if the Action is currently valid on the given document
72       * @return  returns an error message to give system better identifier for problem
73       */
74      public String validateActionRules() {
75          return validateActionRules(getActionRequestService().findAllPendingRequests(routeHeader.getDocumentId()));
76      }
77  
78      public String validateActionRules(List<ActionRequestValue> actionRequests) {
79          if (!getRouteHeader().isValidActionToTake(getActionPerformedCode())) {
80              return "Document is not in a state to be acknowledged";
81          }
82          List<ActionRequestValue> filteredActionRequests = filterActionRequestsByCode(actionRequests, KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ);
83          if (!isActionCompatibleRequest(filteredActionRequests)) {
84              return "No request for the user is compatible " + "with the ACKNOWLEDGE action";
85          }
86          return "";
87      }
88  
89      /* (non-Javadoc)
90       * @see org.kuali.rice.kew.actions.ActionTakenEvent#isActionCompatibleRequest(java.util.List, java.lang.String)
91       */
92      @Override
93      public boolean isActionCompatibleRequest(List requests) {
94  
95          // we allow pre-approval
96          if (requests.isEmpty()) {
97              return true;
98          }
99  
100         // can always cancel saved or initiated document
101         if (routeHeader.isStateInitiated() || routeHeader.isStateSaved()) {
102             return true;
103         }
104 
105         boolean actionCompatible = false;
106         Iterator ars = requests.iterator();
107         ActionRequestValue actionRequest = null;
108 
109         while (ars.hasNext()) {
110             actionRequest = (ActionRequestValue) ars.next();
111             String request = actionRequest.getActionRequested();
112 
113             // Acknowledge Taken Code matches Fyi and Ack
114             if ( (KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ.equals(request)) || (KewApiConstants.ACTION_REQUEST_FYI_REQ.equals(request)) ) {
115                 actionCompatible = true;
116                 break;
117             }
118         }
119 
120         return actionCompatible;
121     }
122 
123     /**
124      * Records the Acknowldege action. - Checks to make sure the document status allows the action. - Checks that the user has not taken a previous action. - Deactivates the pending requests for this user - Records the action
125      *
126      * @throws InvalidActionTakenException
127      * @throws ResourceUnavailableException
128      */
129     public void recordAction() throws InvalidActionTakenException {
130         MDC.put("docId", getRouteHeader().getDocumentId());
131         updateSearchableAttributesIfPossible();
132 
133         LOG.debug("Acknowledging document : " + annotation);
134 
135         LOG.debug("Checking to see if the action is legal");
136         List actionRequests = getActionRequestService().findAllValidRequests(getPrincipal().getPrincipalId(), routeHeader.getDocumentId(), KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ);
137         if (actionRequests == null || actionRequests.isEmpty()) {
138             DocumentTypePolicy allowUnrequested = getRouteHeader().getDocumentType().getAllowUnrequestedActionPolicy();
139             if (allowUnrequested != null) {
140             	if (!allowUnrequested.getPolicyValue()) {
141             		throw new InvalidActionTakenException("No request for the user is compatible " + "with the ACKNOWLEDGE action. " + "Doctype policy ALLOW_UNREQUESTED_ACTION is set to false and someone else likely just took action on the document.");
142             	}
143             }
144         }
145 
146         String errorMessage = validateActionRules(actionRequests);
147         if (!org.apache.commons.lang.StringUtils.isEmpty(errorMessage)) {
148             throw new InvalidActionTakenException(errorMessage);
149         }
150 
151         LOG.debug("Record the acknowledge action");
152         Recipient delegator = findDelegatorForActionRequests(actionRequests);
153         ActionTakenValue actionTaken = saveActionTaken(delegator);
154         LOG.debug("Deactivate all pending action requests");
155         getActionRequestService().deactivateRequests(actionTaken, actionRequests);
156         notifyActionTaken(actionTaken);
157     }
158 }