001 /**
002 * Copyright 2005-2014 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 */
016 package org.kuali.rice.kew.actions;
017
018 import java.util.ArrayList;
019 import java.util.List;
020
021 import org.apache.commons.collections.CollectionUtils;
022 import org.apache.log4j.MDC;
023 import org.kuali.rice.kew.actionrequest.ActionRequestValue;
024 import org.kuali.rice.kew.actionrequest.Recipient;
025 import org.kuali.rice.kew.actiontaken.ActionTakenValue;
026 import org.kuali.rice.kew.api.action.AdHocRevoke;
027 import org.kuali.rice.kew.api.exception.InvalidActionTakenException;
028 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
029 import org.kuali.rice.kew.api.KewApiConstants;
030 import org.kuali.rice.kim.api.identity.principal.PrincipalContract;
031
032
033 /**
034 * The RevokeAdHocApprove revokes the specified AdHoc requests.
035 *
036 * @author Kuali Rice Team (rice.collab@kuali.org)
037 */
038 public class RevokeAdHocAction extends ActionTakenEvent {
039
040 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(RevokeAdHocAction.class);
041
042 private String actionRequestId;
043 private AdHocRevoke revoke;
044
045 public RevokeAdHocAction(DocumentRouteHeaderValue routeHeader, PrincipalContract principal) {
046 super(KewApiConstants.ACTION_TAKEN_ADHOC_REVOKED_CD, routeHeader, principal);
047 }
048
049 public RevokeAdHocAction(DocumentRouteHeaderValue routeHeader, PrincipalContract principal, String actionRequestId, String annotation) {
050 super(KewApiConstants.ACTION_TAKEN_ADHOC_REVOKED_CD, routeHeader, principal, annotation);
051 this.actionRequestId = actionRequestId;
052 }
053
054 public RevokeAdHocAction(DocumentRouteHeaderValue routeHeader, PrincipalContract principal, AdHocRevoke revoke, String annotation) {
055 super(KewApiConstants.ACTION_TAKEN_ADHOC_REVOKED_CD, routeHeader, principal, annotation);
056 this.revoke = revoke;
057 }
058
059 /* (non-Javadoc)
060 * @see org.kuali.rice.kew.actions.ActionTakenEvent#isActionCompatibleRequest(java.util.List)
061 */
062 @Override
063 public String validateActionRules() {
064 if (!getRouteHeader().isValidActionToTake(getActionPerformedCode())) {
065 return "Revoke adhoc request is not valid on this document";
066 }
067 return "";
068 }
069
070 @Override
071 public String validateActionRules(List<ActionRequestValue> actionRequests) {
072 return validateActionRules();
073 }
074
075 /**
076 * Records the approve action.
077 * - Checks to make sure the document status allows the action.
078 * - Checks that the user has not taken a previous action.
079 * - Deactivates the pending requests for this user
080 * - Records the action
081 *
082 * @throws InvalidActionTakenException
083 */
084 public void recordAction() throws InvalidActionTakenException {
085 MDC.put("docId", getRouteHeader().getDocumentId());
086 updateSearchableAttributesIfPossible();
087
088 String errorMessage = validateActionRules();
089 if (!org.apache.commons.lang.StringUtils.isEmpty(errorMessage)) {
090 throw new InvalidActionTakenException(errorMessage);
091 }
092
093 LOG.debug("Revoking adhoc request : " + annotation);
094
095 List<ActionRequestValue> requestsToRevoke = new ArrayList<ActionRequestValue>();
096 List<ActionRequestValue> actionRequests = getActionRequestService().findPendingRootRequestsByDocId(getDocumentId());
097 for (ActionRequestValue actionRequest : actionRequests)
098 {
099 if (matchesActionRequest(revoke, actionRequest))
100 {
101 requestsToRevoke.add(actionRequest);
102 }
103 }
104 if (requestsToRevoke.isEmpty() && actionRequestId != null) {
105 throw new InvalidActionTakenException("Failed to revoke action request with id " + actionRequestId +
106 ". ID does not represent a valid ad hoc request!");
107 }
108
109 Recipient delegator = findDelegatorForActionRequests(actionRequests);
110 LOG.debug("Record the revoke action");
111 ActionTakenValue actionTaken = saveActionTaken(delegator);
112
113 LOG.debug("Revoke all matching action requests, number of matching requests: " + requestsToRevoke.size());
114 getActionRequestService().deactivateRequests(actionTaken, requestsToRevoke);
115 notifyActionTaken(actionTaken);
116
117 }
118
119 /**
120 * Determines if the given action request is an ad hoc request which matches this set of criteria.
121 */
122 protected boolean matchesActionRequest(AdHocRevoke adHocRevokeCommand, ActionRequestValue actionRequest) {
123 if (!actionRequest.isAdHocRequest()) {
124 return false;
125 }
126 if (actionRequestId != null) {
127 return actionRequestId.equals(actionRequest.getActionRequestId());
128 } else if (adHocRevokeCommand != null) {
129 boolean principalOrGroupId = !CollectionUtils.isEmpty(adHocRevokeCommand.getPrincipalIds()) || !CollectionUtils.isEmpty(adHocRevokeCommand.getGroupIds());
130 if (!CollectionUtils.isEmpty(adHocRevokeCommand.getNodeNames()) && !adHocRevokeCommand.getNodeNames().contains(actionRequest.getNodeInstance().getName())) {
131 return false;
132 }
133 if (actionRequest.isUserRequest() && !CollectionUtils.isEmpty(adHocRevokeCommand.getPrincipalIds())) {
134 return adHocRevokeCommand.getPrincipalIds().contains(actionRequest.getPrincipalId());
135 }
136 if (actionRequest.isGroupRequest() && !CollectionUtils.isEmpty(adHocRevokeCommand.getGroupIds())) {
137 return adHocRevokeCommand.getGroupIds().contains(actionRequest.getGroupId());
138 }
139 return !principalOrGroupId;
140 }
141 return true;
142 }
143
144 }