1
2
3
4
5
6
7
8
9
10
11
12
13
14
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.action.ActionType;
22 import org.kuali.rice.kew.api.exception.InvalidActionTakenException;
23 import org.kuali.rice.kew.api.exception.WorkflowException;
24 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
25 import org.kuali.rice.kew.service.KEWServiceLocator;
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
35
36
37
38
39 public class CancelAction extends ActionTakenEvent {
40
41 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(CancelAction.class);
42
43 public CancelAction(DocumentRouteHeaderValue rh, PrincipalContract principal) {
44 this(ActionType.CANCEL, rh, principal, null);
45 }
46
47 public CancelAction(DocumentRouteHeaderValue rh, PrincipalContract principal, String annotation) {
48 this(ActionType.CANCEL, rh, principal, annotation);
49 }
50
51
52 CancelAction(ActionType type, DocumentRouteHeaderValue rh, PrincipalContract principal, String annotation) {
53 super(type.getCode(), rh, principal, annotation);
54 }
55
56
57
58
59 @Override
60 public String validateActionRules() {
61 return validateActionRules(getActionRequestService().findAllPendingRequests(routeHeader.getDocumentId()));
62 }
63
64 public String validateActionRules(List<ActionRequestValue> actionRequests) {
65
66 if (!getRouteHeader().isValidActionToTake(getActionPerformedCode())) {
67 return "Document is not in a state to be cancelled";
68 }
69 List<ActionRequestValue> filteredActionRequests = filterActionRequestsByCode(actionRequests, KewApiConstants.ACTION_REQUEST_COMPLETE_REQ);
70 if (!isActionCompatibleRequest(filteredActionRequests)) {
71 return "No request for the user is compatible with the Cancel Action";
72 }
73
74 if (! KEWServiceLocator.getDocumentTypePermissionService().canCancel(getPrincipal().getPrincipalId(), getRouteHeader())) {
75 return "User is not authorized to Cancel document";
76 }
77 return "";
78 }
79
80
81
82
83 @Override
84 public boolean isActionCompatibleRequest(List<ActionRequestValue> requests) {
85
86
87 if (routeHeader.isStateInitiated() || routeHeader.isStateSaved()) {
88 return true;
89 }
90
91 boolean actionCompatible = false;
92 Iterator ars = requests.iterator();
93 ActionRequestValue actionRequest = null;
94
95 while (ars.hasNext()) {
96 actionRequest = (ActionRequestValue) ars.next();
97 String request = actionRequest.getActionRequested();
98
99
100 if ( (KewApiConstants.ACTION_REQUEST_APPROVE_REQ.equals(request)) ||
101 (KewApiConstants.ACTION_REQUEST_COMPLETE_REQ.equals(request)) ) {
102 actionCompatible = true;
103 break;
104 }
105 }
106
107 return actionCompatible;
108 }
109
110
111 protected void markDocumentStatus() throws InvalidActionTakenException {
112 getRouteHeader().markDocumentCanceled();
113 }
114
115 public void recordAction() throws InvalidActionTakenException {
116 MDC.put("docId", getRouteHeader().getDocumentId());
117 updateSearchableAttributesIfPossible();
118
119 LOG.debug("Canceling document : " + annotation);
120
121 List actionRequests = getActionRequestService().findAllValidRequests(getPrincipal().getPrincipalId(), getDocumentId(), KewApiConstants.ACTION_REQUEST_COMPLETE_REQ);
122 LOG.debug("Checking to see if the action is legal");
123 String errorMessage = validateActionRules(actionRequests);
124 if (!org.apache.commons.lang.StringUtils.isEmpty(errorMessage)) {
125 throw new InvalidActionTakenException(errorMessage);
126 }
127
128 LOG.debug("Record the cancel action");
129 ActionTakenValue actionTaken = saveActionTaken(findDelegatorForActionRequests(actionRequests));
130
131 LOG.debug("Deactivate all pending action requests");
132 actionRequests = getActionRequestService().findPendingByDoc(getDocumentId());
133
134 getActionRequestService().deactivateRequests(actionTaken, actionRequests);
135 notifyActionTaken(actionTaken);
136
137 LOG.debug("Canceling document");
138
139 try {
140 String oldStatus = getRouteHeader().getDocRouteStatus();
141 markDocumentStatus();
142 String newStatus = getRouteHeader().getDocRouteStatus();
143 DocumentRouteHeaderValue routeHeaderValue = KEWServiceLocator.getRouteHeaderService().
144 saveRouteHeader(getRouteHeader());
145 setRouteHeader(routeHeaderValue);
146 notifyStatusChange(newStatus, oldStatus);
147 } catch (WorkflowException ex) {
148 LOG.warn(ex, ex);
149 throw new InvalidActionTakenException(ex.getMessage());
150 }
151 }
152 }