1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.kuali.rice.kew.actions;
18
19 import java.util.Iterator;
20 import java.util.List;
21
22 import org.apache.log4j.MDC;
23 import org.kuali.rice.kew.actionrequest.ActionRequestValue;
24 import org.kuali.rice.kew.actiontaken.ActionTakenValue;
25 import org.kuali.rice.kew.exception.InvalidActionTakenException;
26 import org.kuali.rice.kew.exception.WorkflowException;
27 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
28 import org.kuali.rice.kew.service.KEWServiceLocator;
29 import org.kuali.rice.kew.util.KEWConstants;
30 import org.kuali.rice.kew.util.Utilities;
31 import org.kuali.rice.kim.bo.entity.KimPrincipal;
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, KimPrincipal principal) {
44 super(KEWConstants.ACTION_TAKEN_CANCELED_CD, rh, principal);
45 }
46
47 public CancelAction(DocumentRouteHeaderValue rh, KimPrincipal principal, String annotation) {
48 super(KEWConstants.ACTION_TAKEN_CANCELED_CD, rh, principal, annotation);
49 }
50
51
52
53
54 @Override
55 public String validateActionRules() {
56 return validateActionRules(getActionRequestService().findAllPendingRequests(routeHeader.getRouteHeaderId()));
57 }
58
59 public String validateActionRules(List<ActionRequestValue> actionRequests) {
60
61 if (!getRouteHeader().isValidActionToTake(getActionPerformedCode())) {
62 return "Document is not in a state to be cancelled";
63 }
64 List<ActionRequestValue> filteredActionRequests = filterActionRequestsByCode(actionRequests, KEWConstants.ACTION_REQUEST_COMPLETE_REQ);
65 if (!isActionCompatibleRequest(filteredActionRequests)) {
66 return "No request for the user is compatible with the Cancel Action";
67 }
68
69 if (! KEWServiceLocator.getDocumentTypePermissionService().canCancel(getPrincipal().getPrincipalId(), getRouteHeaderId().toString(), getRouteHeader().getDocumentType(), getRouteHeader().getCurrentNodeNames(), getRouteHeader().getDocRouteStatus(), getRouteHeader().getInitiatorWorkflowId())) {
70 return "User is not authorized to Cancel document";
71 }
72 return "";
73 }
74
75
76
77
78 @Override
79 public boolean isActionCompatibleRequest(List<ActionRequestValue> requests) {
80
81
82 if (routeHeader.isStateInitiated() || routeHeader.isStateSaved()) {
83 return true;
84 }
85
86 boolean actionCompatible = false;
87 Iterator ars = requests.iterator();
88 ActionRequestValue actionRequest = null;
89
90 while (ars.hasNext()) {
91 actionRequest = (ActionRequestValue) ars.next();
92 String request = actionRequest.getActionRequested();
93
94
95 if ( (KEWConstants.ACTION_REQUEST_APPROVE_REQ.equals(request)) ||
96 (KEWConstants.ACTION_REQUEST_COMPLETE_REQ.equals(request)) ) {
97 actionCompatible = true;
98 break;
99 }
100 }
101
102 return actionCompatible;
103 }
104
105 public void recordAction() throws InvalidActionTakenException {
106 MDC.put("docId", getRouteHeader().getRouteHeaderId());
107 updateSearchableAttributesIfPossible();
108
109 LOG.debug("Canceling document : " + annotation);
110
111 List actionRequests = getActionRequestService().findAllValidRequests(getPrincipal().getPrincipalId(), getRouteHeaderId(), KEWConstants.ACTION_REQUEST_COMPLETE_REQ);
112 LOG.debug("Checking to see if the action is legal");
113 String errorMessage = validateActionRules(actionRequests);
114 if (!Utilities.isEmpty(errorMessage)) {
115 throw new InvalidActionTakenException(errorMessage);
116 }
117
118 LOG.debug("Record the cancel action");
119 ActionTakenValue actionTaken = saveActionTaken(findDelegatorForActionRequests(actionRequests));
120
121 LOG.debug("Deactivate all pending action requests");
122 actionRequests = getActionRequestService().findPendingByDoc(getRouteHeaderId());
123
124 getActionRequestService().deactivateRequests(actionTaken, actionRequests);
125 notifyActionTaken(actionTaken);
126
127 LOG.debug("Canceling document");
128
129 try {
130 String oldStatus = getRouteHeader().getDocRouteStatus();
131 getRouteHeader().markDocumentCanceled();
132 String newStatus = getRouteHeader().getDocRouteStatus();
133 KEWServiceLocator.getRouteHeaderService().saveRouteHeader(getRouteHeader());
134 notifyStatusChange(newStatus, oldStatus);
135 } catch (WorkflowException ex) {
136 LOG.warn(ex, ex);
137 throw new InvalidActionTakenException(ex.getMessage());
138 }
139 }
140 }