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.cxf.common.util.StringUtils;
19 import org.kuali.rice.kew.actionrequest.*;
20 import org.kuali.rice.kew.engine.node.RouteNodeInstance;
21 import org.kuali.rice.kew.api.exception.InvalidActionTakenException;
22 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
23 import org.kuali.rice.kew.service.KEWServiceLocator;
24 import org.kuali.rice.kew.api.KewApiConstants;
25 import org.kuali.rice.kim.api.identity.principal.PrincipalContract;
26 import org.kuali.rice.kim.api.group.Group;
27
28
29 import java.util.List;
30
31
32
33
34
35
36
37 public class AdHocAction extends ActionTakenEvent {
38
39
40
41 private static final String NO_ACTION_TAKEN_CODE = null;
42
43 private String actionRequested;
44 private String nodeName;
45 private Integer priority;
46 private String responsibilityDesc;
47 private Boolean forceAction;
48 private Recipient recipient;
49 private String annotation;
50 private String requestLabel;
51
52 public AdHocAction(DocumentRouteHeaderValue routeHeader, PrincipalContract principal) {
53 super(NO_ACTION_TAKEN_CODE, routeHeader, principal);
54 }
55
56 public AdHocAction(DocumentRouteHeaderValue routeHeader, PrincipalContract principal, String annotation, String actionRequested, String nodeName, Integer priority, Recipient recipient, String responsibilityDesc, Boolean forceAction, String requestLabel) {
57 super(NO_ACTION_TAKEN_CODE, routeHeader, principal, annotation);
58 this.actionRequested = actionRequested;
59 this.nodeName = nodeName;
60 this.priority = priority;
61 this.responsibilityDesc = responsibilityDesc;
62 this.forceAction = forceAction;
63 this.recipient = recipient;
64 this.annotation = annotation;
65 this.requestLabel = requestLabel;
66 }
67
68 public void recordAction() throws InvalidActionTakenException {
69 String errorMessage = validateActionRules();
70 if (!org.apache.commons.lang.StringUtils.isEmpty(errorMessage)) {
71 throw new InvalidActionTakenException(errorMessage);
72 }
73 List targetNodes = KEWServiceLocator.getRouteNodeService().getCurrentNodeInstances(getDocumentId());
74 String error = adhocRouteAction(targetNodes, false);
75 if (!org.apache.commons.lang.StringUtils.isEmpty(error)) {
76 throw new InvalidActionTakenException(error);
77 }
78 }
79
80
81
82
83 @Override
84 public String validateActionRules() {
85 List targetNodes = KEWServiceLocator.getRouteNodeService().getCurrentNodeInstances(getDocumentId());
86 return validateActionRulesInternal(targetNodes);
87 }
88
89 @Override
90 public String validateActionRules(List<ActionRequestValue> actionRequests) {
91 return validateActionRules();
92 }
93
94 private String validateActionRulesInternal(List<RouteNodeInstance> targetNodes) {
95
96 if (recipient != null) {
97 if (recipient instanceof KimPrincipalRecipient) {
98 KimPrincipalRecipient principalRecipient = (KimPrincipalRecipient)recipient;
99 if (!KEWServiceLocator.getDocumentTypePermissionService().canReceiveAdHocRequest(principalRecipient.getPrincipalId(), getRouteHeader().getDocumentType(), actionRequested)) {
100 return "The principal '" + principalRecipient.getPrincipal().getPrincipalName() + "' does not have permission to recieve ad hoc requests on DocumentType '" + getRouteHeader().getDocumentType().getName() + "'";
101 }
102 } else if (recipient instanceof KimGroupRecipient) {
103 Group group = ((KimGroupRecipient)recipient).getGroup();
104 if (!KEWServiceLocator.getDocumentTypePermissionService().canGroupReceiveAdHocRequest("" + group.getId(), getRouteHeader().getDocumentType(), actionRequested)) {
105 return "The group '" + group.getName() + "' does not have permission to recieve ad hoc requests on DocumentType '" + getRouteHeader().getDocumentType().getName() + "'";
106 }
107 } else {
108 return "Invalid Recipient type encountered: " + recipient.getClass();
109 }
110 }
111 return adhocRouteAction(targetNodes, true);
112 }
113
114 private String adhocRouteAction(List<RouteNodeInstance> targetNodes, boolean forValidationOnly) {
115
116
117
118 boolean requestCreated = false;
119 for (RouteNodeInstance routeNode : targetNodes)
120 {
121
122 if (nodeName == null || routeNode.getName().equals(nodeName))
123 {
124 String message = createAdHocRequest(routeNode, forValidationOnly);
125 if (!StringUtils.isEmpty(message))
126 {
127 return message;
128 }
129 requestCreated = true;
130 if (nodeName == null)
131 {
132 break;
133 }
134 }
135 }
136
137 if (!requestCreated && targetNodes.isEmpty()) {
138 String message = createAdHocRequest(null, forValidationOnly);
139 if (!StringUtils.isEmpty(message)) {
140 return message;
141 }
142 requestCreated = true;
143 }
144
145 if (!requestCreated) {
146 return "Didn't create request. The node name " + nodeName + " given is probably invalid ";
147 }
148 return "";
149 }
150
151 private String createAdHocRequest(RouteNodeInstance routeNode, boolean forValidationOnly) {
152 ActionRequestValue adhocRequest = new ActionRequestValue();
153 if (!forValidationOnly) {
154 ActionRequestFactory arFactory = new ActionRequestFactory(routeHeader, routeNode);
155 adhocRequest = arFactory.createActionRequest(actionRequested, recipient, responsibilityDesc, forceAction, annotation);
156 adhocRequest.setResponsibilityId(KewApiConstants.ADHOC_REQUEST_RESPONSIBILITY_ID);
157 adhocRequest.setRequestLabel(requestLabel);
158 if (priority != null) {
159 adhocRequest.setPriority(priority);
160 }
161 } else {
162 adhocRequest.setActionRequested(actionRequested);
163 }
164 if (adhocRequest.isApproveOrCompleteRequest() && ! (routeHeader.isEnroute() || routeHeader.isStateInitiated() ||
165 routeHeader.isStateSaved())) {
166 return "Cannot AdHoc a Complete or Approve request when document is in state '" + routeHeader.getDocRouteStatusLabel() + "'.";
167 }
168 if (!forValidationOnly) {
169
170 if (routeHeader.isDisaproved() || routeHeader.isCanceled() || routeHeader.isFinal() || routeHeader.isProcessed()) {
171 getActionRequestService().activateRequest(adhocRequest);
172 } else {
173 KEWServiceLocator.getActionRequestService().saveActionRequest(adhocRequest);
174 }
175 }
176 return "";
177 }
178 }