Coverage Report - org.kuali.rice.kew.rule.FlexRM
 
Classes in this File Line Coverage Branch Coverage Complexity
FlexRM
0%
0/141
0%
0/108
5.333
 
 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.rule;
 17  
 
 18  
 import org.apache.commons.lang.ObjectUtils;
 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.reflect.ObjectDefinition;
 23  
 import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
 24  
 import org.kuali.rice.core.api.util.ClassLoaderUtils;
 25  
 import org.kuali.rice.kew.actionrequest.ActionRequestFactory;
 26  
 import org.kuali.rice.kew.actionrequest.ActionRequestValue;
 27  
 import org.kuali.rice.kew.actionrequest.KimGroupRecipient;
 28  
 import org.kuali.rice.kew.actionrequest.KimPrincipalRecipient;
 29  
 import org.kuali.rice.kew.actionrequest.Recipient;
 30  
 import org.kuali.rice.kew.actionrequest.service.ActionRequestService;
 31  
 import org.kuali.rice.kew.api.KewApiServiceLocator;
 32  
 import org.kuali.rice.kew.api.action.ActionRequestStatus;
 33  
 import org.kuali.rice.kew.api.exception.WorkflowException;
 34  
 import org.kuali.rice.kew.api.extension.ExtensionDefinition;
 35  
 import org.kuali.rice.kew.api.rule.RuleDelegation;
 36  
 import org.kuali.rice.kew.api.rule.RuleResponsibility;
 37  
 import org.kuali.rice.kew.api.rule.RuleService;
 38  
 import org.kuali.rice.kew.api.rule.RuleTemplateAttribute;
 39  
 import org.kuali.rice.kew.engine.RouteContext;
 40  
 import org.kuali.rice.kew.engine.node.NodeState;
 41  
 import org.kuali.rice.kew.engine.node.RouteNode;
 42  
 import org.kuali.rice.kew.engine.node.RouteNodeInstance;
 43  
 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
 44  
 import org.kuali.rice.kew.service.KEWServiceLocator;
 45  
 import org.kuali.rice.kew.user.RoleRecipient;
 46  
 import org.kuali.rice.kew.api.KewApiConstants;
 47  
 import org.kuali.rice.kew.util.PerformanceLogger;
 48  
 import org.kuali.rice.kew.util.ResponsibleParty;
 49  
 import org.kuali.rice.kew.util.Utilities;
 50  
 
 51  
 import java.sql.Timestamp;
 52  
 import java.util.ArrayList;
 53  
 import java.util.List;
 54  
 import java.util.Map;
 55  
 
 56  
 
 57  
 /**
 58  
  * Generates Action Requests for a Document using the rule system and the specified
 59  
  * {@link org.kuali.rice.kew.rule.bo.RuleTemplateBo}.
 60  
  *
 61  
  * @see ActionRequestValue
 62  
  * @see org.kuali.rice.kew.rule.bo.RuleTemplateBo
 63  
  * @see RuleBaseValues
 64  
  *
 65  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 66  
  */
 67  
 public class FlexRM {
 68  
 
 69  0
         private static final Logger LOG = Logger.getLogger(FlexRM.class);
 70  
 
 71  
         /**
 72  
          * The default type of rule selector implementation to use if none is explicitly
 73  
          * specified for the node.
 74  
          */
 75  
         public static final String DEFAULT_RULE_SELECTOR = "Template";
 76  
         /**
 77  
          * Package in which rule selector implementations live
 78  
          */
 79  
         private static final String RULE_SELECTOR_PACKAGE = "org.kuali.rice.kew.rule";
 80  
         /**
 81  
          * The class name suffix all rule selectors should have; e.g. FooRuleSelector
 82  
          */
 83  
         private static final String RULE_SELECTOR_SUFFIX= "RuleSelector";
 84  
 
 85  
         private final Timestamp effectiveDate;
 86  
         /**
 87  
          * An accumulator that keeps track of the number of rules that have been selected over the lifespan of
 88  
          * this FlexRM instance.
 89  
          */
 90  
         private int selectedRules;
 91  
 
 92  0
         public FlexRM() {
 93  0
                 this.effectiveDate = null;
 94  0
         }
 95  
 
 96  0
         public FlexRM(Timestamp effectiveDate) {
 97  0
                 this.effectiveDate = effectiveDate;
 98  0
         }
 99  
 
 100  
         /*public List<ActionRequestValue> getActionRequests(DocumentRouteHeaderValue routeHeader, String ruleTemplateName) throws KEWUserNotFoundException, WorkflowException {
 101  
         return getActionRequests(routeHeader, null, ruleTemplateName);
 102  
     }*/
 103  
 
 104  
         // loads a RuleSelector implementation
 105  
         protected RuleSelector loadRuleSelector(RouteNode routeNodeDef, RouteNodeInstance nodeInstance) {
 106  
                 // first see if there ruleselector is configured on a nodeinstance basis
 107  0
                 NodeState ns = null;
 108  0
                 if (nodeInstance != null) {
 109  0
                         ns = nodeInstance.getNodeState(KewApiConstants.RULE_SELECTOR_NODE_STATE_KEY);
 110  
                 }
 111  0
                 String ruleSelectorName = null;
 112  0
                 if (ns != null) {
 113  0
                         ruleSelectorName = ns.getValue();
 114  
                 } else {
 115  
                         // otherwise pull it from the RouteNode definition/prototype
 116  0
                         Map<String, String> nodeCfgParams = Utilities.getKeyValueCollectionAsMap(
 117  
                                         routeNodeDef.
 118  
                                         getConfigParams());
 119  0
                         ruleSelectorName = nodeCfgParams.get(RouteNode.RULE_SELECTOR_CFG_KEY);
 120  
                 }
 121  
 
 122  0
                 if (ruleSelectorName == null) {
 123  0
                         ruleSelectorName = DEFAULT_RULE_SELECTOR;
 124  
                 }
 125  0
                 ruleSelectorName = StringUtils.capitalize(ruleSelectorName);
 126  
 
 127  
                 // load up the rule selection implementation
 128  0
                 String className = RULE_SELECTOR_PACKAGE + "." + ruleSelectorName + RULE_SELECTOR_SUFFIX;
 129  
                 Class<?> ruleSelectorClass;
 130  
                 try {
 131  0
                         ruleSelectorClass = ClassLoaderUtils.getDefaultClassLoader().loadClass(className);
 132  0
                 } catch (ClassNotFoundException cnfe) {
 133  0
                         throw new IllegalStateException("Rule selector implementation '" + className + "' not found", cnfe);
 134  0
                 }
 135  0
                 if (!RuleSelector.class.isAssignableFrom(ruleSelectorClass)) {
 136  0
                         throw new IllegalStateException("Specified class '" + ruleSelectorClass + "' does not implement RuleSelector interface");
 137  
                 }
 138  
                 RuleSelector ruleSelector;
 139  
                 try {
 140  0
                         ruleSelector = ((Class<RuleSelector>) ruleSelectorClass).newInstance();
 141  0
                 } catch (Exception e) {
 142  0
                         if (e instanceof RuntimeException) {
 143  0
                                 throw (RuntimeException)e;
 144  
                         }
 145  0
                         throw new IllegalStateException("Error instantiating rule selector implementation '" + ruleSelectorClass + "'", e);
 146  0
                 }
 147  
 
 148  0
                 return ruleSelector;
 149  
         }
 150  
 
 151  
         /**
 152  
          * Generates action requests
 153  
          * @param routeHeader the document route header
 154  
          * @param nodeInstance the route node instance; this may NOT be null
 155  
          * @param ruleTemplateName the rule template
 156  
          * @return list of action requests
 157  
          * @throws WorkflowException
 158  
          */
 159  
         public List<ActionRequestValue> getActionRequests(DocumentRouteHeaderValue routeHeader, RouteNodeInstance nodeInstance, String ruleTemplateName) {
 160  0
                 return getActionRequests(routeHeader, nodeInstance.getRouteNode(), nodeInstance, ruleTemplateName);
 161  
         }
 162  
 
 163  
         /**
 164  
          * Generates action requests
 165  
          * @param routeHeader the document route header
 166  
          * @param routeNodeDef the RouteNode definition of the route node instance
 167  
          * @param nodeInstance the route node instance; this may be null!
 168  
          * @param ruleTemplateName the rule template
 169  
          * @return list of action requests
 170  
          * @throws WorkflowException
 171  
          */
 172  
         public List<ActionRequestValue> getActionRequests(DocumentRouteHeaderValue routeHeader, RouteNode routeNodeDef, RouteNodeInstance nodeInstance, String ruleTemplateName) {
 173  0
                 RouteContext context = RouteContext.getCurrentRouteContext();
 174  
                 // TODO really the route context just needs to be able to support nested create and clears
 175  
                 // (i.e. a Stack model similar to transaction intercepting in Spring) and we wouldn't have to do this
 176  0
                 if (context.getDocument() == null) {
 177  0
                         context.setDocument(routeHeader);
 178  
                 }
 179  0
                 if (context.getNodeInstance() == null) {
 180  0
                         context.setNodeInstance(nodeInstance);
 181  
                 }
 182  
 
 183  0
                 LOG.debug("Making action requests for document " + routeHeader.getDocumentId());
 184  
 
 185  0
                 RuleSelector ruleSelector = loadRuleSelector(routeNodeDef, nodeInstance);
 186  
 
 187  0
                 List<Rule> rules = ruleSelector.selectRules(context, routeHeader, nodeInstance, ruleTemplateName, effectiveDate);
 188  
 
 189  
                 // XXX: FIXME: this is a special case hack to expose info from the default selection implementation
 190  
                 // this is used in exactly one place, RoutingReportAction, to make a distinction between no rules being
 191  
                 // selected, and no rules actually matching when evaluated
 192  
                 // if (numberOfRules == 0) {
 193  
                 //   errors.add(new WorkflowServiceErrorImpl("There are no rules.", "routereport.noRules"));
 194  
                 // } else {
 195  
                 //   errors.add(new WorkflowServiceErrorImpl("There are rules, but no matches.", "routereport.noMatchingRules"));
 196  
                 // }
 197  0
                 if (ruleSelector instanceof TemplateRuleSelector) {
 198  0
                         selectedRules += ((TemplateRuleSelector) ruleSelector).getNumberOfSelectedRules();
 199  
                 }
 200  
 
 201  0
                 PerformanceLogger performanceLogger = new PerformanceLogger();
 202  
 
 203  0
                 ActionRequestFactory arFactory = new ActionRequestFactory(routeHeader, context.getNodeInstance());
 204  
 
 205  0
                 List<ActionRequestValue> actionRequests = new ArrayList<ActionRequestValue>();
 206  0
                 if (rules != null) {
 207  0
                         LOG.info("Total number of rules selected by RuleSelector for documentType=" + routeHeader.getDocumentType().getName() + " and ruleTemplate=" + ruleTemplateName + ": " + rules.size());
 208  0
                         for (Rule rule: rules) {
 209  0
                                 RuleExpressionResult result = rule.evaluate(rule, context);
 210  0
                                 if (result.isSuccess() && result.getResponsibilities() != null) {
 211  
                                         // actionRequests.addAll(makeActionRequests(context, rule, routeHeader, null, null));
 212  0
                     org.kuali.rice.kew.api.rule.Rule ruleDef = org.kuali.rice.kew.api.rule.Rule.Builder.create(rule.getDefinition()).build();
 213  0
                                         makeActionRequests(arFactory, result.getResponsibilities(), context, ruleDef, routeHeader, null, null);
 214  
                                 }
 215  0
                         }
 216  
                 }
 217  0
                 actionRequests = new ArrayList<ActionRequestValue>(arFactory.getRequestGraphs());
 218  0
                 performanceLogger.log("Time to make action request for template " + ruleTemplateName);
 219  
 
 220  0
                 return actionRequests;
 221  
         }
 222  
 
 223  
         public ResponsibleParty resolveResponsibilityId(String responsibilityId) {
 224  0
                 if (responsibilityId == null) {
 225  0
                         throw new IllegalArgumentException("A null responsibilityId was passed to resolve responsibility!");
 226  
                 }
 227  0
                 RuleResponsibility resp = getRuleService().getRuleResponsibility(responsibilityId);
 228  0
                 ResponsibleParty responsibleParty = new ResponsibleParty();
 229  0
                 if (resp!=null && resp.isUsingRole()) {
 230  0
                         responsibleParty.setRoleName(resp.getResolvedRoleName());
 231  0
                 } else if (resp!=null && resp.isUsingPrincipal()) {
 232  0
                         responsibleParty.setPrincipalId(resp.getPrincipalId());
 233  0
                 } else if (resp!=null && resp.isUsingGroup()) {
 234  0
                         responsibleParty.setGroupId(resp.getGroupId());
 235  
                 } else {
 236  0
                         throw new RiceRuntimeException("Failed to resolve responsibility from responsibility ID " + responsibilityId + ".  Responsibility was an invalid type: " + resp);
 237  
                 }
 238  0
                 return responsibleParty;
 239  
         }
 240  
 
 241  
         private void makeActionRequests(ActionRequestFactory arFactory, RouteContext context, org.kuali.rice.kew.api.rule.Rule rule, DocumentRouteHeaderValue routeHeader, ActionRequestValue parentRequest, RuleDelegation ruleDelegation)
 242  
                         throws WorkflowException {
 243  
 
 244  0
                 List<org.kuali.rice.kew.api.rule.RuleResponsibility> responsibilities = rule.getRuleResponsibilities();
 245  0
                 makeActionRequests(arFactory, responsibilities, context, rule, routeHeader, parentRequest, ruleDelegation);
 246  0
         }
 247  
 
 248  
         public void makeActionRequests(ActionRequestFactory arFactory, List<org.kuali.rice.kew.api.rule.RuleResponsibility> responsibilities, RouteContext context, org.kuali.rice.kew.api.rule.Rule rule, DocumentRouteHeaderValue routeHeader, ActionRequestValue parentRequest, RuleDelegation ruleDelegation) {
 249  
 
 250  
                 //        Set actionRequests = new HashSet();
 251  0
         for (org.kuali.rice.kew.api.rule.RuleResponsibility responsibility : responsibilities)
 252  
         {
 253  
             //            arFactory = new ActionRequestFactory(routeHeader);
 254  
 
 255  0
             if (responsibility.isUsingRole())
 256  
             {
 257  0
                 makeRoleActionRequests(arFactory, context, rule, responsibility, routeHeader, parentRequest, ruleDelegation);
 258  
             } else
 259  
             {
 260  0
                 makeActionRequest(arFactory, context, rule, routeHeader, responsibility, parentRequest, ruleDelegation);
 261  
             }
 262  
             //            if (arFactory.getRequestGraph() != null) {
 263  
             //            actionRequests.add(arFactory.getRequestGraph());
 264  
             //            }
 265  
         }
 266  0
         }
 267  
 
 268  
         private void buildDelegationGraph(ActionRequestFactory arFactory, RouteContext context, 
 269  
                         org.kuali.rice.kew.api.rule.Rule delegationRule, DocumentRouteHeaderValue routeHeaderValue, ActionRequestValue parentRequest, RuleDelegation ruleDelegation) {
 270  0
                 context.setActionRequest(parentRequest);
 271  0
         RuleBaseValues delRuleBo = KEWServiceLocator.getRuleService().getRuleByName(delegationRule.getName());
 272  0
                 if (delegationRule.isActive()) {
 273  0
             for (org.kuali.rice.kew.api.rule.RuleResponsibility delegationResp : delegationRule.getRuleResponsibilities())
 274  
             {
 275  0
                 if (delegationResp.isUsingRole())
 276  
                 {
 277  0
                     makeRoleActionRequests(arFactory, context, delegationRule, delegationResp, routeHeaderValue, parentRequest, ruleDelegation);
 278  0
                 } else if (delRuleBo.isMatch(context.getDocumentContent()))
 279  
                 {
 280  0
                     makeActionRequest(arFactory, context, delegationRule, routeHeaderValue, delegationResp, parentRequest, ruleDelegation);
 281  
                 }
 282  
             }
 283  
                 }
 284  0
         }
 285  
 
 286  
         /**
 287  
          * Generates action requests for a role responsibility
 288  
          */
 289  
         private void makeRoleActionRequests(ActionRequestFactory arFactory, RouteContext context, 
 290  
                         org.kuali.rice.kew.api.rule.Rule rule, org.kuali.rice.kew.api.rule.RuleResponsibility resp, DocumentRouteHeaderValue routeHeader, ActionRequestValue parentRequest,
 291  
                         RuleDelegation ruleDelegation)
 292  
         {
 293  0
                 String roleName = resp.getResolvedRoleName();
 294  
                 //RoleAttribute roleAttribute = resp.resolveRoleAttribute();
 295  0
         RoleAttribute roleAttribute = null;
 296  0
         if (resp.isUsingRole()) {
 297  
             //get correct extension definition
 298  0
             roleAttribute = (RoleAttribute) GlobalResourceLoader.getResourceLoader().getObject(new ObjectDefinition(
 299  
                     resp.getRoleAttributeName()));
 300  
 
 301  0
             if (roleAttribute instanceof XmlConfiguredAttribute) {
 302  0
                 ExtensionDefinition roleAttributeDefinition = null;
 303  0
                 for (RuleTemplateAttribute ruleTemplateAttribute : rule.getRuleTemplate().getRuleTemplateAttributes()) {
 304  0
                     if (resp.getRoleAttributeName().equals(ruleTemplateAttribute.getRuleAttribute().getResourceDescriptor())) {
 305  0
                         roleAttributeDefinition = ruleTemplateAttribute.getRuleAttribute();
 306  0
                         break;
 307  
                     }
 308  
                 }
 309  0
                 ((XmlConfiguredAttribute)roleAttribute).setExtensionDefinition(roleAttributeDefinition);
 310  
             }
 311  
         }
 312  
                 //setRuleAttribute(roleAttribute, rule, resp.getRoleAttributeName());
 313  0
                 List<String> qualifiedRoleNames = new ArrayList<String>();
 314  0
                 if (parentRequest != null && parentRequest.getQualifiedRoleName() != null) {
 315  0
                         qualifiedRoleNames.add(parentRequest.getQualifiedRoleName());
 316  
                 } else {
 317  0
                 qualifiedRoleNames.addAll(roleAttribute.getQualifiedRoleNames(roleName, context.getDocumentContent()));
 318  
                 }
 319  0
         for (String qualifiedRoleName : qualifiedRoleNames) {
 320  0
             if (parentRequest == null && isDuplicateActionRequestDetected(routeHeader, context.getNodeInstance(), resp, qualifiedRoleName)) {
 321  0
                 continue;
 322  
             }
 323  
 
 324  0
             ResolvedQualifiedRole resolvedRole = roleAttribute.resolveQualifiedRole(context, roleName, qualifiedRoleName);
 325  0
             RoleRecipient recipient = new RoleRecipient(roleName, qualifiedRoleName, resolvedRole);
 326  0
             if (parentRequest == null) {
 327  0
                 ActionRequestValue roleRequest = arFactory.addRoleRequest(recipient, resp.getActionRequestedCd(),
 328  
                         resp.getApprovePolicy(), resp.getPriority(), resp.getResponsibilityId(), rule.isForceAction(),
 329  
                         rule.getDescription(), rule.getId());
 330  
 
 331  0
                 List<RuleDelegation> ruleDelegations = getRuleService().getRuleDelegationsByResponsibiltityId(resp.getResponsibilityId());
 332  0
                 if (ruleDelegations != null && !ruleDelegations.isEmpty()) {
 333  
                     // create delegations for all the children
 334  0
                     for (ActionRequestValue request : roleRequest.getChildrenRequests()) {
 335  0
                         for (RuleDelegation childRuleDelegation : ruleDelegations) {
 336  0
                             buildDelegationGraph(arFactory, context, childRuleDelegation.getDelegationRule(), routeHeader, request, childRuleDelegation);
 337  
                         }
 338  
                     }
 339  
                 }
 340  
 
 341  0
             } else {
 342  0
                 arFactory.addDelegationRoleRequest(parentRequest, resp.getApprovePolicy(), recipient, resp.getResponsibilityId(), rule.isForceAction(), ruleDelegation.getDelegationType(), rule.getDescription(), rule.getId());
 343  
             }
 344  0
         }
 345  0
         }
 346  
 
 347  
         /**
 348  
          * Determines if the attribute has a setRuleAttribute method and then sets the value appropriately if it does.
 349  
          */
 350  
         /*private void setRuleAttribute(RoleAttribute roleAttribute, org.kuali.rice.kew.api.rule.Rule rule, String roleAttributeName) {
 351  
                 // look for a setRuleAttribute method on the RoleAttribute
 352  
                 Method setRuleAttributeMethod = null;
 353  
                 try {
 354  
                         setRuleAttributeMethod = roleAttribute.getClass().getMethod("setExtensionDefinition", RuleAttribute.class);
 355  
                 } catch (NoSuchMethodException e) {
 356  
             LOG.info("method setRuleAttribute not found on " + RuleAttribute.class.getName());
 357  
         }
 358  
                 if (setRuleAttributeMethod == null) {
 359  
                         return;
 360  
                 }
 361  
                 // find the RuleAttribute by looking through the RuleTemplate
 362  
                 RuleTemplate ruleTemplate = rule.getRuleTemplate();
 363  
                 if (ruleTemplate != null) {
 364  
             for (RuleTemplateAttribute ruleTemplateAttribute : ruleTemplate.getActiveRuleTemplateAttributes())
 365  
             {
 366  
                 RuleAttribute ruleAttribute = ExtensionUtils.loadExtension(ruleTemplateAttribute.getRuleAttribute());
 367  
                 if (ruleAttribute.getResourceDescriptor().equals(roleAttributeName))
 368  
                 {
 369  
                     // this is our RuleAttribute!
 370  
                     try
 371  
                     {
 372  
                         setRuleAttributeMethod.invoke(roleAttribute, ruleAttribute);
 373  
                         break;
 374  
                     } catch (Exception e)
 375  
                     {
 376  
                         throw new WorkflowRuntimeException("Failed to set ExtensionDefinition on our RoleAttribute!", e);
 377  
                     }
 378  
                 }
 379  
             }
 380  
                 }
 381  
         }*/
 382  
 
 383  
         /**
 384  
          * Generates action requests for a non-role responsibility, either a user or workgroup
 385  
      * @throws org.kuali.rice.kew.api.exception.WorkflowException
 386  
      */
 387  
         private void makeActionRequest(ActionRequestFactory arFactory, RouteContext context, org.kuali.rice.kew.api.rule.Rule rule, DocumentRouteHeaderValue routeHeader, org.kuali.rice.kew.api.rule.RuleResponsibility resp, ActionRequestValue parentRequest,
 388  
                         RuleDelegation ruleDelegation) {
 389  0
                 if (parentRequest == null && isDuplicateActionRequestDetected(routeHeader, context.getNodeInstance(), resp, null)) {
 390  0
                         return;
 391  
                 }
 392  
                 Recipient recipient;
 393  0
                 if (resp.isUsingPrincipal()) {
 394  0
                 recipient = new KimPrincipalRecipient(resp.getPrincipalId());
 395  0
         } else if (resp.isUsingGroup()) {
 396  0
             recipient = new KimGroupRecipient(resp.getGroupId());
 397  
         } else {
 398  0
             throw new RiceRuntimeException("Illegal rule responsibility type encountered");
 399  
         }
 400  
                 ActionRequestValue actionRequest;
 401  0
                 if (parentRequest == null) {
 402  0
                         actionRequest = arFactory.addRootActionRequest(resp.getActionRequestedCd(),
 403  
                                         resp.getPriority(),
 404  
                                         recipient,
 405  
                                         rule.getDescription(),
 406  
                                         resp.getResponsibilityId(),
 407  
                                         rule.isForceAction(),
 408  
                                         resp.getApprovePolicy(),
 409  
                                         rule.getId());
 410  
 
 411  0
                         List<RuleDelegation> ruleDelegations = getRuleService().getRuleDelegationsByResponsibiltityId(
 412  
                     resp.getResponsibilityId());
 413  0
                         if (ruleDelegations != null && !ruleDelegations.isEmpty()) {
 414  0
                                 for (RuleDelegation childRuleDelegation : ruleDelegations) {
 415  0
                                         buildDelegationGraph(arFactory, context, childRuleDelegation.getDelegationRule(), routeHeader, actionRequest, childRuleDelegation);
 416  
                                 }
 417  
                         }
 418  
                         
 419  0
                 } else {
 420  0
                         arFactory.addDelegationRequest(parentRequest, recipient, resp.getResponsibilityId(), rule.isForceAction(), ruleDelegation.getDelegationType(), rule.getDescription(), rule.getId());
 421  
                 }
 422  0
         }
 423  
 
 424  
         private boolean isDuplicateActionRequestDetected(DocumentRouteHeaderValue routeHeader, RouteNodeInstance nodeInstance, org.kuali.rice.kew.api.rule.RuleResponsibility resp, String qualifiedRoleName) {
 425  0
                 List<ActionRequestValue> requests = getActionRequestService().findByStatusAndDocId(ActionRequestStatus.DONE.getCode(), routeHeader.getDocumentId());
 426  0
         for (ActionRequestValue request : requests)
 427  
         {
 428  0
             if (((nodeInstance != null
 429  
                     && request.getNodeInstance() != null
 430  
                     && request.getNodeInstance().getRouteNodeInstanceId().equals(nodeInstance.getRouteNodeInstanceId())
 431  
                  ) || request.getRouteLevel().equals(routeHeader.getDocRouteLevel())
 432  
                 )
 433  
                     && request.getResponsibilityId().equals(resp.getResponsibilityId())
 434  
                         && ObjectUtils.equals(request.getQualifiedRoleName(), qualifiedRoleName)) {
 435  0
                 return true;
 436  
             }
 437  
         }
 438  0
                 return false;
 439  
         }
 440  
 
 441  
         public RuleService getRuleService() {
 442  0
                 return KewApiServiceLocator.getRuleService();
 443  
         }
 444  
 
 445  
         private ActionRequestService getActionRequestService() {
 446  0
                 return KEWServiceLocator.getActionRequestService();
 447  
         }
 448  
 
 449  
         public int getNumberOfMatchingRules() {
 450  0
                 return selectedRules;
 451  
         }
 452  
 
 453  
 }