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