Coverage Report - org.kuali.rice.kew.actionrequest.service.impl.ActionRequestServiceImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
ActionRequestServiceImpl
0%
0/469
0%
0/338
3.573
 
 1  
 /**
 2  
  * Copyright 2005-2011 The Kuali Foundation
 3  
  *
 4  
  * Licensed under the Educational Community License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  * http://www.opensource.org/licenses/ecl2.php
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 package org.kuali.rice.kew.actionrequest.service.impl;
 17  
 
 18  
 import java.util.ArrayList;
 19  
 import java.util.Collection;
 20  
 import java.util.Collections;
 21  
 import java.util.HashMap;
 22  
 import java.util.HashSet;
 23  
 import java.util.Iterator;
 24  
 import java.util.List;
 25  
 import java.util.Map;
 26  
 import java.util.Set;
 27  
 
 28  
 import org.apache.commons.lang.ObjectUtils;
 29  
 import org.apache.commons.lang.StringUtils;
 30  
 import org.apache.log4j.Logger;
 31  
 import org.kuali.rice.core.api.config.CoreConfigHelper;
 32  
 import org.kuali.rice.core.api.exception.RiceRuntimeException;
 33  
 import org.kuali.rice.core.framework.services.CoreFrameworkServiceLocator;
 34  
 import org.kuali.rice.kew.actionitem.ActionItem;
 35  
 import org.kuali.rice.kew.actionlist.service.ActionListService;
 36  
 import org.kuali.rice.kew.actionrequest.ActionRequestValue;
 37  
 import org.kuali.rice.kew.actionrequest.Recipient;
 38  
 import org.kuali.rice.kew.actionrequest.dao.ActionRequestDAO;
 39  
 import org.kuali.rice.kew.actionrequest.service.ActionRequestService;
 40  
 import org.kuali.rice.kew.api.document.DocumentRefreshQueue;
 41  
 import org.kuali.rice.kew.actiontaken.ActionTakenValue;
 42  
 import org.kuali.rice.kew.actiontaken.service.ActionTakenService;
 43  
 import org.kuali.rice.kew.api.action.ActionRequestPolicy;
 44  
 import org.kuali.rice.kew.api.action.ActionRequestStatus;
 45  
 import org.kuali.rice.kew.api.action.RecipientType;
 46  
 import org.kuali.rice.kew.doctype.bo.DocumentType;
 47  
 import org.kuali.rice.kew.engine.ActivationContext;
 48  
 import org.kuali.rice.kew.engine.node.RouteNodeInstance;
 49  
 import org.kuali.rice.kew.exception.WorkflowServiceErrorException;
 50  
 import org.kuali.rice.kew.exception.WorkflowServiceErrorImpl;
 51  
 import org.kuali.rice.kew.messaging.MessageServiceNames;
 52  
 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
 53  
 import org.kuali.rice.kew.routeheader.service.RouteHeaderService;
 54  
 import org.kuali.rice.kew.routemodule.RouteModule;
 55  
 import org.kuali.rice.kew.service.KEWServiceLocator;
 56  
 import org.kuali.rice.kew.util.FutureRequestDocumentStateManager;
 57  
 import org.kuali.rice.kew.api.KewApiConstants;
 58  
 import org.kuali.rice.kew.util.PerformanceLogger;
 59  
 import org.kuali.rice.kew.util.ResponsibleParty;
 60  
 import org.kuali.rice.kim.api.identity.principal.Principal;
 61  
 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
 62  
 import org.kuali.rice.krad.util.KRADConstants;
 63  
 
 64  
 /**
 65  
  * Default implementation of the {@link ActionRequestService}.
 66  
  *
 67  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 68  
  */
 69  0
 public class ActionRequestServiceImpl implements ActionRequestService {
 70  0
     private static final Logger LOG = Logger.getLogger(ActionRequestServiceImpl.class);
 71  
 
 72  
     private ActionRequestDAO actionRequestDAO;
 73  
 
 74  
     public ActionRequestValue findByActionRequestId(String actionRequestId) {
 75  0
         return getActionRequestDAO().getActionRequestByActionRequestId(actionRequestId);
 76  
     }
 77  
 
 78  
     public Map<String, String> getActionsRequested(DocumentRouteHeaderValue routeHeader, String principalId, boolean completeAndApproveTheSame) {
 79  0
             return getActionsRequested(principalId, routeHeader.getActionRequests(), completeAndApproveTheSame);
 80  
     }
 81  
     
 82  
     /**
 83  
      * Returns a Map of actions that are requested for the given principalId in the given list of action requests.
 84  
      * @param principalId
 85  
      * @param actionRequests
 86  
      * @param completeAndApproveTheSame
 87  
      * @return
 88  
      */
 89  
     protected Map<String, String> getActionsRequested(String principalId, List<ActionRequestValue> actionRequests, boolean completeAndApproveTheSame) {
 90  0
             Map<String, String> actionsRequested = new HashMap<String, String>();
 91  0
         actionsRequested.put(KewApiConstants.ACTION_REQUEST_FYI_REQ, "false");
 92  0
         actionsRequested.put(KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ, "false");
 93  0
         actionsRequested.put(KewApiConstants.ACTION_REQUEST_APPROVE_REQ, "false");
 94  0
         actionsRequested.put(KewApiConstants.ACTION_REQUEST_COMPLETE_REQ, "false");
 95  0
             String topActionRequested = KewApiConstants.ACTION_REQUEST_FYI_REQ;
 96  0
         for (ActionRequestValue actionRequest : actionRequests) {
 97  
             // we are getting the full list of requests here, so no need to look at role requests, if we did this then
 98  
             // we could get a "false positive" for "all approve" roles where only part of the request graph is marked
 99  
             // as "done"
 100  0
             if (!RecipientType.ROLE.getCode().equals(actionRequest.getRecipientTypeCd()) &&
 101  
                     actionRequest.isRecipientRoutedRequest(principalId) && actionRequest.isActive()) {
 102  0
                 int actionRequestComparison = ActionRequestValue.compareActionCode(actionRequest.getActionRequested(), topActionRequested, completeAndApproveTheSame);
 103  0
                 if (actionRequest.isFYIRequest() && actionRequestComparison >= 0) {
 104  0
                     actionsRequested.put(KewApiConstants.ACTION_REQUEST_FYI_REQ, "true");
 105  0
                 } else if (actionRequest.isAcknowledgeRequest() && actionRequestComparison >= 0) {
 106  0
                     actionsRequested.put(KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ, "true");
 107  0
                     actionsRequested.put(KewApiConstants.ACTION_REQUEST_FYI_REQ, "false");
 108  0
                     topActionRequested = actionRequest.getActionRequested();
 109  0
                 } else if (actionRequest.isApproveRequest() && actionRequestComparison >= 0) {
 110  0
                     actionsRequested.put(KewApiConstants.ACTION_REQUEST_APPROVE_REQ, "true");
 111  0
                     actionsRequested.put(KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ, "false");
 112  0
                     actionsRequested.put(KewApiConstants.ACTION_REQUEST_FYI_REQ, "false");
 113  0
                     topActionRequested = actionRequest.getActionRequested();
 114  0
                 } else if (actionRequest.isCompleteRequst() && actionRequestComparison >= 0) {
 115  0
                         actionsRequested.put(KewApiConstants.ACTION_REQUEST_COMPLETE_REQ, "true");
 116  0
                         actionsRequested.put(KewApiConstants.ACTION_REQUEST_APPROVE_REQ, "false");
 117  0
                     actionsRequested.put(KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ, "false");
 118  0
                     actionsRequested.put(KewApiConstants.ACTION_REQUEST_FYI_REQ, "false");
 119  0
                         if (completeAndApproveTheSame) {
 120  0
                                 actionsRequested.put(KewApiConstants.ACTION_REQUEST_APPROVE_REQ, "true");
 121  
                         }
 122  0
                     topActionRequested = actionRequest.getActionRequested();
 123  
                 }
 124  0
             }
 125  
         }
 126  0
         return actionsRequested;
 127  
     }
 128  
 
 129  
     public ActionRequestValue initializeActionRequestGraph(ActionRequestValue actionRequest,
 130  
             DocumentRouteHeaderValue document, RouteNodeInstance nodeInstance) {
 131  0
         if (actionRequest.getParentActionRequest() != null) {
 132  0
             LOG.warn("-->A non parent action request from doc " + document.getDocumentId());
 133  0
             actionRequest = KEWServiceLocator.getActionRequestService().getRoot(actionRequest);
 134  
         }
 135  0
         propagatePropertiesToRequestGraph(actionRequest, document, nodeInstance);
 136  0
         return actionRequest;
 137  
     }
 138  
 
 139  
     private void propagatePropertiesToRequestGraph(ActionRequestValue actionRequest, DocumentRouteHeaderValue document,
 140  
             RouteNodeInstance nodeInstance) {
 141  0
         setPropertiesToRequest(actionRequest, document, nodeInstance);
 142  0
         for (ActionRequestValue actionRequestValue : actionRequest.getChildrenRequests())
 143  
         {
 144  0
             propagatePropertiesToRequestGraph(actionRequestValue, document, nodeInstance);
 145  
         }
 146  0
     }
 147  
 
 148  
     private void setPropertiesToRequest(ActionRequestValue actionRequest, DocumentRouteHeaderValue document,
 149  
             RouteNodeInstance nodeInstance) {
 150  0
         actionRequest.setDocumentId(document.getDocumentId());
 151  0
         actionRequest.setDocVersion(document.getDocVersion());
 152  0
         actionRequest.setRouteLevel(document.getDocRouteLevel());
 153  0
         actionRequest.setNodeInstance(nodeInstance);
 154  0
         actionRequest.setStatus(ActionRequestStatus.INITIALIZED.getCode());
 155  0
     }
 156  
 
 157  
 
 158  
 
 159  
     public void activateRequests(Collection actionRequests) {
 160  0
         activateRequests(actionRequests, new ActivationContext(!ActivationContext.CONTEXT_IS_SIMULATION));
 161  0
     }
 162  
 
 163  
     public void activateRequests(Collection actionRequests, boolean simulate) {
 164  0
         activateRequests(actionRequests, new ActivationContext(simulate));
 165  0
     }
 166  
 
 167  
     public void activateRequests(Collection actionRequests, ActivationContext activationContext) {
 168  0
         if (actionRequests == null) {
 169  0
             return;
 170  
         }
 171  0
         PerformanceLogger performanceLogger = null;
 172  0
         if ( LOG.isInfoEnabled() ) {
 173  0
                 performanceLogger = new PerformanceLogger();
 174  
         }
 175  0
         activationContext.setGeneratedActionItems(new ArrayList<ActionItem>());
 176  0
         activateRequestsInternal(actionRequests, activationContext);
 177  0
         if (!activationContext.isSimulation()) {
 178  0
             KEWServiceLocator.getNotificationService().notify(ActionItem.to(activationContext.getGeneratedActionItems()));
 179  
         }
 180  0
         if ( LOG.isInfoEnabled() ) {
 181  0
                 performanceLogger.log("Time to " + (activationContext.isSimulation() ? "simulate activation of " : "activate ")
 182  
                                 + actionRequests.size() + " action requests.");
 183  
         }
 184  0
         if ( LOG.isDebugEnabled() ) {
 185  0
                 LOG.debug("Generated " + activationContext.getGeneratedActionItems().size() + " action items.");
 186  
         }
 187  0
     }
 188  
 
 189  
     public void activateRequest(ActionRequestValue actionRequest) {
 190  0
         activateRequests(Collections.singletonList(actionRequest), new ActivationContext(!ActivationContext.CONTEXT_IS_SIMULATION));
 191  0
     }
 192  
 
 193  
     public void activateRequest(ActionRequestValue actionRequest, boolean simulate) {
 194  0
         activateRequests(Collections.singletonList(actionRequest), new ActivationContext(simulate));
 195  0
     }
 196  
 
 197  
     public void activateRequest(ActionRequestValue actionRequest, ActivationContext activationContext) {
 198  0
         activateRequests(Collections.singletonList(actionRequest), activationContext);
 199  0
     }
 200  
 
 201  
     public List activateRequestNoNotification(ActionRequestValue actionRequest, boolean simulate) {
 202  0
         return activateRequestNoNotification(actionRequest, new ActivationContext(simulate));
 203  
     }
 204  
 
 205  
     public List activateRequestNoNotification(ActionRequestValue actionRequest, ActivationContext activationContext) {
 206  0
         activationContext.setGeneratedActionItems(new ArrayList<ActionItem>());
 207  0
         activateRequestInternal(actionRequest, activationContext);
 208  0
         return activationContext.getGeneratedActionItems();
 209  
     }
 210  
 
 211  
     /**
 212  
      * Internal helper method for activating a Collection of action requests and their children. Maintains an accumulator
 213  
      * for generated action items.
 214  
      * @param actionRequests
 215  
      * @param activationContext
 216  
      */
 217  
     private void activateRequestsInternal(Collection actionRequests, ActivationContext activationContext) {
 218  0
         if (actionRequests == null) {
 219  0
             return;
 220  
         }
 221  0
         List<?> actionRequestList = new ArrayList<Object>(actionRequests);
 222  0
         for (int i = 0; i < actionRequestList.size(); i++) {
 223  0
                 activateRequestInternal((ActionRequestValue) actionRequestList.get(i), activationContext);
 224  
         }
 225  0
     }
 226  
 
 227  
     /**
 228  
      * Internal helper method for activating a single action requests and it's children. Maintains an accumulator for
 229  
      * generated action items.
 230  
      */
 231  
     private void activateRequestInternal(ActionRequestValue actionRequest, ActivationContext activationContext) {
 232  0
         PerformanceLogger performanceLogger = null;
 233  0
         if ( LOG.isInfoEnabled() ) {
 234  0
                 performanceLogger = new PerformanceLogger();
 235  
         }
 236  0
         if (actionRequest == null || actionRequest.isActive() || actionRequest.isDeactivated()) {
 237  0
             return;
 238  
         }
 239  0
         processResponsibilityId(actionRequest);
 240  0
         if (deactivateOnActionAlreadyTaken(actionRequest, activationContext)) {
 241  0
             return;
 242  
         }
 243  0
         if (deactivateOnInactiveGroup(actionRequest, activationContext)) {
 244  0
             return;
 245  
         }
 246  0
         if (deactivateOnEmptyGroup(actionRequest, activationContext)) {
 247  0
                 return;
 248  
         }
 249  0
         actionRequest.setStatus(ActionRequestStatus.ACTIVATED.getCode());
 250  0
         if (!activationContext.isSimulation()) {
 251  0
             saveActionRequest(actionRequest);
 252  0
             activationContext.getGeneratedActionItems().addAll(generateActionItems(actionRequest, activationContext));
 253  
         }
 254  0
         activateRequestsInternal(actionRequest.getChildrenRequests(), activationContext);
 255  0
         activateRequestInternal(actionRequest.getParentActionRequest(), activationContext);
 256  0
         if ( LOG.isInfoEnabled() ) {
 257  0
                 if (activationContext.isSimulation()) {
 258  0
                 performanceLogger.log("Time to simulate activation of request.");
 259  
                 } else {
 260  0
                     performanceLogger.log("Time to activate action request with id " + actionRequest.getActionRequestId());
 261  
                 }
 262  
         }
 263  0
     }
 264  
 
 265  
     /**
 266  
      * Generates ActionItems for the given ActionRequest and returns the List of generated Action Items.
 267  
      *
 268  
      * @param actionRequest
 269  
      * @param activationContext
 270  
      * @return the List of generated ActionItems
 271  
      */
 272  
     private List<ActionItem> generateActionItems(ActionRequestValue actionRequest, ActivationContext activationContext) {
 273  0
             if ( LOG.isDebugEnabled() ) {
 274  0
                     LOG.debug("generating the action items for request " + actionRequest.getActionRequestId());
 275  
             }
 276  0
         List<ActionItem> actionItems = new ArrayList<ActionItem>();
 277  0
         if (!actionRequest.isPrimaryDelegator()) {
 278  0
             if (actionRequest.isGroupRequest()) {
 279  0
                 List<String> principalIds =  KimApiServiceLocator.getGroupService().getMemberPrincipalIds(actionRequest.getGroupId());
 280  0
                 actionItems.addAll(createActionItemsForPrincipals(actionRequest, principalIds));
 281  0
             } else if (actionRequest.isUserRequest()) {
 282  0
                 ActionItem actionItem = getActionListService().createActionItemForActionRequest(actionRequest);
 283  0
                 actionItems.add(actionItem);
 284  
             }
 285  
         }
 286  0
         if (!activationContext.isSimulation()) {
 287  0
             for (ActionItem actionItem: actionItems) {
 288  0
                     if ( LOG.isDebugEnabled() ) {
 289  0
                             LOG.debug("Saving action item: " + actionItems);
 290  
                     }
 291  0
                 getActionListService().saveActionItem(actionItem);
 292  
             }
 293  
         } else {
 294  0
                 actionRequest.getSimulatedActionItems().addAll(actionItems);
 295  
         }
 296  0
         return actionItems;
 297  
     }
 298  
 
 299  
     private List<ActionItem> createActionItemsForPrincipals(ActionRequestValue actionRequest, List<String> principalIds) {
 300  0
         List<ActionItem> actionItems = new ArrayList<ActionItem>();
 301  0
         for (String principalId: principalIds) {
 302  0
             ActionItem actionItem = getActionListService().createActionItemForActionRequest(actionRequest);
 303  0
             actionItem.setPrincipalId(principalId);
 304  0
             actionItem.setRoleName(actionRequest.getQualifiedRoleName());
 305  0
             actionItems.add(actionItem);
 306  0
         }
 307  0
         return actionItems;
 308  
     }
 309  
 
 310  
     private void processResponsibilityId(ActionRequestValue actionRequest) {
 311  0
             if (actionRequest.getResolveResponsibility()) {
 312  0
                 String responsibilityId = actionRequest.getResponsibilityId();
 313  
                 try {
 314  0
                     RouteModule routeModule = KEWServiceLocator.getRouteModuleService().findRouteModule(actionRequest);
 315  0
                     if (responsibilityId != null && actionRequest.isRouteModuleRequest()) {
 316  0
                             if ( LOG.isDebugEnabled() ) {
 317  0
                                     LOG.debug("Resolving responsibility id for action request id=" + actionRequest.getActionRequestId()
 318  
                                 + " and responsibility id=" + actionRequest.getResponsibilityId());
 319  
                             }
 320  0
                         ResponsibleParty responsibleParty = routeModule.resolveResponsibilityId(actionRequest.getResponsibilityId());
 321  0
                         if (responsibleParty == null) {
 322  0
                             return;
 323  
                         }
 324  0
                         if (responsibleParty.getPrincipalId() != null) {
 325  0
                             Principal user = KimApiServiceLocator.getIdentityService()
 326  
                                     .getPrincipal(responsibleParty.getPrincipalId());
 327  0
                             actionRequest.setPrincipalId(user.getPrincipalId());
 328  0
                         } else if (responsibleParty.getGroupId() != null) {
 329  0
                                 actionRequest.setGroupId(responsibleParty.getGroupId());
 330  0
                         } else if (responsibleParty.getRoleName() != null) {
 331  0
                             actionRequest.setRoleName(responsibleParty.getRoleName());
 332  
                         }
 333  
                     }
 334  0
                 } catch (Exception e) {
 335  0
                     LOG.error("Exception thrown when trying to resolve responsibility id " + responsibilityId, e);
 336  0
                     throw new RuntimeException(e);
 337  0
                 }
 338  
             }
 339  0
     }
 340  
 
 341  
     protected boolean deactivateOnActionAlreadyTaken(ActionRequestValue actionRequestToActivate,
 342  
             ActivationContext activationContext) {
 343  
 
 344  0
         FutureRequestDocumentStateManager futureRequestStateMngr = null;
 345  
 
 346  0
         if (actionRequestToActivate.isGroupRequest()) {
 347  0
             futureRequestStateMngr = new FutureRequestDocumentStateManager(actionRequestToActivate.getRouteHeader(), actionRequestToActivate.getGroup());
 348  0
         } else if (actionRequestToActivate.isUserRequest()) {
 349  0
             futureRequestStateMngr = new FutureRequestDocumentStateManager(actionRequestToActivate.getRouteHeader(), actionRequestToActivate.getPrincipalId());
 350  
         } else {
 351  0
             return false;
 352  
         }
 353  
 
 354  0
         if (futureRequestStateMngr.isReceiveFutureRequests()) {
 355  0
             return false;
 356  
         }
 357  0
         if (!actionRequestToActivate.getForceAction() || futureRequestStateMngr.isDoNotReceiveFutureRequests()) {
 358  0
             ActionTakenValue previousActionTaken = null;
 359  0
             if (!activationContext.isSimulation()) {
 360  0
                 previousActionTaken = getActionTakenService().getPreviousAction(actionRequestToActivate);
 361  
             } else {
 362  0
                 previousActionTaken = getActionTakenService().getPreviousAction(actionRequestToActivate,
 363  
                         activationContext.getSimulatedActionsTaken());
 364  
             }
 365  0
             if (previousActionTaken != null) {
 366  0
                 if ( LOG.isDebugEnabled() ) {
 367  0
                         LOG.debug("found a satisfying action taken so setting this request done.  Action Request Id "
 368  
                             + actionRequestToActivate.getActionRequestId());
 369  
                 }
 370  
                 // set up the delegation for an action taken if this is a delegate request and the delegate has
 371  
                 // already taken action.
 372  0
                 if (!previousActionTaken.isForDelegator() && actionRequestToActivate.getParentActionRequest() != null) {
 373  0
                     previousActionTaken.setDelegator(actionRequestToActivate.getParentActionRequest().getRecipient());
 374  0
                     if (!activationContext.isSimulation()) {
 375  0
                         getActionTakenService().saveActionTaken(previousActionTaken);
 376  
                     }
 377  
                 }
 378  0
                 deactivateRequest(previousActionTaken, actionRequestToActivate, null, activationContext);
 379  0
                 return true;
 380  
             }
 381  
         }
 382  0
         if ( LOG.isDebugEnabled() ) {
 383  0
                 LOG.debug("Forcing action for action request " + actionRequestToActivate.getActionRequestId());
 384  
         }
 385  0
         return false;
 386  
     }
 387  
     
 388  
     /**
 389  
      * Checks if the action request which is being activated has a group with no members.  If this is the case then it will immediately
 390  
      * initiate de-activation on the request since a group with no members will result in no action items being generated so should be
 391  
      * effectively skipped.
 392  
      */
 393  
     protected boolean deactivateOnEmptyGroup(ActionRequestValue actionRequestToActivate, ActivationContext activationContext) {
 394  0
             if (actionRequestToActivate.isGroupRequest()) {
 395  0
                      if (KimApiServiceLocator.getGroupService().getMemberPrincipalIds(actionRequestToActivate.getGroup().getId()).isEmpty()) {
 396  0
                              deactivateRequest(null, actionRequestToActivate, null, activationContext);
 397  0
                              return true;
 398  
                  }
 399  
             }
 400  0
             return false;
 401  
     }
 402  
 
 403  
     /**
 404  
      * Checks if the action request which is being activated is being assigned to an inactive group.  If this is the case and if the FailOnInactiveGroup 
 405  
      * policy is set to false then it will immediately initiate de-activation on the request
 406  
      */
 407  
     protected boolean deactivateOnInactiveGroup(ActionRequestValue actionRequestToActivate, ActivationContext activationContext) {
 408  0
         if (actionRequestToActivate.isGroupRequest()) {
 409  0
             if (!actionRequestToActivate.getGroup().isActive() && !actionRequestToActivate.getRouteHeader().getDocumentType().getFailOnInactiveGroup().getPolicyValue()) {
 410  0
                 deactivateRequest(null, actionRequestToActivate, null, activationContext);
 411  0
                 return true;
 412  
             }
 413  
         }
 414  0
         return false;
 415  
     }
 416  
     
 417  
     public void deactivateRequest(ActionTakenValue actionTaken, ActionRequestValue actionRequest) {
 418  0
         deactivateRequest(actionTaken, actionRequest, null, new ActivationContext(!ActivationContext.CONTEXT_IS_SIMULATION));
 419  0
     }
 420  
 
 421  
     public void deactivateRequest(ActionTakenValue actionTaken, ActionRequestValue actionRequest, boolean simulate) {
 422  0
         deactivateRequest(actionTaken, actionRequest, null, new ActivationContext(simulate));
 423  0
     }
 424  
 
 425  
     public void deactivateRequest(ActionTakenValue actionTaken, ActionRequestValue actionRequest,
 426  
             ActivationContext activationContext) {
 427  0
         deactivateRequest(actionTaken, actionRequest, null, activationContext);
 428  0
     }
 429  
 
 430  
     public void deactivateRequests(ActionTakenValue actionTaken, List actionRequests) {
 431  0
         deactivateRequests(actionTaken, actionRequests, null,
 432  
                 new ActivationContext(!ActivationContext.CONTEXT_IS_SIMULATION));
 433  0
     }
 434  
 
 435  
     public void deactivateRequests(ActionTakenValue actionTaken, List actionRequests, boolean simulate) {
 436  0
         deactivateRequests(actionTaken, actionRequests, null, new ActivationContext(simulate));
 437  0
     }
 438  
 
 439  
     public void deactivateRequests(ActionTakenValue actionTaken, List actionRequests, ActivationContext activationContext) {
 440  0
         deactivateRequests(actionTaken, actionRequests, null, activationContext);
 441  0
     }
 442  
 
 443  
     private void deactivateRequests(ActionTakenValue actionTaken, Collection actionRequests,
 444  
             ActionRequestValue deactivationRequester, ActivationContext activationContext) {
 445  0
         if (actionRequests == null) {
 446  0
             return;
 447  
         }
 448  0
         for (Iterator iterator = actionRequests.iterator(); iterator.hasNext();) {
 449  0
             ActionRequestValue actionRequest = (ActionRequestValue) iterator.next();
 450  0
             deactivateRequest(actionTaken, actionRequest, deactivationRequester, activationContext);
 451  0
         }
 452  0
     }
 453  
 
 454  
     private void deactivateRequest(ActionTakenValue actionTaken, ActionRequestValue actionRequest,
 455  
             ActionRequestValue deactivationRequester, ActivationContext activationContext) {
 456  0
         if (actionRequest == null || actionRequest.isDeactivated()
 457  
                 || haltForAllApprove(actionRequest, deactivationRequester)) {
 458  0
             return;
 459  
         }
 460  0
         actionRequest.setStatus(ActionRequestStatus.DONE.getCode());
 461  0
         actionRequest.setActionTaken(actionTaken);
 462  0
         if (actionTaken != null) {
 463  0
             actionTaken.getActionRequests().add(actionRequest);
 464  
         }
 465  0
         if (!activationContext.isSimulation()) {
 466  0
             getActionRequestDAO().saveActionRequest(actionRequest);
 467  0
             deleteActionItems(actionRequest);
 468  
         }
 469  0
         deactivateRequests(actionTaken, actionRequest.getChildrenRequests(), actionRequest, activationContext);
 470  0
         deactivateRequest(actionTaken, actionRequest.getParentActionRequest(), actionRequest, activationContext);
 471  0
     }
 472  
 
 473  
     /**
 474  
      * Returns true if we are dealing with an 'All Approve' request, the requester of the deactivation is a child of the
 475  
      * 'All Approve' request, and all of the children have not been deactivated. If all of the children are already
 476  
      * deactivated or a non-child request initiated deactivation, then this method returns false. false otherwise.
 477  
      * @param actionRequest
 478  
      * @param deactivationRequester
 479  
      * @return
 480  
      */
 481  
     private boolean haltForAllApprove(ActionRequestValue actionRequest, ActionRequestValue deactivationRequester) {
 482  0
         if (ActionRequestPolicy.ALL.getCode().equals(actionRequest.getApprovePolicy())
 483  
                 && actionRequest.hasChild(deactivationRequester)) {
 484  0
             boolean allDeactivated = true;
 485  0
             for (ActionRequestValue childRequest : actionRequest.getChildrenRequests())
 486  
             {
 487  0
                 if (!(allDeactivated = childRequest.isDeactivated()))
 488  
                 {
 489  0
                     return true;
 490  
                 }
 491  
             }
 492  
         }
 493  0
         return false;
 494  
     }
 495  
 
 496  
     public List<ActionRequestValue> getRootRequests(Collection<ActionRequestValue> actionRequests) {
 497  0
             Set<ActionRequestValue> unsavedRequests = new HashSet<ActionRequestValue>();
 498  0
             Map<String, ActionRequestValue> requestMap = new HashMap<String, ActionRequestValue>();
 499  0
             for (ActionRequestValue actionRequest1 : actionRequests)
 500  
             {
 501  0
                     ActionRequestValue actionRequest = (ActionRequestValue) actionRequest1;
 502  0
                     ActionRequestValue rootRequest = getRoot(actionRequest);
 503  0
                     if (rootRequest.getActionRequestId() != null)
 504  
                     {
 505  0
                             requestMap.put(rootRequest.getActionRequestId(), rootRequest);
 506  
                     } else
 507  
                     {
 508  0
                             unsavedRequests.add(rootRequest);
 509  
                     }
 510  0
             }
 511  0
             List<ActionRequestValue> requests = new ArrayList<ActionRequestValue>();
 512  0
             requests.addAll(requestMap.values());
 513  0
             requests.addAll(unsavedRequests);
 514  0
             return requests;
 515  
     }
 516  
 
 517  
     public ActionRequestValue getRoot(ActionRequestValue actionRequest) {
 518  0
         if (actionRequest == null) {
 519  0
             return null;
 520  
         }
 521  0
         if (actionRequest.getParentActionRequest() != null) {
 522  0
             return getRoot(actionRequest.getParentActionRequest());
 523  
         }
 524  0
         return actionRequest;
 525  
     }
 526  
     
 527  
     /**
 528  
      * Returns all pending requests for a given routing identity
 529  
      * @param documentId the id of the document header being routed
 530  
      * @return a List of all pending ActionRequestValues for the document
 531  
      */
 532  
     public List<ActionRequestValue> findAllPendingRequests(String documentId) {
 533  0
             ActionRequestDAO arDAO = getActionRequestDAO();
 534  0
         List<ActionRequestValue> pendingArs = arDAO.findByStatusAndDocId(ActionRequestStatus.ACTIVATED.getCode(), documentId);
 535  0
         return pendingArs;
 536  
     }
 537  
 
 538  
     public List findAllValidRequests(String principalId, String documentId, String requestCode) {
 539  0
         ActionRequestDAO arDAO = getActionRequestDAO();
 540  0
         Collection pendingArs = arDAO.findByStatusAndDocId(ActionRequestStatus.ACTIVATED.getCode(), documentId);
 541  0
         return findAllValidRequests(principalId, pendingArs, requestCode);
 542  
     }
 543  
 
 544  
     public List findAllValidRequests(String principalId, Collection actionRequests, String requestCode) {
 545  0
         List matchedArs = new ArrayList();
 546  0
         List<String> arGroups = KimApiServiceLocator.getGroupService().getGroupIdsByPrincipalId(principalId);
 547  0
         return filterActionRequestsByCode((List<ActionRequestValue>)actionRequests, principalId, arGroups, requestCode);
 548  
     }
 549  
     
 550  
     /**
 551  
          * Filters action requests based on if they occur after the given requestCode, and if they relate to 
 552  
          * the given principal
 553  
          * @param actionRequests the List of ActionRequestValues to filter
 554  
          * @param principalId the id of the principal to find active requests for
 555  
          * @param principalGroupIds List of group ids that the principal belongs to
 556  
          * @param requestCode the request code for all ActionRequestValues to be after
 557  
          * @return the filtered List of ActionRequestValues
 558  
          */
 559  
         public List<ActionRequestValue> filterActionRequestsByCode(List<ActionRequestValue> actionRequests, String principalId, List<String> principalGroupIds, String requestCode) {
 560  0
                 List<ActionRequestValue> filteredActionRequests = new ArrayList<ActionRequestValue>();
 561  
                 
 562  0
                 List<String> arGroups = null;
 563  0
         for (ActionRequestValue ar : actionRequests) {
 564  0
             if (ActionRequestValue.compareActionCode(ar.getActionRequested(), requestCode, true) > 0) {
 565  0
                 continue;
 566  
             }
 567  0
             if (ar.isUserRequest() && principalId.equals(ar.getPrincipalId())) {
 568  0
                     filteredActionRequests.add(ar);
 569  0
             } else if (ar.isGroupRequest() && principalGroupIds != null && !principalGroupIds.isEmpty()) {
 570  0
                     for (String groupId : principalGroupIds) {
 571  0
                             if (groupId.equals(ar.getGroupId())) {
 572  0
                                     filteredActionRequests.add(ar);
 573  
                             }
 574  
                     }
 575  
             }
 576  
         }
 577  
                 
 578  0
                 return filteredActionRequests;
 579  
         }
 580  
 
 581  
     public void updateActionRequestsForResponsibilityChange(Set<String> responsibilityIds) {
 582  0
             PerformanceLogger performanceLogger = null;
 583  0
             if ( LOG.isInfoEnabled() ) {
 584  0
                     performanceLogger = new PerformanceLogger();
 585  
             }
 586  0
         Collection documentsAffected = getRouteHeaderService().findPendingByResponsibilityIds(responsibilityIds);
 587  0
         String cacheWaitValue = CoreFrameworkServiceLocator.getParameterService().getParameterValueAsString(KewApiConstants.KEW_NAMESPACE, KRADConstants.DetailTypes.RULE_DETAIL_TYPE, KewApiConstants.RULE_CACHE_REQUEUE_DELAY);
 588  0
         Long cacheWait = KewApiConstants.DEFAULT_CACHE_REQUEUE_WAIT_TIME;
 589  0
         if (!org.apache.commons.lang.StringUtils.isEmpty(cacheWaitValue)) {
 590  
             try {
 591  0
                 cacheWait = Long.valueOf(cacheWaitValue);
 592  0
             } catch (NumberFormatException e) {
 593  0
                 LOG.warn("Cache wait time is not a valid number: " + cacheWaitValue);
 594  0
             }
 595  
         }
 596  0
         if ( LOG.isInfoEnabled() ) {
 597  0
                 LOG.info("Scheduling requeue of " + documentsAffected.size() + " documents, affected by " + responsibilityIds.size()
 598  
                     + " responsibility changes.  Installing a processing wait time of " + cacheWait
 599  
                     + " milliseconds to avoid stale rule cache.");
 600  
         }
 601  0
         for (Object aDocumentsAffected : documentsAffected)
 602  
         {
 603  0
             String documentId = (String) aDocumentsAffected;
 604  
 
 605  0
              String applicationId = null;
 606  0
              DocumentType documentType = KEWServiceLocator.getDocumentTypeService().findByDocumentId(documentId);
 607  
                     
 608  0
              if (documentType != null) {
 609  0
                 applicationId = documentType.getApplicationId();
 610  
              }
 611  
 
 612  0
             if (applicationId == null)
 613  
             {
 614  0
                 applicationId = CoreConfigHelper.getApplicationId();
 615  
             }
 616  0
             if(documentType.getRegenerateActionRequestsOnChange().getPolicyValue()) {
 617  0
                 DocumentRefreshQueue documentRequeuer = MessageServiceNames.getDocumentRequeuerService(applicationId,
 618  
                         documentId, cacheWait);
 619  0
                 documentRequeuer.refreshDocument(documentId);
 620  
             }
 621  0
         }
 622  0
         if ( LOG.isInfoEnabled() ) {
 623  0
                 performanceLogger.log("Time to updateActionRequestsForResponsibilityChange");
 624  
         }
 625  0
     }
 626  
 
 627  
     /**
 628  
      * Deletes an action request and all of its action items following the graph down through the action request's
 629  
      * children. This method should be invoked on a top-level action request.
 630  
      */
 631  
     public void deleteActionRequestGraph(ActionRequestValue actionRequest) {
 632  0
         deleteActionItems(actionRequest);
 633  0
         if (actionRequest.getActionTakenId() != null) {
 634  0
             ActionTakenValue actionTaken = getActionTakenService().findByActionTakenId(actionRequest.getActionTakenId());
 635  
 
 636  0
             if(actionTaken != null){//iu patch
 637  0
             getActionTakenService().delete(actionTaken);
 638  
             }//iu patch
 639  
            
 640  
         }
 641  0
         getActionRequestDAO().delete(actionRequest.getActionRequestId());
 642  0
         for (ActionRequestValue child: actionRequest.getChildrenRequests()) {
 643  0
             deleteActionRequestGraph(child);
 644  
         }
 645  0
     }
 646  
 
 647  
     /**
 648  
      * Deletes the action items for the action request
 649  
      * @param actionRequest the action request whose action items to delete
 650  
      */
 651  
     private void deleteActionItems(ActionRequestValue actionRequest) {
 652  0
             List<ActionItem> actionItems = actionRequest.getActionItems();
 653  0
             if ( LOG.isDebugEnabled() ) {
 654  0
                     LOG.debug("deleting " + actionItems.size() + " action items for action request: " + actionRequest);
 655  
             }
 656  0
         for (ActionItem actionItem: actionItems) {
 657  0
                 if ( LOG.isDebugEnabled() ) {
 658  0
                         LOG.debug("deleting action item: " + actionItem);
 659  
                 }
 660  0
             getActionListService().deleteActionItem(actionItem);
 661  
         }
 662  0
     }
 663  
 
 664  
 
 665  
     public List<ActionRequestValue> findByDocumentIdIgnoreCurrentInd(String documentId) {
 666  0
         return getActionRequestDAO().findByDocumentIdIgnoreCurrentInd(documentId);
 667  
     }
 668  
 
 669  
     public List<ActionRequestValue> findAllActionRequestsByDocumentId(String documentId) {
 670  0
         return getActionRequestDAO().findAllByDocId(documentId);
 671  
     }
 672  
 
 673  
     public List<ActionRequestValue> findAllRootActionRequestsByDocumentId(String documentId) {
 674  0
         return getActionRequestDAO().findAllRootByDocId(documentId);
 675  
     }
 676  
 
 677  
     public List<ActionRequestValue> findPendingByActionRequestedAndDocId(String actionRequestedCd, String documentId) {
 678  0
         return getActionRequestDAO().findPendingByActionRequestedAndDocId(actionRequestedCd, documentId);
 679  
     }
 680  
 
 681  
     /**
 682  
      * @see org.kuali.rice.kew.actionrequest.service.ActionRequestService#getPrincipalIdsWithPendingActionRequestByActionRequestedAndDocId(java.lang.String, java.lang.String)
 683  
      */
 684  
     public List<String> getPrincipalIdsWithPendingActionRequestByActionRequestedAndDocId(String actionRequestedCd, String documentId) {
 685  0
             List<String> principalIds = new ArrayList<String>();
 686  0
             List<ActionRequestValue> actionRequests = findPendingByActionRequestedAndDocId(actionRequestedCd, documentId);
 687  0
                 for(ActionRequestValue actionRequest: actionRequests){
 688  0
                         if(actionRequest.isUserRequest()){
 689  0
                                 principalIds.add(actionRequest.getPrincipalId());
 690  0
                         } else if(actionRequest.isGroupRequest()){
 691  0
                                 principalIds.addAll(
 692  
                                                 KimApiServiceLocator.getGroupService().getMemberPrincipalIds(actionRequest.getGroupId()));
 693  
                         }
 694  
                 }
 695  0
             return principalIds;
 696  
     }
 697  
 
 698  
     public List<ActionRequestValue> findPendingByDocIdAtOrBelowRouteLevel(String documentId, Integer routeLevel) {
 699  0
         return getActionRequestDAO().findPendingByDocIdAtOrBelowRouteLevel(documentId, routeLevel);
 700  
     }
 701  
 
 702  
     public List<ActionRequestValue> findPendingRootRequestsByDocId(String documentId) {
 703  0
         return getRootRequests(findPendingByDoc(documentId));
 704  
     }
 705  
 
 706  
     public List<ActionRequestValue> findPendingRootRequestsByDocIdAtRouteNode(String documentId, String nodeInstanceId) {
 707  0
         return getActionRequestDAO().findPendingRootRequestsByDocIdAtRouteNode(documentId, nodeInstanceId);
 708  
     }
 709  
 
 710  
     public List<ActionRequestValue> findRootRequestsByDocIdAtRouteNode(String documentId, String nodeInstanceId) {
 711  0
         return getActionRequestDAO().findRootRequestsByDocIdAtRouteNode(documentId, nodeInstanceId);
 712  
     }
 713  
 
 714  
     public List<ActionRequestValue> findPendingRootRequestsByDocIdAtOrBelowRouteLevel(String documentId, Integer routeLevel) {
 715  0
         return getActionRequestDAO().findPendingRootRequestsByDocIdAtOrBelowRouteLevel(documentId, routeLevel);
 716  
     }
 717  
 
 718  
     public List<ActionRequestValue> findPendingRootRequestsByDocIdAtRouteLevel(String documentId, Integer routeLevel) {
 719  0
         return getActionRequestDAO().findPendingRootRequestsByDocIdAtRouteLevel(documentId, routeLevel);
 720  
     }
 721  
 
 722  
     public List<ActionRequestValue> findPendingRootRequestsByDocumentType(String documentTypeId) {
 723  0
         return getActionRequestDAO().findPendingRootRequestsByDocumentType(documentTypeId);
 724  
     }
 725  
 
 726  
     public void saveActionRequest(ActionRequestValue actionRequest) {
 727  0
         if (actionRequest.isGroupRequest()) {
 728  0
             if (!actionRequest.getGroup().isActive() && actionRequest.getRouteHeader().getDocumentType().getFailOnInactiveGroup().getPolicyValue()) {
 729  0
                         throw new RiceRuntimeException("Attempted to save an action request with an inactive group.");
 730  
                 }
 731  
         }
 732  0
         getActionRequestDAO().saveActionRequest(actionRequest);
 733  0
     }
 734  
 
 735  
     public List<ActionRequestValue> findPendingByDoc(String documentId) {
 736  0
         return getActionRequestDAO().findAllPendingByDocId(documentId);
 737  
     }
 738  
 
 739  
     public List<ActionRequestValue> findPendingByDocRequestCdRouteLevel(String documentId, String requestCode, Integer routeLevel) {
 740  0
         List<ActionRequestValue> requests = new ArrayList<ActionRequestValue>();
 741  0
         for (Object object : getActionRequestDAO().findAllPendingByDocId(documentId))
 742  
         {
 743  0
             ActionRequestValue actionRequest = (ActionRequestValue) object;
 744  0
             if (ActionRequestValue.compareActionCode(actionRequest.getActionRequested(), requestCode, true) > 0)
 745  
             {
 746  0
                 continue;
 747  
             }
 748  0
             if (actionRequest.getRouteLevel().intValue() == routeLevel.intValue())
 749  
             {
 750  0
                 requests.add(actionRequest);
 751  
             }
 752  0
         }
 753  0
         return requests;
 754  
     }
 755  
 
 756  
     public List<ActionRequestValue> findPendingByDocRequestCdNodeName(String documentId, String requestCode, String nodeName) {
 757  0
         List<ActionRequestValue> requests = new ArrayList<ActionRequestValue>();
 758  0
         for (Object object : getActionRequestDAO().findAllPendingByDocId(documentId))
 759  
         {
 760  0
             ActionRequestValue actionRequest = (ActionRequestValue) object;
 761  0
             if (ActionRequestValue.compareActionCode(actionRequest.getActionRequested(), requestCode, true) > 0)
 762  
             {
 763  0
                 continue;
 764  
             }
 765  0
             if (actionRequest.getNodeInstance() != null && actionRequest.getNodeInstance().getName().equals(nodeName))
 766  
             {
 767  0
                 requests.add(actionRequest);
 768  
             }
 769  0
         }
 770  0
         return requests;
 771  
     }
 772  
 
 773  
     public List findActivatedByGroup(String groupId) {
 774  0
         return getActionRequestDAO().findActivatedByGroup(groupId);
 775  
     }
 776  
 
 777  
     private ActionListService getActionListService() {
 778  0
         return (ActionListService) KEWServiceLocator.getActionListService();
 779  
     }
 780  
 
 781  
     private ActionTakenService getActionTakenService() {
 782  0
         return (ActionTakenService) KEWServiceLocator.getActionTakenService();
 783  
     }
 784  
 
 785  
     public ActionRequestDAO getActionRequestDAO() {
 786  0
         return actionRequestDAO;
 787  
     }
 788  
 
 789  
     public void setActionRequestDAO(ActionRequestDAO actionRequestDAO) {
 790  0
         this.actionRequestDAO = actionRequestDAO;
 791  0
     }
 792  
 
 793  
     private RouteHeaderService getRouteHeaderService() {
 794  0
         return (RouteHeaderService) KEWServiceLocator.getService(KEWServiceLocator.DOC_ROUTE_HEADER_SRV);
 795  
     }
 796  
 
 797  
     public List<ActionRequestValue> findByStatusAndDocId(String statusCd, String documentId) {
 798  0
         return getActionRequestDAO().findByStatusAndDocId(statusCd, documentId);
 799  
     }
 800  
 
 801  
     public void alterActionRequested(List actionRequests, String actionRequestCd) {
 802  0
         for (Object actionRequest1 : actionRequests)
 803  
         {
 804  0
             ActionRequestValue actionRequest = (ActionRequestValue) actionRequest1;
 805  
 
 806  0
             actionRequest.setActionRequested(actionRequestCd);
 807  0
             for (ActionItem item : actionRequest.getActionItems())
 808  
             {
 809  0
                 item.setActionRequestCd(actionRequestCd);
 810  
             }
 811  
 
 812  0
             saveActionRequest(actionRequest);
 813  0
         }
 814  0
     }
 815  
 
 816  
     // TODO this still won't work in certain cases when checking from the root
 817  
     public boolean isDuplicateRequest(ActionRequestValue actionRequest) {
 818  0
         List<ActionRequestValue> requests = findAllRootActionRequestsByDocumentId(actionRequest.getDocumentId());
 819  0
         for (ActionRequestValue existingRequest : requests) {
 820  0
             if (existingRequest.getStatus().equals(ActionRequestStatus.DONE.getCode())
 821  
                     && existingRequest.getRouteLevel().equals(actionRequest.getRouteLevel())
 822  
                     && ObjectUtils.equals(existingRequest.getPrincipalId(), actionRequest.getPrincipalId())
 823  
                     && ObjectUtils.equals(existingRequest.getGroupId(), actionRequest.getGroupId())
 824  
                     && ObjectUtils.equals(existingRequest.getRoleName(), actionRequest.getRoleName())
 825  
                     && ObjectUtils.equals(existingRequest.getQualifiedRoleName(), actionRequest.getQualifiedRoleName())
 826  
                     && existingRequest.getActionRequested().equals(actionRequest.getActionRequested())) {
 827  0
                 return true;
 828  
             }
 829  
         }
 830  0
         return false;
 831  
     }
 832  
 
 833  
     public Recipient findDelegator(List actionRequests) {
 834  0
         Recipient delegator = null;
 835  0
         String requestCode = KewApiConstants.ACTION_REQUEST_FYI_REQ;
 836  0
         for (Object actionRequest1 : actionRequests)
 837  
         {
 838  0
             ActionRequestValue actionRequest = (ActionRequestValue) actionRequest1;
 839  0
             ActionRequestValue delegatorRequest = findDelegatorRequest(actionRequest);
 840  0
             if (delegatorRequest != null)
 841  
             {
 842  0
                 if (ActionRequestValue.compareActionCode(delegatorRequest.getActionRequested(), requestCode, true) >= 0)
 843  
                 {
 844  0
                     delegator = delegatorRequest.getRecipient();
 845  0
                     requestCode = delegatorRequest.getActionRequested();
 846  
                 }
 847  
             }
 848  0
         }
 849  0
         return delegator;
 850  
     }
 851  
 
 852  
     public Recipient findDelegator(ActionRequestValue actionRequest) {
 853  0
         ActionRequestValue delegatorRequest = findDelegatorRequest(actionRequest);
 854  0
         Recipient delegator = null;
 855  0
         if (delegatorRequest != null) {
 856  0
             delegator = delegatorRequest.getRecipient();
 857  
         }
 858  0
         return delegator;
 859  
     }
 860  
 
 861  
     public ActionRequestValue findDelegatorRequest(ActionRequestValue actionRequest) {
 862  0
         ActionRequestValue parentRequest = actionRequest.getParentActionRequest();
 863  0
         if (parentRequest != null && !(parentRequest.isUserRequest() || parentRequest.isGroupRequest())) {
 864  0
             parentRequest = findDelegatorRequest(parentRequest);
 865  
         }
 866  0
         return parentRequest;
 867  
     }
 868  
 
 869  
     public void deleteByDocumentId(String documentId) {
 870  0
         actionRequestDAO.deleteByDocumentId(documentId);
 871  0
     }
 872  
 
 873  
     public void deleteByActionRequestId(String actionRequestId) {
 874  0
         actionRequestDAO.delete(actionRequestId);
 875  0
     }
 876  
 
 877  
     public void validateActionRequest(ActionRequestValue actionRequest) {
 878  0
         LOG.debug("Enter validateActionRequest(..)");
 879  0
         List<WorkflowServiceErrorImpl> errors = new ArrayList<WorkflowServiceErrorImpl>();
 880  
 
 881  0
         String actionRequestCd = actionRequest.getActionRequested();
 882  0
         if (actionRequestCd == null || actionRequestCd.trim().equals("")) {
 883  0
             errors.add(new WorkflowServiceErrorImpl("ActionRequest cd null.", "actionrequest.actionrequestcd.empty",
 884  
                     actionRequest.getActionRequestId().toString()));
 885  0
         } else if (!KewApiConstants.ACTION_REQUEST_CD.containsKey(actionRequestCd)) {
 886  0
             errors.add(new WorkflowServiceErrorImpl("ActionRequest cd invalid.", "actionrequest.actionrequestcd.invalid",
 887  
                     actionRequest.getActionRequestId().toString()));
 888  
         }
 889  
 
 890  0
         String documentId = actionRequest.getDocumentId();
 891  0
         if (documentId == null || StringUtils.isEmpty(documentId)) {
 892  0
                 errors.add(new WorkflowServiceErrorImpl("ActionRequest Document id empty.", "actionrequest.documentid.empty",
 893  
                     actionRequest.getActionRequestId().toString()));
 894  0
         } else if (getRouteHeaderService().getRouteHeader(documentId) == null) {
 895  0
             errors.add(new WorkflowServiceErrorImpl("ActionRequest Document id invalid.",
 896  
                     "actionrequest.documentid.invalid", actionRequest.getActionRequestId().toString()));
 897  
         }
 898  
 
 899  0
         String actionRequestStatus = actionRequest.getStatus();
 900  0
         if (actionRequestStatus == null || actionRequestStatus.trim().equals("")) {
 901  0
             errors.add(new WorkflowServiceErrorImpl("ActionRequest status null.", "actionrequest.actionrequeststatus.empty",
 902  
                     actionRequest.getActionRequestId().toString()));
 903  0
         } else if (ActionRequestStatus.fromCode(actionRequestStatus) == null) {
 904  0
             errors.add(new WorkflowServiceErrorImpl("ActionRequest status invalid.",
 905  
                     "actionrequest.actionrequeststatus.invalid", actionRequest.getActionRequestId().toString()));
 906  
         }
 907  
 
 908  0
         if (actionRequest.getResponsibilityId() == null) {
 909  0
             errors.add(new WorkflowServiceErrorImpl("ActionRequest responsibility id null.",
 910  
                     "actionrequest.responsibilityid.empty", actionRequest.getActionRequestId().toString()));
 911  
         }
 912  
 
 913  0
         Integer priority = actionRequest.getPriority();
 914  0
         if (priority == null) {
 915  0
             errors.add(new WorkflowServiceErrorImpl("ActionRequest priority null.", "actionrequest.priority.empty",
 916  
                     actionRequest.getActionRequestId().toString()));
 917  
         }
 918  
 
 919  
         // if(actionRequest.getRouteMethodName() == null || actionRequest.getRouteMethodName().trim().equals("")){
 920  
         // errors.add(new WorkflowServiceErrorImpl("ActionRequest route method name null.",
 921  
         // "actionrequest.routemethodname.empty", actionRequest.getActionRequestId().toString()));
 922  
         // }
 923  
 
 924  0
         Integer routeLevel = actionRequest.getRouteLevel();
 925  0
         if (routeLevel == null) {
 926  0
             errors.add(new WorkflowServiceErrorImpl("ActionRequest route level null.", "actionrequest.routelevel.empty",
 927  
                     actionRequest.getActionRequestId().toString()));
 928  0
         } else if (routeLevel < -1) {
 929  0
             errors.add(new WorkflowServiceErrorImpl("ActionRequest route level invalid.",
 930  
                     "actionrequest.routelevel.invalid", actionRequest.getActionRequestId().toString()));
 931  
         }
 932  
 
 933  0
         Integer version = actionRequest.getDocVersion();
 934  0
         if (version == null) {
 935  0
             errors.add(new WorkflowServiceErrorImpl("ActionRequest doc version null.", "actionrequest.docversion.empty",
 936  
                     actionRequest.getActionRequestId().toString()));
 937  
         }
 938  
 
 939  0
         if (actionRequest.getCreateDate() == null) {
 940  0
             errors.add(new WorkflowServiceErrorImpl("ActionRequest create date null.", "actionrequest.createdate.empty",
 941  
                     actionRequest.getActionRequestId().toString()));
 942  
         }
 943  
 
 944  0
         String recipientType = actionRequest.getRecipientTypeCd();
 945  0
         if (recipientType != null && !recipientType.trim().equals("")) {
 946  0
             if (recipientType.equals(KewApiConstants.WORKGROUP)) {
 947  0
                 String workgroupId = actionRequest.getGroupId();
 948  0
                 if (workgroupId == null) {
 949  0
                     errors.add(new WorkflowServiceErrorImpl("ActionRequest workgroup null.",
 950  
                             "actionrequest.workgroup.empty", actionRequest.getActionRequestId().toString()));
 951  0
                 } else if (KimApiServiceLocator.getGroupService().getGroup(workgroupId) == null) {
 952  0
                     errors.add(new WorkflowServiceErrorImpl("ActionRequest workgroup invalid.",
 953  
                             "actionrequest.workgroup.invalid", actionRequest.getActionRequestId().toString()));
 954  
                 }
 955  
 
 956  
             }
 957  0
             if (recipientType.equals(KewApiConstants.PERSON)) {
 958  0
                 String principalId = actionRequest.getPrincipalId();
 959  0
                 if (principalId == null || principalId.trim().equals("")) {
 960  0
                     errors.add(new WorkflowServiceErrorImpl("ActionRequest person id null.", "actionrequest.persosn.empty",
 961  
                             actionRequest.getActionRequestId().toString()));
 962  
                 } else {
 963  0
                         Principal principal = KimApiServiceLocator.getIdentityService().getPrincipal(principalId);
 964  0
                         if (principal == null) {
 965  0
                                 errors.add(new WorkflowServiceErrorImpl("ActionRequest person id invalid.",
 966  
                                                 "actionrequest.personid.invalid", actionRequest.getActionRequestId().toString()));
 967  
                         }
 968  
                 }
 969  
 
 970  0
                 if (recipientType.equals(KewApiConstants.ROLE)
 971  
                         && (actionRequest.getRoleName() == null || actionRequest.getRoleName().trim().equals(""))) {
 972  0
                     errors.add(new WorkflowServiceErrorImpl("ActionRequest role name null.", "actionrequest.rolename.null",
 973  
                             actionRequest.getActionRequestId().toString()));
 974  
                 }
 975  
             }
 976  0
             LOG.debug("Exit validateActionRequest(..) ");
 977  0
             if (!errors.isEmpty()) {
 978  0
                 throw new WorkflowServiceErrorException("ActionRequest Validation Error", errors);
 979  
             }
 980  
         }
 981  0
     }
 982  
 
 983  
     public List getDelegateRequests(ActionRequestValue actionRequest) {
 984  0
         List<ActionRequestValue> delegateRequests = new ArrayList<ActionRequestValue>();
 985  0
         List requests = getTopLevelRequests(actionRequest);
 986  0
         for (Object request : requests)
 987  
         {
 988  0
             ActionRequestValue parentActionRequest = (ActionRequestValue) request;
 989  0
             delegateRequests.addAll(parentActionRequest.getChildrenRequests());
 990  0
         }
 991  0
         return delegateRequests;
 992  
     }
 993  
 
 994  
     public List getTopLevelRequests(ActionRequestValue actionRequest) {
 995  0
         List<ActionRequestValue> topLevelRequests = new ArrayList<ActionRequestValue>();
 996  0
         if (actionRequest.isRoleRequest()) {
 997  0
             topLevelRequests.addAll(actionRequest.getChildrenRequests());
 998  
         } else {
 999  0
             topLevelRequests.add(actionRequest);
 1000  
         }
 1001  0
         return topLevelRequests;
 1002  
     }
 1003  
 
 1004  
     public boolean isValidActionRequestCode(String actionRequestCode) {
 1005  0
         return actionRequestCode != null && KewApiConstants.ACTION_REQUEST_CODES.containsKey(actionRequestCode);
 1006  
     }
 1007  
 
 1008  
     public boolean doesPrincipalHaveRequest(String principalId, String documentId) {
 1009  0
         if (getActionRequestDAO().doesDocumentHaveUserRequest(principalId, documentId)) {
 1010  0
             return true;
 1011  
         }
 1012  
         // TODO since we only store the workgroup id for workgroup requests, if the user is in a workgroup that has a request
 1013  
         // than we need get all the requests with workgroup ids and see if our user is in that group
 1014  0
         List<String> groupIds = getActionRequestDAO().getRequestGroupIds(documentId);
 1015  0
         for (String groupId : groupIds) {
 1016  0
             if (KimApiServiceLocator.getGroupService().isMemberOfGroup(principalId, groupId)) {
 1017  0
                 return true;
 1018  
             }
 1019  
         }
 1020  0
         return false;
 1021  
     }
 1022  
 
 1023  
 }