001/** 002 * Copyright 2005-2015 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.kuali.rice.kew.actions; 017 018import org.apache.log4j.MDC; 019import org.kuali.rice.kew.actionrequest.ActionRequestValue; 020import org.kuali.rice.kew.actiontaken.ActionTakenValue; 021import org.kuali.rice.kew.api.exception.InvalidActionTakenException; 022import org.kuali.rice.kew.doctype.DocumentTypePolicy; 023import org.kuali.rice.kew.api.exception.ResourceUnavailableException; 024import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue; 025import org.kuali.rice.kew.api.KewApiConstants; 026import org.kuali.rice.kim.api.identity.principal.PrincipalContract; 027 028 029import java.util.Iterator; 030import java.util.List; 031 032 033/** 034 * 035 * ClearFYIAction deactivates the user requests. 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. Any requests related to this user 040 * are deactivated. 041 * 042 * @author Kuali Rice Team (rice.collab@kuali.org) 043 */ 044public class ClearFYIAction extends ActionTakenEvent { 045 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(ClearFYIAction.class); 046 047 /** 048 * @param rh 049 * RouteHeader for the document upon which the action is taken. 050 * @param principal 051 * User taking the action. 052 */ 053 public ClearFYIAction(DocumentRouteHeaderValue rh, PrincipalContract principal) { 054 super(KewApiConstants.ACTION_TAKEN_FYI_CD, rh, principal); 055 } 056 057 /** 058 * @param rh 059 * RouteHeader for the document upon which the action is taken. 060 * @param principal 061 * User taking the action. 062 * @param annotation 063 * User comment on the action taken 064 */ 065 public ClearFYIAction(DocumentRouteHeaderValue rh, PrincipalContract principal, String annotation) { 066 super(KewApiConstants.ACTION_TAKEN_FYI_CD, rh, principal, annotation); 067 } 068 069 /** 070 * Method to check if the Action is currently valid on the given document 071 * @return returns an error message to give system better identifier for problem 072 */ 073 public String validateActionRules() { 074 return validateActionRules(getActionRequestService().findAllPendingRequests(routeHeader.getDocumentId())); 075 } 076 077 public String validateActionRules(List<ActionRequestValue> actionRequests) { 078 if (!getRouteHeader().isValidActionToTake(getActionPerformedCode())) { 079 return "Document is not in a state to have FYI processed"; 080 } 081 List<ActionRequestValue> filteredActionRequests = filterActionRequestsByCode(actionRequests, KewApiConstants.ACTION_REQUEST_FYI_REQ); 082 if (!isActionCompatibleRequest(filteredActionRequests)) { 083 return "No request for the user is compatible " + "with the ClearFYI action"; 084 } 085 return ""; 086 } 087 088 public boolean isActionCompatibleRequest(List requests) { 089 090 // can always cancel saved or initiated document 091 if (routeHeader.isStateInitiated() || routeHeader.isStateSaved()) { 092 return true; 093 } 094 095 boolean actionCompatible = false; 096 Iterator ars = requests.iterator(); 097 ActionRequestValue actionRequest = null; 098 099 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}