View Javadoc
1   /**
2    * Copyright 2005-2016 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.actiontaken.ActionTakenValue;
21  import org.kuali.rice.kew.api.exception.InvalidActionTakenException;
22  import org.kuali.rice.kew.doctype.DocumentTypePolicy;
23  import org.kuali.rice.kew.api.exception.ResourceUnavailableException;
24  import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
25  import org.kuali.rice.kew.api.KewApiConstants;
26  import org.kuali.rice.kim.api.identity.principal.PrincipalContract;
27  
28  
29  import java.util.Iterator;
30  import java.util.List;
31  
32  
33  /**
34   *
35   * ClearFYIAction deactivates the user requests.
36   *
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. Any requests related to this user
40   * are deactivated.
41   *
42   * @author Kuali Rice Team (rice.collab@kuali.org)
43   */
44  public class ClearFYIAction extends ActionTakenEvent {
45      private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(ClearFYIAction.class);
46  
47      /**
48       * @param rh
49       *            RouteHeader for the document upon which the action is taken.
50       * @param principal
51       *            User taking the action.
52       */
53      public ClearFYIAction(DocumentRouteHeaderValue rh, PrincipalContract principal) {
54          super(KewApiConstants.ACTION_TAKEN_FYI_CD, rh, principal);
55      }
56  
57      /**
58       * @param rh
59       *            RouteHeader for the document upon which the action is taken.
60       * @param principal
61       *            User taking the action.
62       * @param annotation
63       *            User comment on the action taken
64       */
65      public ClearFYIAction(DocumentRouteHeaderValue rh, PrincipalContract principal, String annotation) {
66          super(KewApiConstants.ACTION_TAKEN_FYI_CD, rh, principal, annotation);
67      }
68      
69      /**
70       * Method to check if the Action is currently valid on the given document
71       * @return  returns an error message to give system better identifier for problem
72       */
73      public String validateActionRules() {
74          return validateActionRules(getActionRequestService().findAllPendingRequests(routeHeader.getDocumentId()));
75      }
76  
77      public String validateActionRules(List<ActionRequestValue> actionRequests) {
78          if (!getRouteHeader().isValidActionToTake(getActionPerformedCode())) {
79              return "Document is not in a state to have FYI processed";
80          }
81          List<ActionRequestValue> filteredActionRequests = filterActionRequestsByCode(actionRequests, KewApiConstants.ACTION_REQUEST_FYI_REQ);
82          if (!isActionCompatibleRequest(filteredActionRequests)) {
83              return "No request for the user is compatible " + "with the ClearFYI action";
84          }
85          return "";
86      }
87  
88      public boolean isActionCompatibleRequest(List requests) {
89  
90          // can always cancel saved or initiated document
91          if (routeHeader.isStateInitiated() || routeHeader.isStateSaved()) {
92              return true;
93          }
94  
95          boolean actionCompatible = false;
96          Iterator ars = requests.iterator();
97          ActionRequestValue actionRequest = null;
98  
99          while (ars.hasNext()) {
100             actionRequest = (ActionRequestValue) ars.next();
101 
102             //FYI request matches all but deny and cancel
103             if (KewApiConstants.ACTION_REQUEST_FYI_REQ.equals(actionRequest.getActionRequested())) {
104                 actionCompatible = true;
105                 break;
106             }
107         }
108 
109         return actionCompatible;
110     }
111 
112     /**
113      * Processes the clear FYI 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
114      *
115      * @throws InvalidActionTakenException
116      * @throws ResourceUnavailableException
117      */
118     public void recordAction() throws InvalidActionTakenException {
119         MDC.put("docId", getRouteHeader().getDocumentId());
120         updateSearchableAttributesIfPossible();
121 
122         LOG.debug("Clear FYI for document : " + annotation);
123         LOG.debug("Checking to see if the action is legal");
124 
125         List actionRequests = getActionRequestService().findAllValidRequests(getPrincipal().getPrincipalId(), getDocumentId(), KewApiConstants.ACTION_REQUEST_FYI_REQ);
126         if (actionRequests == null || actionRequests.isEmpty()) {
127         	DocumentTypePolicy allowUnrequested = getRouteHeader().getDocumentType().getAllowUnrequestedActionPolicy();
128         	if (allowUnrequested != null) {
129         		if (!allowUnrequested.getPolicyValue()) {
130         			throw new InvalidActionTakenException("No request for the user is compatible " + "with the ClearFYI action. " + "Doctype policy ALLOW_UNREQUESTED_ACTION is set to false and someone else likely just took action on the document.");
131         		}
132         	}
133         }
134         
135         String errorMessage = validateActionRules(actionRequests);
136         if (!org.apache.commons.lang.StringUtils.isEmpty(errorMessage)) {
137             throw new InvalidActionTakenException(errorMessage);
138         }
139 
140         ActionTakenValue actionTaken = saveActionTaken(findDelegatorForActionRequests(actionRequests));
141 
142         LOG.debug("Deactivate all pending action requests");
143         getActionRequestService().deactivateRequests(actionTaken, actionRequests);
144         notifyActionTaken(actionTaken);
145     }
146 }