Coverage Report - org.kuali.rice.kew.impl.action.WorkflowDocumentActionsServiceImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
WorkflowDocumentActionsServiceImpl
0%
0/451
0%
0/214
2.241
WorkflowDocumentActionsServiceImpl$1
0%
0/3
N/A
2.241
WorkflowDocumentActionsServiceImpl$10
0%
0/3
N/A
2.241
WorkflowDocumentActionsServiceImpl$11
0%
0/3
N/A
2.241
WorkflowDocumentActionsServiceImpl$12
0%
0/3
N/A
2.241
WorkflowDocumentActionsServiceImpl$13
0%
0/3
N/A
2.241
WorkflowDocumentActionsServiceImpl$14
0%
0/3
N/A
2.241
WorkflowDocumentActionsServiceImpl$15
0%
0/3
N/A
2.241
WorkflowDocumentActionsServiceImpl$16
0%
0/3
N/A
2.241
WorkflowDocumentActionsServiceImpl$17
0%
0/3
N/A
2.241
WorkflowDocumentActionsServiceImpl$18
0%
0/3
N/A
2.241
WorkflowDocumentActionsServiceImpl$19
0%
0/3
N/A
2.241
WorkflowDocumentActionsServiceImpl$2
0%
0/3
N/A
2.241
WorkflowDocumentActionsServiceImpl$20
0%
0/3
N/A
2.241
WorkflowDocumentActionsServiceImpl$21
0%
0/3
N/A
2.241
WorkflowDocumentActionsServiceImpl$22
0%
0/3
N/A
2.241
WorkflowDocumentActionsServiceImpl$23
0%
0/3
N/A
2.241
WorkflowDocumentActionsServiceImpl$24
0%
0/3
N/A
2.241
WorkflowDocumentActionsServiceImpl$25
0%
0/3
N/A
2.241
WorkflowDocumentActionsServiceImpl$26
0%
0/3
N/A
2.241
WorkflowDocumentActionsServiceImpl$27
0%
0/3
N/A
2.241
WorkflowDocumentActionsServiceImpl$3
0%
0/3
N/A
2.241
WorkflowDocumentActionsServiceImpl$4
0%
0/3
N/A
2.241
WorkflowDocumentActionsServiceImpl$5
0%
0/3
N/A
2.241
WorkflowDocumentActionsServiceImpl$6
0%
0/3
N/A
2.241
WorkflowDocumentActionsServiceImpl$7
0%
0/3
N/A
2.241
WorkflowDocumentActionsServiceImpl$8
0%
0/3
N/A
2.241
WorkflowDocumentActionsServiceImpl$9
0%
0/3
N/A
2.241
WorkflowDocumentActionsServiceImpl$DocumentActionCallback
N/A
N/A
2.241
WorkflowDocumentActionsServiceImpl$StandardDocumentActionCallback
0%
0/2
N/A
2.241
 
 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.impl.action;
 17  
 
 18  
 import org.apache.commons.collections.CollectionUtils;
 19  
 import org.apache.commons.lang.StringUtils;
 20  
 import org.apache.log4j.Logger;
 21  
 import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
 22  
 import org.kuali.rice.core.api.exception.RiceRuntimeException;
 23  
 import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
 24  
 import org.kuali.rice.core.framework.services.CoreFrameworkServiceLocator;
 25  
 import org.kuali.rice.kew.actionitem.ActionItem;
 26  
 import org.kuali.rice.kew.actionrequest.ActionRequestValue;
 27  
 import org.kuali.rice.kew.actionrequest.KimPrincipalRecipient;
 28  
 import org.kuali.rice.kew.actionrequest.Recipient;
 29  
 import org.kuali.rice.kew.actiontaken.ActionTakenValue;
 30  
 import org.kuali.rice.kew.api.WorkflowRuntimeException;
 31  
 import org.kuali.rice.kew.api.action.ActionRequest;
 32  
 import org.kuali.rice.kew.api.action.ActionRequestType;
 33  
 import org.kuali.rice.kew.api.action.ActionType;
 34  
 import org.kuali.rice.kew.api.action.AdHocRevoke;
 35  
 import org.kuali.rice.kew.api.action.AdHocToGroup;
 36  
 import org.kuali.rice.kew.api.action.AdHocToPrincipal;
 37  
 import org.kuali.rice.kew.api.action.DocumentActionParameters;
 38  
 import org.kuali.rice.kew.api.action.DocumentActionResult;
 39  
 import org.kuali.rice.kew.api.action.InvalidActionTakenException;
 40  
 import org.kuali.rice.kew.api.action.MovePoint;
 41  
 import org.kuali.rice.kew.api.action.RequestedActions;
 42  
 import org.kuali.rice.kew.api.action.ReturnPoint;
 43  
 import org.kuali.rice.kew.api.action.RoutingReportCriteria;
 44  
 import org.kuali.rice.kew.api.action.ValidActions;
 45  
 import org.kuali.rice.kew.api.action.WorkflowDocumentActionsService;
 46  
 import org.kuali.rice.kew.api.doctype.DocumentTypeService;
 47  
 import org.kuali.rice.kew.api.doctype.IllegalDocumentTypeException;
 48  
 import org.kuali.rice.kew.api.document.Document;
 49  
 import org.kuali.rice.kew.api.document.DocumentContentUpdate;
 50  
 import org.kuali.rice.kew.api.document.DocumentDetail;
 51  
 import org.kuali.rice.kew.api.document.DocumentUpdate;
 52  
 import org.kuali.rice.kew.api.document.PropertyDefinition;
 53  
 import org.kuali.rice.kew.api.document.attribute.WorkflowAttributeDefinition;
 54  
 import org.kuali.rice.kew.api.document.attribute.WorkflowAttributeValidationError;
 55  
 import org.kuali.rice.kew.api.exception.WorkflowException;
 56  
 import org.kuali.rice.kew.definition.AttributeDefinition;
 57  
 import org.kuali.rice.kew.doctype.bo.DocumentType;
 58  
 import org.kuali.rice.kew.dto.DTOConverter;
 59  
 import org.kuali.rice.kew.engine.ActivationContext;
 60  
 import org.kuali.rice.kew.engine.node.RouteNode;
 61  
 import org.kuali.rice.kew.engine.node.RouteNodeInstance;
 62  
 import org.kuali.rice.kew.engine.simulation.SimulationCriteria;
 63  
 import org.kuali.rice.kew.engine.simulation.SimulationResults;
 64  
 import org.kuali.rice.kew.engine.simulation.SimulationWorkflowEngine;
 65  
 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
 66  
 import org.kuali.rice.kew.rule.WorkflowRuleAttribute;
 67  
 import org.kuali.rice.kew.rule.WorkflowAttributeXmlValidator;
 68  
 import org.kuali.rice.kew.rule.bo.RuleAttribute;
 69  
 import org.kuali.rice.kew.rule.xmlrouting.GenericXMLRuleAttribute;
 70  
 import org.kuali.rice.kew.service.KEWServiceLocator;
 71  
 import org.kuali.rice.kew.api.KewApiConstants;
 72  
 import org.kuali.rice.kim.api.identity.principal.Principal;
 73  
 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
 74  
 import org.kuali.rice.krad.util.KRADConstants;
 75  
 import org.kuali.rice.krad.util.ObjectUtils;
 76  
 
 77  
 import java.util.ArrayList;
 78  
 import java.util.Collections;
 79  
 import java.util.HashMap;
 80  
 import java.util.HashSet;
 81  
 import java.util.List;
 82  
 import java.util.Map;
 83  
 import java.util.Set;
 84  
 
 85  
 /**
 86  
  * Reference implementation of the {@link WorkflowDocumentActionsService} api.
 87  
  * 
 88  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 89  
  * 
 90  
  */
 91  0
 public class WorkflowDocumentActionsServiceImpl implements WorkflowDocumentActionsService {
 92  
 
 93  0
     private static final Logger LOG = Logger.getLogger(WorkflowDocumentActionsServiceImpl.class);
 94  
 
 95  
     private DocumentTypeService documentTypeService;
 96  
 
 97  0
     private static final DocumentActionCallback ACKNOWLEDGE_CALLBACK = new StandardDocumentActionCallback() {
 98  
         public DocumentRouteHeaderValue doInDocumentBo(DocumentRouteHeaderValue documentBo, String principalId,
 99  
                 String annotation) throws WorkflowException {
 100  0
             return KEWServiceLocator.getWorkflowDocumentService().acknowledgeDocument(principalId, documentBo,
 101  
                     annotation);
 102  
         }
 103  
 
 104  
         public String getActionName() {
 105  0
             return ActionType.ACKNOWLEDGE.getLabel();
 106  
         }
 107  
     };
 108  
 
 109  0
     private static final DocumentActionCallback APPROVE_CALLBACK = new StandardDocumentActionCallback() {
 110  
         public DocumentRouteHeaderValue doInDocumentBo(DocumentRouteHeaderValue documentBo, String principalId,
 111  
                 String annotation) throws WorkflowException {
 112  0
             return KEWServiceLocator.getWorkflowDocumentService().approveDocument(principalId, documentBo, annotation);
 113  
         }
 114  
 
 115  
         public String getActionName() {
 116  0
             return ActionType.APPROVE.getLabel();
 117  
         }
 118  
     };
 119  
 
 120  0
     private static final DocumentActionCallback CANCEL_CALLBACK = new StandardDocumentActionCallback() {
 121  
         public DocumentRouteHeaderValue doInDocumentBo(DocumentRouteHeaderValue documentBo, String principalId,
 122  
                 String annotation) throws WorkflowException {
 123  0
             return KEWServiceLocator.getWorkflowDocumentService().cancelDocument(principalId, documentBo, annotation);
 124  
         }
 125  
 
 126  
         public String getActionName() {
 127  0
             return ActionType.CANCEL.getLabel();
 128  
         }
 129  
     };
 130  
 
 131  0
     private static final DocumentActionCallback FYI_CALLBACK = new StandardDocumentActionCallback() {
 132  
         public DocumentRouteHeaderValue doInDocumentBo(DocumentRouteHeaderValue documentBo, String principalId,
 133  
                 String annotation) throws WorkflowException {
 134  0
             return KEWServiceLocator.getWorkflowDocumentService().clearFYIDocument(principalId, documentBo, annotation);
 135  
         }
 136  
 
 137  
         public String getActionName() {
 138  0
             return ActionType.FYI.getLabel();
 139  
         }
 140  
     };
 141  
 
 142  0
     private static final DocumentActionCallback COMPLETE_CALLBACK = new StandardDocumentActionCallback() {
 143  
         public DocumentRouteHeaderValue doInDocumentBo(DocumentRouteHeaderValue documentBo, String principalId,
 144  
                 String annotation) throws WorkflowException {
 145  0
             return KEWServiceLocator.getWorkflowDocumentService().completeDocument(principalId, documentBo, annotation);
 146  
         }
 147  
 
 148  
         public String getActionName() {
 149  0
             return ActionType.COMPLETE.getLabel();
 150  
         }
 151  
     };
 152  
 
 153  0
     private static final DocumentActionCallback DISAPPROVE_CALLBACK = new StandardDocumentActionCallback() {
 154  
         public DocumentRouteHeaderValue doInDocumentBo(DocumentRouteHeaderValue documentBo, String principalId,
 155  
                 String annotation) throws WorkflowException {
 156  0
             return KEWServiceLocator.getWorkflowDocumentService().disapproveDocument(principalId, documentBo,
 157  
                     annotation);
 158  
         }
 159  
 
 160  
         public String getActionName() {
 161  0
             return ActionType.DISAPPROVE.getLabel();
 162  
         }
 163  
     };
 164  
 
 165  0
     private static final DocumentActionCallback ROUTE_CALLBACK = new StandardDocumentActionCallback() {
 166  
         public DocumentRouteHeaderValue doInDocumentBo(DocumentRouteHeaderValue documentBo, String principalId,
 167  
                 String annotation) throws WorkflowException {
 168  0
             return KEWServiceLocator.getWorkflowDocumentService().routeDocument(principalId, documentBo, annotation);
 169  
         }
 170  
 
 171  
         public String getActionName() {
 172  0
             return ActionType.ROUTE.getLabel();
 173  
         }
 174  
     };
 175  
 
 176  0
     private static final DocumentActionCallback BLANKET_APPROVE_CALLBACK = new StandardDocumentActionCallback() {
 177  
         public DocumentRouteHeaderValue doInDocumentBo(DocumentRouteHeaderValue documentBo, String principalId,
 178  
                 String annotation) throws WorkflowException {
 179  0
             return KEWServiceLocator.getWorkflowDocumentService().blanketApproval(principalId, documentBo, annotation,
 180  
                     new HashSet<String>());
 181  
         }
 182  
 
 183  
         public String getActionName() {
 184  0
             return ActionType.BLANKET_APPROVE.getLabel();
 185  
         }
 186  
     };
 187  
 
 188  0
     private static final DocumentActionCallback SAVE_CALLBACK = new StandardDocumentActionCallback() {
 189  
         public DocumentRouteHeaderValue doInDocumentBo(DocumentRouteHeaderValue documentBo, String principalId,
 190  
                 String annotation) throws WorkflowException {
 191  0
             return KEWServiceLocator.getWorkflowDocumentService().saveDocument(principalId, documentBo, annotation);
 192  
         }
 193  
 
 194  
         public String getActionName() {
 195  0
             return ActionType.SAVE.getLabel();
 196  
         }
 197  
     };
 198  
 
 199  0
     private static final DocumentActionCallback PLACE_IN_EXCEPTION_CALLBACK = new StandardDocumentActionCallback() {
 200  
         public DocumentRouteHeaderValue doInDocumentBo(DocumentRouteHeaderValue documentBo, String principalId,
 201  
                 String annotation) throws WorkflowException {
 202  0
             return KEWServiceLocator.getWorkflowDocumentService().placeInExceptionRouting(principalId, documentBo,
 203  
                     annotation);
 204  
         }
 205  
 
 206  
         public String getActionName() {
 207  0
             return "Place In Exception";
 208  
         }
 209  
     };
 210  
 
 211  
     protected DocumentRouteHeaderValue init(DocumentActionParameters parameters) {
 212  0
         String documentId = parameters.getDocumentId();
 213  0
         String principalId = parameters.getPrincipalId();
 214  0
         DocumentUpdate documentUpdate = parameters.getDocumentUpdate();
 215  0
         DocumentContentUpdate documentContentUpdate = parameters.getDocumentContentUpdate();
 216  0
         incomingParamCheck(documentId, "documentId");
 217  0
         incomingParamCheck(principalId, "principalId");
 218  0
         if (LOG.isDebugEnabled()) {
 219  0
             LOG.debug("Initializing Document from incoming documentId: " + documentId);
 220  
         }
 221  0
         KEWServiceLocator.getRouteHeaderService().lockRouteHeader(documentId, true);
 222  
 
 223  0
         DocumentRouteHeaderValue document = KEWServiceLocator.getRouteHeaderService().getRouteHeader(documentId);
 224  0
         if (document == null) {
 225  0
             throw new RiceIllegalArgumentException("Failed to locate a document for document id: " + documentId);
 226  
         }
 227  0
         boolean modified = false;
 228  0
         if (documentUpdate != null) {
 229  0
             document.applyDocumentUpdate(documentUpdate);
 230  0
             modified = true;
 231  
         }
 232  0
         if (documentContentUpdate != null) {
 233  0
             String newDocumentContent = DTOConverter.buildUpdatedDocumentContent(document.getDocContent(),
 234  
                     documentContentUpdate, document.getDocumentTypeName());
 235  0
             document.setDocContent(newDocumentContent);
 236  0
             modified = true;
 237  
         }
 238  
 
 239  0
         if (modified) {
 240  0
             KEWServiceLocator.getRouteHeaderService().saveRouteHeader(document);
 241  
 
 242  
             /* 
 243  
              * Branch data is not persisted when we call saveRouteHeader so we must Explicitly
 244  
              * save the branch.  Noticed issue in: KULRICE-4074 when the future action request info,
 245  
              * which is stored in the branch, was not being persisted.
 246  
              * 
 247  
              * The call to setRouteHeaderData will ensure that the variable data is in the branch, but we have
 248  
              * to persist the route header before we can save the branch info.
 249  
              * 
 250  
              * Placing here to minimize system impact.  We should investigate placing this logic into 
 251  
              * saveRouteHeader... but at that point we should just turn auto-update = true on the branch relationship
 252  
              * 
 253  
              */
 254  0
             this.saveRouteNodeInstances(document);
 255  
 
 256  
         }
 257  
 
 258  0
         return document;
 259  
     }
 260  
 
 261  
     /**
 262  
      * This method explicitly saves the branch data if it exists in the routeHeaderValue
 263  
      * 
 264  
      * @param routeHeader
 265  
      */
 266  
     private void saveRouteNodeInstances(DocumentRouteHeaderValue routeHeader) {
 267  
 
 268  0
         List<RouteNodeInstance> routeNodes = routeHeader.getInitialRouteNodeInstances();
 269  0
         if (routeNodes != null && !routeNodes.isEmpty()) {
 270  0
             for (RouteNodeInstance rni : routeNodes) {
 271  0
                 KEWServiceLocator.getRouteNodeService().save(rni);
 272  
             }
 273  
         }
 274  
 
 275  0
     }
 276  
 
 277  
     @Override
 278  
     public Document create(String documentTypeName,
 279  
             String initiatorPrincipalId, DocumentUpdate documentUpdate,
 280  
             DocumentContentUpdate documentContentUpdate)
 281  
             throws RiceIllegalArgumentException, IllegalDocumentTypeException, InvalidActionTakenException {
 282  
 
 283  0
         incomingParamCheck(documentTypeName, "documentTypeName");
 284  0
         incomingParamCheck(initiatorPrincipalId, "initiatorPrincipalId");
 285  
 
 286  0
         if (LOG.isDebugEnabled()) {
 287  0
             LOG.debug("Create Document [documentTypeName=" + documentTypeName + ", initiatorPrincipalId="
 288  
                     + initiatorPrincipalId + "]");
 289  
         }
 290  
 
 291  0
         String documentTypeId = documentTypeService.getIdByName(documentTypeName);
 292  0
         if (documentTypeId == null) {
 293  0
             throw new RiceIllegalArgumentException("Failed to locate a document type with the given name: "
 294  
                     + documentTypeName);
 295  
         }
 296  
 
 297  0
         DocumentRouteHeaderValue documentBo = new DocumentRouteHeaderValue();
 298  0
         documentBo.setDocumentTypeId(documentTypeId);
 299  0
         documentBo.setInitiatorWorkflowId(initiatorPrincipalId);
 300  0
         if (documentUpdate != null) {
 301  0
             documentBo.setDocTitle(documentUpdate.getTitle());
 302  0
             documentBo.setAppDocId(documentUpdate.getApplicationDocumentId());
 303  
         }
 304  0
         if (documentContentUpdate != null) {
 305  0
             String newDocumentContent = DTOConverter.buildUpdatedDocumentContent(null, documentContentUpdate,
 306  
                     documentTypeName);
 307  0
             documentBo.setDocContent(newDocumentContent);
 308  
         }
 309  
 
 310  
         try {
 311  0
             documentBo = KEWServiceLocator.getWorkflowDocumentService()
 312  
                     .createDocument(initiatorPrincipalId, documentBo);
 313  0
         } catch (WorkflowException e) {
 314  
             // TODO remove this once we stop throwing WorkflowException everywhere!
 315  0
             translateException(e);
 316  0
         }
 317  0
         return DocumentRouteHeaderValue.to(documentBo);
 318  
     }
 319  
 
 320  
     @Override
 321  
     public ValidActions determineValidActions(String documentId, String principalId) {
 322  0
         incomingParamCheck(documentId, "documentId");
 323  0
         incomingParamCheck(principalId, "principalId");
 324  0
         DocumentRouteHeaderValue documentBo = KEWServiceLocator.getRouteHeaderService().getRouteHeader(documentId);
 325  0
         if (documentBo == null) {
 326  0
             throw new RiceIllegalArgumentException("Failed to locate a document for document id: " + documentId);
 327  
         }
 328  0
         return determineValidActionsInternal(documentBo, principalId);
 329  
     }
 330  
 
 331  
     protected ValidActions determineValidActionsInternal(DocumentRouteHeaderValue documentBo, String principalId) {
 332  0
         Principal principal = KEWServiceLocator.getIdentityHelperService().getPrincipal(principalId);
 333  0
         return KEWServiceLocator.getActionRegistry().getNewValidActions(principal, documentBo);
 334  
     }
 335  
 
 336  
     @Override
 337  
     public RequestedActions determineRequestedActions(String documentId, String principalId) {
 338  0
         incomingParamCheck(documentId, "documentId");
 339  0
         incomingParamCheck(principalId, "principalId");
 340  0
         DocumentRouteHeaderValue documentBo = KEWServiceLocator.getRouteHeaderService().getRouteHeader(documentId);
 341  0
         if (documentBo == null) {
 342  0
             throw new RiceIllegalArgumentException("Failed to locate a document for document id: " + documentId);
 343  
         }
 344  0
         KEWServiceLocator.getIdentityHelperService().validatePrincipalId(principalId);
 345  0
         return determineRequestedActionsInternal(documentBo, principalId);
 346  
     }
 347  
 
 348  
     protected RequestedActions determineRequestedActionsInternal(DocumentRouteHeaderValue documentBo, String principalId) {
 349  0
         Map<String, String> actionsRequested = KEWServiceLocator.getActionRequestService().getActionsRequested(documentBo,
 350  
                 principalId, true);
 351  0
         boolean completeRequested = false;
 352  0
         boolean approveRequested = false;
 353  0
         boolean acknowledgeRequested = false;
 354  0
         boolean fyiRequested = false;
 355  0
         for (String actionRequestCode : actionsRequested.keySet()) {
 356  0
             if (ActionRequestType.FYI.getCode().equals(actionRequestCode)) {
 357  0
                 fyiRequested = Boolean.parseBoolean(actionsRequested.get(actionRequestCode));
 358  0
             } else if (ActionRequestType.ACKNOWLEDGE.getCode().equals(actionRequestCode)) {
 359  0
                 acknowledgeRequested = Boolean.parseBoolean(actionsRequested.get(actionRequestCode));
 360  0
             } else if (ActionRequestType.APPROVE.getCode().equals(actionRequestCode)) {
 361  0
                 approveRequested = Boolean.parseBoolean(actionsRequested.get(actionRequestCode));
 362  0
             } else if (ActionRequestType.COMPLETE.getCode().equals(actionRequestCode)) {
 363  0
                 completeRequested = Boolean.parseBoolean(actionsRequested.get(actionRequestCode));
 364  
             }
 365  
         }
 366  0
         return RequestedActions.create(completeRequested, approveRequested, acknowledgeRequested, fyiRequested);
 367  
     }
 368  
 
 369  
     public DocumentDetail executeSimulation(RoutingReportCriteria reportCriteria) {
 370  0
         incomingParamCheck(reportCriteria, "reportCriteria");
 371  0
         if ( LOG.isDebugEnabled() ) {
 372  0
                 LOG.debug("Executing routing report [docId=" + reportCriteria.getDocumentId() + ", docTypeName=" + reportCriteria.getDocumentTypeName() + "]");
 373  
         }
 374  0
         SimulationCriteria criteria = SimulationCriteria.from(reportCriteria);
 375  0
         return DTOConverter.convertDocumentDetailNew(KEWServiceLocator.getRoutingReportService().report(criteria));
 376  
     }
 377  
 
 378  
     protected DocumentActionResult constructDocumentActionResult(DocumentRouteHeaderValue documentBo, String principalId) {
 379  0
         Document document = DocumentRouteHeaderValue.to(documentBo);
 380  0
         ValidActions validActions = determineValidActionsInternal(documentBo, principalId);
 381  0
         RequestedActions requestedActions = determineRequestedActionsInternal(documentBo, principalId);
 382  0
         return DocumentActionResult.create(document, validActions, requestedActions);
 383  
     }
 384  
 
 385  
     @Override
 386  
     public DocumentActionResult acknowledge(DocumentActionParameters parameters) {
 387  0
         incomingParamCheck(parameters, "parameters");
 388  0
         return executeActionInternal(parameters, ACKNOWLEDGE_CALLBACK);
 389  
     }
 390  
 
 391  
     @Override
 392  
     public DocumentActionResult approve(DocumentActionParameters parameters) {
 393  0
         incomingParamCheck(parameters, "parameters");
 394  0
         return executeActionInternal(parameters, APPROVE_CALLBACK);
 395  
     }
 396  
 
 397  
     @Override
 398  
     public DocumentActionResult adHocToPrincipal(DocumentActionParameters parameters,
 399  
             final AdHocToPrincipal adHocToPrincipal) {
 400  0
         incomingParamCheck(parameters, "parameters");
 401  0
         incomingParamCheck(adHocToPrincipal, "adHocToPrincipal");
 402  0
         return executeActionInternal(parameters,
 403  0
                 new DocumentActionCallback() {
 404  
                     @Override
 405  
                     public String getLogMessage(String documentId, String principalId, String annotation) {
 406  0
                         return "AdHoc Route To Principal [principalId=" + principalId +
 407  
                                 ", docId=" + documentId +
 408  
                                 ", actionRequest=" + adHocToPrincipal.getActionRequested() +
 409  
                                 ", nodeName=" + adHocToPrincipal.getNodeName() +
 410  
                                 ", targetPrincipalId=" + adHocToPrincipal.getTargetPrincipalId() +
 411  
                                 ", forceAction=" + adHocToPrincipal.isForceAction() +
 412  
                                 ", annotation=" + annotation +
 413  
                                 ", requestLabel=" + adHocToPrincipal.getRequestLabel() + "]";
 414  
                     }
 415  
 
 416  
                     @Override
 417  
                     public DocumentRouteHeaderValue doInDocumentBo(DocumentRouteHeaderValue documentBo,
 418  
                             String principalId, String annotation) throws WorkflowException {
 419  0
                         return KEWServiceLocator.getWorkflowDocumentService().adHocRouteDocumentToPrincipal(
 420  
                                 principalId,
 421  
                                     documentBo,
 422  
                                     adHocToPrincipal.getActionRequested().getCode(),
 423  
                                     adHocToPrincipal.getNodeName(),
 424  
                                     adHocToPrincipal.getPriority(),
 425  
                                     annotation,
 426  
                                     adHocToPrincipal.getTargetPrincipalId(),
 427  
                                     adHocToPrincipal.getResponsibilityDescription(),
 428  
                                     adHocToPrincipal.isForceAction(),
 429  
                                     adHocToPrincipal.getRequestLabel());
 430  
                     }
 431  
                 });
 432  
     }
 433  
 
 434  
     @Override
 435  
     public DocumentActionResult adHocToGroup(DocumentActionParameters parameters,
 436  
             final AdHocToGroup adHocToGroup) {
 437  0
         incomingParamCheck(parameters, "parameters");
 438  0
         incomingParamCheck(adHocToGroup, "adHocToGroup");
 439  0
         return executeActionInternal(parameters,
 440  0
                 new DocumentActionCallback() {
 441  
                     @Override
 442  
                     public String getLogMessage(String documentId, String principalId, String annotation) {
 443  0
                         return "AdHoc Route To Group [principalId=" + principalId +
 444  
                                 ", docId=" + documentId +
 445  
                                 ", actionRequest=" + adHocToGroup.getActionRequested() +
 446  
                                 ", nodeName=" + adHocToGroup.getNodeName() +
 447  
                                 ", targetGroupId=" + adHocToGroup.getTargetGroupId() +
 448  
                                 ", forceAction=" + adHocToGroup.isForceAction() +
 449  
                                 ", annotation=" + annotation +
 450  
                                 ", requestLabel=" + adHocToGroup.getRequestLabel() + "]";
 451  
                     }
 452  
 
 453  
                     @Override
 454  
                     public DocumentRouteHeaderValue doInDocumentBo(DocumentRouteHeaderValue documentBo,
 455  
                             String principalId, String annotation) throws WorkflowException {
 456  0
                         return KEWServiceLocator.getWorkflowDocumentService().adHocRouteDocumentToGroup(principalId,
 457  
                                     documentBo,
 458  
                                     adHocToGroup.getActionRequested().getCode(),
 459  
                                     adHocToGroup.getNodeName(),
 460  
                                     adHocToGroup.getPriority(),
 461  
                                     annotation,
 462  
                                     adHocToGroup.getTargetGroupId(),
 463  
                                     adHocToGroup.getResponsibilityDescription(),
 464  
                                     adHocToGroup.isForceAction(),
 465  
                                     adHocToGroup.getRequestLabel());
 466  
                     }
 467  
                 });
 468  
     }
 469  
 
 470  
     @Override
 471  
     public DocumentActionResult revokeAdHocRequestById(DocumentActionParameters parameters,
 472  
             final String actionRequestId) {
 473  0
         incomingParamCheck(parameters, "parameters");
 474  0
         incomingParamCheck(actionRequestId, "actionRequestId");
 475  0
         return executeActionInternal(parameters,
 476  0
                 new DocumentActionCallback() {
 477  
                     @Override
 478  
                     public String getLogMessage(String documentId, String principalId, String annotation) {
 479  0
                         return "Revoke AdHoc from Principal [principalId=" + principalId +
 480  
                                 ", documentId=" + documentId +
 481  
                                 ", annotation=" + annotation +
 482  
                                 ", actionRequestId=" + actionRequestId + "]";
 483  
                     }
 484  
 
 485  
                     @Override
 486  
                     public DocumentRouteHeaderValue doInDocumentBo(DocumentRouteHeaderValue documentBo,
 487  
                             String principalId, String annotation) throws WorkflowException {
 488  0
                         return KEWServiceLocator.getWorkflowDocumentService().revokeAdHocRequests(principalId,
 489  
                                 documentBo, actionRequestId, annotation);
 490  
                     }
 491  
                 });
 492  
     }
 493  
 
 494  
     @Override
 495  
     public DocumentActionResult revokeAdHocRequests(DocumentActionParameters parameters,
 496  
             final AdHocRevoke revoke) {
 497  0
         incomingParamCheck(parameters, "parameters");
 498  0
         incomingParamCheck(revoke, "revoke");
 499  0
         return executeActionInternal(parameters,
 500  0
                 new DocumentActionCallback() {
 501  
                     @Override
 502  
                     public String getLogMessage(String documentId, String principalId, String annotation) {
 503  0
                         return "Revoke AdHoc Requests [principalId=" + principalId +
 504  
                                 ", docId=" + documentId +
 505  
                                 ", annotation=" + annotation +
 506  
                                 ", revoke=" + revoke.toString() + "]";
 507  
                     }
 508  
 
 509  
                     @Override
 510  
                     public DocumentRouteHeaderValue doInDocumentBo(DocumentRouteHeaderValue documentBo,
 511  
                             String principalId, String annotation) throws WorkflowException {
 512  0
                         return KEWServiceLocator.getWorkflowDocumentService().revokeAdHocRequests(principalId,
 513  
                                 documentBo, revoke, annotation);
 514  
                     }
 515  
                 });
 516  
     }
 517  
 
 518  
     @Override
 519  
     public DocumentActionResult revokeAllAdHocRequests(DocumentActionParameters parameters) {
 520  0
         incomingParamCheck(parameters, "parameters");
 521  0
         return executeActionInternal(parameters,
 522  0
                 new DocumentActionCallback() {
 523  
                     @Override
 524  
                     public String getLogMessage(String documentId, String principalId, String annotation) {
 525  0
                         return "Revoke All AdHoc Requests [principalId=" + principalId +
 526  
                                 ", docId=" + documentId +
 527  
                                 ", annotation=" + annotation + "]";
 528  
                     }
 529  
 
 530  
                     @Override
 531  
                     public DocumentRouteHeaderValue doInDocumentBo(DocumentRouteHeaderValue documentBo,
 532  
                             String principalId, String annotation) throws WorkflowException {
 533  0
                         return KEWServiceLocator.getWorkflowDocumentService().revokeAdHocRequests(principalId,
 534  
                                 documentBo, (AdHocRevoke) null, annotation);
 535  
                     }
 536  
                 });
 537  
     }
 538  
 
 539  
     @Override
 540  
     public DocumentActionResult cancel(DocumentActionParameters parameters) {
 541  0
         incomingParamCheck(parameters, "parameters");
 542  0
         return executeActionInternal(parameters, CANCEL_CALLBACK);
 543  
     }
 544  
 
 545  
     @Override
 546  
     public DocumentActionResult clearFyi(DocumentActionParameters parameters) {
 547  0
         incomingParamCheck(parameters, "parameters");
 548  0
         return executeActionInternal(parameters, FYI_CALLBACK);
 549  
     }
 550  
 
 551  
     @Override
 552  
     public DocumentActionResult complete(DocumentActionParameters parameters) {
 553  0
         incomingParamCheck(parameters, "parameters");
 554  0
         return executeActionInternal(parameters, COMPLETE_CALLBACK);
 555  
     }
 556  
 
 557  
     @Override
 558  
     public DocumentActionResult disapprove(DocumentActionParameters parameters) {
 559  0
         incomingParamCheck(parameters, "parameters");
 560  0
         return executeActionInternal(parameters, DISAPPROVE_CALLBACK);
 561  
     }
 562  
 
 563  
     @Override
 564  
     public DocumentActionResult route(DocumentActionParameters parameters) {
 565  0
         incomingParamCheck(parameters, "parameters");
 566  0
         return executeActionInternal(parameters, ROUTE_CALLBACK);
 567  
     }
 568  
 
 569  
     @Override
 570  
     public DocumentActionResult blanketApprove(DocumentActionParameters parameters) {
 571  0
         incomingParamCheck(parameters, "parameters");
 572  0
         return executeActionInternal(parameters, BLANKET_APPROVE_CALLBACK);
 573  
     }
 574  
 
 575  
     @Override
 576  
     public DocumentActionResult blanketApproveToNodes(DocumentActionParameters parameters,
 577  
             final Set<String> nodeNames) {
 578  0
         incomingParamCheck(parameters, "parameters");
 579  0
         incomingParamCheck(nodeNames, "nodeNames");
 580  0
         return executeActionInternal(parameters,
 581  0
                 new DocumentActionCallback() {
 582  
                     public DocumentRouteHeaderValue doInDocumentBo(DocumentRouteHeaderValue documentBo,
 583  
                             String principalId, String annotation) throws WorkflowException {
 584  0
                         return KEWServiceLocator.getWorkflowDocumentService().blanketApproval(principalId, documentBo,
 585  
                                 annotation, nodeNames);
 586  
                     }
 587  
 
 588  
                     public String getLogMessage(String documentId, String principalId, String annotation) {
 589  0
                         return "Blanket Approve [principalId=" + principalId + ", documentId=" + documentId
 590  
                                 + ", annotation=" + annotation + ", nodeNames=" + nodeNames + "]";
 591  
                     }
 592  
                 });
 593  
     }
 594  
 
 595  
     @Override
 596  
     public DocumentActionResult returnToPreviousNode(DocumentActionParameters parameters,
 597  
             final ReturnPoint returnPoint) {
 598  0
         incomingParamCheck(parameters, "parameters");
 599  0
         incomingParamCheck(returnPoint, "returnPoint");
 600  0
         return executeActionInternal(parameters,
 601  0
                 new DocumentActionCallback() {
 602  
                     public DocumentRouteHeaderValue doInDocumentBo(DocumentRouteHeaderValue documentBo,
 603  
                             String principalId, String annotation) throws WorkflowException {
 604  0
                         return KEWServiceLocator.getWorkflowDocumentService().returnDocumentToPreviousNode(principalId,
 605  
                                 documentBo, returnPoint.getNodeName(), annotation);
 606  
                     }
 607  
 
 608  
                     public String getLogMessage(String documentId, String principalId, String annotation) {
 609  0
                         return "Return to Previous [principalId=" + principalId + ", documentId=" + documentId
 610  
                                 + ", annotation=" + annotation + ", destNodeName=" + returnPoint.getNodeName() + "]";
 611  
                     }
 612  
                 });
 613  
     }
 614  
 
 615  
     @Override
 616  
     public DocumentActionResult move(DocumentActionParameters parameters,
 617  
             final MovePoint movePoint) {
 618  0
         incomingParamCheck(parameters, "parameters");
 619  0
         incomingParamCheck(movePoint, "movePoint");
 620  0
         return executeActionInternal(parameters,
 621  0
                 new DocumentActionCallback() {
 622  
                     public DocumentRouteHeaderValue doInDocumentBo(DocumentRouteHeaderValue documentBo,
 623  
                             String principalId, String annotation) throws WorkflowException {
 624  0
                         return KEWServiceLocator.getWorkflowDocumentService().moveDocument(principalId, documentBo,
 625  
                                 movePoint, annotation);
 626  
                     }
 627  
 
 628  
                     public String getLogMessage(String documentId, String principalId, String annotation) {
 629  0
                         return "Move Document [principalId=" + principalId + ", documentId=" + documentId
 630  
                                 + ", annotation=" + annotation + ", movePoint=" + movePoint + "]";
 631  
                     }
 632  
                 });
 633  
     }
 634  
 
 635  
     @Override
 636  
     public DocumentActionResult takeGroupAuthority(DocumentActionParameters parameters,
 637  
             final String groupId) {
 638  0
         incomingParamCheck(parameters, "parameters");
 639  0
         incomingParamCheck(groupId, "groupId");
 640  0
         return executeActionInternal(parameters,
 641  0
                 new StandardDocumentActionCallback() {
 642  
                     public DocumentRouteHeaderValue doInDocumentBo(DocumentRouteHeaderValue documentBo,
 643  
                             String principalId, String annotation) throws WorkflowException {
 644  0
                         return KEWServiceLocator.getWorkflowDocumentService().takeGroupAuthority(principalId,
 645  
                                 documentBo, groupId, annotation);
 646  
                     }
 647  
 
 648  
                     public String getActionName() {
 649  0
                         return ActionType.TAKE_GROUP_AUTHORITY.getLabel();
 650  
                     }
 651  
                 });
 652  
     }
 653  
 
 654  
     @Override
 655  
     public DocumentActionResult releaseGroupAuthority(DocumentActionParameters parameters,
 656  
             final String groupId) {
 657  0
         incomingParamCheck(parameters, "parameters");
 658  0
         incomingParamCheck(groupId, "groupId");
 659  0
         return executeActionInternal(parameters,
 660  0
                 new StandardDocumentActionCallback() {
 661  
                     public DocumentRouteHeaderValue doInDocumentBo(DocumentRouteHeaderValue documentBo,
 662  
                             String principalId, String annotation) throws WorkflowException {
 663  0
                         return KEWServiceLocator.getWorkflowDocumentService().releaseGroupAuthority(principalId,
 664  
                                 documentBo, groupId, annotation);
 665  
                     }
 666  
 
 667  
                     public String getActionName() {
 668  0
                         return ActionType.RELEASE_GROUP_AUTHORITY.getLabel();
 669  
                     }
 670  
                 });
 671  
 
 672  
     }
 673  
 
 674  
     @Override
 675  
     public DocumentActionResult save(DocumentActionParameters parameters) {
 676  0
         incomingParamCheck(parameters, "parameters");
 677  0
         return executeActionInternal(parameters, SAVE_CALLBACK);
 678  
     }
 679  
 
 680  
     @Override
 681  
     public DocumentActionResult saveDocumentData(DocumentActionParameters parameters) {
 682  0
         incomingParamCheck(parameters, "parameters");
 683  0
         return executeActionInternal(parameters, new DocumentActionCallback() {
 684  
 
 685  
             @Override
 686  
             public String getLogMessage(String documentId, String principalId, String annotation) {
 687  0
                 return "Saving Routing Data [principalId=" + principalId + ", docId=" + documentId + "]";
 688  
             }
 689  
 
 690  
             @Override
 691  
             public DocumentRouteHeaderValue doInDocumentBo(
 692  
                     DocumentRouteHeaderValue documentBo, String principalId,
 693  
                     String annotation) throws WorkflowException {
 694  0
                 return KEWServiceLocator.getWorkflowDocumentService().saveRoutingData(principalId, documentBo);
 695  
             }
 696  
         });
 697  
     }
 698  
 
 699  
     @Override
 700  
     public Document delete(String documentId, String principalId) {
 701  0
         incomingParamCheck(documentId, "documentId");
 702  0
         incomingParamCheck(principalId, "principalId");
 703  0
         DocumentRouteHeaderValue documentBo = init(DocumentActionParameters.create(documentId, principalId, null));
 704  0
         if (LOG.isDebugEnabled()) {
 705  0
             LOG.debug("Delete [principalId=" + principalId + ", documentId=" + documentId + "]");
 706  
         }
 707  0
         Document document = null;
 708  
         try {
 709  0
             document = DocumentRouteHeaderValue.to(documentBo);
 710  0
             KEWServiceLocator.getWorkflowDocumentService().deleteDocument(principalId, documentBo);
 711  
 
 712  0
         } catch (WorkflowException e) {
 713  0
             translateException(e);
 714  0
         }
 715  0
         return document;
 716  
     }
 717  
 
 718  
     @Override
 719  
     public void logAnnotation(String documentId, String principalId, String annotation) {
 720  0
         incomingParamCheck(documentId, "documentId");
 721  0
         incomingParamCheck(principalId, "principalId");
 722  0
         incomingParamCheck(annotation, "annotation");
 723  0
         DocumentRouteHeaderValue documentBo = KEWServiceLocator.getRouteHeaderService().getRouteHeader(documentId);
 724  
         try {
 725  0
             KEWServiceLocator.getWorkflowDocumentService().logDocumentAction(principalId, documentBo, annotation);
 726  0
         } catch (WorkflowException e) {
 727  0
             translateException(e);
 728  0
         }
 729  0
     }
 730  
 
 731  
     @Override
 732  
     public void initiateIndexing(String documentId) {
 733  0
         incomingParamCheck(documentId, "documentId");
 734  
         // TODO ewestfal - THIS METHOD NEEDS JAVADOCS
 735  0
         throw new UnsupportedOperationException("implement me!!!");
 736  
     }
 737  
 
 738  
     @Override
 739  
     public DocumentActionResult superUserBlanketApprove(DocumentActionParameters parameters,
 740  
             final boolean executePostProcessor) {
 741  0
         incomingParamCheck(parameters, "parameters");
 742  0
         return executeActionInternal(parameters,
 743  0
                 new DocumentActionCallback() {
 744  
                     public DocumentRouteHeaderValue doInDocumentBo(DocumentRouteHeaderValue documentBo,
 745  
                             String principalId, String annotation) throws WorkflowException {
 746  0
                         return KEWServiceLocator.getWorkflowDocumentService().superUserApprove(principalId, documentBo,
 747  
                                 annotation, executePostProcessor);
 748  
                     }
 749  
 
 750  
                     public String getLogMessage(String documentId, String principalId, String annotation) {
 751  0
                         return "SU Blanket Approve [principalId=" + principalId + ", documentId=" + documentId
 752  
                                 + ", annotation=" + annotation + "]";
 753  
                     }
 754  
                 });
 755  
     }
 756  
 
 757  
     @Override
 758  
     public DocumentActionResult superUserNodeApprove(DocumentActionParameters parameters,
 759  
             final boolean executePostProcessor, final String nodeName) {
 760  0
                 incomingParamCheck(parameters, "parameters");
 761  0
                 incomingParamCheck(nodeName, "nodeName");
 762  0
         return executeActionInternal(parameters,
 763  0
                 new DocumentActionCallback() {
 764  
                     public DocumentRouteHeaderValue doInDocumentBo(DocumentRouteHeaderValue documentBo,
 765  
                             String principalId, String annotation) throws WorkflowException {
 766  0
                         return KEWServiceLocator.getWorkflowDocumentService().superUserNodeApproveAction(principalId,
 767  
                                 documentBo, nodeName, annotation, executePostProcessor);
 768  
                     }
 769  
 
 770  
                     public String getLogMessage(String documentId, String principalId, String annotation) {
 771  0
                         return "SU Node Approve Action [principalId=" + principalId + ", documentId=" + documentId
 772  
                                 + ", nodeName=" + nodeName + ", annotation=" + annotation + "]";
 773  
                     }
 774  
                 });
 775  
 
 776  
     }
 777  
 
 778  
     @Override
 779  
     public DocumentActionResult superUserTakeRequestedAction(DocumentActionParameters parameters,
 780  
             final boolean executePostProcessor, final String actionRequestId) {
 781  0
                 incomingParamCheck(parameters, "parameters");
 782  0
                 incomingParamCheck(actionRequestId, "actionRequestId");
 783  0
         return executeActionInternal(parameters,
 784  0
                 new DocumentActionCallback() {
 785  
                     public DocumentRouteHeaderValue doInDocumentBo(DocumentRouteHeaderValue documentBo,
 786  
                             String principalId, String annotation) throws WorkflowException {
 787  0
                         return KEWServiceLocator.getWorkflowDocumentService().superUserActionRequestApproveAction(
 788  
                                 principalId, documentBo, actionRequestId, annotation,
 789  
                                 executePostProcessor);
 790  
                     }
 791  
 
 792  
                     public String getLogMessage(String documentId, String principalId, String annotation) {
 793  0
                         return "SU Take Requested Action [principalId=" + principalId + ", docume tId=" + documentId
 794  
                                 + ", actionRequestId=" + actionRequestId + ", annotation=" + annotation + "]";
 795  
                     }
 796  
                 });
 797  
     }
 798  
 
 799  
     @Override
 800  
     public DocumentActionResult superUserDisapprove(DocumentActionParameters parameters,
 801  
             final boolean executePostProcessor) {
 802  0
                         incomingParamCheck(parameters, "parameters");
 803  0
         return executeActionInternal(parameters,
 804  0
                 new DocumentActionCallback() {
 805  
                     public DocumentRouteHeaderValue doInDocumentBo(DocumentRouteHeaderValue documentBo,
 806  
                             String principalId, String annotation) throws WorkflowException {
 807  0
                         return KEWServiceLocator.getWorkflowDocumentService().superUserDisapproveAction(principalId,
 808  
                                 documentBo, annotation, executePostProcessor);
 809  
                     }
 810  
 
 811  
                     public String getLogMessage(String documentId, String principalId, String annotation) {
 812  0
                         return "SU Disapprove [principalId=" + principalId + ", documentId=" + documentId
 813  
                                 + ", annotation=" + annotation + "]";
 814  
                     }
 815  
                 });
 816  
     }
 817  
 
 818  
     @Override
 819  
     public DocumentActionResult superUserCancel(DocumentActionParameters parameters, final boolean executePostProcessor) {
 820  0
                         incomingParamCheck(parameters, "parameters");
 821  0
         return executeActionInternal(parameters,
 822  0
                 new DocumentActionCallback() {
 823  
                     public DocumentRouteHeaderValue doInDocumentBo(DocumentRouteHeaderValue documentBo,
 824  
                             String principalId, String annotation) throws WorkflowException {
 825  0
                         return KEWServiceLocator.getWorkflowDocumentService().superUserCancelAction(principalId,
 826  
                                 documentBo, annotation, executePostProcessor);
 827  
                     }
 828  
 
 829  
                     public String getLogMessage(String documentId, String principalId, String annotation) {
 830  0
                         return "SU Cancel [principalId=" + principalId + ", documentId=" + documentId + ", annotation="
 831  
                                 + annotation + "]";
 832  
                     }
 833  
                 });
 834  
     }
 835  
 
 836  
     @Override
 837  
     public DocumentActionResult superUserReturnToPreviousNode(DocumentActionParameters parameters,
 838  
             final boolean executePostProcessor, final ReturnPoint returnPoint) {
 839  0
             incomingParamCheck(parameters, "parameters");
 840  0
             incomingParamCheck(returnPoint, "returnPoint");
 841  0
         return executeActionInternal(parameters,
 842  0
                 new DocumentActionCallback() {
 843  
                     public DocumentRouteHeaderValue doInDocumentBo(DocumentRouteHeaderValue documentBo,
 844  
                             String principalId, String annotation) throws WorkflowException {
 845  0
                         return KEWServiceLocator.getWorkflowDocumentService().superUserReturnDocumentToPreviousNode(
 846  
                                 principalId, documentBo, returnPoint.getNodeName(), annotation, executePostProcessor);
 847  
                     }
 848  
 
 849  
                     public String getLogMessage(String documentId, String principalId, String annotation) {
 850  0
                         return "SU Return to Previous Node [principalId=" + principalId + ", documentId=" + documentId
 851  
                                 + ", annotation=" + annotation + ", returnPoint=" + returnPoint + "]";
 852  
                     }
 853  
                 });
 854  
 
 855  
     }
 856  
 
 857  
     @Override
 858  
     public DocumentActionResult placeInExceptionRouting(DocumentActionParameters parameters) {
 859  0
         incomingParamCheck(parameters, "parameters");
 860  0
         return executeActionInternal(parameters, PLACE_IN_EXCEPTION_CALLBACK);
 861  
     }
 862  
 
 863  
     @Override
 864  
     public boolean documentWillHaveAtLeastOneActionRequest(RoutingReportCriteria reportCriteria, List<String> actionRequestedCodes, boolean ignoreCurrentActionRequests) {
 865  0
         incomingParamCheck(reportCriteria, "reportCriteria");
 866  0
         incomingParamCheck(actionRequestedCodes, "actionRequestedCodes");
 867  
         try {
 868  0
                 SimulationWorkflowEngine simulationEngine = KEWServiceLocator.getSimulationEngine();
 869  0
                 SimulationCriteria criteria = SimulationCriteria.from(reportCriteria);
 870  
                 // set activate requests to true by default so force action works correctly
 871  0
                 criteria.setActivateRequests(Boolean.TRUE);
 872  0
                 SimulationResults results = simulationEngine.runSimulation(criteria);
 873  0
             List<ActionRequestValue> actionRequestsToProcess = results.getSimulatedActionRequests();
 874  0
             if (!ignoreCurrentActionRequests) {
 875  0
                 actionRequestsToProcess.addAll(results.getDocument().getActionRequests());
 876  
             }
 877  0
             for (ActionRequestValue actionRequest : actionRequestsToProcess) {
 878  0
                 if (actionRequest.isDone()) {
 879  
                     // an action taken has eliminated this request from being active
 880  0
                     continue;
 881  
                 }
 882  
                                 // if no action request codes are passed in.... assume any request found is
 883  0
                             if (CollectionUtils.isEmpty(actionRequestedCodes) ) {
 884  
                                     // we found an action request
 885  0
                                     return true;
 886  
                             }
 887  
                             // check the action requested codes passed in
 888  0
                             for (String requestedActionRequestCode : actionRequestedCodes) {
 889  0
                                         if (requestedActionRequestCode.equals(actionRequest.getActionRequested())) {
 890  0
                                             boolean satisfiesDestinationUserCriteria = (criteria.getDestinationRecipients().isEmpty()) || (isRecipientRoutedRequest(actionRequest,criteria.getDestinationRecipients()));
 891  0
                                             if (satisfiesDestinationUserCriteria) {
 892  0
                                                 if (StringUtils.isBlank(criteria.getDestinationNodeName())) {
 893  0
                                                     return true;
 894  0
                                                 } else if (StringUtils.equals(criteria.getDestinationNodeName(),actionRequest.getNodeInstance().getName())) {
 895  0
                                                     return true;
 896  
                                                 }
 897  
                                             }
 898  0
                                         }
 899  
                                 }
 900  
                         }
 901  0
                 return false;
 902  0
         } catch (Exception ex) {
 903  0
                 String error = "Problems evaluating documentWillHaveAtLeastOneActionRequest: " + ex.getMessage();
 904  0
             LOG.error(error,ex);
 905  0
             if (ex instanceof RuntimeException) {
 906  0
                     throw (RuntimeException)ex;
 907  
             }
 908  0
             throw new RuntimeException(error, ex);
 909  
         }
 910  
     }
 911  
 
 912  
     private boolean isRecipientRoutedRequest(ActionRequestValue actionRequest, List<Recipient> recipients) throws WorkflowException {
 913  0
         for (Recipient recipient : recipients) {
 914  0
             if (actionRequest.isRecipientRoutedRequest(recipient)) {
 915  0
                 return true;
 916  
             }
 917  
         }
 918  0
         return false;
 919  
     }
 920  
 
 921  
     @Override
 922  
     public void reResolveRoleByDocTypeName(String documentTypeName, String roleName, String qualifiedRoleNameLabel) {
 923  0
         incomingParamCheck(documentTypeName, "documentTypeName");
 924  0
         incomingParamCheck(roleName, "roleName");
 925  0
         incomingParamCheck(qualifiedRoleNameLabel, "qualifiedRoleNameLabel");
 926  0
         if ( LOG.isDebugEnabled() ) {
 927  0
                 LOG.debug("Re-resolving Role [docTypeName=" + documentTypeName + ", roleName=" + roleName + ", qualifiedRoleNameLabel=" + qualifiedRoleNameLabel + "]");
 928  
         }
 929  0
             DocumentType documentType = KEWServiceLocator.getDocumentTypeService().findByName(documentTypeName);
 930  0
             if (org.apache.commons.lang.StringUtils.isEmpty(qualifiedRoleNameLabel)) {
 931  0
                     KEWServiceLocator.getRoleService().reResolveRole(documentType, roleName);
 932  
             } else {
 933  0
                     KEWServiceLocator.getRoleService().reResolveQualifiedRole(documentType, roleName, qualifiedRoleNameLabel);
 934  
             }
 935  0
     }
 936  
 
 937  
     public void reResolveRoleByDocumentId(String documentId, String roleName, String qualifiedRoleNameLabel) {
 938  0
         incomingParamCheck(documentId, "documentId");
 939  0
         incomingParamCheck(roleName, "roleName");
 940  0
         incomingParamCheck(qualifiedRoleNameLabel, "qualifiedRoleNameLabel");
 941  0
         if ( LOG.isDebugEnabled() ) {
 942  0
                 LOG.debug("Re-resolving Role [documentId=" + documentId + ", roleName=" + roleName + ", qualifiedRoleNameLabel=" + qualifiedRoleNameLabel + "]");
 943  
         }
 944  0
         DocumentRouteHeaderValue routeHeader = loadDocument(documentId);
 945  0
             if (org.apache.commons.lang.StringUtils.isEmpty(qualifiedRoleNameLabel)) {
 946  0
                     KEWServiceLocator.getRoleService().reResolveRole(routeHeader, roleName);
 947  
             } else {
 948  0
                     KEWServiceLocator.getRoleService().reResolveQualifiedRole(routeHeader, roleName, qualifiedRoleNameLabel);
 949  
             }
 950  0
     }
 951  
 
 952  
     @Override
 953  
     public List<WorkflowAttributeValidationError> validateWorkflowAttributeDefinition(
 954  
             WorkflowAttributeDefinition definition) {
 955  0
         if (definition == null) {
 956  0
             throw new RiceIllegalArgumentException("definition was null");
 957  
         }
 958  0
         if ( LOG.isDebugEnabled() ) {
 959  0
             LOG.debug("Validating WorkflowAttributeDefinition [attributeName="+definition.getAttributeName()+"]");
 960  
         }
 961  0
         AttributeDefinition attributeDefinition = DTOConverter.convertWorkflowAttributeDefinition(definition);
 962  0
         WorkflowRuleAttribute attribute = null;
 963  0
         if (attributeDefinition != null) {
 964  0
             attribute = (WorkflowRuleAttribute) GlobalResourceLoader.getObject(attributeDefinition.getObjectDefinition());
 965  
         }
 966  0
         if (attribute instanceof GenericXMLRuleAttribute) {
 967  0
             Map<String, String> attributePropMap = new HashMap<String, String>();
 968  0
             GenericXMLRuleAttribute xmlAttribute = (GenericXMLRuleAttribute)attribute;
 969  0
             xmlAttribute.setExtensionDefinition(RuleAttribute.to(attributeDefinition.getRuleAttribute()));
 970  0
             for (PropertyDefinition propertyDefinition : definition.getPropertyDefinitions()) {
 971  0
                 attributePropMap.put(propertyDefinition.getName(), propertyDefinition.getValue());
 972  
             }
 973  0
             xmlAttribute.setParamMap(attributePropMap);
 974  
     }
 975  0
         List<WorkflowAttributeValidationError> errors = new ArrayList<WorkflowAttributeValidationError>();
 976  
         //validate inputs from client application if the attribute is capable
 977  0
         if (attribute instanceof WorkflowAttributeXmlValidator) {
 978  0
             List<org.kuali.rice.kew.rule.WorkflowAttributeValidationError> validationErrors = ((WorkflowAttributeXmlValidator)attribute).validateClientRoutingData();
 979  0
             if (validationErrors != null) {
 980  0
                 for (org.kuali.rice.kew.rule.WorkflowAttributeValidationError validationError : validationErrors) {
 981  0
                     errors.add(org.kuali.rice.kew.rule.WorkflowAttributeValidationError.to(validationError));
 982  
                 }
 983  
             }
 984  
         }
 985  0
         return errors;
 986  
     }
 987  
 
 988  
     @Override
 989  
     public boolean isFinalApprover(String documentId, String principalId) {
 990  0
         incomingParamCheck(documentId, "documentId");
 991  0
         incomingParamCheck(principalId, "principalId");
 992  0
         if ( LOG.isDebugEnabled() ) {
 993  0
                 LOG.debug("Evaluating isFinalApprover [docId=" + documentId + ", principalId=" + principalId + "]");
 994  
         }
 995  0
         DocumentRouteHeaderValue routeHeader = loadDocument(documentId);
 996  0
         List<ActionRequestValue> requests = KEWServiceLocator.getActionRequestService().findPendingByDoc(documentId);
 997  0
         List<RouteNode> finalApproverNodes = KEWServiceLocator.getRouteNodeService().findFinalApprovalRouteNodes(routeHeader.getDocumentType().getDocumentTypeId());
 998  0
         if (finalApproverNodes.isEmpty()) {
 999  0
                 if ( LOG.isDebugEnabled() ) {
 1000  0
                         LOG.debug("Could not locate final approval nodes for document " + documentId);
 1001  
                 }
 1002  0
             return false;
 1003  
         }
 1004  0
         Set<String> finalApproverNodeNames = new HashSet<String>();
 1005  0
         for (RouteNode node : finalApproverNodes) {
 1006  0
             finalApproverNodeNames.add(node.getRouteNodeName());
 1007  
         }
 1008  
 
 1009  0
         int approveRequest = 0;
 1010  0
         for (ActionRequestValue request : requests) {
 1011  0
             RouteNodeInstance nodeInstance = request.getNodeInstance();
 1012  0
             if (nodeInstance == null) {
 1013  0
                     if ( LOG.isDebugEnabled() ) {
 1014  0
                             LOG.debug("Found an action request on the document with a null node instance, indicating EXCEPTION routing.");
 1015  
                     }
 1016  0
                 return false;
 1017  
             }
 1018  0
             if (finalApproverNodeNames.contains(nodeInstance.getRouteNode().getRouteNodeName())) {
 1019  0
                 if (request.isApproveOrCompleteRequest()) {
 1020  0
                     approveRequest++;
 1021  0
                     if ( LOG.isDebugEnabled() ) {
 1022  0
                             LOG.debug("Found request is approver " + request.getActionRequestId());
 1023  
                     }
 1024  0
                     if (! request.isRecipientRoutedRequest(principalId)) {
 1025  0
                             if ( LOG.isDebugEnabled() ) {
 1026  0
                                     LOG.debug("Action Request not for user " + principalId);
 1027  
                             }
 1028  0
                         return false;
 1029  
                     }
 1030  
                 }
 1031  
             }
 1032  0
         }
 1033  
 
 1034  0
         if (approveRequest == 0) {
 1035  0
             return false;
 1036  
         }
 1037  0
         if ( LOG.isDebugEnabled() ) {
 1038  0
                 LOG.debug("Principal "+principalId+" is final approver for document " + documentId);
 1039  
         }
 1040  0
         return true;
 1041  
     }
 1042  
 
 1043  
     @Override
 1044  
     public boolean routeNodeHasApproverActionRequest(String documentTypeName, String docContent, String nodeName) {
 1045  0
         incomingParamCheck(documentTypeName, "documentTypeName");
 1046  0
         incomingParamCheck(docContent, "docContent");
 1047  0
         incomingParamCheck(nodeName, "nodeName");
 1048  0
         if ( LOG.isDebugEnabled() ) {
 1049  0
                 LOG.debug("Evaluating routeNodeHasApproverActionRequest [docTypeName=" + documentTypeName + ", nodeName=" + nodeName + "]");
 1050  
         }
 1051  0
         DocumentType documentType = KEWServiceLocator.getDocumentTypeService().findByName(documentTypeName);
 1052  0
         RouteNode routeNode = KEWServiceLocator.getRouteNodeService().findRouteNodeByName(documentType.getDocumentTypeId(), nodeName);
 1053  0
         return routeNodeHasApproverActionRequest(documentType, docContent, routeNode, new Integer(KewApiConstants.INVALID_ROUTE_LEVEL));
 1054  
     }
 1055  
 
 1056  
     /**
 1057  
      * Really this method needs to be implemented using the executeSimulation functionality (the SimulationEngine).
 1058  
      * This would get rid of the needs for us to call to FlexRM directly.
 1059  
      */
 1060  
     private boolean routeNodeHasApproverActionRequest(DocumentType documentType, String docContent, RouteNode node, Integer routeLevel) {
 1061  0
         incomingParamCheck(documentType, "documentType");
 1062  0
         incomingParamCheck(docContent, "docContent");
 1063  0
         incomingParamCheck(node, "node");
 1064  0
         incomingParamCheck(routeLevel, "routeLevel");
 1065  
 
 1066  
 /*        DocumentRouteHeaderValue routeHeader = new DocumentRouteHeaderValue();
 1067  
         routeHeader.setDocumentId("");
 1068  
         routeHeader.setDocumentTypeId(documentType.getDocumentTypeId());
 1069  
         routeHeader.setDocRouteLevel(routeLevel);
 1070  
         routeHeader.setDocVersion(new Integer(KewApiConstants.DocumentContentVersions.CURRENT));*/
 1071  
 
 1072  
         //TODO THIS NEEDS TESTING!!!!! IT WAS A GUESS ON HOW THIS WORKS
 1073  0
         RoutingReportCriteria.Builder builder = RoutingReportCriteria.Builder.createByDocumentTypeName(documentType.getName());
 1074  0
         builder.setTargetNodeName(node.getName());
 1075  0
         builder.setXmlContent(docContent);
 1076  0
         DocumentDetail docDetail = executeSimulation(builder.build());
 1077  0
         if (docDetail != null) {
 1078  0
             for (ActionRequest actionRequest : docDetail.getActionRequests()) {
 1079  0
                 if (actionRequest.isApprovalRequest()) {
 1080  0
                     return true;
 1081  
                 }
 1082  
             }
 1083  
         }
 1084  
         /*if (node.getRuleTemplate() != null && node.isFlexRM()) {
 1085  
             String ruleTemplateName = node.getRuleTemplate().getName();
 1086  
             builder.setXmlContent(docContent);
 1087  
             routeHeader.setDocRouteStatus(KewApiConstants.ROUTE_HEADER_INITIATED_CD);
 1088  
             FlexRM flexRM = new FlexRM();
 1089  
                     RouteContext context = RouteContext.getCurrentRouteContext();
 1090  
                     context.setDocument(routeHeader);
 1091  
                     try {
 1092  
                             List actionRequests = flexRM.getActionRequests(routeHeader, node, null, ruleTemplateName);
 1093  
                             for (Iterator iter = actionRequests.iterator(); iter.hasNext();) {
 1094  
                                     ActionRequestValue actionRequest = (ActionRequestValue) iter.next();
 1095  
                                     if (actionRequest.isApproveOrCompleteRequest()) {
 1096  
                                             return true;
 1097  
                                     }
 1098  
                             }
 1099  
                     } finally {
 1100  
                             RouteContext.clearCurrentRouteContext();
 1101  
                     }
 1102  
         }*/
 1103  0
         return false;
 1104  
     }
 1105  
 
 1106  
     @Override
 1107  
     public boolean isLastApproverAtNode(String documentId, String principalId, String nodeName)  {
 1108  0
         incomingParamCheck(documentId, "documentId");
 1109  0
         incomingParamCheck(principalId, "principalId");
 1110  0
         incomingParamCheck(nodeName, "nodeName");
 1111  0
         if ( LOG.isDebugEnabled() ) {
 1112  0
                 LOG.debug("Evaluating isLastApproverAtNode [docId=" + documentId + ", principalId=" + principalId + ", nodeName=" + nodeName + "]");
 1113  
         }
 1114  0
         loadDocument(documentId);
 1115  
         // If this app constant is set to true, then we will attempt to simulate activation of non-active requests before
 1116  
         // attempting to deactivate them, this is in order to address the force action issue reported by EPIC in issue
 1117  
         // http://fms.dfa.cornell.edu:8080/browse/KULWF-366
 1118  0
         Boolean activateFirst = CoreFrameworkServiceLocator.getParameterService().getParameterValueAsBoolean(
 1119  
                 KewApiConstants.KEW_NAMESPACE, KRADConstants.DetailTypes.FEATURE_DETAIL_TYPE, KewApiConstants.IS_LAST_APPROVER_ACTIVATE_FIRST_IND);
 1120  0
         if (activateFirst == null) {
 1121  0
             activateFirst = Boolean.FALSE;
 1122  
         }
 1123  
 
 1124  0
         List<ActionRequestValue> requests = KEWServiceLocator.getActionRequestService().findPendingByDocRequestCdNodeName(documentId, KewApiConstants.ACTION_REQUEST_APPROVE_REQ, nodeName);
 1125  0
         if (requests == null || requests.isEmpty()) {
 1126  0
             return false;
 1127  
         }
 1128  
 
 1129  
         // Deep-copy the action requests for the simulation.
 1130  0
         List<ActionRequestValue> copiedRequests = new ArrayList<ActionRequestValue>();
 1131  0
         for (ActionRequestValue request : requests) {
 1132  0
                 ActionRequestValue actionRequest = (ActionRequestValue) ObjectUtils.deepCopy(
 1133  
                     (ActionRequestValue) request);
 1134  
                 // Deep-copy the action items as well, since they are indirectly retrieved from the action request via service calls.
 1135  0
                 for (ActionItem actionItem : actionRequest.getActionItems()) {
 1136  0
                         actionRequest.getSimulatedActionItems().add((ActionItem) ObjectUtils.deepCopy(actionItem));
 1137  
                 }
 1138  0
                 copiedRequests.add(actionRequest);
 1139  0
         }
 1140  
 
 1141  0
         ActivationContext activationContext = new ActivationContext(ActivationContext.CONTEXT_IS_SIMULATION);
 1142  0
         for (ActionRequestValue request : copiedRequests) {
 1143  0
             if (activateFirst.booleanValue() && !request.isActive()) {
 1144  0
                 KEWServiceLocator.getActionRequestService().activateRequest(request, activationContext);
 1145  
             }
 1146  0
             if (request.isUserRequest() && request.getPrincipalId().equals(principalId)) {
 1147  0
                 KEWServiceLocator.getActionRequestService().deactivateRequest(null, request, activationContext);
 1148  0
             } else if (request.isGroupRequest() && KimApiServiceLocator.getGroupService().isMemberOfGroup(principalId, request.getGroup().getId())) {
 1149  0
                 KEWServiceLocator.getActionRequestService().deactivateRequest(null, request, activationContext);
 1150  
             }
 1151  
         }
 1152  0
         boolean allDeactivated = true;
 1153  0
         for (ActionRequestValue actionRequest: copiedRequests) {
 1154  0
             allDeactivated = allDeactivated && actionRequest.isDeactivated();
 1155  
         }
 1156  0
         return allDeactivated;
 1157  
     }
 1158  
 
 1159  
     @Override
 1160  
     public boolean isUserInRouteLog(String documentId, String principalId, boolean lookFuture) {
 1161  0
             incomingParamCheck(documentId, "documentId");
 1162  0
         incomingParamCheck(principalId, "principalId");
 1163  0
         return isUserInRouteLogWithOptionalFlattening(documentId, principalId, lookFuture, false);
 1164  
     }
 1165  
 
 1166  
     @Override
 1167  
     public boolean isUserInRouteLogWithOptionalFlattening(String documentId, String principalId, boolean lookFuture, boolean flattenNodes) {
 1168  0
         incomingParamCheck(documentId, "documentId");
 1169  0
         incomingParamCheck(principalId, "principalId");
 1170  0
         boolean authorized = false;
 1171  0
         if ( LOG.isDebugEnabled() ) {
 1172  0
                 LOG.debug("Evaluating isUserInRouteLog [docId=" + documentId + ", principalId=" + principalId + ", lookFuture=" + lookFuture + "]");
 1173  
         }
 1174  0
         DocumentRouteHeaderValue routeHeader = loadDocument(documentId);
 1175  0
         if (routeHeader == null) {
 1176  0
             throw new IllegalArgumentException("Document for documentId: " + documentId + " does not exist");
 1177  
         }
 1178  0
         Principal principal = KEWServiceLocator.getIdentityHelperService().getPrincipal(principalId);
 1179  0
         if (principal == null) {
 1180  0
             throw new IllegalArgumentException("Principal for principalId: " + principalId + " does not exist");
 1181  
         }
 1182  0
         List<ActionTakenValue> actionsTaken = KEWServiceLocator.getActionTakenService().findByDocumentIdWorkflowId(documentId, principal.getPrincipalId());
 1183  
 
 1184  0
         if(routeHeader.getInitiatorWorkflowId().equals(principal.getPrincipalId())){
 1185  0
                 return true;
 1186  
         }
 1187  
 
 1188  0
         if (!actionsTaken.isEmpty()) {
 1189  0
                 LOG.debug("found action taken by user");
 1190  0
                 authorized = true;
 1191  
         }
 1192  
 
 1193  0
         List<ActionRequestValue> actionRequests = KEWServiceLocator.getActionRequestService().findAllActionRequestsByDocumentId(documentId);
 1194  0
         if (actionRequestListHasPrincipal(principal, actionRequests)) {
 1195  0
                 authorized = true;
 1196  
         }
 1197  
 
 1198  0
         if (!lookFuture || authorized) {
 1199  0
                 return authorized;
 1200  
         }
 1201  
 
 1202  
 
 1203  0
         SimulationWorkflowEngine simulationEngine = KEWServiceLocator.getSimulationEngine();
 1204  0
         SimulationCriteria criteria = SimulationCriteria.createSimulationCritUsingDocumentId(documentId);
 1205  0
         criteria.setDestinationNodeName(null); // process entire document to conclusion
 1206  0
         criteria.getDestinationRecipients().add(new KimPrincipalRecipient(principal));
 1207  0
         criteria.setFlattenNodes(flattenNodes);
 1208  
 
 1209  
         try {
 1210  0
                 SimulationResults results = simulationEngine.runSimulation(criteria);
 1211  0
                 if (actionRequestListHasPrincipal(principal, results.getSimulatedActionRequests())) {
 1212  0
                         authorized = true;
 1213  
                 }
 1214  0
         } catch (Exception e) {
 1215  0
                 throw new RiceRuntimeException(e);
 1216  0
         }
 1217  
 
 1218  0
         return authorized;
 1219  
     }
 1220  
 
 1221  
     private boolean actionRequestListHasPrincipal(Principal principal, List<ActionRequestValue> actionRequests) {
 1222  0
         for (ActionRequestValue actionRequest : actionRequests) {
 1223  0
             if (actionRequest.isRecipientRoutedRequest(new KimPrincipalRecipient(principal))) {
 1224  0
                 return true;
 1225  
             }
 1226  
         }
 1227  0
         return false;
 1228  
     }
 1229  
 
 1230  
     public List<String> getPrincipalIdsInRouteLog(String documentId, boolean lookFuture) {
 1231  0
         if (StringUtils.isEmpty(documentId)) {
 1232  0
             throw new IllegalArgumentException("documentId passed in is null or blank");
 1233  
         }
 1234  0
             Set<String> principalIds = new HashSet<String>();
 1235  
         try {
 1236  0
                 if ( LOG.isDebugEnabled() ) {
 1237  0
                         LOG.debug("Evaluating isUserInRouteLog [docId=" + documentId + ", lookFuture=" + lookFuture + "]");
 1238  
                 }
 1239  0
             DocumentRouteHeaderValue routeHeader = loadDocument(documentId);
 1240  0
             List<ActionTakenValue> actionsTakens =
 1241  
                     (List<ActionTakenValue>)KEWServiceLocator.getActionTakenService().findByDocumentId(documentId);
 1242  
             //TODO: confirm that the initiator is not already there in the actionstaken
 1243  0
             principalIds.add(routeHeader.getInitiatorWorkflowId());
 1244  0
             for(ActionTakenValue actionTaken: actionsTakens){
 1245  0
                     principalIds.add(actionTaken.getPrincipalId());
 1246  
             }
 1247  0
             List<ActionRequestValue> actionRequests =
 1248  
                     KEWServiceLocator.getActionRequestService().findAllActionRequestsByDocumentId(documentId);
 1249  0
             for(ActionRequestValue actionRequest: actionRequests){
 1250  0
                     principalIds.addAll(getPrincipalIdsForActionRequest(actionRequest));
 1251  
             }
 1252  0
             if (!lookFuture) {
 1253  0
                     return new ArrayList<String>(principalIds);
 1254  
             }
 1255  0
             SimulationWorkflowEngine simulationEngine = KEWServiceLocator.getSimulationEngine();
 1256  0
             SimulationCriteria criteria = SimulationCriteria.createSimulationCritUsingDocumentId(documentId);
 1257  0
             criteria.setDestinationNodeName(null); // process entire document to conclusion
 1258  0
             SimulationResults results = simulationEngine.runSimulation(criteria);
 1259  0
             actionRequests = (List<ActionRequestValue>)results.getSimulatedActionRequests();
 1260  0
             for(ActionRequestValue actionRequest: actionRequests){
 1261  0
                     principalIds.addAll(getPrincipalIdsForActionRequest(actionRequest));
 1262  
             }
 1263  0
         } catch (Exception ex) {
 1264  0
             LOG.warn("Problems getting principalIds in Route Log for documentId: "+documentId+". Exception:"+ex.getMessage(),ex);
 1265  0
         }
 1266  0
             return new ArrayList<String>(principalIds);
 1267  
     }
 1268  
 
 1269  
     private DocumentRouteHeaderValue loadDocument(String documentId) {
 1270  0
         return KEWServiceLocator.getRouteHeaderService().getRouteHeader(documentId);
 1271  
     }
 1272  
 
 1273  
     /**
 1274  
          * This method gets all of the principalIds for the given ActionRequestValue.  It drills down into
 1275  
          * groups if need be.
 1276  
          *
 1277  
          * @param actionRequest
 1278  
          */
 1279  
         private List<String> getPrincipalIdsForActionRequest(ActionRequestValue actionRequest) {
 1280  0
                 List<String> results = Collections.emptyList();
 1281  0
                 if (actionRequest.getPrincipalId() != null) {
 1282  0
                         results = Collections.singletonList(actionRequest.getPrincipalId());
 1283  0
                 } else if (actionRequest.getGroupId() != null) {
 1284  0
                         List<String> principalIdsForGroup =
 1285  
                                 KimApiServiceLocator.getGroupService().getMemberPrincipalIds(actionRequest.getGroupId());
 1286  0
                         if (principalIdsForGroup != null) {
 1287  0
                                 results = principalIdsForGroup;
 1288  
                         }
 1289  
                 }
 1290  0
                 return results;
 1291  
         }
 1292  
 
 1293  
     private void incomingParamCheck(Object object, String name) {
 1294  0
         if (object == null) {
 1295  0
             throw new RiceIllegalArgumentException(name + " was null");
 1296  0
         } else if (object instanceof String
 1297  
                 && StringUtils.isBlank((String) object)) {
 1298  0
             throw new RiceIllegalArgumentException(name + " was blank");
 1299  
         }
 1300  0
     }
 1301  
 
 1302  
     public void setDocumentTypeService(DocumentTypeService documentTypeService) {
 1303  0
         this.documentTypeService = documentTypeService;
 1304  0
     }
 1305  
 
 1306  
     /**
 1307  
      * TODO - this code is temporary until we get rid of all the crazy throwing of
 1308  
      * "WorkflowException"
 1309  
      */
 1310  
     private void translateException(WorkflowException e) {
 1311  0
         if (e instanceof org.kuali.rice.kew.api.exception.InvalidActionTakenException) {
 1312  0
             throw new InvalidActionTakenException(e.getMessage(), e);
 1313  
         }
 1314  0
         throw new WorkflowRuntimeException(e.getMessage(), e);
 1315  
     }
 1316  
 
 1317  
     protected DocumentActionResult executeActionInternal(DocumentActionParameters parameters,
 1318  
             DocumentActionCallback callback) {
 1319  0
         if (parameters == null) {
 1320  0
             throw new RiceIllegalArgumentException("Document action parameters was null.");
 1321  
         }
 1322  0
         if (LOG.isDebugEnabled()) {
 1323  0
             LOG.debug(callback.getLogMessage(parameters.getDocumentId(), parameters.getPrincipalId(),
 1324  
                     parameters.getAnnotation()));
 1325  
         }
 1326  0
         DocumentRouteHeaderValue documentBo = init(parameters);
 1327  
         try {
 1328  0
             documentBo = callback.doInDocumentBo(documentBo, parameters.getPrincipalId(), parameters.getAnnotation());
 1329  0
         } catch (WorkflowException e) {
 1330  
             // TODO fix this up once the checked exception goes away
 1331  0
             translateException(e);
 1332  0
         }
 1333  0
         return constructDocumentActionResult(documentBo, parameters.getPrincipalId());
 1334  
     }
 1335  
 
 1336  
     protected static interface DocumentActionCallback {
 1337  
 
 1338  
         DocumentRouteHeaderValue doInDocumentBo(DocumentRouteHeaderValue documentBo, String principalId,
 1339  
                 String annotation) throws WorkflowException;
 1340  
 
 1341  
         String getLogMessage(String documentId, String principalId, String annotation);
 1342  
 
 1343  
     }
 1344  
 
 1345  0
     protected static abstract class StandardDocumentActionCallback implements DocumentActionCallback {
 1346  
 
 1347  
         public final String getLogMessage(String documentId, String principalId, String annotation) {
 1348  0
             return getActionName() + " [principalId=" + principalId + ", documentId=" + documentId + ", annotation="
 1349  
                     + annotation + "]";
 1350  
         }
 1351  
 
 1352  
         protected abstract String getActionName();
 1353  
 
 1354  
     }
 1355  
 
 1356  
 }