Coverage Report - org.kuali.rice.kew.service.impl.WorkflowUtilityWebServiceImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
WorkflowUtilityWebServiceImpl
0%
0/643
0%
0/378
4.739
 
 1  
 /*
 2  
  * Copyright 2006-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  
 
 17  
 package org.kuali.rice.kew.service.impl;
 18  
 
 19  
 import org.apache.commons.lang.StringUtils;
 20  
 import org.apache.log4j.Logger;
 21  
 import org.kuali.rice.core.api.exception.RiceRuntimeException;
 22  
 import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
 23  
 import org.kuali.rice.core.framework.services.CoreFrameworkServiceLocator;
 24  
 import org.kuali.rice.core.util.AttributeSet;
 25  
 import org.kuali.rice.core.util.KeyValue;
 26  
 import org.kuali.rice.kew.actionitem.ActionItem;
 27  
 import org.kuali.rice.kew.actionrequest.ActionRequestValue;
 28  
 import org.kuali.rice.kew.actionrequest.KimPrincipalRecipient;
 29  
 import org.kuali.rice.kew.actionrequest.Recipient;
 30  
 import org.kuali.rice.kew.actiontaken.ActionTakenValue;
 31  
 import org.kuali.rice.kew.definition.AttributeDefinition;
 32  
 import org.kuali.rice.kew.docsearch.DocSearchCriteriaDTO;
 33  
 import org.kuali.rice.kew.docsearch.DocumentSearchResultComponents;
 34  
 import org.kuali.rice.kew.doctype.bo.DocumentType;
 35  
 import org.kuali.rice.kew.documentlink.DocumentLink;
 36  
 import org.kuali.rice.kew.dto.ActionItemDTO;
 37  
 import org.kuali.rice.kew.dto.ActionRequestDTO;
 38  
 import org.kuali.rice.kew.dto.ActionTakenDTO;
 39  
 import org.kuali.rice.kew.dto.DTOConverter;
 40  
 import org.kuali.rice.kew.dto.DocumentContentDTO;
 41  
 import org.kuali.rice.kew.dto.DocumentDetailDTO;
 42  
 import org.kuali.rice.kew.dto.DocumentLinkDTO;
 43  
 import org.kuali.rice.kew.dto.DocumentSearchCriteriaDTO;
 44  
 import org.kuali.rice.kew.dto.DocumentSearchResultDTO;
 45  
 import org.kuali.rice.kew.dto.DocumentStatusTransitionDTO;
 46  
 import org.kuali.rice.kew.dto.DocumentTypeDTO;
 47  
 import org.kuali.rice.kew.dto.PropertyDefinitionDTO;
 48  
 import org.kuali.rice.kew.dto.ReportCriteriaDTO;
 49  
 import org.kuali.rice.kew.dto.RouteHeaderDTO;
 50  
 import org.kuali.rice.kew.dto.RouteNodeInstanceDTO;
 51  
 import org.kuali.rice.kew.dto.RuleDTO;
 52  
 import org.kuali.rice.kew.dto.RuleExtensionDTO;
 53  
 import org.kuali.rice.kew.dto.RuleReportCriteriaDTO;
 54  
 import org.kuali.rice.kew.dto.WorkflowAttributeDefinitionDTO;
 55  
 import org.kuali.rice.kew.dto.WorkflowAttributeValidationErrorDTO;
 56  
 import org.kuali.rice.kew.engine.ActivationContext;
 57  
 import org.kuali.rice.kew.engine.CompatUtils;
 58  
 import org.kuali.rice.kew.engine.RouteContext;
 59  
 import org.kuali.rice.kew.engine.node.RouteNode;
 60  
 import org.kuali.rice.kew.engine.node.RouteNodeInstance;
 61  
 import org.kuali.rice.kew.engine.simulation.SimulationCriteria;
 62  
 import org.kuali.rice.kew.engine.simulation.SimulationResults;
 63  
 import org.kuali.rice.kew.engine.simulation.SimulationWorkflowEngine;
 64  
 import org.kuali.rice.kew.exception.WorkflowException;
 65  
 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
 66  
 import org.kuali.rice.kew.routeheader.DocumentStatusTransition;
 67  
 import org.kuali.rice.kew.rule.FlexRM;
 68  
 import org.kuali.rice.kew.rule.RuleBaseValues;
 69  
 import org.kuali.rice.kew.rule.WorkflowAttribute;
 70  
 import org.kuali.rice.kew.rule.WorkflowAttributeValidationError;
 71  
 import org.kuali.rice.kew.rule.WorkflowAttributeXmlValidator;
 72  
 import org.kuali.rice.kew.rule.xmlrouting.GenericXMLRuleAttribute;
 73  
 import org.kuali.rice.kew.service.KEWServiceLocator;
 74  
 import org.kuali.rice.kew.service.WorkflowUtility;
 75  
 import org.kuali.rice.kew.util.KEWConstants;
 76  
 import org.kuali.rice.kew.util.KEWWebServiceConstants;
 77  
 import org.kuali.rice.kim.api.entity.principal.Principal;
 78  
 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
 79  
 
 80  
 import org.kuali.rice.kns.UserSession;
 81  
 import org.kuali.rice.kns.util.GlobalVariables;
 82  
 import org.kuali.rice.kns.util.KNSConstants;
 83  
 import org.kuali.rice.kns.util.ObjectUtils;
 84  
 
 85  
 import javax.jws.WebService;
 86  
 import java.math.BigDecimal;
 87  
 import java.sql.Timestamp;
 88  
 import java.util.ArrayList;
 89  
 import java.util.Arrays;
 90  
 import java.util.Collection;
 91  
 import java.util.Collections;
 92  
 import java.util.Date;
 93  
 import java.util.HashMap;
 94  
 import java.util.HashSet;
 95  
 import java.util.Iterator;
 96  
 import java.util.List;
 97  
 import java.util.Map;
 98  
 import java.util.Set;
 99  
 
 100  
 @SuppressWarnings({"unchecked"})
 101  
 @WebService(endpointInterface = KEWWebServiceConstants.WorkflowUtility.INTERFACE_CLASS,
 102  
         serviceName = KEWWebServiceConstants.WorkflowUtility.WEB_SERVICE_NAME,
 103  
         portName = KEWWebServiceConstants.WorkflowUtility.WEB_SERVICE_PORT,
 104  
         targetNamespace = KEWWebServiceConstants.MODULE_TARGET_NAMESPACE)
 105  0
 public class WorkflowUtilityWebServiceImpl implements WorkflowUtility {
 106  
 
 107  0
     private static final Logger LOG = Logger.getLogger(WorkflowUtilityWebServiceImpl.class);
 108  
 
 109  
     public RouteHeaderDTO getRouteHeaderWithPrincipal(String principalId, String documentId) throws WorkflowException {
 110  0
         if (documentId == null) {
 111  0
             LOG.error("null documentId passed in.  Throwing RuntimeExcpetion");
 112  0
             throw new RuntimeException("Null documentId passed in.");
 113  
         }
 114  0
         if (principalId == null) {
 115  0
             LOG.error("null principalId passed in.");
 116  0
             throw new RuntimeException("null principalId passed in");
 117  
         }
 118  0
         if ( LOG.isDebugEnabled() ) {
 119  0
             LOG.debug("Fetching RouteHeaderVO [id="+documentId+", user="+principalId+"]");
 120  
         }
 121  0
         DocumentRouteHeaderValue document = loadDocument(documentId);
 122  0
         RouteHeaderDTO routeHeaderVO = DTOConverter.convertRouteHeader(document, principalId);
 123  0
         if (routeHeaderVO == null) {
 124  0
                 LOG.error("Returning null RouteHeaderVO [id=" + documentId + ", user=" + principalId + "]");
 125  
         }
 126  0
         if ( LOG.isDebugEnabled() ) {
 127  0
             LOG.debug("Returning RouteHeaderVO [id=" + documentId + ", user=" + principalId + "]");
 128  
         }
 129  0
         return routeHeaderVO;
 130  
     }
 131  
 
 132  
     public AttributeSet getActionsRequested(String principalId, String documentId) {
 133  0
         if (documentId == null) {
 134  0
             LOG.error("null documentId passed in.  Throwing RuntimeExcpetion");
 135  0
             throw new RuntimeException("Null documentId passed in.");
 136  
         }
 137  0
         if (principalId == null) {
 138  0
             LOG.error("null principalId passed in.");
 139  0
             throw new RuntimeException("null principalId passed in");
 140  
         }
 141  0
         if ( LOG.isDebugEnabled() ) {
 142  0
             LOG.debug("Fetching DocumentRouteHeaderValue [id="+documentId+", user="+principalId+"]");
 143  
         }
 144  0
         DocumentRouteHeaderValue document = loadDocument(documentId);
 145  0
         return KEWServiceLocator.getActionRequestService().getActionsRequested(document, principalId, true);
 146  
     }
 147  
 
 148  
     public RouteHeaderDTO getRouteHeader(String documentId) throws WorkflowException {
 149  0
         if (documentId == null) {
 150  0
             LOG.error("null documentId passed in.");
 151  0
             throw new RuntimeException("null documentId passed in");
 152  
         }
 153  0
         if ( LOG.isDebugEnabled() ) {
 154  0
             LOG.debug("Fetching RouteHeaderVO [id="+documentId+"]");
 155  
         }
 156  0
         DocumentRouteHeaderValue document = loadDocument(documentId);
 157  
         
 158  0
         UserSession userSession = GlobalVariables.getUserSession();
 159  0
         String principalId = null;
 160  0
         if (userSession != null) { // get the principalId if we can
 161  0
                 principalId = userSession.getPrincipalId();
 162  
         }
 163  
         
 164  0
         RouteHeaderDTO routeHeaderVO = DTOConverter.convertRouteHeader(document, principalId);
 165  0
         if (routeHeaderVO == null) {
 166  0
                 LOG.error("Returning null RouteHeaderVO [id=" + documentId + "]");
 167  
         }
 168  0
         if ( LOG.isDebugEnabled() ) {
 169  0
             LOG.debug("Returning RouteHeaderVO [id=" + documentId + "]");
 170  
         }
 171  0
         return routeHeaderVO;
 172  
     }
 173  
 
 174  
     public String getDocumentStatus(String documentId) throws WorkflowException {
 175  0
         if (documentId == null) {
 176  0
             LOG.error("null documentId passed in.");
 177  0
             throw new IllegalArgumentException("null documentId passed in");
 178  
         }
 179  0
         String documentStatus = KEWServiceLocator.getRouteHeaderService().getDocumentStatus(documentId);
 180  0
         if (StringUtils.isEmpty(documentStatus)) {
 181  0
             throw new WorkflowException("Could not locate a document with the ID " + documentId);
 182  
         }
 183  0
         return documentStatus;
 184  
     }
 185  
 
 186  
     public DocumentDetailDTO getDocumentDetail(String documentId) throws WorkflowException {
 187  0
         if (documentId == null) {
 188  0
             LOG.error("null documentId passed in.");
 189  0
             throw new RuntimeException("null documentId passed in");
 190  
         }
 191  0
         if ( LOG.isDebugEnabled() ) {
 192  0
                 LOG.debug("Fetching DocumentDetailVO [id="+documentId+"]");
 193  
         }
 194  0
         DocumentRouteHeaderValue document = loadDocument(documentId);
 195  0
         DocumentDetailDTO documentDetailVO = DTOConverter.convertDocumentDetail(document);
 196  0
         if (documentDetailVO == null) {
 197  0
                 LOG.error("Returning null DocumentDetailVO [id=" + documentId + "]");
 198  
         }
 199  0
         if ( LOG.isDebugEnabled() ) {
 200  0
                 LOG.debug("Returning DocumentDetailVO [id=" + documentId + "]");
 201  
         }
 202  0
         return documentDetailVO;
 203  
     }
 204  
 
 205  
     public RouteNodeInstanceDTO getNodeInstance(Long nodeInstanceId) throws WorkflowException {
 206  0
         if (nodeInstanceId == null) {
 207  0
             LOG.error("null nodeInstanceId passed in.");
 208  0
             throw new RuntimeException("null nodeInstanceId passed in");
 209  
         }
 210  0
         if ( LOG.isDebugEnabled() ) {
 211  0
                 LOG.debug("Fetching RouteNodeInstanceVO [id="+nodeInstanceId+"]");
 212  
         }
 213  0
         RouteNodeInstance nodeInstance = KEWServiceLocator.getRouteNodeService().findRouteNodeInstanceById(nodeInstanceId);
 214  0
         return DTOConverter.convertRouteNodeInstance(nodeInstance);
 215  
     }
 216  
 
 217  
     public DocumentTypeDTO getDocumentType(Long documentTypeId) throws WorkflowException {
 218  0
         if (documentTypeId == null) {
 219  0
             LOG.error("null documentTypeId passed in.");
 220  0
             throw new RuntimeException("null documentTypeId passed in.");
 221  
         }
 222  0
         if ( LOG.isDebugEnabled() ) {
 223  0
                 LOG.debug("Fetching DocumentTypeVO [documentTypeId="+documentTypeId+"]");
 224  
         }
 225  0
         return KEWServiceLocator.getDocumentTypeService().getDocumentTypeVO(documentTypeId);
 226  
     }
 227  
 
 228  
     public DocumentTypeDTO getDocumentTypeByName(String documentTypeName) throws WorkflowException {
 229  0
         if (documentTypeName == null) {
 230  0
             LOG.error("null documentTypeName passed in.");
 231  0
             throw new RuntimeException("null documentTypeName passed in");
 232  
         }
 233  0
         if ( LOG.isDebugEnabled() ) {
 234  0
                 LOG.debug("Fetching DocumentTypeVO [documentTypeName="+documentTypeName+"]");
 235  
         }
 236  0
         DocumentTypeDTO documentType = KEWServiceLocator.getDocumentTypeService().getDocumentTypeVO(documentTypeName);
 237  0
         return documentType;
 238  
     }
 239  
 
 240  
     public Long getNewResponsibilityId() {
 241  0
             LOG.debug("Getting new responsibility id.");
 242  0
         Long rid = KEWServiceLocator.getResponsibilityIdService().getNewResponsibilityId();
 243  0
         if ( LOG.isDebugEnabled() ) {
 244  0
                 LOG.debug("returning responsibility Id " + rid);
 245  
         }
 246  0
         return rid;
 247  
     }
 248  
 
 249  
     public Integer getUserActionItemCount(String principalId) throws WorkflowException {
 250  0
         return Integer.valueOf(KEWServiceLocator.getActionListService().getCount(principalId));
 251  
     }
 252  
 
 253  
         public ActionItemDTO[] getActionItemsForPrincipal(String principalId) throws WorkflowException {
 254  
         //added by Derek
 255  0
         Collection actionItems = KEWServiceLocator.getActionListService().getActionList(principalId, null);
 256  0
         ActionItemDTO[] actionItemVOs = new ActionItemDTO[actionItems.size()];
 257  0
         int i = 0;
 258  0
         for (Iterator iterator = actionItems.iterator(); iterator.hasNext(); i++) {
 259  0
             ActionItem actionItem = (ActionItem) iterator.next();
 260  0
             actionItemVOs[i] = DTOConverter.convertActionItem(actionItem);
 261  
         }
 262  0
         return actionItemVOs;
 263  
     }
 264  
 
 265  
     public ActionItemDTO[] getAllActionItems(String documentId) throws WorkflowException {
 266  0
         Collection actionItems = KEWServiceLocator.getActionListService().getActionListForSingleDocument(documentId);
 267  0
         ActionItemDTO[] actionItemVOs = new ActionItemDTO[actionItems.size()];
 268  0
         int i = 0;
 269  0
         for (Iterator iterator = actionItems.iterator(); iterator.hasNext(); i++) {
 270  0
             ActionItem actionItem = (ActionItem) iterator.next();
 271  0
             actionItemVOs[i] = DTOConverter.convertActionItem(actionItem);
 272  
         }
 273  0
         return actionItemVOs;
 274  
     }
 275  
 
 276  
     public ActionItemDTO[] getActionItems(String documentId, String[] actionRequestedCodes) throws WorkflowException {
 277  0
         List<String> actionRequestedCds = Arrays.asList(actionRequestedCodes);
 278  0
         ActionItemDTO[] actionItems = getAllActionItems(documentId);
 279  0
         List<ActionItemDTO> matchingActionitems = new ArrayList<ActionItemDTO>();
 280  0
         for (ActionItemDTO actionItemVO : actionItems) {
 281  0
             if (actionRequestedCds.contains(actionItemVO.getActionRequestCd())) {
 282  0
                 matchingActionitems.add(actionItemVO);
 283  
             }
 284  
         }
 285  0
         ActionItemDTO[] returnActionItems = new ActionItemDTO[matchingActionitems.size()];
 286  0
         int j = 0;
 287  0
         for (ActionItemDTO actionItemVO : matchingActionitems) {
 288  0
             returnActionItems[j] = actionItemVO;
 289  0
             j++;
 290  
         }
 291  0
         return returnActionItems;
 292  
     }
 293  
 
 294  
     public ActionRequestDTO[] getAllActionRequests(String documentId) throws WorkflowException {
 295  0
         return getActionRequests(documentId, null, null);
 296  
     }
 297  
 
 298  
     /**
 299  
      * Returns a flattened list of ActionRequests which match the given criteria.
 300  
      * Because the list is flattened, that means that all children requests from
 301  
      * all graphs are returned in the top-level list.
 302  
      */
 303  
     public ActionRequestDTO[] getActionRequests(String documentId, String nodeName, String principalId) throws WorkflowException {
 304  0
         if (documentId == null) {
 305  0
             LOG.error("null documentId passed in.");
 306  0
             throw new RuntimeException("null documentId passed in.");
 307  
         }
 308  0
         if ( LOG.isDebugEnabled() ) {
 309  0
                 LOG.debug("Fetching ActionRequestVOs [docId="+documentId+"]");
 310  
         }
 311  0
         List actionRequests = KEWServiceLocator.getActionRequestService().findAllActionRequestsByDocumentId(documentId);
 312  0
         List matchingActionRequests = new ArrayList();
 313  0
         for (Iterator iterator = actionRequests.iterator(); iterator.hasNext();) {
 314  0
             ActionRequestValue actionRequestValue = (ActionRequestValue) iterator.next();
 315  0
             if (actionRequestMatches(actionRequestValue, nodeName, principalId)) {
 316  0
                 matchingActionRequests.add(actionRequestValue);
 317  
             }
 318  0
         }
 319  0
         ActionRequestDTO[] actionRequestVOs = new ActionRequestDTO[matchingActionRequests.size()];
 320  0
         int i = 0;
 321  0
         for (Iterator iter = matchingActionRequests.iterator(); iter.hasNext(); i++) {
 322  0
             ActionRequestValue actionRequest = (ActionRequestValue) iter.next();
 323  0
             actionRequestVOs[i] = DTOConverter.convertActionRequest(actionRequest);
 324  
         }
 325  0
         return actionRequestVOs;
 326  
     }
 327  
 
 328  
     private boolean actionRequestMatches(ActionRequestValue actionRequest, String nodeName, String principalId) throws WorkflowException {
 329  0
         boolean matchesUserId = true;  // assume a match in case user is empty
 330  0
         boolean matchesNodeName = true;  // assume a match in case node name is empty
 331  0
         if (StringUtils.isNotBlank(nodeName)) {
 332  0
             matchesNodeName = nodeName.equals(actionRequest.getPotentialNodeName());
 333  
         }
 334  0
         if (principalId != null) {
 335  0
             matchesUserId = actionRequest.isRecipientRoutedRequest(principalId);
 336  
         }
 337  0
         return matchesNodeName && matchesUserId;
 338  
     }
 339  
 
 340  
     public ActionTakenDTO[] getActionsTaken(String documentId) throws WorkflowException {
 341  0
         if (documentId == null) {
 342  0
             LOG.error("null documentId passed in.");
 343  0
             throw new RuntimeException("null documentId passed in.");
 344  
         }
 345  0
         if ( LOG.isDebugEnabled() ) {
 346  0
                 LOG.debug("Fetching ActionTakenVOs [docId="+documentId+"]");
 347  
         }
 348  0
         Collection actionsTaken = KEWServiceLocator.getActionTakenService().findByDocumentId(documentId);
 349  0
         ActionTakenDTO[] actionTakenVOs = new ActionTakenDTO[actionsTaken.size()];
 350  0
         int i = 0;
 351  0
         for (Iterator iter = actionsTaken.iterator(); iter.hasNext(); i++) {
 352  0
             ActionTakenValue actionTaken = (ActionTakenValue) iter.next();
 353  0
             actionTakenVOs[i] = DTOConverter.convertActionTakenWithActionRequests(actionTaken);
 354  
         }
 355  0
         return actionTakenVOs;
 356  
     }
 357  
 
 358  
     /**
 359  
      * This work is also being done in the bowels of convertDocumentContentVO in DTOConverter so some code
 360  
      * could be reduced.
 361  
      *
 362  
      * @param definition
 363  
      * @return WorkflowAttributeValidationErrorVO[] errors from client input into attribute
 364  
      */
 365  
     public WorkflowAttributeValidationErrorDTO[] validateWorkflowAttributeDefinitionVO(WorkflowAttributeDefinitionDTO definition) throws WorkflowException {
 366  0
         if (definition == null) {
 367  0
             LOG.error("null definition passed in.");
 368  0
             throw new RuntimeException("null definition passed in.");
 369  
         }
 370  0
         if ( LOG.isDebugEnabled() ) {
 371  0
                 LOG.debug("Validating WorkflowAttributeDefinitionVO [attributeName="+definition.getAttributeName()+"]");
 372  
         }
 373  0
         AttributeDefinition attributeDefinition = DTOConverter.convertWorkflowAttributeDefinitionVO(definition, null);
 374  0
         WorkflowAttribute attribute = null;
 375  0
         if (attributeDefinition != null) {
 376  0
                 attribute = (WorkflowAttribute) GlobalResourceLoader.getObject(attributeDefinition.getObjectDefinition());
 377  
         }
 378  0
         if (attribute instanceof GenericXMLRuleAttribute) {
 379  0
             Map<String, String> attributePropMap = new HashMap<String, String>();
 380  0
             GenericXMLRuleAttribute xmlAttribute = (GenericXMLRuleAttribute)attribute;
 381  0
             xmlAttribute.setRuleAttribute(attributeDefinition.getRuleAttribute());
 382  0
             for (int i = 0; i < definition.getProperties().length; i++) {
 383  0
                 PropertyDefinitionDTO property = definition.getProperties()[i];
 384  0
                 attributePropMap.put(property.getName(), property.getValue());
 385  
             }
 386  0
             xmlAttribute.setParamMap(attributePropMap);
 387  
         }
 388  
         //validate inputs from client application if the attribute is capable
 389  0
         if (attribute instanceof WorkflowAttributeXmlValidator) {
 390  0
             List errors = ((WorkflowAttributeXmlValidator)attribute).validateClientRoutingData();
 391  0
             WorkflowAttributeValidationErrorDTO[] errorVOs = new WorkflowAttributeValidationErrorDTO[errors.size()];
 392  0
             for (int i = 0; i < errorVOs.length; i++) {
 393  0
                 errorVOs[i] = DTOConverter.convertWorkflowAttributeValidationError((WorkflowAttributeValidationError)errors.get(i));
 394  
             }
 395  0
             return errorVOs;
 396  
         } else {
 397  
             // WORKAROUND: if it is not validatable, then just quietly succeed
 398  0
             return new WorkflowAttributeValidationErrorDTO[0];
 399  
         }
 400  
     }
 401  
 
 402  
     public RouteNodeInstanceDTO[] getDocumentRouteNodeInstances(String documentId) throws WorkflowException {
 403  0
             if ( LOG.isDebugEnabled() ) {
 404  0
                     LOG.debug("Fetching RouteNodeInstanceVOs [docId=" + documentId + "]");
 405  
             }
 406  0
             return convertRouteNodeInstances(KEWServiceLocator.getRouteNodeService().getFlattenedNodeInstances(loadDocument(documentId), true));
 407  
     }
 408  
 
 409  
     public RouteNodeInstanceDTO[] getActiveNodeInstances(String documentId) throws WorkflowException {
 410  0
             if ( LOG.isDebugEnabled() ) {
 411  0
                     LOG.debug("Fetching active RouteNodeInstanceVOs [docId=" + documentId + "]");
 412  
             }
 413  0
         loadDocument(documentId);
 414  0
         return convertRouteNodeInstances(KEWServiceLocator.getRouteNodeService().getActiveNodeInstances(documentId));
 415  
     }
 416  
 
 417  
     public RouteNodeInstanceDTO[] getTerminalNodeInstances(String documentId) throws WorkflowException {
 418  0
             if ( LOG.isDebugEnabled() ) {
 419  0
                     LOG.debug("Fetching terminal RouteNodeInstanceVOs [docId=" + documentId + "]");
 420  
             }
 421  0
             loadDocument(documentId);
 422  0
         return convertRouteNodeInstances(KEWServiceLocator.getRouteNodeService().getTerminalNodeInstances(documentId));
 423  
     }
 424  
 
 425  
     public RouteNodeInstanceDTO[] getCurrentNodeInstances(String documentId) throws WorkflowException {
 426  0
             if ( LOG.isDebugEnabled() ) {
 427  0
                     LOG.debug("Fetching current RouteNodeInstanceVOs [docId=" + documentId + "]");
 428  
             }
 429  0
             loadDocument(documentId);
 430  0
             return convertRouteNodeInstances(KEWServiceLocator.getRouteNodeService().getCurrentNodeInstances(documentId));
 431  
     }
 432  
 
 433  
     private RouteNodeInstanceDTO[] convertRouteNodeInstances(List nodeInstances) throws WorkflowException {
 434  0
         RouteNodeInstanceDTO[] nodeInstanceVOs = new RouteNodeInstanceDTO[nodeInstances.size()];
 435  0
         int i = 0;
 436  0
         for (Iterator iter = nodeInstances.iterator(); iter.hasNext(); ) {
 437  0
             nodeInstanceVOs[i++] = DTOConverter.convertRouteNodeInstance((RouteNodeInstance) iter.next());
 438  
         }
 439  0
         return nodeInstanceVOs;
 440  
     }
 441  
 
 442  
     public boolean isUserInRouteLog(String documentId, String principalId, boolean lookFuture) throws WorkflowException {
 443  0
             return isUserInRouteLogWithOptionalFlattening(documentId, principalId, lookFuture, false);
 444  
     }
 445  
     
 446  
     public boolean isUserInRouteLogWithOptionalFlattening(String documentId, String principalId, boolean lookFuture, boolean flattenNodes) throws WorkflowException {
 447  0
         if (documentId == null) {
 448  0
             LOG.error("null documentId passed in.");
 449  0
             throw new RuntimeException("null documentId passed in.");
 450  
         }
 451  0
         if (principalId == null ){
 452  0
             LOG.error("null principalId passed in.");
 453  0
             throw new RiceRuntimeException("null principalId passed in.");
 454  
         }
 455  0
         boolean authorized = false;
 456  0
         if ( LOG.isDebugEnabled() ) {
 457  0
                 LOG.debug("Evaluating isUserInRouteLog [docId=" + documentId + ", principalId=" + principalId + ", lookFuture=" + lookFuture + "]");
 458  
         }
 459  0
         DocumentRouteHeaderValue routeHeader = loadDocument(documentId);
 460  0
         Principal principal = KEWServiceLocator.getIdentityHelperService().getPrincipal(principalId);
 461  0
         List actionsTaken = KEWServiceLocator.getActionTakenService().findByDocumentIdWorkflowId(documentId, principal.getPrincipalId());
 462  
 
 463  0
         if(routeHeader.getInitiatorWorkflowId().equals(principal.getPrincipalId())){
 464  0
                 return true;
 465  
         }
 466  
 
 467  0
         if (actionsTaken.size() > 0) {
 468  0
                 LOG.debug("found action taken by user");
 469  0
                 authorized = true;
 470  
         }
 471  
 
 472  0
         List actionRequests = KEWServiceLocator.getActionRequestService().findAllActionRequestsByDocumentId(documentId);
 473  0
         if (actionRequestListHasPrincipal(principal, actionRequests)) {
 474  0
                 authorized = true;
 475  
         }
 476  
 
 477  0
         if (!lookFuture) {
 478  0
                 return authorized;
 479  
         }
 480  
 
 481  
 
 482  0
         SimulationWorkflowEngine simulationEngine = KEWServiceLocator.getSimulationEngine();
 483  0
         SimulationCriteria criteria = SimulationCriteria.createSimulationCritUsingDocumentId(documentId);
 484  0
         criteria.setDestinationNodeName(null); // process entire document to conclusion
 485  0
         criteria.getDestinationRecipients().add(new KimPrincipalRecipient(principal));
 486  0
         criteria.setFlattenNodes(flattenNodes);
 487  
 
 488  
         try {
 489  0
                 SimulationResults results = simulationEngine.runSimulation(criteria);
 490  0
                 if (actionRequestListHasPrincipal(principal, results.getSimulatedActionRequests())) {
 491  0
                         authorized = true;
 492  
                 }
 493  0
         } catch (Exception e) {
 494  0
                 throw new RiceRuntimeException(e);
 495  0
         }
 496  
 
 497  0
         return authorized;
 498  
     }
 499  
 
 500  
     /**
 501  
      * @see org.kuali.rice.kew.service.WorkflowUtility#getPrincipalIdsInRouteLog(java.lang.Long, boolean)
 502  
      */
 503  
     public String[] getPrincipalIdsInRouteLog(String documentId, boolean lookFuture) throws WorkflowException {
 504  0
         if (documentId == null) {
 505  0
             LOG.error("null documentId passed in.");
 506  0
             throw new RuntimeException("null documentId passed in.");
 507  
         }
 508  0
             Set<String> principalIds = new HashSet<String>();
 509  
         try {
 510  0
                 if ( LOG.isDebugEnabled() ) {
 511  0
                         LOG.debug("Evaluating isUserInRouteLog [docId=" + documentId + ", lookFuture=" + lookFuture + "]");
 512  
                 }
 513  0
             DocumentRouteHeaderValue routeHeader = loadDocument(documentId);
 514  0
             List<ActionTakenValue> actionsTakens =
 515  
                     (List<ActionTakenValue>)KEWServiceLocator.getActionTakenService().findByDocumentId(documentId);
 516  
             //TODO: confirm that the initiator is not already there in the actionstaken
 517  0
             principalIds.add(routeHeader.getInitiatorWorkflowId());
 518  0
             for(ActionTakenValue actionTaken: actionsTakens){
 519  0
                     principalIds.add(actionTaken.getPrincipalId());
 520  
             }
 521  0
             List<ActionRequestValue> actionRequests =
 522  
                     KEWServiceLocator.getActionRequestService().findAllActionRequestsByDocumentId(documentId);
 523  0
             for(ActionRequestValue actionRequest: actionRequests){
 524  0
                     principalIds.addAll(getPrincipalIdsForActionRequest(actionRequest));
 525  
             }
 526  0
             if (!lookFuture) {
 527  0
                     return principalIds.toArray(new String[]{});
 528  
             }
 529  0
             SimulationWorkflowEngine simulationEngine = KEWServiceLocator.getSimulationEngine();
 530  0
             SimulationCriteria criteria = SimulationCriteria.createSimulationCritUsingDocumentId(documentId);
 531  0
             criteria.setDestinationNodeName(null); // process entire document to conclusion
 532  0
             SimulationResults results = simulationEngine.runSimulation(criteria);
 533  0
             actionRequests = (List<ActionRequestValue>)results.getSimulatedActionRequests();
 534  0
             for(ActionRequestValue actionRequest: actionRequests){
 535  0
                     principalIds.addAll(getPrincipalIdsForActionRequest(actionRequest));
 536  
             }
 537  0
         } catch (Exception ex) {
 538  0
             LOG.warn("Problems getting principalIds in Route Log for documentId: "+documentId+". Exception:"+ex.getMessage(),ex);
 539  0
         }
 540  0
             return principalIds.toArray(new String[]{});
 541  
     }
 542  
 
 543  
         /**
 544  
          * This method gets all of the principalIds for the given ActionRequestValue.  It drills down into
 545  
          * groups if need be.
 546  
          * 
 547  
          * @param actionRequest
 548  
          */
 549  
         private List<String> getPrincipalIdsForActionRequest(ActionRequestValue actionRequest) {
 550  0
                 List<String> results = Collections.emptyList();
 551  0
                 if (actionRequest.getPrincipalId() != null) {
 552  0
                         results = Collections.singletonList(actionRequest.getPrincipalId());
 553  0
                 } else if (actionRequest.getGroupId() != null) {
 554  0
                         List<String> principalIdsForGroup = 
 555  
                                 KimApiServiceLocator.getGroupService().getMemberPrincipalIds(actionRequest.getGroupId());
 556  0
                         if (principalIdsForGroup != null) {
 557  0
                                 results = principalIdsForGroup;
 558  
                         }
 559  
                 }
 560  0
                 return results;
 561  
         }
 562  
 
 563  
     /***
 564  
      * @see org.kuali.rice.kew.service.WorkflowUtility#getPrincipalIdsWithPendingActionRequestByActionRequestedAndDocId(java.lang.String, java.lang.Long)
 565  
      */
 566  
     public String[] getPrincipalIdsWithPendingActionRequestByActionRequestedAndDocId(String actionRequestedCd, String documentId){
 567  0
             List<String> results = KEWServiceLocator.getActionRequestService().
 568  
                                     getPrincipalIdsWithPendingActionRequestByActionRequestedAndDocId(actionRequestedCd, documentId);
 569  0
             if (ObjectUtils.isNull(results)) {
 570  0
                     return null;
 571  
             }
 572  0
             return results.toArray(new String[]{});
 573  
     }
 574  
 
 575  
     private boolean actionRequestListHasPrincipal(Principal principal, List actionRequests) throws WorkflowException {
 576  0
         for (Iterator iter = actionRequests.iterator(); iter.hasNext();) {
 577  0
             ActionRequestValue actionRequest = (ActionRequestValue) iter.next();
 578  0
             if (actionRequest.isRecipientRoutedRequest(new KimPrincipalRecipient(principal))) {
 579  0
                 return true;
 580  
             }
 581  0
         }
 582  0
         return false;
 583  
     }
 584  
 
 585  
     private boolean isRecipientRoutedRequest(ActionRequestValue actionRequest, List<Recipient> recipients) throws WorkflowException {
 586  0
         for (Recipient recipient : recipients) {
 587  0
             if (actionRequest.isRecipientRoutedRequest(recipient)) {
 588  0
                 return true;
 589  
             }
 590  
         }
 591  0
         return false;
 592  
     }
 593  
 
 594  
     /**
 595  
      * @see org.kuali.rice.kew.service.WorkflowUtility#documentWillHaveAtLeastOneActionRequest(org.kuali.rice.kew.dto.ReportCriteriaDTO, java.lang.String[], boolean)
 596  
      */
 597  
     public boolean documentWillHaveAtLeastOneActionRequest(ReportCriteriaDTO reportCriteriaDTO, String[] actionRequestedCodes, boolean ignoreCurrentActionRequests) {
 598  
         try {
 599  0
                 SimulationWorkflowEngine simulationEngine = KEWServiceLocator.getSimulationEngine();
 600  0
                 SimulationCriteria criteria = DTOConverter.convertReportCriteriaDTO(reportCriteriaDTO);
 601  
                 // set activate requests to true by default so force action works correctly
 602  0
                 criteria.setActivateRequests(Boolean.TRUE);
 603  0
                 SimulationResults results = simulationEngine.runSimulation(criteria);
 604  0
             List actionRequestsToProcess = results.getSimulatedActionRequests();
 605  0
             if (!ignoreCurrentActionRequests) {
 606  0
                 actionRequestsToProcess.addAll(results.getDocument().getActionRequests());
 607  
             }
 608  0
             for (Iterator iter = actionRequestsToProcess.iterator(); iter.hasNext();) {
 609  0
                                 ActionRequestValue actionRequest = (ActionRequestValue) iter.next();
 610  0
                 if (actionRequest.isDone()) {
 611  
                     // an action taken has eliminated this request from being active
 612  0
                     continue;
 613  
                 }
 614  
                                 // if no action request codes are passed in.... assume any request found is
 615  0
                             if ( (actionRequestedCodes == null) || (actionRequestedCodes.length == 0) ) {
 616  
                                     // we found an action request
 617  0
                                     return true;
 618  
                             }
 619  
                             // check the action requested codes passed in
 620  0
                             for (String requestedActionRequestCode : actionRequestedCodes) {
 621  0
                                         if (requestedActionRequestCode.equals(actionRequest.getActionRequested())) {
 622  0
                                             boolean satisfiesDestinationUserCriteria = (criteria.getDestinationRecipients().isEmpty()) || (isRecipientRoutedRequest(actionRequest,criteria.getDestinationRecipients()));
 623  0
                                             if (satisfiesDestinationUserCriteria) {
 624  0
                                                 if (StringUtils.isBlank(criteria.getDestinationNodeName())) {
 625  0
                                                     return true;
 626  0
                                                 } else if (StringUtils.equals(criteria.getDestinationNodeName(),actionRequest.getNodeInstance().getName())) {
 627  0
                                                     return true;
 628  
                                                 }
 629  
                                             }
 630  
                                         }
 631  
                                 }
 632  0
                         }
 633  0
                 return false;
 634  0
         } catch (Exception ex) {
 635  0
                 String error = "Problems evaluating documentWillHaveAtLeastOneActionRequest: " + ex.getMessage();
 636  0
             LOG.error(error,ex);
 637  0
             if (ex instanceof RuntimeException) {
 638  0
                     throw (RuntimeException)ex;
 639  
             }
 640  0
             throw new RuntimeException(error, ex);
 641  
         }
 642  
     }
 643  
 
 644  
     public boolean isLastApproverInRouteLevel(String documentId, String principalId, Integer routeLevel) throws WorkflowException {
 645  0
         if (routeLevel == null) {
 646  0
             LOG.error("null routeLevel passed in.");
 647  0
             throw new RuntimeException("null routeLevel passed in.");
 648  
         }
 649  0
         if ( LOG.isDebugEnabled() ) {
 650  0
                 LOG.debug("Evaluating isLastApproverInRouteLevel [docId=" + documentId + ", principalId=" + principalId + ", routeLevel=" + routeLevel + "]");
 651  
         }
 652  0
         DocumentRouteHeaderValue document = loadDocument(documentId);
 653  0
         RouteNode node = CompatUtils.getNodeForLevel(document.getDocumentType(), routeLevel);
 654  0
         if (node == null) {
 655  0
             throw new RuntimeException("Cannot resolve given route level to an approriate node name: " + routeLevel);
 656  
         }
 657  0
         return isLastApproverAtNode(documentId, principalId, node.getRouteNodeName());
 658  
     }
 659  
 
 660  
     public boolean isLastApproverAtNode(String documentId, String principalId, String nodeName) throws WorkflowException {
 661  0
         if (documentId == null) {
 662  0
             LOG.error("null documentId passed in.");
 663  0
             throw new RuntimeException("null documentId passed in.");
 664  
         }
 665  0
         if (principalId == null ){
 666  0
             LOG.error("null principalId passed in.");
 667  0
             throw new RuntimeException("null principalId passed in.");
 668  
         }
 669  0
         if ( LOG.isDebugEnabled() ) {
 670  0
                 LOG.debug("Evaluating isLastApproverAtNode [docId=" + documentId + ", principalId=" + principalId + ", nodeName=" + nodeName + "]");
 671  
         }
 672  0
         loadDocument(documentId);
 673  
         // If this app constant is set to true, then we will attempt to simulate activation of non-active requests before
 674  
         // attempting to deactivate them, this is in order to address the force action issue reported by EPIC in issue
 675  
         // http://fms.dfa.cornell.edu:8080/browse/KULWF-366
 676  0
         Boolean activateFirst = CoreFrameworkServiceLocator.getParameterService().getParameterValueAsBoolean(KEWConstants.KEW_NAMESPACE, KNSConstants.DetailTypes.FEATURE_DETAIL_TYPE, KEWConstants.IS_LAST_APPROVER_ACTIVATE_FIRST_IND);
 677  0
         if (activateFirst == null) {
 678  0
             activateFirst = Boolean.FALSE;
 679  
         }
 680  
 
 681  0
         List requests = KEWServiceLocator.getActionRequestService().findPendingByDocRequestCdNodeName(documentId, KEWConstants.ACTION_REQUEST_APPROVE_REQ, nodeName);
 682  0
         if (requests == null || requests.isEmpty()) {
 683  0
             return false;
 684  
         }
 685  
         
 686  
         // Deep-copy the action requests for the simulation.
 687  0
         for (int i = requests.size() - 1; i >= 0; i--) {
 688  0
                 ActionRequestValue actionRequest = (ActionRequestValue) ObjectUtils.deepCopy((ActionRequestValue)requests.get(i));
 689  
                 // Deep-copy the action items as well, since they are indirectly retrieved from the action request via service calls.
 690  0
                 for (ActionItem actionItem : actionRequest.getActionItems()) {
 691  0
                         actionRequest.getSimulatedActionItems().add((ActionItem) ObjectUtils.deepCopy(actionItem));
 692  
                 }
 693  0
                 requests.set(i, actionRequest);
 694  
         }
 695  
         
 696  0
         ActivationContext activationContext = new ActivationContext(ActivationContext.CONTEXT_IS_SIMULATION);
 697  0
         for (Iterator iterator = requests.iterator(); iterator.hasNext();) {
 698  0
             ActionRequestValue request = (ActionRequestValue) iterator.next();
 699  0
             if (activateFirst && !request.isActive()) {
 700  0
                 KEWServiceLocator.getActionRequestService().activateRequest(request, activationContext);
 701  
             }
 702  0
             if (request.isUserRequest() && request.getPrincipalId().equals(principalId)) {
 703  0
                 KEWServiceLocator.getActionRequestService().deactivateRequest(null, request, activationContext);
 704  0
             } else if (request.isGroupRequest() && KimApiServiceLocator.getIdentityManagementService().isMemberOfGroup(principalId, request.getGroup().getId())) {
 705  0
                 KEWServiceLocator.getActionRequestService().deactivateRequest(null, request, activationContext);
 706  
             }
 707  0
         }
 708  0
         boolean allDeactivated = true;
 709  0
         for (Iterator iter = requests.iterator(); iter.hasNext();) {
 710  0
             ActionRequestValue actionRequest = (ActionRequestValue) iter.next();
 711  0
             allDeactivated = allDeactivated && actionRequest.isDeactivated();
 712  0
         }
 713  0
         return allDeactivated;
 714  
     }
 715  
 
 716  
     /**
 717  
      * Used to determine if a given route level will produce Approve Action Requests.
 718  
      *
 719  
      * @deprecated use routeNodeHasApproverActionRequest instead
 720  
      */
 721  
     public boolean routeLevelHasApproverActionRequest(String documentTypeName, String docContent, Integer routeLevel) throws WorkflowException {
 722  0
         if (documentTypeName == null) {
 723  0
             LOG.error("null document type name passed in.");
 724  0
             throw new RuntimeException("null document type passed in.");
 725  
         }
 726  0
         if (routeLevel == null) {
 727  0
             LOG.error("null routeLevel passed in.");
 728  0
             throw new RuntimeException("null routeLevel passed in.");
 729  
         }
 730  0
         if ( LOG.isDebugEnabled() ) {
 731  0
                 LOG.debug("Evaluating routeLevelHasApproverActionRequest [docTypeName=" + documentTypeName + ", routeLevel=" + routeLevel + "]");
 732  
         }
 733  0
         DocumentType documentType = KEWServiceLocator.getDocumentTypeService().findByName(documentTypeName);
 734  0
         if (!CompatUtils.isRouteLevelCompatible(documentType)) {
 735  0
             throw new WorkflowException("The given document type is not route level compatible: " + documentTypeName);
 736  
         }
 737  0
         RouteNode routeNode = CompatUtils.getNodeForLevel(documentType, routeLevel);
 738  0
         return routeNodeHasApproverActionRequest(documentType, docContent, routeNode, routeLevel);
 739  
     }
 740  
 
 741  
     public boolean routeNodeHasApproverActionRequest(String documentTypeName, String docContent, String nodeName) throws WorkflowException {
 742  0
         if (documentTypeName == null) {
 743  0
             LOG.error("null docType passed in.");
 744  0
             throw new RuntimeException("null docType passed in.");
 745  
         }
 746  0
         if (nodeName == null) {
 747  0
             LOG.error("null nodeName passed in.");
 748  0
             throw new RuntimeException("null nodeName passed in.");
 749  
         }
 750  0
         if ( LOG.isDebugEnabled() ) {
 751  0
                 LOG.debug("Evaluating routeNodeHasApproverActionRequest [docTypeName=" + documentTypeName + ", nodeName=" + nodeName + "]");
 752  
         }
 753  0
         DocumentType documentType = KEWServiceLocator.getDocumentTypeService().findByName(documentTypeName);
 754  0
         RouteNode routeNode = KEWServiceLocator.getRouteNodeService().findRouteNodeByName(documentType.getDocumentTypeId(), nodeName);
 755  0
         return routeNodeHasApproverActionRequest(documentType, docContent, routeNode, new Integer(KEWConstants.INVALID_ROUTE_LEVEL));
 756  
     }
 757  
 
 758  
     /**
 759  
      * Really this method needs to be implemented using the routingReport functionality (the SimulationEngine).
 760  
      * This would get rid of the needs for us to call to FlexRM directly.
 761  
      */
 762  
     private boolean routeNodeHasApproverActionRequest(DocumentType documentType, String docContent, RouteNode node, Integer routeLevel) throws WorkflowException {
 763  0
         if (documentType == null) {
 764  0
             LOG.error("could not locate document type.");
 765  0
             throw new RuntimeException("could not locate document type.");
 766  
         }
 767  0
         if (docContent == null) {
 768  0
             LOG.error("null docContent passed in.");
 769  0
             throw new RuntimeException("null docContent passed in.");
 770  
         }
 771  0
         if (node == null) {
 772  0
             LOG.error("could not locate route node.");
 773  0
             throw new RuntimeException("could not locate route node.");
 774  
         }
 775  
 
 776  0
         DocumentRouteHeaderValue routeHeader = new DocumentRouteHeaderValue();
 777  0
         routeHeader.setDocumentId("");
 778  0
         routeHeader.setDocumentTypeId(documentType.getDocumentTypeId());
 779  0
         routeHeader.setDocRouteLevel(routeLevel);
 780  0
         routeHeader.setDocVersion(new Integer(KEWConstants.CURRENT_DOCUMENT_VERSION));
 781  
 
 782  0
         if (node.getRuleTemplate() != null && node.isFlexRM()) {
 783  0
             String ruleTemplateName = node.getRuleTemplate().getName();
 784  0
             routeHeader.setDocContent(docContent);
 785  0
             routeHeader.setDocRouteStatus(KEWConstants.ROUTE_HEADER_INITIATED_CD);
 786  0
             FlexRM flexRM = new FlexRM();
 787  0
                     RouteContext context = RouteContext.getCurrentRouteContext();
 788  0
                     context.setDocument(routeHeader);
 789  
                     try {
 790  0
                             List actionRequests = flexRM.getActionRequests(routeHeader, node, null, ruleTemplateName);
 791  0
                             for (Iterator iter = actionRequests.iterator(); iter.hasNext();) {
 792  0
                                     ActionRequestValue actionRequest = (ActionRequestValue) iter.next();
 793  0
                                     if (actionRequest.isApproveOrCompleteRequest()) {
 794  0
                                             return true;
 795  
                                     }
 796  0
                             }
 797  
                     } finally {
 798  0
                             RouteContext.clearCurrentRouteContext();
 799  0
                     }
 800  
         }
 801  0
         return false;
 802  
     }
 803  
 
 804  
     private void incomingParamCheck(Object object, String name) {
 805  0
         if (object == null) {
 806  0
             LOG.error("null " + name + " passed in.");
 807  0
             throw new RuntimeException("null " + name + " passed in.");
 808  
         }
 809  0
     }
 810  
 
 811  
     public void reResolveRoleByDocTypeName(String documentTypeName, String roleName, String qualifiedRoleNameLabel) throws WorkflowException {
 812  0
         incomingParamCheck(documentTypeName, "documentTypeName");
 813  0
         incomingParamCheck(roleName, "roleName");
 814  0
         incomingParamCheck(qualifiedRoleNameLabel, "qualifiedRoleNameLabel");
 815  0
         if ( LOG.isDebugEnabled() ) {
 816  0
                 LOG.debug("Re-resolving Role [docTypeName=" + documentTypeName + ", roleName=" + roleName + ", qualifiedRoleNameLabel=" + qualifiedRoleNameLabel + "]");
 817  
         }
 818  0
             DocumentType documentType = KEWServiceLocator.getDocumentTypeService().findByName(documentTypeName);
 819  0
             if (org.apache.commons.lang.StringUtils.isEmpty(qualifiedRoleNameLabel)) {
 820  0
                     KEWServiceLocator.getRoleService().reResolveRole(documentType, roleName);
 821  
             } else {
 822  0
                     KEWServiceLocator.getRoleService().reResolveQualifiedRole(documentType, roleName, qualifiedRoleNameLabel);
 823  
             }
 824  0
     }
 825  
 
 826  
     public void reResolveRoleByDocumentId(String documentId, String roleName, String qualifiedRoleNameLabel) throws WorkflowException {
 827  0
         incomingParamCheck(documentId, "documentId");
 828  0
         incomingParamCheck(roleName, "roleName");
 829  0
         incomingParamCheck(qualifiedRoleNameLabel, "qualifiedRoleNameLabel");
 830  0
         if ( LOG.isDebugEnabled() ) {
 831  0
                 LOG.debug("Re-resolving Role [documentId=" + documentId + ", roleName=" + roleName + ", qualifiedRoleNameLabel=" + qualifiedRoleNameLabel + "]");
 832  
         }
 833  0
         DocumentRouteHeaderValue routeHeader = loadDocument(documentId);
 834  0
             if (org.apache.commons.lang.StringUtils.isEmpty(qualifiedRoleNameLabel)) {
 835  0
                     KEWServiceLocator.getRoleService().reResolveRole(routeHeader, roleName);
 836  
             } else {
 837  0
                     KEWServiceLocator.getRoleService().reResolveQualifiedRole(routeHeader, roleName, qualifiedRoleNameLabel);
 838  
             }
 839  0
     }
 840  
 
 841  
     public DocumentDetailDTO routingReport(ReportCriteriaDTO reportCriteria) throws WorkflowException {
 842  0
         incomingParamCheck(reportCriteria, "reportCriteria");
 843  0
         if ( LOG.isDebugEnabled() ) {
 844  0
                 LOG.debug("Executing routing report [docId=" + reportCriteria.getDocumentId() + ", docTypeName=" + reportCriteria.getDocumentTypeName() + "]");
 845  
         }
 846  0
         SimulationCriteria criteria = DTOConverter.convertReportCriteriaDTO(reportCriteria);
 847  0
         return DTOConverter.convertDocumentDetail(KEWServiceLocator.getRoutingReportService().report(criteria));
 848  
     }
 849  
 
 850  
     public boolean isFinalApprover(String documentId, String principalId) throws WorkflowException {
 851  0
         incomingParamCheck(documentId, "documentId");
 852  0
         incomingParamCheck(principalId, "principalId");
 853  0
         if ( LOG.isDebugEnabled() ) {
 854  0
                 LOG.debug("Evaluating isFinalApprover [docId=" + documentId + ", principalId=" + principalId + "]");
 855  
         }
 856  0
         DocumentRouteHeaderValue routeHeader = loadDocument(documentId);
 857  0
         List requests = KEWServiceLocator.getActionRequestService().findPendingByDoc(documentId);
 858  0
         List finalApproverNodes = KEWServiceLocator.getRouteNodeService().findFinalApprovalRouteNodes(routeHeader.getDocumentType().getDocumentTypeId());
 859  0
         if (finalApproverNodes.isEmpty()) {
 860  0
                 if ( LOG.isDebugEnabled() ) {
 861  0
                         LOG.debug("Could not locate final approval nodes for document " + documentId);
 862  
                 }
 863  0
             return false;
 864  
         }
 865  0
         Set finalApproverNodeNames = new HashSet();
 866  0
         for (Iterator iterator = finalApproverNodes.iterator(); iterator.hasNext();) {
 867  0
             RouteNode node = (RouteNode) iterator.next();
 868  0
             finalApproverNodeNames.add(node.getRouteNodeName());
 869  0
         }
 870  
 
 871  0
         int approveRequest = 0;
 872  0
         for (Iterator iter = requests.iterator(); iter.hasNext();) {
 873  0
             ActionRequestValue request = (ActionRequestValue) iter.next();
 874  0
             RouteNodeInstance nodeInstance = request.getNodeInstance();
 875  0
             if (nodeInstance == null) {
 876  0
                     if ( LOG.isDebugEnabled() ) {
 877  0
                             LOG.debug("Found an action request on the document with a null node instance, indicating EXCEPTION routing.");
 878  
                     }
 879  0
                 return false;
 880  
             }
 881  0
             if (finalApproverNodeNames.contains(nodeInstance.getRouteNode().getRouteNodeName())) {
 882  0
                 if (request.isApproveOrCompleteRequest()) {
 883  0
                     approveRequest++;
 884  0
                     if ( LOG.isDebugEnabled() ) {
 885  0
                             LOG.debug("Found request is approver " + request.getActionRequestId());
 886  
                     }
 887  0
                     if (! request.isRecipientRoutedRequest(principalId)) {
 888  0
                             if ( LOG.isDebugEnabled() ) {
 889  0
                                     LOG.debug("Action Request not for user " + principalId);
 890  
                             }
 891  0
                         return false;
 892  
                     }
 893  
                 }
 894  
             }
 895  0
         }
 896  
 
 897  0
         if (approveRequest == 0) {
 898  0
             return false;
 899  
         }
 900  0
         if ( LOG.isDebugEnabled() ) {
 901  0
                 LOG.debug("Principal "+principalId+" is final approver for document " + documentId);
 902  
         }
 903  0
         return true;
 904  
     }
 905  
 
 906  
     public boolean isSuperUserForDocumentType(String principalId, Long documentTypeId) throws WorkflowException {
 907  0
             if ( LOG.isDebugEnabled() ) {
 908  0
                     LOG.debug("Determining super user status [principalId=" + principalId + ", documentTypeId=" + documentTypeId + "]");
 909  
             }
 910  0
             DocumentType documentType = KEWServiceLocator.getDocumentTypeService().findById(documentTypeId);
 911  0
             boolean isSuperUser = KEWServiceLocator.getDocumentTypePermissionService().canAdministerRouting(principalId, documentType);
 912  0
             if ( LOG.isDebugEnabled() ) {
 913  0
                     LOG.debug("Super user status is " + isSuperUser + ".");
 914  
             }
 915  0
             return isSuperUser;
 916  
     }
 917  
 
 918  
     private DocumentRouteHeaderValue loadDocument(String documentId) {
 919  0
         return KEWServiceLocator.getRouteHeaderService().getRouteHeader(documentId);
 920  
     }
 921  
 
 922  
     public DocumentContentDTO getDocumentContent(String documentId) throws WorkflowException {
 923  0
             if ( LOG.isDebugEnabled() ) {
 924  0
                     LOG.debug("Fetching document content [docId=" + documentId + "]");
 925  
             }
 926  0
             DocumentRouteHeaderValue document = KEWServiceLocator.getRouteHeaderService().getRouteHeader(documentId);
 927  0
             return DTOConverter.convertDocumentContent(document.getDocContent(), documentId);
 928  
     }
 929  
 
 930  
         public String[] getPreviousRouteNodeNames(String documentId) throws WorkflowException {
 931  0
                 if ( LOG.isDebugEnabled() ) {
 932  0
                         LOG.debug("Fetching previous node names [docId=" + documentId + "]");
 933  
                 }
 934  0
                 DocumentRouteHeaderValue document = KEWServiceLocator.getRouteHeaderService().getRouteHeader(documentId);
 935  
                 //going conservative for now.  if the doc isn't enroute or exception nothing will be returned.
 936  0
                 if (document.isEnroute() || document.isInException()) {
 937  
 
 938  0
                         List activeNodeInstances = KEWServiceLocator.getRouteNodeService().getActiveNodeInstances(document);
 939  0
                         long largetActivatedNodeId = 0;
 940  0
                         for (Iterator iter = activeNodeInstances.iterator(); iter.hasNext();) {
 941  0
                                 RouteNodeInstance routeNodeInstance = (RouteNodeInstance) iter.next();
 942  0
                                 if (routeNodeInstance.getRouteNode().getRouteNodeId().longValue() > largetActivatedNodeId) {
 943  0
                                         largetActivatedNodeId = routeNodeInstance.getRouteNode().getRouteNodeId().longValue();
 944  
                                 }
 945  0
                         }
 946  
 
 947  0
                         List routeNodes = KEWServiceLocator.getRouteNodeService().getFlattenedNodeInstances(document, false);
 948  0
                         List nodeNames = new ArrayList();
 949  
 
 950  0
                         for (Iterator iter = routeNodes.iterator(); iter.hasNext();) {
 951  0
                                 RouteNodeInstance routeNode = (RouteNodeInstance) iter.next();
 952  0
                                 if (routeNode.isComplete() && !nodeNames.contains(routeNode.getName())) {
 953  
                                         //if the prototype of the nodeInstance we're analyzing is less than the largest id of all our active prototypes
 954  
                                         //then add it to the list.  This is an attempt to account for return to previous hitting a single node multiple times
 955  0
                                         if (routeNode.getRouteNode().getRouteNodeId().longValue() < largetActivatedNodeId) {
 956  0
                                                 nodeNames.add(routeNode.getName());
 957  
                                         }
 958  
                                 }
 959  0
                         }
 960  0
                         return (String[]) nodeNames.toArray(new String[nodeNames.size()]);
 961  
                 } else {
 962  0
                         return new String[0];
 963  
                 }
 964  
         }
 965  
 
 966  
     public RuleDTO[] ruleReport(RuleReportCriteriaDTO ruleReportCriteria) throws WorkflowException {
 967  0
         incomingParamCheck(ruleReportCriteria, "ruleReportCriteria");
 968  0
         if (ruleReportCriteria == null) {
 969  0
             throw new IllegalArgumentException("At least one criterion must be sent in a RuleReportCriteriaDTO object");
 970  
         }
 971  0
         if ( LOG.isDebugEnabled() ) {
 972  0
                 LOG.debug("Executing rule report [responsibleUser=" + ruleReportCriteria.getResponsiblePrincipalId() + ", responsibleWorkgroup=" +
 973  
                     ruleReportCriteria.getResponsibleGroupId() + "]");
 974  
         }
 975  0
         Map extensionValues = new HashMap();
 976  0
         if (ruleReportCriteria.getRuleExtensionVOs() != null) {
 977  0
             for (int i = 0; i < ruleReportCriteria.getRuleExtensionVOs().length; i++) {
 978  0
                 RuleExtensionDTO ruleExtensionVO = ruleReportCriteria.getRuleExtensionVOs()[i];
 979  0
                 KeyValue ruleExtension = DTOConverter.convertRuleExtensionVO(ruleExtensionVO);
 980  0
                 extensionValues.put(ruleExtension.getKey(), ruleExtension.getValue());
 981  
             }
 982  
         }
 983  0
         Collection<String> actionRequestCodes = new ArrayList<String>();
 984  0
         if ( (ruleReportCriteria.getActionRequestCodes() != null) && (ruleReportCriteria.getActionRequestCodes().length != 0) ) {
 985  0
             actionRequestCodes = Arrays.asList(ruleReportCriteria.getActionRequestCodes());
 986  
         }
 987  0
         Collection rulesFound = KEWServiceLocator.getRuleService().search(ruleReportCriteria.getDocumentTypeName(),ruleReportCriteria.getRuleTemplateName(),
 988  
                 ruleReportCriteria.getRuleDescription(), ruleReportCriteria.getResponsibleGroupId(),
 989  
                 ruleReportCriteria.getResponsiblePrincipalId(),
 990  
                 ruleReportCriteria.isConsiderWorkgroupMembership(),ruleReportCriteria.isIncludeDelegations(),
 991  
                 ruleReportCriteria.isActiveIndicator(),extensionValues,actionRequestCodes);
 992  0
         RuleDTO[] returnableRules = new RuleDTO[rulesFound.size()];
 993  0
         int i = 0;
 994  0
         for (Iterator iter = rulesFound.iterator(); iter.hasNext();) {
 995  0
             RuleBaseValues rule = (RuleBaseValues) iter.next();
 996  0
             returnableRules[i] = DTOConverter.convertRule(rule);
 997  0
             i++;
 998  0
         }
 999  0
         return returnableRules;
 1000  
     }
 1001  
 
 1002  
     public DocumentSearchResultDTO performDocumentSearch(DocumentSearchCriteriaDTO criteriaVO) throws WorkflowException {
 1003  0
         return performDocumentSearchWithPrincipal(null, criteriaVO);
 1004  
     }
 1005  
 
 1006  
     public DocumentSearchResultDTO performDocumentSearchWithPrincipal(String principalId, DocumentSearchCriteriaDTO criteriaVO) throws WorkflowException {
 1007  0
         DocSearchCriteriaDTO criteria = DTOConverter.convertDocumentSearchCriteriaDTO(criteriaVO);
 1008  0
         criteria.setOverridingUserSession(true);
 1009  0
         if (principalId != null) {
 1010  0
                 KEWServiceLocator.getIdentityHelperService().validatePrincipalId(principalId);
 1011  
         } else {
 1012  
                 // if the principal is null then we need to use the system "kr" user for execution of the search
 1013  0
                 principalId = KEWServiceLocator.getIdentityHelperService().getSystemPrincipal().getPrincipalId();
 1014  
         }
 1015  0
         DocumentSearchResultComponents components = KEWServiceLocator.getDocumentSearchService().getListRestrictedByCriteria(principalId, criteria);
 1016  0
         DocumentSearchResultDTO resultVO = DTOConverter.convertDocumentSearchResultComponents(components);
 1017  0
         resultVO.setOverThreshold(criteria.isOverThreshold());
 1018  0
         resultVO.setSecurityFilteredRows(Integer.valueOf(criteria.getSecurityFilteredRows()));
 1019  0
         return resultVO;
 1020  
     }
 1021  
 
 1022  
     /**
 1023  
      * @see org.kuali.rice.kew.service.WorkflowUtility#getDocumentInitiatorPrincipalId(java.lang.Long)
 1024  
      */
 1025  
     public String getDocumentInitiatorPrincipalId(String documentId)
 1026  
                     throws WorkflowException {
 1027  0
         if (documentId == null) {
 1028  0
             LOG.error("null documentId passed in.");
 1029  0
             throw new RuntimeException("null documentId passed in.");
 1030  
         }
 1031  
 
 1032  0
         DocumentRouteHeaderValue header = KEWServiceLocator.getRouteHeaderService().getRouteHeader(documentId, false);
 1033  0
         if ( header == null) {
 1034  0
                 return null;
 1035  
         }
 1036  0
             return header.getInitiatorWorkflowId();
 1037  
     }
 1038  
     /**
 1039  
      * @see org.kuali.rice.kew.service.WorkflowUtility#getDocumentRoutedByPrincipalId(java.lang.Long)
 1040  
      */
 1041  
     public String getDocumentRoutedByPrincipalId(String documentId)
 1042  
                     throws WorkflowException {
 1043  0
         if (documentId == null) {
 1044  0
             LOG.error("null documentId passed in.");
 1045  0
             throw new RuntimeException("null documentId passed in.");
 1046  
         }
 1047  
 
 1048  0
         DocumentRouteHeaderValue header = KEWServiceLocator.getRouteHeaderService().getRouteHeader(documentId, false);
 1049  0
         if ( header == null) {
 1050  0
                 return null;
 1051  
         }
 1052  0
             return header.getRoutedByUserWorkflowId();
 1053  
     }
 1054  
 
 1055  
     /**
 1056  
          *
 1057  
          * @see org.kuali.rice.kew.service.WorkflowUtility#getSearchableAttributeDateTimeValuesByKey(java.lang.Long, java.lang.String)
 1058  
          */
 1059  
         public Timestamp[] getSearchableAttributeDateTimeValuesByKey(
 1060  
                         String documentId, String key) {
 1061  0
                 List<Timestamp> results = KEWServiceLocator.getRouteHeaderService().getSearchableAttributeDateTimeValuesByKey(documentId, key);
 1062  0
                 if (ObjectUtils.isNull(results)) {
 1063  0
                         return null;
 1064  
                 }
 1065  0
                 return results.toArray(new Timestamp[]{});
 1066  
         }
 1067  
 
 1068  
         /**
 1069  
          *
 1070  
          * @see org.kuali.rice.kew.service.WorkflowUtility#getSearchableAttributeFloatValuesByKey(java.lang.Long, java.lang.String)
 1071  
          */
 1072  
         public BigDecimal[] getSearchableAttributeFloatValuesByKey(String documentId, String key) {
 1073  0
                 List<BigDecimal> results = KEWServiceLocator.getRouteHeaderService().getSearchableAttributeFloatValuesByKey(documentId, key);
 1074  0
                 if (ObjectUtils.isNull(results)) {
 1075  0
                         return null;
 1076  
                 }
 1077  0
                 return results.toArray(new BigDecimal[]{});
 1078  
         }
 1079  
 
 1080  
         /**
 1081  
          *
 1082  
          * @see org.kuali.rice.kew.service.WorkflowUtility#getSearchableAttributeLongValuesByKey(java.lang.Long, java.lang.String)
 1083  
          */
 1084  
         public Long[] getSearchableAttributeLongValuesByKey(String documentId, String key) {
 1085  0
                 List<Long> results = KEWServiceLocator.getRouteHeaderService().getSearchableAttributeLongValuesByKey(documentId, key);
 1086  0
                 if (ObjectUtils.isNull(results)) {
 1087  0
                         return null;
 1088  
                 }
 1089  0
                 return results.toArray(new Long[]{});
 1090  
         }
 1091  
 
 1092  
         /**
 1093  
          *
 1094  
          * @see org.kuali.rice.kew.service.WorkflowUtility#getSearchableAttributeStringValuesByKey(java.lang.Long, java.lang.String)
 1095  
          */
 1096  
         public String[] getSearchableAttributeStringValuesByKey(String documentId, String key) {
 1097  0
                 List<String> results = KEWServiceLocator.getRouteHeaderService().getSearchableAttributeStringValuesByKey(documentId, key);
 1098  0
                 if (ObjectUtils.isNull(results)) {
 1099  0
                         return null;
 1100  
                 }
 1101  0
                 return results.toArray(new String[]{});
 1102  
         }
 1103  
 
 1104  
     public String getFutureRequestsKey(String principalId) {
 1105  0
         return KEWConstants.RECEIVE_FUTURE_REQUESTS_BRANCH_STATE_KEY + "," + principalId + "," + new Date().toString() + ", " + Math.random();
 1106  
     }
 1107  
 
 1108  
     public String getReceiveFutureRequestsValue() {
 1109  0
         return KEWConstants.RECEIVE_FUTURE_REQUESTS_BRANCH_STATE_VALUE;
 1110  
     }
 1111  
 
 1112  
     public String getDoNotReceiveFutureRequestsValue() {
 1113  0
         return KEWConstants.DONT_RECEIVE_FUTURE_REQUESTS_BRANCH_STATE_VALUE;
 1114  
     }
 1115  
 
 1116  
     public String getClearFutureRequestsValue() {
 1117  0
         return KEWConstants.CLEAR_FUTURE_REQUESTS_BRANCH_STATE_VALUE;
 1118  
     }
 1119  
     
 1120  
     public boolean hasRouteNode(String documentTypeName, String routeNodeName) throws WorkflowException {
 1121  0
         if (documentTypeName == null) {
 1122  0
             LOG.error("null documentTypeName passed in.");
 1123  0
             throw new RuntimeException("null documentTypeName passed in");
 1124  
         }
 1125  0
         if (routeNodeName == null) {
 1126  0
             LOG.error("null routeNodeName passed in.");
 1127  0
             throw new RuntimeException("null routeNodeName passed in");
 1128  
         }
 1129  0
             DocumentTypeDTO docType = getDocumentTypeByName(documentTypeName);
 1130  0
             if(docType==null){
 1131  0
             LOG.error("docType null for the documentTypeName passed in "+documentTypeName);
 1132  0
             throw new RuntimeException("docType null for the documentTypeName passed in "+documentTypeName);
 1133  
         }
 1134  0
             RouteNode routeNode = KEWServiceLocator.getRouteNodeService().findRouteNodeByName(docType.getDocTypeId(), routeNodeName);
 1135  
             
 1136  0
             if(routeNode==null){
 1137  0
                     if(docType.getDocTypeParentName() == null)
 1138  0
                             return false;
 1139  
                     else
 1140  0
                             return hasRouteNode(docType.getDocTypeParentName(), routeNodeName);        
 1141  
             }
 1142  
             else
 1143  0
                     return true;
 1144  
             
 1145  
     }
 1146  
 
 1147  
     public boolean isCurrentActiveDocumentType(String documentTypeName) throws WorkflowException {
 1148  0
             DocumentType docType = KEWServiceLocator.getDocumentTypeService().findByName(documentTypeName);
 1149  0
             return docType != null && docType.isActive();
 1150  
     }
 1151  
     
 1152  
         public DocumentDetailDTO getDocumentDetailFromAppId(
 1153  
                         String documentTypeName, String appId) throws WorkflowException {
 1154  0
         if (documentTypeName == null) {
 1155  0
             LOG.error("null documentTypeName passed in.");
 1156  0
             throw new RuntimeException("null documentTypeName passed in");
 1157  
         }
 1158  0
         if (appId == null) {
 1159  0
             LOG.error("null appId passed in.");
 1160  0
             throw new RuntimeException("null appId passed in");
 1161  
         }
 1162  
         
 1163  0
         Collection documentIds = KEWServiceLocator.getRouteHeaderService().findByDocTypeAndAppId(documentTypeName, appId);
 1164  
         
 1165  0
         if(documentIds==null||documentIds.isEmpty()){
 1166  0
             LOG.error("No RouteHeader Ids found for criteria");
 1167  0
                     throw new WorkflowException("No RouteHeader Ids found for criteria");
 1168  
         }
 1169  0
         if(documentIds.size()>1){
 1170  0
             LOG.error("More than one RouteHeader Id found for criteria");
 1171  0
                     throw new WorkflowException("More than one RouteHeader Id found for criteria");
 1172  
                 }
 1173  
 
 1174  0
         return getDocumentDetail((String)documentIds.iterator().next());
 1175  
         }
 1176  
         
 1177  
         public String getAppDocId(String documentId) {
 1178  0
                   return KEWServiceLocator.getRouteHeaderService().getAppDocId(documentId);
 1179  
          }
 1180  
     
 1181  
     public DocumentStatusTransitionDTO[] getDocumentStatusTransitionHistory(String documentId) throws WorkflowException {
 1182  0
         if (documentId == null) {
 1183  0
             LOG.error("null documentId passed in.");
 1184  0
             throw new RuntimeException("null documentId passed in");
 1185  
         }
 1186  0
         if ( LOG.isDebugEnabled() ) {
 1187  0
             LOG.debug("Fetching document status transition history [id="+documentId+"]");
 1188  
         }
 1189  0
         DocumentRouteHeaderValue document = loadDocument(documentId);
 1190  
         
 1191  0
         UserSession userSession = GlobalVariables.getUserSession();
 1192  0
         String principalId = null;
 1193  0
         if (userSession != null) { // get the principalId if we can
 1194  0
                 principalId = userSession.getPrincipalId();
 1195  
         }
 1196  0
         List<DocumentStatusTransition> list = document.getAppDocStatusHistory();
 1197  
 
 1198  0
         DocumentStatusTransitionDTO[] transitionHistory = new DocumentStatusTransitionDTO[list.size()];        
 1199  0
         int i = 0;
 1200  0
         for (Object element : list) {
 1201  0
                 DocumentStatusTransition transition = (DocumentStatusTransition) element;
 1202  0
             transitionHistory[i] = DTOConverter.convertDocumentStatusTransition(transition);
 1203  0
             i++;
 1204  0
         }
 1205  0
         return transitionHistory;
 1206  
     }
 1207  
 
 1208  
         //for document link
 1209  
 
 1210  
         public void deleteDocumentLink(DocumentLinkDTO docLink) throws WorkflowException {
 1211  0
                 KEWServiceLocator.getDocumentLinkService().deleteDocumentLink(initDocLink(docLink));
 1212  0
         }
 1213  
 
 1214  
         /**
 1215  
          * This overridden method ...
 1216  
          * 
 1217  
          * @see org.kuali.rice.kew.routeheader.service.WorkflowDocumentService#addDocumentLink(org.kuali.rice.kew.documentlink.DocumentLink)
 1218  
          */
 1219  
         public void addDocumentLink(DocumentLinkDTO docLinkVO) throws WorkflowException {
 1220  0
                 KEWServiceLocator.getDocumentLinkService().saveDocumentLink(initDocLink(docLinkVO));
 1221  0
         }
 1222  
 
 1223  
         /**
 1224  
          * This overridden method ...
 1225  
          * 
 1226  
          * @see org.kuali.rice.kew.routeheader.service.WorkflowDocumentService#getgetLinkedDocumentsByDocId(java.lang.Long)
 1227  
          */
 1228  
         public List<DocumentLinkDTO> getLinkedDocumentsByDocId(String documentId) throws WorkflowException {
 1229  0
                 return DTOConverter.convertDocumentLinkToArrayList(KEWServiceLocator.getDocumentLinkService().getLinkedDocumentsByDocId(documentId));
 1230  
         }
 1231  
 
 1232  
         /**
 1233  
          * This overridden method ...
 1234  
          * 
 1235  
          * @see org.kuali.rice.kew.routeheader.service.WorkflowDocumentService#getDocumentLink(org.kuali.rice.kew.documentlink.DocumentLink)
 1236  
          */
 1237  
         public DocumentLinkDTO getLinkedDocument(DocumentLinkDTO docLinkVO) throws WorkflowException{
 1238  0
                 return DTOConverter.convertDocumentLink(KEWServiceLocator.getDocumentLinkService().getLinkedDocument(initDocLink(docLinkVO)));
 1239  
         }
 1240  
 
 1241  
         /**
 1242  
          * This overridden method ...
 1243  
          * 
 1244  
          * @see org.kuali.rice.kew.routeheader.service.WorkflowDocumentService#deleteDocumentLinkByDocId(java.lang.Long)
 1245  
          */
 1246  
         public void deleteDocumentLinksByDocId(String documentId) throws WorkflowException{
 1247  0
                 KEWServiceLocator.getDocumentLinkService().deleteDocumentLinksByDocId(documentId);
 1248  0
         }
 1249  
 
 1250  
         private DocumentLink initDocLink(DocumentLinkDTO docLinkVO){
 1251  0
                 DocumentLink docLink = new DocumentLink();
 1252  0
                 docLink.setDocLinkId(docLinkVO.getLinbkId());
 1253  0
                 docLink.setOrgnDocId(docLinkVO.getOrgnDocId());
 1254  0
                 docLink.setDestDocId(docLinkVO.getDestDocId());
 1255  
 
 1256  0
                 return docLink;
 1257  
         }
 1258  
 }