1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.kuali.rice.kew.superuser.web;
18
19 import java.util.Collection;
20 import java.util.Iterator;
21
22 import javax.servlet.http.HttpServletRequest;
23 import javax.servlet.http.HttpServletResponse;
24 import javax.xml.namespace.QName;
25
26 import org.apache.commons.lang.ArrayUtils;
27 import org.apache.commons.lang.StringUtils;
28 import org.apache.struts.action.ActionForm;
29 import org.apache.struts.action.ActionForward;
30 import org.apache.struts.action.ActionMapping;
31 import org.kuali.rice.core.resourceloader.GlobalResourceLoader;
32 import org.kuali.rice.core.util.JSTLConstants;
33 import org.kuali.rice.kew.actionrequest.ActionRequestValue;
34 import org.kuali.rice.kew.doctype.bo.DocumentType;
35 import org.kuali.rice.kew.dto.AdHocRevokeDTO;
36 import org.kuali.rice.kew.dto.DTOConverter;
37 import org.kuali.rice.kew.dto.RouteNodeInstanceDTO;
38 import org.kuali.rice.kew.exception.WorkflowException;
39 import org.kuali.rice.kew.exception.WorkflowServiceErrorException;
40 import org.kuali.rice.kew.exception.WorkflowServiceErrorImpl;
41 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
42 import org.kuali.rice.kew.service.KEWServiceLocator;
43 import org.kuali.rice.kew.service.WorkflowDocument;
44 import org.kuali.rice.kew.service.WorkflowDocumentActions;
45 import org.kuali.rice.kew.service.WorkflowInfo;
46 import org.kuali.rice.kew.util.KEWConstants;
47 import org.kuali.rice.kew.web.AppSpecificRouteRecipient;
48 import org.kuali.rice.kew.web.KewKualiAction;
49 import org.kuali.rice.kew.web.session.UserSession;
50 import org.kuali.rice.kim.bo.entity.KimPrincipal;
51 import org.kuali.rice.kim.service.IdentityManagementService;
52 import org.kuali.rice.kim.service.KIMServiceLocator;
53 import org.kuali.rice.kns.exception.ValidationException;
54 import org.kuali.rice.kns.util.GlobalVariables;
55 import org.kuali.rice.kns.util.KNSConstants;
56
57
58
59
60
61
62
63 public class SuperUserAction extends KewKualiAction {
64 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(SuperUserAction.class);
65 public static final String UNAUTHORIZED = "authorizationFailure";
66
67
68
69
70
71 @Override
72 public ActionForward execute(ActionMapping mapping, ActionForm form,
73 HttpServletRequest request, HttpServletResponse response)
74 throws Exception {
75 initForm(request, form);
76 return super.execute(mapping, form, request, response);
77 }
78
79 @Override
80 public ActionForward refresh(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
81 ((SuperUserForm) form).getActionRequests().clear();
82 initForm(request, form);
83 return defaultDispatch(mapping, form, request, response);
84 }
85
86 public ActionForward displaySuperUserDocument(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
87 SuperUserForm superUserForm = (SuperUserForm) form;
88 superUserForm.setDocHandlerUrl(KEWConstants.DOC_HANDLER_REDIRECT_PAGE + "?docId=" + superUserForm.getRouteHeaderId() + "&" + KEWConstants.COMMAND_PARAMETER + "=" + KEWConstants.SUPERUSER_COMMAND);
89 return defaultDispatch(mapping, form, request, response);
90 }
91
92 public ActionForward routeLevelApprove(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
93 LOG.info("entering routeLevelApprove()...");
94 SuperUserForm superUserForm = (SuperUserForm) form;
95 Long documentId = superUserForm.getRouteHeader().getRouteHeaderId();
96 WorkflowDocumentActions documentActions = getWorkflowDocumentActions(documentId);
97 documentActions.superUserNodeApproveAction(getUserSession(request).getPrincipalId(), documentId, superUserForm.getDestNodeName(), superUserForm.getAnnotation(), superUserForm.isRunPostProcessorLogic());
98 saveDocumentMessage("general.routing.superuser.routeLevelApproved", request, superUserForm.getRouteHeaderIdString(), null);
99 LOG.info("exiting routeLevelApprove()...");
100 superUserForm.getActionRequests().clear();
101 initForm(request, form);
102 return defaultDispatch(mapping, form, request, response);
103 }
104
105 public ActionForward approve(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
106 LOG.info("entering approve() ...");
107 SuperUserForm superUserForm = (SuperUserForm) form;
108 Long documentId = superUserForm.getRouteHeader().getRouteHeaderId();
109 WorkflowDocumentActions documentActions = getWorkflowDocumentActions(documentId);
110 documentActions.superUserApprove(getUserSession(request).getPrincipalId(), DTOConverter.convertRouteHeader(superUserForm.getRouteHeader(), null), superUserForm.getAnnotation(), superUserForm.isRunPostProcessorLogic());
111 saveDocumentMessage("general.routing.superuser.approved", request, superUserForm.getRouteHeaderIdString(), null);
112 LOG.info("exiting approve() ...");
113 superUserForm.getActionRequests().clear();
114 initForm(request, form);
115 return defaultDispatch(mapping, form, request, response);
116 }
117
118 public ActionForward disapprove(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
119 LOG.info("entering disapprove() ...");
120 SuperUserForm superUserForm = (SuperUserForm) form;
121 Long documentId = superUserForm.getRouteHeader().getRouteHeaderId();
122 WorkflowDocumentActions documentActions = getWorkflowDocumentActions(documentId);
123 documentActions.superUserDisapprove(getUserSession(request).getPrincipalId(), DTOConverter.convertRouteHeader(superUserForm.getRouteHeader(), null), superUserForm.getAnnotation(), superUserForm.isRunPostProcessorLogic());
124 saveDocumentMessage("general.routing.superuser.disapproved", request, superUserForm.getRouteHeaderIdString(), null);
125 LOG.info("exiting disapprove() ...");
126 superUserForm.getActionRequests().clear();
127 initForm(request, form);
128 return defaultDispatch(mapping, form, request, response);
129 }
130
131 public ActionForward cancel(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
132 LOG.info("entering cancel() ...");
133 SuperUserForm superUserForm = (SuperUserForm) form;
134 Long documentId = superUserForm.getRouteHeader().getRouteHeaderId();
135 WorkflowDocumentActions documentActions = getWorkflowDocumentActions(documentId);
136 documentActions.superUserCancel(getUserSession(request).getPrincipalId(), DTOConverter.convertRouteHeader(superUserForm.getRouteHeader(), null), superUserForm.getAnnotation(), superUserForm.isRunPostProcessorLogic());
137 saveDocumentMessage("general.routing.superuser.canceled", request, superUserForm.getRouteHeaderIdString(), null);
138 LOG.info("exiting cancel() ...");
139 superUserForm.getActionRequests().clear();
140 initForm(request, form);
141 return defaultDispatch(mapping, form, request, response);
142 }
143
144 public ActionForward returnToPreviousNode(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
145 LOG.info("entering returnToPreviousNode() ...");
146 SuperUserForm superUserForm = (SuperUserForm) form;
147 Long documentId = superUserForm.getRouteHeader().getRouteHeaderId();
148 WorkflowDocumentActions documentActions = getWorkflowDocumentActions(documentId);
149 documentActions.superUserReturnToPreviousNode(getUserSession(request).getPrincipalId(), documentId, superUserForm.getReturnDestNodeName(), superUserForm.getAnnotation(), superUserForm.isRunPostProcessorLogic());
150 saveDocumentMessage("general.routing.returnedToPreviousNode", request, "document", superUserForm.getReturnDestNodeName().toString());
151 LOG.info("exiting returnToPreviousRouteLevel() ...");
152 superUserForm.getActionRequests().clear();
153 initForm(request, form);
154 return defaultDispatch(mapping, form, request, response);
155 }
156
157 public ActionForward actionRequestApprove(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
158 LOG.info("entering actionRequestApprove() ...");
159 SuperUserForm superUserForm = (SuperUserForm) form;
160
161
162 String methodToCallAttr = (String) request.getAttribute(KNSConstants.METHOD_TO_CALL_ATTRIBUTE);
163 superUserForm.setActionTakenRecipientCode(StringUtils.substringBetween(methodToCallAttr, KNSConstants.METHOD_TO_CALL_PARM1_LEFT_DEL, KNSConstants.METHOD_TO_CALL_PARM1_RIGHT_DEL));
164 superUserForm.setActionTakenNetworkId(StringUtils.substringBetween(methodToCallAttr, KNSConstants.METHOD_TO_CALL_PARM2_LEFT_DEL, KNSConstants.METHOD_TO_CALL_PARM2_RIGHT_DEL));
165 superUserForm.setActionTakenWorkGroupId(StringUtils.substringBetween(methodToCallAttr, KNSConstants.METHOD_TO_CALL_PARM4_LEFT_DEL, KNSConstants.METHOD_TO_CALL_PARM4_RIGHT_DEL));
166 superUserForm.setActionTakenActionRequestId(StringUtils.substringBetween(methodToCallAttr, KNSConstants.METHOD_TO_CALL_PARM5_LEFT_DEL, KNSConstants.METHOD_TO_CALL_PARM5_RIGHT_DEL));
167
168 LOG.debug("Routing super user action request approve action");
169 boolean runPostProcessorLogic = ArrayUtils.contains(superUserForm.getActionRequestRunPostProcessorCheck(), superUserForm.getActionTakenActionRequestId());
170 Long documentId = superUserForm.getRouteHeader().getRouteHeaderId();
171 WorkflowDocumentActions documentActions = getWorkflowDocumentActions(documentId);
172 documentActions.superUserActionRequestApproveAction(getUserSession(request).getPrincipalId(), documentId, new Long(superUserForm.getActionTakenActionRequestId()), superUserForm.getAnnotation(), runPostProcessorLogic);
173 String messageString;
174 String actionReqest = StringUtils.substringBetween(methodToCallAttr, KNSConstants.METHOD_TO_CALL_PARM6_LEFT_DEL, KNSConstants.METHOD_TO_CALL_PARM6_RIGHT_DEL);
175 if (actionReqest.equalsIgnoreCase("acknowledge")){
176 messageString = "general.routing.superuser.actionRequestAcknowledged";
177 }else if (actionReqest.equalsIgnoreCase("FYI")){
178 messageString = "general.routing.superuser.actionRequestFYI";
179 }else if (actionReqest.equalsIgnoreCase("complete")){
180 messageString = "general.routing.superuser.actionRequestCompleted";
181 }else if (actionReqest.equalsIgnoreCase("approved")){
182 messageString = "general.routing.superuser.actionRequestApproved";
183 }else {
184 messageString = "general.routing.superuser.actionRequestApproved";
185 }
186 saveDocumentMessage(messageString, request, superUserForm.getRouteHeaderIdString(), superUserForm.getActionTakenActionRequestId());
187 LOG.info("exiting actionRequestApprove() ...");
188 superUserForm.getActionRequests().clear();
189 initForm(request, form);
190
191
192 int removalIndex = findAppSpecificRecipientIndex(superUserForm, Long.parseLong(superUserForm.getActionTakenActionRequestId()));
193 if (removalIndex >= 0) {
194 superUserForm.getAppSpecificRouteList().remove(removalIndex);
195 }
196
197 return defaultDispatch(mapping, form, request, response);
198 }
199
200
201
202
203
204
205
206
207 private int findAppSpecificRecipientIndex(SuperUserForm superUserForm, long actionRequestId) {
208 int tempIndex = 0;
209 for (Iterator<?> appRouteIter = superUserForm.getAppSpecificRouteList().iterator(); appRouteIter.hasNext();) {
210 Long tempActnReqId = ((AppSpecificRouteRecipient) appRouteIter.next()).getActionRequestId();
211 if (tempActnReqId != null && tempActnReqId.longValue() == actionRequestId) {
212 return tempIndex;
213 }
214 tempIndex++;
215 }
216 return -1;
217 }
218
219 public ActionForward initForm(HttpServletRequest request, ActionForm form) throws Exception {
220 request.setAttribute("Constants", new JSTLConstants(KEWConstants.class));
221 SuperUserForm superUserForm = (SuperUserForm) form;
222 DocumentRouteHeaderValue routeHeader = KEWServiceLocator.getRouteHeaderService().getRouteHeader(superUserForm.getRouteHeaderId());
223 superUserForm.setRouteHeader(routeHeader);
224 String principalId = getUserSession(request).getPrincipalId();
225 boolean isAuthorized = KEWServiceLocator.getDocumentTypePermissionService().canAdministerRouting(principalId, routeHeader.getDocumentType());
226 superUserForm.setAuthorized(isAuthorized);
227 if (!isAuthorized) {
228 saveDocumentMessage("general.routing.superuser.notAuthorized", request, superUserForm.getRouteHeaderIdString(), null);
229 return null;
230 }
231
232 superUserForm.setFutureNodeNames(KEWServiceLocator.getRouteNodeService().findFutureNodeNames(routeHeader.getRouteHeaderId()));
233
234
235 Collection actionRequests = KEWServiceLocator.getActionRequestService().findPendingByDoc(routeHeader.getRouteHeaderId());
236 Iterator requestIterator = actionRequests.iterator();
237 while (requestIterator.hasNext()) {
238 ActionRequestValue req = (ActionRequestValue) requestIterator.next();
239
240 superUserForm.getActionRequests().add(req);
241
242 }
243
244
245 superUserForm.setDocId(superUserForm.getRouteHeaderId());
246 if (superUserForm.getDocId() != null) {
247 superUserForm.setWorkflowDocument(new WorkflowDocument(getUserSession(request).getPrincipalId(), superUserForm.getDocId()));
248 superUserForm.establishVisibleActionRequestCds();
249 }
250
251 return null;
252 }
253
254 private void saveDocumentMessage(String messageKey, HttpServletRequest request, String subVariable1, String subVariable2) {
255 if (subVariable2 == null) {
256 GlobalVariables.getMessageMap().putInfo("document", messageKey, subVariable1);
257 } else {
258 GlobalVariables.getMessageMap().putInfo("document", messageKey, subVariable1, subVariable2);
259 }
260 }
261
262 public ActionForward routeToAppSpecificRecipient(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
263 SuperUserForm superUserForm = (SuperUserForm) form;
264
265
266
267 String routeType = StringUtils.substringBetween((String) request.getAttribute(KNSConstants.METHOD_TO_CALL_ATTRIBUTE),
268 KNSConstants.METHOD_TO_CALL_PARM1_LEFT_DEL, KNSConstants.METHOD_TO_CALL_PARM1_RIGHT_DEL);
269 AppSpecificRouteRecipient recipient = null;
270 if (KEWConstants.PERSON.equals(routeType)) {
271 recipient = superUserForm.getAppSpecificRouteRecipient();
272 recipient.setActionRequested(superUserForm.getAppSpecificRouteActionRequestCd());
273 superUserForm.setAppSpecificPersonId(recipient.getId());
274 }
275 else {
276 recipient = superUserForm.getAppSpecificRouteRecipient2();
277 recipient.setActionRequested(superUserForm.getAppSpecificRouteActionRequestCd2());
278 superUserForm.setAppSpecificWorkgroupId(recipient.getId());
279 }
280
281 validateAppSpecificRoute(recipient);
282
283
284 superUserForm.establishVisibleActionRequestCds();
285 if (superUserForm.getAppSpecificRouteActionRequestCds().get(recipient.getActionRequested()) == null) {
286 GlobalVariables.getMessageMap().putError("appSpecificRouteRecipient" +
287 ((KEWConstants.WORKGROUP.equals(recipient.getType())) ? "2" : "") + ".id", "appspecificroute.actionrequested.invalid");
288
289 throw new ValidationException("The requested action of '" + recipient.getActionRequested() + "' is no longer available for this document");
290 }
291
292 try {
293 String routeNodeName = getAdHocRouteNodeName(superUserForm.getWorkflowDocument().getRouteHeaderId());
294
295 if (KEWConstants.PERSON.equals(routeType)) {
296 String recipientPrincipalId = KEWServiceLocator.getIdentityHelperService().getIdForPrincipalName(recipient.getId());
297 superUserForm.getWorkflowDocument().adHocRouteDocumentToPrincipal(recipient.getActionRequested(), routeNodeName, superUserForm.getAnnotation(), recipientPrincipalId, "", true);
298 } else {
299 String recipientGroupId = KEWServiceLocator.getIdentityHelperService().getIdForGroupName(recipient.getNamespaceCode(), recipient.getId());
300 superUserForm.getWorkflowDocument().adHocRouteDocumentToGroup(recipient.getActionRequested(), routeNodeName, superUserForm.getAnnotation(), recipientGroupId, "", true);
301 }
302 } catch (Exception e) {
303 LOG.error("Error generating app specific route request", e);
304 throw new WorkflowServiceErrorException("AppSpecific Route Error", new WorkflowServiceErrorImpl("AppSpecific Route Error", "appspecificroute.systemerror"));
305 }
306
307 superUserForm.getActionRequests().clear();
308 initForm(request, form);
309
310
311 ActionRequestValue latestActnReq = getLatestActionRequest(superUserForm);
312 if (latestActnReq != null) {
313 recipient.setActionRequestId(latestActnReq.getActionRequestId());
314 }
315
316 superUserForm.getAppSpecificRouteList().add(recipient);
317 superUserForm.resetAppSpecificRoute();
318
319 return start(mapping, form, request, response);
320 }
321
322
323
324
325
326
327 private ActionRequestValue getLatestActionRequest(SuperUserForm superUserForm) {
328 ActionRequestValue latestActnReq = null;
329 long latestId = -1;
330
331 for (Iterator<?> actnReqIter = superUserForm.getActionRequests().iterator(); actnReqIter.hasNext();) {
332 ActionRequestValue tmpActnReq = (ActionRequestValue) actnReqIter.next();
333 if (tmpActnReq.getActionRequestId().longValue() > latestId) {
334 latestActnReq = tmpActnReq;
335 latestId = tmpActnReq.getActionRequestId().longValue();
336 }
337 }
338 return latestActnReq;
339 }
340
341
342
343
344 public ActionForward removeAppSpecificRecipient(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
345 SuperUserForm superUserForm = (SuperUserForm) form;
346
347 String strIndex = StringUtils.substringBetween((String) request.getAttribute(KNSConstants.METHOD_TO_CALL_ATTRIBUTE),
348 KNSConstants.METHOD_TO_CALL_PARM1_LEFT_DEL, KNSConstants.METHOD_TO_CALL_PARM1_RIGHT_DEL);
349 if (StringUtils.isBlank(strIndex)) {
350 throw new WorkflowException("No adhoc route recipient index specified");
351 }
352 int removeIndex = Integer.parseInt(strIndex);
353 if (removeIndex < 0 || removeIndex >= superUserForm.getAppSpecificRouteList().size()) {
354 throw new WorkflowException("Invalid adhoc route recipient index specified");
355 }
356
357 AppSpecificRouteRecipient removedRec = (AppSpecificRouteRecipient) superUserForm.getAppSpecificRouteList().get(removeIndex);
358 AdHocRevokeDTO adHocRevokeDTO = new AdHocRevokeDTO();
359 if (removedRec.getActionRequestId() != null) {
360 adHocRevokeDTO.setActionRequestId(removedRec.getActionRequestId());
361 }
362
363 if (KEWConstants.PERSON.equals(removedRec.getType())) {
364 adHocRevokeDTO.setPrincipalId(KEWServiceLocator.getIdentityHelperService().getIdForPrincipalName(removedRec.getId()));
365 }
366 else {
367 adHocRevokeDTO.setGroupId(KEWServiceLocator.getIdentityHelperService().getIdForGroupName(removedRec.getNamespaceCode(), removedRec.getId()));
368 }
369 superUserForm.getWorkflowDocument().revokeAdHocRequests(adHocRevokeDTO, "");
370 superUserForm.getAppSpecificRouteList().remove(removeIndex);
371
372 superUserForm.getActionRequests().clear();
373 initForm(request, form);
374 return start(mapping, form, request, response);
375 }
376
377 private WorkflowDocumentActions getWorkflowDocumentActions(Long documentId) {
378 DocumentType documentType = KEWServiceLocator.getDocumentTypeService().findByDocumentId(documentId);
379 String serviceNamespace = documentType.getServiceNamespace();
380 WorkflowDocumentActions service = (WorkflowDocumentActions)GlobalResourceLoader.getService(new QName(serviceNamespace, "WorkflowDocumentActionsService"));
381 if (service == null) {
382 service = KEWServiceLocator.getWorkflowDocumentActionsService();
383 }
384 return service;
385 }
386
387 protected void validateAppSpecificRoute(AppSpecificRouteRecipient recipient) {
388 if (recipient.getId() == null || recipient.getId().trim().equals("")) {
389 GlobalVariables.getMessageMap().putError("appSpecificRouteRecipient" +
390 ((KEWConstants.WORKGROUP.equals(recipient.getType())) ? "2" : "") + ".id", "appspecificroute.recipient.required");
391 }
392 else {
393 if (KEWConstants.PERSON.equals(recipient.getType())) {
394 KimPrincipal principal = KIMServiceLocator.getIdentityManagementService().getPrincipalByPrincipalName(recipient.getId());
395 if (principal == null) {
396 LOG.error("App Specific user recipient not found");
397 GlobalVariables.getMessageMap().putError("appSpecificRouteRecipient.id", "appspecificroute.user.invalid");
398 }
399 }
400 else if (KEWConstants.WORKGROUP.equals(recipient.getType())) {
401
402 if (getIdentityManagementService().getGroupByName(recipient.getNamespaceCode(), recipient.getId()) == null) {
403 GlobalVariables.getMessageMap().putError("appSpecificRouteRecipient2.id", "appspecificroute.workgroup.invalid");
404 }
405 }
406 }
407 if (GlobalVariables.getMessageMap().hasErrors()) {
408 throw new ValidationException("AppSpecific Route validation Errors");
409 }
410
411 }
412
413 protected String getAdHocRouteNodeName(Long routeHeaderId) throws WorkflowException {
414 WorkflowInfo info = new WorkflowInfo();
415 RouteNodeInstanceDTO[] nodeInstances = info.getActiveNodeInstances(routeHeaderId);
416 if (nodeInstances == null || nodeInstances.length == 0) {
417 nodeInstances = info.getTerminalNodeInstances(routeHeaderId);
418 }
419 if (nodeInstances == null || nodeInstances.length == 0) {
420 throw new WorkflowException("Could not locate a node on the document to send the ad hoc request to.");
421 }
422 return nodeInstances[0].getName();
423 }
424
425 private IdentityManagementService getIdentityManagementService() {
426 return (IdentityManagementService) KIMServiceLocator.getService(KIMServiceLocator.KIM_IDENTITY_MANAGEMENT_SERVICE);
427 }
428 public static UserSession getUserSession(HttpServletRequest request) {
429 return UserSession.getAuthenticatedUser();
430 }
431
432 }