Coverage Report - org.kuali.rice.kew.superuser.web.SuperUserAction
 
Classes in this File Line Coverage Branch Coverage Complexity
SuperUserAction
0%
0/218
0%
0/72
3.81
SuperUserAction$1
0%
0/14
0%
0/16
3.81
 
 1  
 /*
 2  
  * Copyright 2005-2007 The Kuali Foundation
 3  
  *
 4  
  *
 5  
  * Licensed under the Educational Community License, Version 2.0 (the "License");
 6  
  * you may not use this file except in compliance with the License.
 7  
  * You may obtain a copy of the License at
 8  
  *
 9  
  * http://www.opensource.org/licenses/ecl2.php
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 package org.kuali.rice.kew.superuser.web;
 18  
 
 19  
 import java.util.Collection;
 20  
 import java.util.Collections;
 21  
 import java.util.Comparator;
 22  
 import java.util.Iterator;
 23  
 import java.util.List;
 24  
 
 25  
 import javax.servlet.http.HttpServletRequest;
 26  
 import javax.servlet.http.HttpServletResponse;
 27  
 import javax.xml.namespace.QName;
 28  
 
 29  
 import org.apache.commons.lang.ArrayUtils;
 30  
 import org.apache.commons.lang.StringUtils;
 31  
 import org.apache.struts.action.ActionForm;
 32  
 import org.apache.struts.action.ActionForward;
 33  
 import org.apache.struts.action.ActionMapping;
 34  
 import org.kuali.rice.kew.actionrequest.ActionRequestValue;
 35  
 import org.kuali.rice.kew.api.KewApiConstants;
 36  
 import org.kuali.rice.kew.api.KewApiServiceLocator;
 37  
 import org.kuali.rice.kew.api.WorkflowDocumentFactory;
 38  
 import org.kuali.rice.kew.api.action.ActionRequestType;
 39  
 import org.kuali.rice.kew.api.action.AdHocRevoke;
 40  
 import org.kuali.rice.kew.api.action.DocumentActionParameters;
 41  
 import org.kuali.rice.kew.api.action.ReturnPoint;
 42  
 import org.kuali.rice.kew.api.action.WorkflowDocumentActionsService;
 43  
 import org.kuali.rice.kew.doctype.bo.DocumentType;
 44  
 import org.kuali.rice.kew.dto.RouteNodeInstanceDTO;
 45  
 import org.kuali.rice.kew.exception.WorkflowException;
 46  
 import org.kuali.rice.kew.exception.WorkflowServiceErrorException;
 47  
 import org.kuali.rice.kew.exception.WorkflowServiceErrorImpl;
 48  
 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
 49  
 import org.kuali.rice.kew.service.KEWServiceLocator;
 50  
 import org.kuali.rice.kew.service.WorkflowInfo;
 51  
 import org.kuali.rice.kew.util.KEWConstants;
 52  
 import org.kuali.rice.kew.web.AppSpecificRouteRecipient;
 53  
 import org.kuali.rice.kew.web.KewKualiAction;
 54  
 import org.kuali.rice.kim.api.group.GroupService;
 55  
 import org.kuali.rice.kim.api.identity.principal.Principal;
 56  
 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
 57  
 import org.kuali.rice.krad.UserSession;
 58  
 import org.kuali.rice.krad.exception.ValidationException;
 59  
 import org.kuali.rice.krad.util.GlobalVariables;
 60  
 import org.kuali.rice.krad.util.KRADConstants;
 61  
 import org.kuali.rice.ksb.api.KsbApiServiceLocator;
 62  
 
 63  
 /**
 64  
  * A Struts Action which provides super user functionality.
 65  
  * 
 66  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 67  
  */
 68  0
 public class SuperUserAction extends KewKualiAction {
 69  0
     private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(SuperUserAction.class);
 70  
     public static final String UNAUTHORIZED = "authorizationFailure";
 71  
 
 72  
     //public ActionForward start(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
 73  
     //        defaultDispatch(mapping, form, request, response);
 74  
     //}
 75  
 
 76  
     @Override
 77  
     public ActionForward execute(ActionMapping mapping, ActionForm form,
 78  
             HttpServletRequest request, HttpServletResponse response)
 79  
             throws Exception {
 80  0
         initForm(request, form);
 81  0
         return super.execute(mapping, form, request, response);
 82  
     }
 83  
 
 84  
     @Override
 85  
     public ActionForward refresh(ActionMapping mapping, ActionForm form, HttpServletRequest request,
 86  
             HttpServletResponse response) throws Exception {
 87  0
         ((SuperUserForm) form).getActionRequests().clear();
 88  0
         initForm(request, form);
 89  0
         return defaultDispatch(mapping, form, request, response);
 90  
     }
 91  
 
 92  
     public ActionForward displaySuperUserDocument(ActionMapping mapping, ActionForm form, HttpServletRequest request,
 93  
             HttpServletResponse response) throws Exception {
 94  0
         SuperUserForm superUserForm = (SuperUserForm) form;
 95  0
         superUserForm.setDocHandlerUrl(KEWConstants.DOC_HANDLER_REDIRECT_PAGE + "?docId="
 96  
                 + superUserForm.getDocumentId() + "&" + KEWConstants.COMMAND_PARAMETER + "="
 97  
                 + KEWConstants.SUPERUSER_COMMAND);
 98  0
         return defaultDispatch(mapping, form, request, response);
 99  
     }
 100  
 
 101  
     public ActionForward routeLevelApprove(ActionMapping mapping, ActionForm form, HttpServletRequest request,
 102  
             HttpServletResponse response) throws Exception {
 103  0
         LOG.info("entering routeLevelApprove()...");
 104  0
         SuperUserForm superUserForm = (SuperUserForm) form;
 105  0
         String documentId = superUserForm.getRouteHeader().getDocumentId();
 106  0
         WorkflowDocumentActionsService documentActions = getWorkflowDocumentActionsService(documentId);
 107  0
         DocumentActionParameters parameters = DocumentActionParameters.create(documentId, getUserSession(request)
 108  
                 .getPrincipalId(), superUserForm.getAnnotation());
 109  
 
 110  0
         documentActions.superUserNodeApprove(parameters, superUserForm.isRunPostProcessorLogic(),
 111  
                 superUserForm.getDestNodeName());
 112  0
         saveDocumentMessage("general.routing.superuser.routeLevelApproved", request, superUserForm.getDocumentId(),
 113  
                 null);
 114  0
         LOG.info("exiting routeLevelApprove()...");
 115  0
         superUserForm.getActionRequests().clear();
 116  0
         initForm(request, form);
 117  0
         return defaultDispatch(mapping, form, request, response);
 118  
     }
 119  
 
 120  
     public ActionForward approve(ActionMapping mapping, ActionForm form, HttpServletRequest request,
 121  
             HttpServletResponse response) throws Exception {
 122  0
         LOG.info("entering approve() ...");
 123  0
         SuperUserForm superUserForm = (SuperUserForm) form;
 124  0
         String documentId = superUserForm.getRouteHeader().getDocumentId();
 125  0
         WorkflowDocumentActionsService documentActions = getWorkflowDocumentActionsService(documentId);
 126  0
         DocumentActionParameters parameters = DocumentActionParameters.create(documentId, getUserSession(request)
 127  
                 .getPrincipalId(), superUserForm.getAnnotation());
 128  0
         documentActions.superUserBlanketApprove(parameters, superUserForm.isRunPostProcessorLogic());
 129  0
         saveDocumentMessage("general.routing.superuser.approved", request, superUserForm.getDocumentId(), null);
 130  0
         LOG.info("exiting approve() ...");
 131  0
         superUserForm.getActionRequests().clear();
 132  0
         initForm(request, form);
 133  0
         return defaultDispatch(mapping, form, request, response);
 134  
     }
 135  
 
 136  
     public ActionForward disapprove(ActionMapping mapping, ActionForm form, HttpServletRequest request,
 137  
             HttpServletResponse response) throws Exception {
 138  0
         LOG.info("entering disapprove() ...");
 139  0
         SuperUserForm superUserForm = (SuperUserForm) form;
 140  0
         String documentId = superUserForm.getRouteHeader().getDocumentId();
 141  0
         WorkflowDocumentActionsService documentActions = getWorkflowDocumentActionsService(documentId);
 142  0
         DocumentActionParameters parameters = DocumentActionParameters.create(documentId, getUserSession(request)
 143  
                 .getPrincipalId(), superUserForm.getAnnotation());
 144  0
         documentActions.superUserDisapprove(parameters, superUserForm.isRunPostProcessorLogic());
 145  0
         saveDocumentMessage("general.routing.superuser.disapproved", request, superUserForm.getDocumentId(), null);
 146  0
         LOG.info("exiting disapprove() ...");
 147  0
         superUserForm.getActionRequests().clear();
 148  0
         initForm(request, form);
 149  0
         return defaultDispatch(mapping, form, request, response);
 150  
     }
 151  
 
 152  
     public ActionForward cancel(ActionMapping mapping, ActionForm form, HttpServletRequest request,
 153  
             HttpServletResponse response) throws Exception {
 154  0
         LOG.info("entering cancel() ...");
 155  0
         SuperUserForm superUserForm = (SuperUserForm) form;
 156  0
         String documentId = superUserForm.getRouteHeader().getDocumentId();
 157  0
         WorkflowDocumentActionsService documentActions = getWorkflowDocumentActionsService(documentId);
 158  0
         DocumentActionParameters parameters = DocumentActionParameters.create(documentId, getUserSession(request)
 159  
                 .getPrincipalId(), superUserForm.getAnnotation());
 160  0
         documentActions.superUserCancel(parameters, superUserForm.isRunPostProcessorLogic());
 161  0
         saveDocumentMessage("general.routing.superuser.canceled", request, superUserForm.getDocumentId(), null);
 162  0
         LOG.info("exiting cancel() ...");
 163  0
         superUserForm.getActionRequests().clear();
 164  0
         initForm(request, form);
 165  0
         return defaultDispatch(mapping, form, request, response);
 166  
     }
 167  
 
 168  
     public ActionForward returnToPreviousNode(ActionMapping mapping, ActionForm form, HttpServletRequest request,
 169  
             HttpServletResponse response) throws Exception {
 170  0
         LOG.info("entering returnToPreviousNode() ...");
 171  0
         SuperUserForm superUserForm = (SuperUserForm) form;
 172  0
         String documentId = superUserForm.getRouteHeader().getDocumentId();
 173  0
         WorkflowDocumentActionsService documentActions = getWorkflowDocumentActionsService(documentId);
 174  0
         DocumentActionParameters parameters = DocumentActionParameters.create(documentId, getUserSession(request)
 175  
                 .getPrincipalId(), superUserForm.getAnnotation());
 176  0
         documentActions.superUserReturnToPreviousNode(parameters, superUserForm.isRunPostProcessorLogic(),
 177  
                 ReturnPoint.create(superUserForm.getReturnDestNodeName()));
 178  0
         saveDocumentMessage("general.routing.returnedToPreviousNode", request, "document", superUserForm
 179  
                 .getReturnDestNodeName().toString());
 180  0
         LOG.info("exiting returnToPreviousRouteLevel() ...");
 181  0
         superUserForm.getActionRequests().clear();
 182  0
         initForm(request, form);
 183  0
         return defaultDispatch(mapping, form, request, response);
 184  
     }
 185  
 
 186  
     public ActionForward actionRequestApprove(ActionMapping mapping, ActionForm form, HttpServletRequest request,
 187  
             HttpServletResponse response) throws Exception {
 188  0
         LOG.info("entering actionRequestApprove() ...");
 189  0
         SuperUserForm superUserForm = (SuperUserForm) form;
 190  
 
 191  
         // Retrieve the relevant arguments from the "methodToCall" parameter.
 192  0
         String methodToCallAttr = (String) request.getAttribute(KRADConstants.METHOD_TO_CALL_ATTRIBUTE);
 193  0
         superUserForm.setActionTakenRecipientCode(StringUtils.substringBetween(methodToCallAttr,
 194  
                 KRADConstants.METHOD_TO_CALL_PARM1_LEFT_DEL, KRADConstants.METHOD_TO_CALL_PARM1_RIGHT_DEL));
 195  0
         superUserForm.setActionTakenNetworkId(StringUtils.substringBetween(methodToCallAttr,
 196  
                 KRADConstants.METHOD_TO_CALL_PARM2_LEFT_DEL, KRADConstants.METHOD_TO_CALL_PARM2_RIGHT_DEL));
 197  0
         superUserForm.setActionTakenWorkGroupId(StringUtils.substringBetween(methodToCallAttr,
 198  
                 KRADConstants.METHOD_TO_CALL_PARM4_LEFT_DEL, KRADConstants.METHOD_TO_CALL_PARM4_RIGHT_DEL));
 199  0
         superUserForm.setActionTakenActionRequestId(StringUtils.substringBetween(methodToCallAttr,
 200  
                 KRADConstants.METHOD_TO_CALL_PARM5_LEFT_DEL, KRADConstants.METHOD_TO_CALL_PARM5_RIGHT_DEL));
 201  
 
 202  0
         LOG.debug("Routing super user action request approve action");
 203  0
         boolean runPostProcessorLogic = ArrayUtils.contains(superUserForm.getActionRequestRunPostProcessorCheck(),
 204  
                 superUserForm.getActionTakenActionRequestId());
 205  0
         String documentId = superUserForm.getRouteHeader().getDocumentId();
 206  0
         WorkflowDocumentActionsService documentActions = getWorkflowDocumentActionsService(documentId);
 207  0
         DocumentActionParameters parameters = DocumentActionParameters.create(documentId, getUserSession(request)
 208  
                 .getPrincipalId(), superUserForm.getAnnotation());
 209  0
         documentActions.superUserTakeRequestedAction(parameters, runPostProcessorLogic,
 210  
                 superUserForm.getActionTakenActionRequestId());
 211  
         String messageString;
 212  0
         String actionReqest = StringUtils.substringBetween(methodToCallAttr,
 213  
                 KRADConstants.METHOD_TO_CALL_PARM6_LEFT_DEL, KRADConstants.METHOD_TO_CALL_PARM6_RIGHT_DEL);
 214  0
         if (actionReqest.equalsIgnoreCase("acknowledge")) {
 215  0
             messageString = "general.routing.superuser.actionRequestAcknowledged";
 216  0
         } else if (actionReqest.equalsIgnoreCase("FYI")) {
 217  0
             messageString = "general.routing.superuser.actionRequestFYI";
 218  0
         } else if (actionReqest.equalsIgnoreCase("complete")) {
 219  0
             messageString = "general.routing.superuser.actionRequestCompleted";
 220  0
         } else if (actionReqest.equalsIgnoreCase("approved")) {
 221  0
             messageString = "general.routing.superuser.actionRequestApproved";
 222  
         } else {
 223  0
             messageString = "general.routing.superuser.actionRequestApproved";
 224  
         }
 225  0
         saveDocumentMessage(messageString, request, superUserForm.getDocumentId(),
 226  
                 superUserForm.getActionTakenActionRequestId());
 227  0
         LOG.info("exiting actionRequestApprove() ...");
 228  0
         superUserForm.getActionRequests().clear();
 229  0
         initForm(request, form);
 230  
 
 231  
         // If the action request was also an app specific request, remove it from the app specific route recipient list.
 232  0
         int removalIndex = findAppSpecificRecipientIndex(superUserForm, superUserForm.getActionTakenActionRequestId());
 233  
 
 234  0
         if (removalIndex >= 0) {
 235  0
             superUserForm.getAppSpecificRouteList().remove(removalIndex);
 236  
         }
 237  
 
 238  0
         return defaultDispatch(mapping, form, request, response);
 239  
     }
 240  
 
 241  
     /**
 242  
      * Finds the index in the app specific route recipient list of the recipient whose routing was
 243  
      * handled by the given action request.
 244  
      * 
 245  
      * @param superUserForm The SuperUserForm currently being processed.
 246  
      * @param actionRequestId The ID of the action request that handled the routing of the app
 247  
      *        specific recipient that is being removed.
 248  
      * @return The index of the app specific route recipient that was handled by the given action
 249  
      *         request, or -1 if no such recipient was found.
 250  
      */
 251  
     private int findAppSpecificRecipientIndex(SuperUserForm superUserForm, String actionRequestId) {
 252  0
             int tempIndex = 0;
 253  0
             for (Iterator<?> appRouteIter = superUserForm.getAppSpecificRouteList().iterator(); appRouteIter.hasNext();) {
 254  0
                     String tempActnReqId = ((AppSpecificRouteRecipient) appRouteIter.next()).getActionRequestId();
 255  0
                     if (StringUtils.equals(tempActnReqId, actionRequestId)) {
 256  0
                             return tempIndex;
 257  
                     }
 258  0
                     tempIndex++;
 259  0
             }
 260  0
             return -1;
 261  
     }
 262  
 
 263  
     public ActionForward initForm(HttpServletRequest request, ActionForm form) throws Exception {
 264  0
         request.setAttribute("Constants", getServlet().getServletContext().getAttribute("KEWConstants"));
 265  0
         SuperUserForm superUserForm = (SuperUserForm) form;
 266  0
         DocumentRouteHeaderValue routeHeader = KEWServiceLocator.getRouteHeaderService().getRouteHeader(
 267  
                 superUserForm.getDocumentId());
 268  0
         superUserForm.setRouteHeader(routeHeader);
 269  0
         String principalId = getUserSession(request).getPrincipalId();
 270  0
         boolean isAuthorized = KEWServiceLocator.getDocumentTypePermissionService().canAdministerRouting(principalId,
 271  
                 routeHeader.getDocumentType());
 272  0
         superUserForm.setAuthorized(isAuthorized);
 273  0
         if (!isAuthorized) {
 274  0
             saveDocumentMessage("general.routing.superuser.notAuthorized", request, superUserForm.getDocumentId(), null);
 275  0
             return null;
 276  
         }
 277  
 
 278  0
         superUserForm.setFutureNodeNames(KEWServiceLocator.getRouteNodeService().findFutureNodeNames(
 279  
                 routeHeader.getDocumentId()));
 280  
 
 281  0
         Collection actionRequests = KEWServiceLocator.getActionRequestService().findPendingByDoc(
 282  
                 routeHeader.getDocumentId());
 283  0
         Iterator requestIterator = actionRequests.iterator();
 284  0
         while (requestIterator.hasNext()) {
 285  0
             ActionRequestValue req = (ActionRequestValue) requestIterator.next();
 286  
             // if (KEWConstants.ACTION_REQUEST_APPROVE_REQ.equalsIgnoreCase(req.getActionRequested())) {
 287  0
             superUserForm.getActionRequests().add(req);
 288  
             // }
 289  0
         }
 290  
 
 291  0
         superUserForm.setDocId(superUserForm.getDocumentId());
 292  0
         if (superUserForm.getDocId() != null) {
 293  0
             superUserForm.setWorkflowDocument(WorkflowDocumentFactory.loadDocument(getUserSession(request)
 294  
                     .getPrincipalId(), superUserForm.getDocId()));
 295  0
             superUserForm.establishVisibleActionRequestCds();
 296  
         }
 297  
 
 298  0
         return null;
 299  
     }
 300  
 
 301  
     private void saveDocumentMessage(String messageKey, HttpServletRequest request, String subVariable1,
 302  
             String subVariable2) {
 303  0
         if (subVariable2 == null) {
 304  0
             GlobalVariables.getMessageMap().putInfo("document", messageKey, subVariable1);
 305  
         } else {
 306  0
             GlobalVariables.getMessageMap().putInfo("document", messageKey, subVariable1, subVariable2);
 307  
         }
 308  0
     }
 309  
 
 310  
     public ActionForward routeToAppSpecificRecipient(ActionMapping mapping, ActionForm form,
 311  
             HttpServletRequest request, HttpServletResponse response) throws Exception {
 312  0
         SuperUserForm superUserForm = (SuperUserForm) form;
 313  
 
 314  
         //super.routeToAppSpecificRecipient(mapping, form, request, response);
 315  
         //WorkflowRoutingForm routingForm = (WorkflowRoutingForm) form;
 316  0
         String routeType = StringUtils.substringBetween(
 317  
                 (String) request.getAttribute(KRADConstants.METHOD_TO_CALL_ATTRIBUTE),
 318  
                 KRADConstants.METHOD_TO_CALL_PARM1_LEFT_DEL, KRADConstants.METHOD_TO_CALL_PARM1_RIGHT_DEL);
 319  0
         AppSpecificRouteRecipient recipient = null;
 320  0
         if (KEWConstants.PERSON.equals(routeType)) {
 321  0
             recipient = superUserForm.getAppSpecificRouteRecipient();
 322  0
             recipient.setActionRequested(superUserForm.getAppSpecificRouteActionRequestCd());
 323  0
             superUserForm.setAppSpecificPersonId(recipient.getId());
 324  
         } else {
 325  0
             recipient = superUserForm.getAppSpecificRouteRecipient2();
 326  0
             recipient.setActionRequested(superUserForm.getAppSpecificRouteActionRequestCd2());
 327  0
             superUserForm.setAppSpecificWorkgroupId(recipient.getId());
 328  
         }
 329  
 
 330  0
         validateAppSpecificRoute(recipient);
 331  
 
 332  
         // Make sure that the requested action is still available.
 333  0
         superUserForm.establishVisibleActionRequestCds();
 334  0
         if (superUserForm.getAppSpecificRouteActionRequestCds().get(recipient.getActionRequested()) == null) {
 335  0
             GlobalVariables.getMessageMap().putError("appSpecificRouteRecipient" +
 336  
                     ((KEWConstants.WORKGROUP.equals(recipient.getType())) ? "2" : "") + ".id",
 337  
                     "appspecificroute.actionrequested.invalid");
 338  
 
 339  0
             throw new ValidationException("The requested action of '" + recipient.getActionRequested()
 340  
                     + "' is no longer available for this document");
 341  
         }
 342  
 
 343  
         try {
 344  0
             String routeNodeName = getAdHocRouteNodeName(superUserForm.getWorkflowDocument().getDocumentId());
 345  
             //if (KEWConstants.PERSON.equals(recipient.getType())) {
 346  0
             if (KEWConstants.PERSON.equals(routeType)) {
 347  0
                 String recipientPrincipalId = KEWServiceLocator.getIdentityHelperService().getIdForPrincipalName(
 348  
                         recipient.getId());
 349  0
                 superUserForm.getWorkflowDocument().adHocToPrincipal(
 350  
                         ActionRequestType.fromCode(recipient.getActionRequested()), routeNodeName,
 351  
                         superUserForm.getAnnotation(), recipientPrincipalId, "", true);
 352  0
             } else {
 353  0
                 String recipientGroupId = KEWServiceLocator.getIdentityHelperService().getIdForGroupName(
 354  
                         recipient.getNamespaceCode(), recipient.getId());
 355  0
                 superUserForm.getWorkflowDocument().adHocToGroup(
 356  
                         ActionRequestType.fromCode(recipient.getActionRequested()), routeNodeName,
 357  
                         superUserForm.getAnnotation(), recipientGroupId, "", true);
 358  
             }
 359  0
         } catch (Exception e) {
 360  0
             LOG.error("Error generating app specific route request", e);
 361  0
             throw new WorkflowServiceErrorException("AppSpecific Route Error", new WorkflowServiceErrorImpl(
 362  
                     "AppSpecific Route Error", "appspecificroute.systemerror"));
 363  0
         }
 364  
 
 365  0
         superUserForm.getActionRequests().clear();
 366  0
         initForm(request, form);
 367  
 
 368  
         // Retrieve the ID of the latest action request and store it with the app specific route recipient.
 369  0
         ActionRequestValue latestActnReq = getLatestActionRequest(superUserForm);
 370  0
         if (latestActnReq != null) {
 371  0
             recipient.setActionRequestId(latestActnReq.getActionRequestId());
 372  
         }
 373  
         // Add the recipient to the list.
 374  0
         superUserForm.getAppSpecificRouteList().add(recipient);
 375  0
         superUserForm.resetAppSpecificRoute();
 376  
 
 377  0
         return start(mapping, form, request, response);
 378  
     }
 379  
 
 380  
     /**
 381  
      * Searches the current action requests list for the most recent request, which is the one with
 382  
      * the highest ID.
 383  
      * @param superUserForm The SuperUserForm currently being processed.
 384  
      * @return The action request on the form with the highest ID, or null if no action requests
 385  
      *         exist in the list.
 386  
      */
 387  
     private ActionRequestValue getLatestActionRequest(SuperUserForm superUserForm) {
 388  0
             ActionRequestValue latestActnReq = null;
 389  
 //            long latestId = -1;
 390  
             
 391  
             // FIXME: KULRICE-5201 required the following refactor since action request ids are no longer numeric (and in any case the assumption that
 392  
             // they are strictly ordinal by time of creation may be false)
 393  0
             List<ActionRequestValue> actionRequests = superUserForm.getActionRequests();
 394  
             
 395  0
             if (actionRequests != null && actionRequests.size() > 0) {
 396  0
                     Collections.sort(actionRequests, new Comparator<ActionRequestValue>() {
 397  
         
 398  
                                 @Override
 399  
                                 // Should should by date in descending order
 400  
                                 public int compare(ActionRequestValue o1, ActionRequestValue o2) {
 401  0
                                         if (o1 == null && o2 == null)
 402  0
                                                 return 0;
 403  0
                                         if (o1 == null)
 404  0
                                                 return -1;
 405  0
                                         if (o2 == null)
 406  0
                                                 return 1;
 407  
                                         
 408  0
                                         if (o1.getCreateDate() == null && o2.getCreateDate() == null)
 409  0
                                                 return 0;
 410  0
                                         if (o1.getCreateDate() == null)
 411  0
                                                 return -1;
 412  0
                                         if (o2.getCreateDate() == null)
 413  0
                                                 return 1;
 414  
         
 415  0
                                         return o2.getCreateDate().compareTo(o1.getCreateDate());
 416  
                                 }
 417  
                     
 418  
                     });
 419  
 
 420  
                     // If the list above is sorted in descending order then the first item should be the most recent
 421  0
                     latestActnReq = actionRequests.get(0);
 422  
             }
 423  
             
 424  
             // TODO: As part of KULRICE-5329 this change above needs to be verified and compared with code below
 425  
 //            // Search the list for the action request with the highest action request value.
 426  
 //            for (Iterator<?> actnReqIter = superUserForm.getActionRequests().iterator(); actnReqIter.hasNext();) {
 427  
 //                    ActionRequestValue tmpActnReq = (ActionRequestValue) actnReqIter.next();
 428  
 //                    if (tmpActnReq.getActionRequestId().longValue() > latestId) {
 429  
 //                            latestActnReq = tmpActnReq;
 430  
 //                            latestId = tmpActnReq.getActionRequestId().longValue();
 431  
 //                    }
 432  
 //            }
 433  0
             return latestActnReq;
 434  
     }
 435  
 
 436  
     /**
 437  
      * Removes an existing AppSpecificRouteRecipient from the list.
 438  
      */
 439  
     public ActionForward removeAppSpecificRecipient(ActionMapping mapping, ActionForm form, HttpServletRequest request,
 440  
             HttpServletResponse response) throws Exception {
 441  0
         SuperUserForm superUserForm = (SuperUserForm) form;
 442  
         // Make sure a valid route recipient index was specified in the "methodToCall" attribute.
 443  0
         String strIndex = StringUtils.substringBetween(
 444  
                 (String) request.getAttribute(KRADConstants.METHOD_TO_CALL_ATTRIBUTE),
 445  
                 KRADConstants.METHOD_TO_CALL_PARM1_LEFT_DEL, KRADConstants.METHOD_TO_CALL_PARM1_RIGHT_DEL);
 446  0
         if (StringUtils.isBlank(strIndex)) {
 447  0
             throw new WorkflowException("No adhoc route recipient index specified");
 448  
         }
 449  0
         int removeIndex = Integer.parseInt(strIndex);
 450  0
         if (removeIndex < 0 || removeIndex >= superUserForm.getAppSpecificRouteList().size()) {
 451  0
             throw new WorkflowException("Invalid adhoc route recipient index specified");
 452  
         }
 453  
         // Remove the specified recipient from the routing, based on the recipient's ID and the ID of the action request that handled the recipient.
 454  0
         AppSpecificRouteRecipient removedRec = (AppSpecificRouteRecipient) superUserForm.getAppSpecificRouteList().get(
 455  
                 removeIndex);
 456  0
         if (removedRec.getActionRequestId() != null) {
 457  0
             superUserForm.getWorkflowDocument().revokeAdHocRequestById(removedRec.getActionRequestId().toString(), "");
 458  
         } else {
 459  0
             AdHocRevoke adHocRevoke = null;
 460  
             // Set the ID according to whether the recipient is a person or a group.
 461  0
             if (KEWConstants.PERSON.equals(removedRec.getType())) {
 462  0
                 adHocRevoke = AdHocRevoke.createRevokeFromPrincipal(KEWServiceLocator.getIdentityHelperService()
 463  
                         .getIdForPrincipalName(removedRec.getId()));
 464  
             } else {
 465  0
                 adHocRevoke = AdHocRevoke.createRevokeFromGroup(KEWServiceLocator.getIdentityHelperService()
 466  
                         .getIdForGroupName(removedRec.getNamespaceCode(), removedRec.getId()));
 467  
             }
 468  0
             superUserForm.getWorkflowDocument().revokeAdHocRequests(adHocRevoke, "");
 469  
         }
 470  0
         superUserForm.getAppSpecificRouteList().remove(removeIndex);
 471  
 
 472  0
         superUserForm.getActionRequests().clear();
 473  0
         initForm(request, form);
 474  0
         return start(mapping, form, request, response);
 475  
     }
 476  
 
 477  
     private WorkflowDocumentActionsService getWorkflowDocumentActionsService(String documentId) {
 478  0
         DocumentType documentType = KEWServiceLocator.getDocumentTypeService().findByDocumentId(documentId);
 479  0
         String applicationId = documentType.getApplicationId();
 480  0
         QName serviceName = new QName(KewApiConstants.Namespaces.KEW_NAMESPACE_2_0,
 481  
                 KewApiConstants.ServiceNames.WORKFLOW_DOCUMENT_ACTIONS_SERVICE_SOAP);
 482  0
         WorkflowDocumentActionsService service = (WorkflowDocumentActionsService) KsbApiServiceLocator.getServiceBus()
 483  
                 .getService(serviceName, applicationId);
 484  0
         if (service == null) {
 485  0
             service = KewApiServiceLocator.getWorkflowDocumentActionsService();
 486  
         }
 487  0
         return service;
 488  
     }
 489  
 
 490  
     protected void validateAppSpecificRoute(AppSpecificRouteRecipient recipient) {
 491  0
         if (recipient.getId() == null || recipient.getId().trim().equals("")) {
 492  0
             GlobalVariables.getMessageMap().putError("appSpecificRouteRecipient" +
 493  
                     ((KEWConstants.WORKGROUP.equals(recipient.getType())) ? "2" : "") + ".id",
 494  
                     "appspecificroute.recipient.required");
 495  
         } else {
 496  0
             if (KEWConstants.PERSON.equals(recipient.getType())) {
 497  0
                 Principal principal = KimApiServiceLocator.getIdentityService().getPrincipalByPrincipalName(
 498  
                         recipient.getId());
 499  0
                 if (principal == null) {
 500  0
                     LOG.error("App Specific user recipient not found");
 501  0
                     GlobalVariables.getMessageMap().putError("appSpecificRouteRecipient.id",
 502  
                             "appspecificroute.user.invalid");
 503  
                 }
 504  0
             } else if (KEWConstants.WORKGROUP.equals(recipient.getType())) {
 505  
                 //if (getIdentityManagementService().getGroup(recipient.getId()) == null) {
 506  0
                 if (getGroupService().getGroupByName(recipient.getNamespaceCode(), recipient.getId()) == null) {
 507  0
                     GlobalVariables.getMessageMap().putError("appSpecificRouteRecipient2.id",
 508  
                             "appspecificroute.workgroup.invalid");
 509  
                 }
 510  
             }
 511  
         }
 512  0
         if (GlobalVariables.getMessageMap().hasErrors()) {
 513  0
             throw new ValidationException("AppSpecific Route validation Errors");
 514  
         }
 515  
 
 516  0
     }
 517  
 
 518  
     protected String getAdHocRouteNodeName(String documentId) throws WorkflowException {
 519  0
         WorkflowInfo info = new WorkflowInfo();
 520  0
         RouteNodeInstanceDTO[] nodeInstances = info.getActiveNodeInstances(documentId);
 521  0
         if (nodeInstances == null || nodeInstances.length == 0) {
 522  0
             nodeInstances = info.getTerminalNodeInstances(documentId);
 523  
         }
 524  0
         if (nodeInstances == null || nodeInstances.length == 0) {
 525  0
             throw new WorkflowException("Could not locate a node on the document to send the ad hoc request to.");
 526  
         }
 527  0
         return nodeInstances[0].getName();
 528  
     }
 529  
 
 530  
     private GroupService getGroupService() {
 531  0
         return KimApiServiceLocator.getGroupService();
 532  
     }
 533  
 
 534  
     public static UserSession getUserSession(HttpServletRequest request) {
 535  0
         return GlobalVariables.getUserSession();
 536  
     }
 537  
 
 538  
 }