Coverage Report - org.kuali.rice.kew.rule.service.impl.RuleServiceInternalImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
RuleServiceInternalImpl
0%
0/579
0%
0/340
4.087
RuleServiceInternalImpl$RuleDelegationSorter
0%
0/7
0%
0/4
4.087
RuleServiceInternalImpl$RuleRoutingConfig
0%
0/28
0%
0/20
4.087
RuleServiceInternalImpl$RuleVersion
0%
0/1
N/A
4.087
 
 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.service.impl;
 17  
 
 18  
 import org.apache.commons.beanutils.PropertyUtils;
 19  
 import org.apache.commons.lang.ObjectUtils;
 20  
 import org.apache.commons.lang.StringUtils;
 21  
 import org.jdom.Element;
 22  
 import org.kuali.rice.core.api.impex.ExportDataSet;
 23  
 import org.kuali.rice.core.api.impex.xml.XmlConstants;
 24  
 import org.kuali.rice.core.api.util.RiceConstants;
 25  
 import org.kuali.rice.core.api.util.collect.CollectionUtils;
 26  
 import org.kuali.rice.core.framework.services.CoreFrameworkServiceLocator;
 27  
 import org.kuali.rice.kew.actionrequest.service.ActionRequestService;
 28  
 import org.kuali.rice.kew.api.KewApiServiceLocator;
 29  
 import org.kuali.rice.kew.api.WorkflowDocument;
 30  
 import org.kuali.rice.kew.api.WorkflowDocumentFactory;
 31  
 import org.kuali.rice.kew.api.WorkflowRuntimeException;
 32  
 import org.kuali.rice.kew.api.action.ActionRequestPolicy;
 33  
 import org.kuali.rice.kew.api.rule.Rule;
 34  
 import org.kuali.rice.kew.api.rule.RuleExtension;
 35  
 import org.kuali.rice.kew.api.rule.RuleResponsibility;
 36  
 import org.kuali.rice.kew.api.validation.RuleValidationContext;
 37  
 import org.kuali.rice.kew.api.validation.ValidationResults;
 38  
 import org.kuali.rice.kew.doctype.bo.DocumentType;
 39  
 import org.kuali.rice.kew.doctype.service.DocumentTypeService;
 40  
 import org.kuali.rice.kew.exception.WorkflowServiceErrorException;
 41  
 import org.kuali.rice.kew.exception.WorkflowServiceErrorImpl;
 42  
 import org.kuali.rice.kew.responsibility.service.ResponsibilityIdService;
 43  
 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
 44  
 import org.kuali.rice.kew.routeheader.service.RouteHeaderService;
 45  
 import org.kuali.rice.kew.rule.RuleBaseValues;
 46  
 import org.kuali.rice.kew.rule.RuleDelegationBo;
 47  
 import org.kuali.rice.kew.rule.RuleExtensionBo;
 48  
 import org.kuali.rice.kew.rule.RuleExtensionValue;
 49  
 import org.kuali.rice.kew.rule.RuleResponsibilityBo;
 50  
 import org.kuali.rice.kew.rule.RuleRoutingDefinition;
 51  
 import org.kuali.rice.kew.rule.RuleValidationAttribute;
 52  
 import org.kuali.rice.kew.rule.bo.RuleTemplateAttributeBo;
 53  
 import org.kuali.rice.kew.rule.bo.RuleTemplateBo;
 54  
 import org.kuali.rice.kew.rule.dao.RuleDAO;
 55  
 import org.kuali.rice.kew.rule.dao.RuleResponsibilityDAO;
 56  
 import org.kuali.rice.kew.rule.service.RuleDelegationService;
 57  
 import org.kuali.rice.kew.rule.service.RuleServiceInternal;
 58  
 import org.kuali.rice.kew.rule.service.RuleTemplateService;
 59  
 import org.kuali.rice.kew.service.KEWServiceLocator;
 60  
 import org.kuali.rice.kew.api.KewApiConstants;
 61  
 import org.kuali.rice.kew.util.PerformanceLogger;
 62  
 import org.kuali.rice.kew.xml.RuleXmlParser;
 63  
 import org.kuali.rice.kew.xml.export.RuleXmlExporter;
 64  
 import org.kuali.rice.kim.api.group.Group;
 65  
 import org.kuali.rice.kim.api.group.GroupService;
 66  
 import org.kuali.rice.kim.api.identity.principal.PrincipalContract;
 67  
 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
 68  
 import org.kuali.rice.krad.UserSession;
 69  
 import org.kuali.rice.krad.util.GlobalVariables;
 70  
 import org.kuali.rice.krad.util.KRADConstants;
 71  
 
 72  
 import java.io.InputStream;
 73  
 import java.sql.Timestamp;
 74  
 import java.text.ParseException;
 75  
 import java.util.ArrayList;
 76  
 import java.util.Collection;
 77  
 import java.util.Collections;
 78  
 import java.util.Comparator;
 79  
 import java.util.HashMap;
 80  
 import java.util.HashSet;
 81  
 import java.util.Iterator;
 82  
 import java.util.List;
 83  
 import java.util.Map;
 84  
 import java.util.Set;
 85  
 import java.util.UUID;
 86  
 
 87  
 
 88  0
 public class RuleServiceInternalImpl implements RuleServiceInternal {
 89  
 
 90  
     private static final String XML_PARSE_ERROR = "general.error.parsexml";
 91  
 
 92  0
     private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(RuleServiceInternalImpl.class);
 93  
 
 94  
     private RuleDAO ruleDAO;
 95  
     private RuleResponsibilityDAO ruleResponsibilityDAO;
 96  
 
 97  
     public RuleResponsibilityDAO getRuleResponsibilityDAO() {
 98  0
         return ruleResponsibilityDAO;
 99  
     }
 100  
 
 101  
     public RuleBaseValues getRuleByName(String name) {
 102  0
         return ruleDAO.findRuleBaseValuesByName(name);
 103  
     }
 104  
 
 105  
     public RuleBaseValues findDefaultRuleByRuleTemplateId(String ruleTemplateId){
 106  0
         return this.ruleDAO.findDefaultRuleByRuleTemplateId(ruleTemplateId);
 107  
     }
 108  
     public void setRuleResponsibilityDAO(RuleResponsibilityDAO ruleResponsibilityDAO) {
 109  0
         this.ruleResponsibilityDAO = ruleResponsibilityDAO;
 110  0
     }
 111  
 
 112  
     public void save2(RuleBaseValues ruleBaseValues) throws Exception {
 113  0
         save2(ruleBaseValues, null, true);
 114  0
     }
 115  
 
 116  
     public void save2(RuleBaseValues ruleBaseValues, RuleDelegationBo ruleDelegation, boolean saveDelegations) throws Exception {
 117  0
         if (ruleBaseValues.getPreviousRuleId() != null) {
 118  0
             RuleBaseValues oldRule = findRuleBaseValuesById(ruleBaseValues.getPreviousRuleId());
 119  0
             ruleBaseValues.setPreviousVersion(oldRule);
 120  0
             ruleBaseValues.setCurrentInd(Boolean.FALSE);
 121  0
             ruleBaseValues.setVersionNbr(getNextVersionNumber(oldRule));
 122  
         }
 123  0
         if (ruleBaseValues.getVersionNbr() == null) {
 124  0
             ruleBaseValues.setVersionNbr(Integer.valueOf(0));
 125  
         }
 126  0
         if (ruleBaseValues.getCurrentInd() == null) {
 127  0
             ruleBaseValues.setCurrentInd(Boolean.FALSE);
 128  
         }
 129  
         // iterate through all associated responsibilities, and if they are unsaved (responsibilityId is null)
 130  
         // set a new id on them, and recursively save any associated delegation rules
 131  0
         for (Object element : ruleBaseValues.getRuleResponsibilities()) {
 132  0
             RuleResponsibilityBo responsibility = (RuleResponsibilityBo) element;
 133  0
             if (responsibility.getResponsibilityId() == null) {
 134  0
                 responsibility.setResponsibilityId(getResponsibilityIdService().getNewResponsibilityId());
 135  
             }
 136  0
             if (saveDelegations) {
 137  0
                 for (Object element2 : responsibility.getDelegationRules()) {
 138  0
                     RuleDelegationBo localRuleDelegation = (RuleDelegationBo) element2;
 139  0
                     save2(localRuleDelegation.getDelegationRule(), localRuleDelegation, true);
 140  0
                 }
 141  
             }
 142  0
         }
 143  0
         validate2(ruleBaseValues, ruleDelegation, null);
 144  0
         getRuleDAO().save(ruleBaseValues);
 145  0
     }
 146  
 
 147  
     public void makeCurrent(String documentId) {
 148  0
         makeCurrent(findByDocumentId(documentId));
 149  0
     }
 150  
 
 151  
     public void makeCurrent(List<RuleBaseValues> rules) {
 152  0
         PerformanceLogger performanceLogger = new PerformanceLogger();
 153  
 
 154  0
         boolean isGenerateRuleArs = true;
 155  0
         String generateRuleArs = CoreFrameworkServiceLocator.getParameterService().getParameterValueAsString(KewApiConstants.KEW_NAMESPACE, KRADConstants.DetailTypes.RULE_DETAIL_TYPE, KewApiConstants.RULE_GENERATE_ACTION_REQESTS_IND);
 156  0
         if (!StringUtils.isBlank(generateRuleArs)) {
 157  0
             isGenerateRuleArs = KewApiConstants.YES_RULE_CHANGE_AR_GENERATION_VALUE.equalsIgnoreCase(generateRuleArs);
 158  
         }
 159  0
         Set<String> responsibilityIds = new HashSet<String>();
 160  0
         Map<String, RuleBaseValues> rulesToSave = new HashMap<String, RuleBaseValues>();
 161  
 
 162  0
         Collections.sort(rules, new RuleDelegationSorter());
 163  0
         boolean delegateFirst = false;
 164  0
         for (RuleBaseValues rule : rules) {
 165  0
             performanceLogger.log("Preparing rule: " + rule.getDescription());
 166  
 
 167  0
             rule.setCurrentInd(Boolean.TRUE);
 168  0
             Timestamp date = new Timestamp(System.currentTimeMillis());
 169  0
             rule.setActivationDate(date);
 170  
             try {
 171  0
                 rule.setDeactivationDate(new Timestamp(RiceConstants.getDefaultDateFormat().parse("01/01/2100").getTime()));
 172  0
             } catch (Exception e) {
 173  0
                 LOG.error("Parse Exception", e);
 174  0
             }
 175  0
             rulesToSave.put(rule.getId(), rule);
 176  0
             RuleBaseValues oldRule = rule.getPreviousVersion();
 177  0
             if (oldRule != null) {
 178  0
                 performanceLogger.log("Setting previous rule: " + oldRule.getId() + " to non current.");
 179  
 
 180  0
                 oldRule.setCurrentInd(Boolean.FALSE);
 181  0
                 oldRule.setDeactivationDate(date);
 182  0
                 rulesToSave.put(oldRule.getId(), oldRule);
 183  0
                 if (!delegateFirst) {
 184  0
                     responsibilityIds.addAll(getResponsibilityIdsFromGraph(oldRule, isGenerateRuleArs));
 185  
                 }
 186  
                 //TODO if more than one delegate is edited from the create delegation screen (which currently can not happen), then this logic will not work.
 187  0
                 if (rule.getDelegateRule().booleanValue() && rule.getPreviousRuleId() != null) {
 188  0
                     delegateFirst = true;
 189  
                 }
 190  
 
 191  0
                 List<RuleBaseValues> oldDelegationRules = findOldDelegationRules(oldRule, rule, performanceLogger);
 192  0
                 for (RuleBaseValues delegationRule : oldDelegationRules) {
 193  
 
 194  0
                     performanceLogger.log("Setting previous delegation rule: " + delegationRule.getId() + "to non current.");
 195  
 
 196  0
                     delegationRule.setCurrentInd(Boolean.FALSE);
 197  0
                     rulesToSave.put(delegationRule.getId(), delegationRule);
 198  0
                     responsibilityIds.addAll(getResponsibilityIdsFromGraph(delegationRule, isGenerateRuleArs));
 199  
                 }
 200  
             }
 201  0
             for (Object element : rule.getRuleResponsibilities()) {
 202  0
                 RuleResponsibilityBo responsibility = (RuleResponsibilityBo) element;
 203  0
                 for (Object element2 : responsibility.getDelegationRules()) {
 204  0
                     RuleDelegationBo delegation = (RuleDelegationBo) element2;
 205  
 
 206  0
                     delegation.getDelegationRule().setCurrentInd(Boolean.TRUE);
 207  0
                     RuleBaseValues delegatorRule = delegation.getDelegationRule();
 208  
 
 209  0
                     performanceLogger.log("Setting delegate rule: " + delegatorRule.getDescription() + " to current.");
 210  0
                     if (delegatorRule.getActivationDate() == null) {
 211  0
                         delegatorRule.setActivationDate(date);
 212  
                     }
 213  
                     try {
 214  0
                         delegatorRule.setDeactivationDate(new Timestamp(RiceConstants.getDefaultDateFormat().parse("01/01/2100").getTime()));
 215  0
                     } catch (Exception e) {
 216  0
                         LOG.error("Parse Exception", e);
 217  0
                     }
 218  0
                     rulesToSave.put(delegatorRule.getId(), delegatorRule);
 219  0
                 }
 220  0
             }
 221  0
         }
 222  0
         for (RuleBaseValues rule : rulesToSave.values()) {
 223  0
             getRuleDAO().save(rule);
 224  0
             performanceLogger.log("Saved rule: " + rule.getId());
 225  
         }
 226  0
         getActionRequestService().updateActionRequestsForResponsibilityChange(responsibilityIds);
 227  0
         performanceLogger.log("Time to make current");
 228  0
     }
 229  
 
 230  
     /**
 231  
      * TODO consolidate this method with makeCurrent.  The reason there's a seperate implementation is because the
 232  
      * original makeCurrent(...) could not properly handle versioning a List of multiple rules (including multiple
 233  
      * delegates rules for a single parent.  ALso, this work is being done for a patch so we want to mitigate the
 234  
      * impact on the existing rule code.
 235  
      *
 236  
      * <p>This version will only work for remove/replace operations where rules
 237  
      * aren't being added or removed.  This is why it doesn't perform some of the functions like checking
 238  
      * for delegation rules that were removed from a parent rule.
 239  
      */
 240  
     public void makeCurrent2(List<RuleBaseValues> rules) {
 241  0
         PerformanceLogger performanceLogger = new PerformanceLogger();
 242  
 
 243  0
         boolean isGenerateRuleArs = true;
 244  0
         String generateRuleArs = CoreFrameworkServiceLocator.getParameterService().getParameterValueAsString(KewApiConstants.KEW_NAMESPACE, KRADConstants.DetailTypes.RULE_DETAIL_TYPE, KewApiConstants.RULE_GENERATE_ACTION_REQESTS_IND);
 245  0
         if (!StringUtils.isBlank(generateRuleArs)) {
 246  0
             isGenerateRuleArs = KewApiConstants.YES_RULE_CHANGE_AR_GENERATION_VALUE.equalsIgnoreCase(generateRuleArs);
 247  
         }
 248  0
         Set<String> responsibilityIds = new HashSet<String>();
 249  0
         Map<String, RuleBaseValues> rulesToSave = new HashMap<String, RuleBaseValues>();
 250  
 
 251  0
         Collections.sort(rules, new RuleDelegationSorter());
 252  0
         for (RuleBaseValues rule : rules) {
 253  0
             performanceLogger.log("Preparing rule: " + rule.getDescription());
 254  
 
 255  0
             rule.setCurrentInd(Boolean.TRUE);
 256  0
             Timestamp date = new Timestamp(System.currentTimeMillis());
 257  0
             rule.setActivationDate(date);
 258  
             try {
 259  0
                 rule.setDeactivationDate(new Timestamp(RiceConstants.getDefaultDateFormat().parse("01/01/2100").getTime()));
 260  0
             } catch (Exception e) {
 261  0
                 LOG.error("Parse Exception", e);
 262  0
             }
 263  0
             rulesToSave.put(rule.getId(), rule);
 264  0
             RuleBaseValues oldRule = rule.getPreviousVersion();
 265  0
             if (oldRule != null) {
 266  0
                 performanceLogger.log("Setting previous rule: " + oldRule.getId() + " to non current.");
 267  0
                 oldRule.setCurrentInd(Boolean.FALSE);
 268  0
                 oldRule.setDeactivationDate(date);
 269  0
                 rulesToSave.put(oldRule.getId(), oldRule);
 270  0
                 responsibilityIds.addAll(getModifiedResponsibilityIds(oldRule, rule));
 271  
             }
 272  0
             for (Object element : rule.getRuleResponsibilities()) {
 273  0
                 RuleResponsibilityBo responsibility = (RuleResponsibilityBo) element;
 274  0
                 for (Object element2 : responsibility.getDelegationRules()) {
 275  0
                     RuleDelegationBo delegation = (RuleDelegationBo) element2;
 276  0
                     RuleBaseValues delegateRule = delegation.getDelegationRule();
 277  0
                     delegateRule.setCurrentInd(Boolean.TRUE);
 278  0
                     performanceLogger.log("Setting delegate rule: " + delegateRule.getDescription() + " to current.");
 279  0
                     if (delegateRule.getActivationDate() == null) {
 280  0
                         delegateRule.setActivationDate(date);
 281  
                     }
 282  
                     try {
 283  0
                         delegateRule.setDeactivationDate(new Timestamp(RiceConstants.getDefaultDateFormat().parse("01/01/2100").getTime()));
 284  0
                     } catch (Exception e) {
 285  0
                         LOG.error("Parse Exception", e);
 286  0
                     }
 287  0
                     rulesToSave.put(delegateRule.getId(), delegateRule);
 288  0
                 }
 289  0
             }
 290  0
         }
 291  0
         for (RuleBaseValues rule : rulesToSave.values()) {
 292  0
             getRuleDAO().save(rule);
 293  0
             performanceLogger.log("Saved rule: " + rule.getId());
 294  
 
 295  
         }
 296  
 
 297  0
         if (isGenerateRuleArs) {
 298  0
             getActionRequestService().updateActionRequestsForResponsibilityChange(responsibilityIds);
 299  
         }
 300  0
         performanceLogger.log("Time to make current");
 301  0
     }
 302  
 
 303  
     /**
 304  
      * makeCurrent(RuleBaseValues) is the version of makeCurrent which is initiated from the new Routing Rule
 305  
      * Maintenance document.  Because of the changes in the data model and the front end here,
 306  
      * this method can be much less complicated than the previous 2!
 307  
      */
 308  
     public void makeCurrent(RuleBaseValues rule, boolean isRetroactiveUpdatePermitted) {
 309  0
             makeCurrent(null, rule, isRetroactiveUpdatePermitted);
 310  0
     }
 311  
 
 312  
     public void makeCurrent(RuleDelegationBo ruleDelegation, boolean isRetroactiveUpdatePermitted) {
 313  0
             makeCurrent(ruleDelegation, ruleDelegation.getDelegationRule(), isRetroactiveUpdatePermitted);
 314  0
     }
 315  
 
 316  
     protected void makeCurrent(RuleDelegationBo ruleDelegation, RuleBaseValues rule, boolean isRetroactiveUpdatePermitted) {
 317  0
         PerformanceLogger performanceLogger = new PerformanceLogger();
 318  
 
 319  0
         boolean isGenerateRuleArs = false;
 320  0
         if (isRetroactiveUpdatePermitted) {
 321  0
                 isGenerateRuleArs = true;
 322  0
                 String generateRuleArs = CoreFrameworkServiceLocator.getParameterService().getParameterValueAsString(KewApiConstants.KEW_NAMESPACE, KRADConstants.DetailTypes.RULE_DETAIL_TYPE, KewApiConstants.RULE_GENERATE_ACTION_REQESTS_IND);
 323  0
                 if (!StringUtils.isBlank(generateRuleArs)) {
 324  0
                         isGenerateRuleArs = KewApiConstants.YES_RULE_CHANGE_AR_GENERATION_VALUE.equalsIgnoreCase(generateRuleArs);
 325  
                 }
 326  
         }
 327  0
         Set<String> responsibilityIds = new HashSet<String>();
 328  
 
 329  
 
 330  0
         performanceLogger.log("Preparing rule: " + rule.getDescription());
 331  
 
 332  0
         Map<String, RuleBaseValues> rulesToSave = new HashMap<String, RuleBaseValues>();
 333  0
         generateRuleNameIfNeeded(rule);
 334  0
         assignResponsibilityIds(rule);
 335  0
         rule.setCurrentInd(Boolean.TRUE);
 336  0
         Timestamp date = new Timestamp(System.currentTimeMillis());
 337  0
         rule.setActivationDate(date);
 338  0
         rule.setDeactivationDate(null);
 339  
 
 340  0
         rulesToSave.put(rule.getId(), rule);
 341  0
         if (rule.getPreviousRuleId() != null) {
 342  0
                 RuleBaseValues oldRule = findRuleBaseValuesById(rule.getPreviousRuleId());
 343  0
                 rule.setPreviousVersion(oldRule);
 344  
         }
 345  0
         rule.setVersionNbr(0);
 346  0
         rule.setObjectId(null);
 347  0
         RuleBaseValues oldRule = rule.getPreviousVersion();
 348  0
         if (oldRule != null) {
 349  0
                 performanceLogger.log("Setting previous rule: " + oldRule.getId() + " to non current.");
 350  0
                 oldRule.setCurrentInd(Boolean.FALSE);
 351  0
                 oldRule.setDeactivationDate(date);
 352  0
                 rulesToSave.put(oldRule.getId(), oldRule);
 353  0
                 responsibilityIds.addAll(getModifiedResponsibilityIds(oldRule, rule));
 354  0
                 rule.setVersionNbr(getNextVersionNumber(oldRule));
 355  
         }
 356  
                
 357  
 
 358  0
         boolean isRuleDelegation = ruleDelegation != null;
 359  
         
 360  0
         for (RuleBaseValues ruleToSave : rulesToSave.values()) {
 361  0
                 getRuleDAO().save(ruleToSave);
 362  0
                 performanceLogger.log("Saved rule: " + ruleToSave.getId());
 363  
         }
 364  0
         if (isRuleDelegation) {
 365  0
                 responsibilityIds.add(ruleDelegation.getResponsibilityId());
 366  0
                 ruleDelegation.setDelegateRuleId(rule.getId());
 367  0
                 getRuleDelegationService().save(ruleDelegation);
 368  
         }
 369  
         
 370  0
         if (isGenerateRuleArs
 371  
                 && org.apache.commons.collections.CollectionUtils.isNotEmpty(responsibilityIds)) {
 372  0
             getActionRequestService().updateActionRequestsForResponsibilityChange(responsibilityIds);
 373  
         }
 374  0
         performanceLogger.log("Time to make current");
 375  0
     }
 376  
 
 377  
     public RuleBaseValues getParentRule(String ruleBaseValuesId) {
 378  0
         return getRuleDAO().getParentRule(ruleBaseValuesId);
 379  
     }
 380  
 
 381  
     private Set getResponsibilityIdsFromGraph(RuleBaseValues rule, boolean isRuleCollecting) {
 382  0
         Set responsibilityIds = new HashSet();
 383  0
         for (Object element : rule.getRuleResponsibilities()) {
 384  0
             RuleResponsibilityBo responsibility = (RuleResponsibilityBo) element;
 385  0
             if (isRuleCollecting) {
 386  0
                 responsibilityIds.add(responsibility.getResponsibilityId());
 387  
             }
 388  0
         }
 389  0
         return responsibilityIds;
 390  
     }
 391  
 
 392  
     /**
 393  
      * Returns the responsibility IDs that were modified between the 2 given versions of the rule.  Any added
 394  
      * or removed responsibilities are also included in the returned Set.
 395  
      */
 396  
     private Set<String> getModifiedResponsibilityIds(RuleBaseValues oldRule, RuleBaseValues newRule) {
 397  0
         Map<String, RuleResponsibilityBo> modifiedResponsibilityMap = new HashMap<String, RuleResponsibilityBo>();
 398  0
         for (Object element : oldRule.getRuleResponsibilities()) {
 399  0
             RuleResponsibilityBo responsibility = (RuleResponsibilityBo) element;
 400  0
             modifiedResponsibilityMap.put(responsibility.getResponsibilityId(), responsibility);
 401  0
         }
 402  0
         for (Object element : newRule.getRuleResponsibilities()) {
 403  0
             RuleResponsibilityBo responsibility = (RuleResponsibilityBo) element;
 404  0
             RuleResponsibilityBo oldResponsibility = modifiedResponsibilityMap.get(responsibility.getResponsibilityId());
 405  0
             if (oldResponsibility == null) {
 406  
                 // if there's no old responsibility then it's a new responsibility, add it
 407  0
                 modifiedResponsibilityMap.put(responsibility.getResponsibilityId(), responsibility);
 408  0
             } else if (!hasResponsibilityChanged(oldResponsibility, responsibility)) {
 409  
                 // if it hasn't been modified, remove it from the collection of modified ids
 410  0
                 modifiedResponsibilityMap.remove(responsibility.getResponsibilityId());
 411  
             }
 412  0
         }
 413  0
         return modifiedResponsibilityMap.keySet();
 414  
     }
 415  
 
 416  
     /**
 417  
      * Determines if the given responsibilities are different or not.
 418  
      */
 419  
     private boolean hasResponsibilityChanged(RuleResponsibilityBo oldResponsibility, RuleResponsibilityBo newResponsibility) {
 420  0
         return !ObjectUtils.equals(oldResponsibility.getActionRequestedCd(), newResponsibility.getActionRequestedCd()) ||
 421  
         !ObjectUtils.equals(oldResponsibility.getApprovePolicy(), newResponsibility.getActionRequestedCd()) ||
 422  
         !ObjectUtils.equals(oldResponsibility.getPriority(), newResponsibility.getPriority()) ||
 423  
         !ObjectUtils.equals(oldResponsibility.getRole(), newResponsibility.getRole()) ||
 424  
         !ObjectUtils.equals(oldResponsibility.getRuleResponsibilityName(), newResponsibility.getRuleResponsibilityName()) ||
 425  
         !ObjectUtils.equals(oldResponsibility.getRuleResponsibilityType(), newResponsibility.getRuleResponsibilityType());
 426  
     }
 427  
 
 428  
     /**
 429  
      * This method will find any old delegation rules on the previous version of the parent rule which are not on the
 430  
      * new version of the rule so that they can be marked non-current.
 431  
      */
 432  
     private List<RuleBaseValues> findOldDelegationRules(RuleBaseValues oldRule, RuleBaseValues newRule, PerformanceLogger performanceLogger) {
 433  0
         performanceLogger.log("Begin to get delegation rules.");
 434  0
         List<RuleBaseValues> oldDelegations = getRuleDAO().findOldDelegations(oldRule, newRule);
 435  0
         performanceLogger.log("Located "+oldDelegations.size()+" old delegation rules.");
 436  0
         return oldDelegations;
 437  
     }
 438  
 
 439  
     public String routeRuleWithDelegate(String documentId, RuleBaseValues parentRule, RuleBaseValues delegateRule, PrincipalContract principal, String annotation, boolean blanketApprove) throws Exception {
 440  0
         if (parentRule == null) {
 441  0
             throw new IllegalArgumentException("Cannot route a delegate without a parent rule.");
 442  
         }
 443  0
         if (parentRule.getDelegateRule().booleanValue()) {
 444  0
             throw new IllegalArgumentException("Parent rule cannot be a delegate.");
 445  
         }
 446  0
         if (parentRule.getPreviousRuleId() == null && delegateRule.getPreviousRuleId() == null) {
 447  0
             throw new IllegalArgumentException("Previous rule version required.");
 448  
         }
 449  
 
 450  
         // if the parent rule is new, unsaved, then save it
 451  
 //      boolean isRoutingParent = parentRule.getId() == null;
 452  
 //      if (isRoutingParent) {
 453  
 //      // it's very important that we do not save delegations here (that's what the false parameter is for)
 454  
 //      // this is because, if we save the delegations, the existing delegations on our parent rule will become
 455  
 //      // saved as "non current" before the rule is approved!!!
 456  
 //      save2(parentRule, null, false);
 457  
 //      //save2(parentRule, null, true);
 458  
 //      }
 459  
 
 460  
         // XXX: added when the RuleValidation stuff was added, basically we just need to get the RuleDelegation
 461  
         // that points to our delegate rule, this rule code is scary...
 462  0
         RuleDelegationBo ruleDelegation = getRuleDelegation(parentRule, delegateRule);
 463  
 
 464  0
         save2(delegateRule, ruleDelegation, true);
 465  
 
 466  
 //      if the parent rule is new, unsaved, then save it
 467  
         // It's important to save the parent rule after the delegate rule is saved, that way we can ensure that any new rule
 468  
         // delegations have a valid, saved, delegation rule to point to (otherwise we end up with a null constraint violation)
 469  0
         boolean isRoutingParent = parentRule.getId() == null;
 470  0
         if (isRoutingParent) {
 471  
             // it's very important that we do not save delegations here (that's what the false parameter is for)
 472  
             // this is because, if we save the delegations, the existing delegations on our parent rule will become
 473  
             // saved as "non current" before the rule is approved!!!
 474  0
             save2(parentRule, null, false);
 475  
             //save2(parentRule, null, true);
 476  
         }
 477  
 
 478  0
         WorkflowDocument workflowDocument = null;
 479  0
         if (documentId != null) {
 480  0
             workflowDocument = WorkflowDocumentFactory.loadDocument(principal.getPrincipalId(), documentId);
 481  
         } else {
 482  0
             List rules = new ArrayList();
 483  0
             rules.add(delegateRule);
 484  0
             rules.add(parentRule);
 485  0
             workflowDocument = WorkflowDocumentFactory.createDocument(principal.getPrincipalId(), getRuleDocumentTypeName(
 486  
                     rules));
 487  
         }
 488  0
         workflowDocument.setTitle(generateTitle(parentRule, delegateRule));
 489  0
         delegateRule.setDocumentId(workflowDocument.getDocumentId());
 490  0
         workflowDocument.addAttributeDefinition(RuleRoutingDefinition.createAttributeDefinition(parentRule.getDocTypeName()));
 491  0
         getRuleDAO().save(delegateRule);
 492  0
         if (isRoutingParent) {
 493  0
             parentRule.setDocumentId(workflowDocument.getDocumentId());
 494  0
             getRuleDAO().save(parentRule);
 495  
         }
 496  0
         if (blanketApprove) {
 497  0
             workflowDocument.blanketApprove(annotation);
 498  
         } else {
 499  0
             workflowDocument.route(annotation);
 500  
         }
 501  0
         return workflowDocument.getDocumentId();
 502  
     }
 503  
 
 504  
     /**
 505  
      * Gets the RuleDelegation object from the parentRule that points to the delegateRule.
 506  
      */
 507  
     private RuleDelegationBo getRuleDelegation(RuleBaseValues parentRule, RuleBaseValues delegateRule) throws Exception {
 508  0
         for (Object element : parentRule.getRuleResponsibilities()) {
 509  0
             RuleResponsibilityBo responsibility = (RuleResponsibilityBo) element;
 510  0
             for (Object element2 : responsibility.getDelegationRules()) {
 511  0
                 RuleDelegationBo ruleDelegation = (RuleDelegationBo) element2;
 512  
                 // they should be the same object in memory
 513  0
                 if (ruleDelegation.getDelegationRule().equals(delegateRule)) {
 514  0
                     return ruleDelegation;
 515  
                 }
 516  0
             }
 517  0
         }
 518  0
         return null;
 519  
     }
 520  
 
 521  
     private String generateTitle(RuleBaseValues parentRule, RuleBaseValues delegateRule) {
 522  0
         StringBuffer title = new StringBuffer();
 523  0
         if (delegateRule.getPreviousRuleId() != null) {
 524  0
             title.append("Editing Delegation Rule '").append(delegateRule.getDescription()).append("' on '");
 525  
         } else {
 526  0
             title.append("Adding Delegation Rule '").append(delegateRule.getDescription()).append("' to '");
 527  
         }
 528  0
         title.append(parentRule.getDescription()).append("'");
 529  0
         return title.toString();
 530  
     }
 531  
 
 532  
     public void validate(RuleBaseValues ruleBaseValues, List errors) {
 533  0
         if (errors == null) {
 534  0
             errors = new ArrayList();
 535  
         }
 536  0
         if (getDocumentTypeService().findByName(ruleBaseValues.getDocTypeName()) == null) {
 537  0
             errors.add(new WorkflowServiceErrorImpl("Document Type Invalid", "doctype.documenttypeservice.doctypename.required"));
 538  
         }
 539  0
         if (ruleBaseValues.getToDateValue().before(ruleBaseValues.getFromDateValue())) {
 540  0
             errors.add(new WorkflowServiceErrorImpl("From Date is later than to date", "routetemplate.ruleservice.daterange.fromafterto"));
 541  
         }
 542  0
         if (ruleBaseValues.getDescription() == null || ruleBaseValues.getDescription().equals("")) {
 543  0
             errors.add(new WorkflowServiceErrorImpl("Description is required", "routetemplate.ruleservice.description.required"));
 544  
         }
 545  0
         if (ruleBaseValues.getRuleResponsibilities().isEmpty()) {
 546  0
             errors.add(new WorkflowServiceErrorImpl("A responsibility is required", "routetemplate.ruleservice.responsibility.required"));
 547  
         } else {
 548  0
             for (Object element : ruleBaseValues.getRuleResponsibilities()) {
 549  0
                 RuleResponsibilityBo responsibility = (RuleResponsibilityBo) element;
 550  0
                 if (responsibility.getRuleResponsibilityName() != null && KewApiConstants.RULE_RESPONSIBILITY_GROUP_ID.equals(responsibility.getRuleResponsibilityType())) {
 551  0
                     if (getGroupService().getGroup(responsibility.getRuleResponsibilityName()) == null) {
 552  0
                         errors.add(new WorkflowServiceErrorImpl("Workgroup is invalid", "routetemplate.ruleservice.workgroup.invalid"));
 553  
                     }
 554  0
                 } else if (responsibility.getPrincipal() == null && responsibility.getRole() == null) {
 555  0
                     errors.add(new WorkflowServiceErrorImpl("User is invalid", "routetemplate.ruleservice.user.invalid"));
 556  
                 }
 557  0
             }
 558  
         }
 559  0
         if (!errors.isEmpty()) {
 560  0
             throw new WorkflowServiceErrorException("RuleBaseValues validation errors", errors);
 561  
         }
 562  0
     }
 563  
 
 564  
     public void validate2(RuleBaseValues ruleBaseValues, RuleDelegationBo ruleDelegation, List errors) {
 565  0
         if (errors == null) {
 566  0
             errors = new ArrayList();
 567  
         }
 568  0
         if (getDocumentTypeService().findByName(ruleBaseValues.getDocTypeName()) == null) {
 569  0
             errors.add(new WorkflowServiceErrorImpl("Document Type Invalid", "doctype.documenttypeservice.doctypename.required"));
 570  0
             LOG.error("Document Type Invalid");
 571  
         }
 572  0
         if (ruleBaseValues.getToDateValue() == null) {
 573  
             try {
 574  0
                 ruleBaseValues.setToDateValue(new Timestamp(RiceConstants.getDefaultDateFormat().parse("01/01/2100")
 575  
                         .getTime()));
 576  0
             } catch (ParseException e) {
 577  0
                 LOG.error("Error date-parsing default date");
 578  0
                 throw new WorkflowServiceErrorException("Error parsing default date.", e);
 579  0
             }
 580  
         }
 581  0
         if (ruleBaseValues.getFromDateValue() == null) {
 582  0
             ruleBaseValues.setFromDateValue(new Timestamp(System.currentTimeMillis()));
 583  
         }
 584  0
         if (ruleBaseValues.getToDateValue().before(ruleBaseValues.getFromDateValue())) {
 585  0
             errors.add(new WorkflowServiceErrorImpl("From Date is later than to date", "routetemplate.ruleservice.daterange.fromafterto"));
 586  0
             LOG.error("From Date is later than to date");
 587  
         }
 588  0
         if (ruleBaseValues.getDescription() == null || ruleBaseValues.getDescription().equals("")) {
 589  0
             errors.add(new WorkflowServiceErrorImpl("Description is required", "routetemplate.ruleservice.description.required"));
 590  0
             LOG.error("Description is missing");
 591  
         }
 592  
 
 593  0
         for (Object element : ruleBaseValues.getRuleResponsibilities()) {
 594  0
             RuleResponsibilityBo responsibility = (RuleResponsibilityBo) element;
 595  0
             if (responsibility.getRuleResponsibilityName() != null && KewApiConstants.RULE_RESPONSIBILITY_GROUP_ID.equals(responsibility.getRuleResponsibilityType())) {
 596  0
                 if (getGroupService().getGroup(responsibility.getRuleResponsibilityName()) == null) {
 597  0
                     errors.add(new WorkflowServiceErrorImpl("Workgroup is invalid", "routetemplate.ruleservice.workgroup.invalid"));
 598  0
                     LOG.error("Workgroup is invalid");
 599  
                 }
 600  0
             } else if (responsibility.getPrincipal() == null && responsibility.getRole() == null) {
 601  0
                 errors.add(new WorkflowServiceErrorImpl("User is invalid", "routetemplate.ruleservice.user.invalid"));
 602  0
                 LOG.error("User is invalid");
 603  0
             } else if (responsibility.isUsingRole()) {
 604  0
                 if (responsibility.getApprovePolicy() == null || !(responsibility.getApprovePolicy().equals(ActionRequestPolicy.ALL.getCode()) || responsibility.getApprovePolicy().equals(ActionRequestPolicy.FIRST.getCode()))) {
 605  0
                     errors.add(new WorkflowServiceErrorImpl("Approve Policy is Invalid", "routetemplate.ruleservice.approve.policy.invalid"));
 606  0
                     LOG.error("Approve Policy is Invalid");
 607  
                 }
 608  
             }
 609  0
         }
 610  
 
 611  0
         if (ruleBaseValues.getRuleTemplate() != null) {
 612  0
             for (Object element : ruleBaseValues.getRuleTemplate().getActiveRuleTemplateAttributes()) {
 613  0
                 RuleTemplateAttributeBo templateAttribute = (RuleTemplateAttributeBo) element;
 614  0
                 if (!templateAttribute.isRuleValidationAttribute()) {
 615  0
                     continue;
 616  
                 }
 617  0
                 RuleValidationAttribute attribute = templateAttribute.getRuleValidationAttribute();
 618  0
                 UserSession userSession = GlobalVariables.getUserSession();
 619  
                 try {
 620  0
                     RuleValidationContext validationContext = RuleValidationContext.Builder.create(RuleBaseValues.to(ruleBaseValues), RuleDelegationBo
 621  
                             .to(ruleDelegation), userSession.getPrincipalId()).build();
 622  0
                     ValidationResults results = attribute.validate(validationContext);
 623  0
                     if (results != null && !results.getErrors().isEmpty()) {
 624  0
                         errors.add(results);
 625  
                     }
 626  0
                 } catch (Exception e) {
 627  0
                     if (e instanceof RuntimeException) {
 628  0
                         throw (RuntimeException)e;
 629  
                     }
 630  0
                     throw new RuntimeException("Problem validation rule.", e);
 631  0
                 }
 632  
 
 633  0
             }
 634  
         }
 635  0
         if (ruleBaseValues.getRuleExpressionDef() != null) {
 636  
             // rule expressions do not require parse-/save-time validation
 637  
         }
 638  
 
 639  0
         if (!errors.isEmpty()) {
 640  0
             throw new WorkflowServiceErrorException("RuleBaseValues validation errors", errors);
 641  
         }
 642  0
     }
 643  
 
 644  
     public List<RuleBaseValues> findByDocumentId(String documentId) {
 645  0
         return getRuleDAO().findByDocumentId(documentId);
 646  
     }
 647  
 
 648  
     public List<RuleBaseValues> search(String docTypeName, String ruleId, String ruleTemplateId, String ruleDescription, String groupId, String principalId,
 649  
             Boolean delegateRule, Boolean activeInd, Map extensionValues, String workflowIdDirective) {
 650  0
         return getRuleDAO().search(docTypeName, ruleId, ruleTemplateId, ruleDescription, groupId, principalId, delegateRule,
 651  
                 activeInd, extensionValues, workflowIdDirective);
 652  
     }
 653  
 
 654  
     public List<RuleBaseValues> searchByTemplate(String docTypeName, String ruleTemplateName, String ruleDescription, String groupId, String principalId,
 655  
             Boolean workgroupMember, Boolean delegateRule, Boolean activeInd, Map extensionValues, Collection<String> actionRequestCodes) {
 656  
 
 657  0
         if ( (StringUtils.isEmpty(docTypeName)) &&
 658  
                 (StringUtils.isEmpty(ruleTemplateName)) &&
 659  
                 (StringUtils.isEmpty(ruleDescription)) &&
 660  
                 (StringUtils.isEmpty(groupId)) &&
 661  
                 (StringUtils.isEmpty(principalId)) &&
 662  
                 (extensionValues.isEmpty()) &&
 663  
                 (actionRequestCodes.isEmpty()) ) {
 664  
             // all fields are empty
 665  0
             throw new IllegalArgumentException("At least one criterion must be sent");
 666  
         }
 667  
 
 668  0
         RuleTemplateBo ruleTemplate = getRuleTemplateService().findByRuleTemplateName(ruleTemplateName);
 669  0
         String ruleTemplateId = null;
 670  0
         if (ruleTemplate != null) {
 671  0
             ruleTemplateId = ruleTemplate.getId();
 672  
         }
 673  
 
 674  0
         if ( ( (extensionValues != null) && (!extensionValues.isEmpty()) ) &&
 675  
                 (ruleTemplateId == null) ) {
 676  
             // cannot have extensions without a correct template
 677  0
             throw new IllegalArgumentException("A Rule Template Name must be given if using Rule Extension values");
 678  
         }
 679  
 
 680  0
         Collection<String> workgroupIds = new ArrayList<String>();
 681  0
         if (principalId != null) {
 682  0
             KEWServiceLocator.getIdentityHelperService().validatePrincipalId(principalId);
 683  0
             if ( (workgroupMember == null) || (workgroupMember.booleanValue()) ) {
 684  0
                         workgroupIds = getGroupService().getGroupIdsByPrincipalId(principalId);
 685  
                 } else {
 686  
                         // user was passed but workgroups should not be parsed... do nothing
 687  
                 }
 688  0
         } else if (groupId != null) {
 689  0
                 Group group = KEWServiceLocator.getIdentityHelperService().getGroup(groupId);
 690  0
                 if (group == null) {
 691  0
                         throw new IllegalArgumentException("Group does not exist in for given group id: " + groupId);
 692  
                 } else  {
 693  0
                         workgroupIds.add(group.getId());
 694  
                 }
 695  
         }
 696  
 
 697  0
         return getRuleDAO().search(docTypeName, ruleTemplateId, ruleDescription, workgroupIds, principalId,
 698  
                 delegateRule,activeInd, extensionValues, actionRequestCodes);
 699  
     }
 700  
 
 701  
     public void delete(String ruleBaseValuesId) {
 702  0
         getRuleDAO().delete(ruleBaseValuesId);
 703  0
     }
 704  
 
 705  
     public RuleBaseValues findRuleBaseValuesById(String ruleBaseValuesId) {
 706  0
         return getRuleDAO().findRuleBaseValuesById(ruleBaseValuesId);
 707  
     }
 708  
 
 709  
     public RuleResponsibilityBo findRuleResponsibility(String responsibilityId) {
 710  0
         return getRuleDAO().findRuleResponsibility(responsibilityId);
 711  
     }
 712  
 
 713  
     public List fetchAllCurrentRulesForTemplateDocCombination(String ruleTemplateName, String documentType) {
 714  0
                 String ruleTemplateId = getRuleTemplateService().findByRuleTemplateName(ruleTemplateName).getId();
 715  0
             return getRuleDAO().fetchAllCurrentRulesForTemplateDocCombination(ruleTemplateId, getDocGroupAndTypeList(documentType));
 716  
     }
 717  
 
 718  
     public List fetchAllCurrentRulesForTemplateDocCombination(String ruleTemplateName, String documentType, Timestamp effectiveDate){
 719  0
         String ruleTemplateId = getRuleTemplateService().findByRuleTemplateName(ruleTemplateName).getId();
 720  0
         PerformanceLogger performanceLogger = new PerformanceLogger();
 721  0
         performanceLogger.log("Time to fetchRules by template " + ruleTemplateName + " not caching.");
 722  0
         return getRuleDAO().fetchAllCurrentRulesForTemplateDocCombination(ruleTemplateId, getDocGroupAndTypeList(documentType), effectiveDate);
 723  
     }
 724  
     public List fetchAllRules(boolean currentRules) {
 725  0
         return getRuleDAO().fetchAllRules(currentRules);
 726  
     }
 727  
 
 728  
     private List getDocGroupAndTypeList(String documentType) {
 729  0
         List docTypeList = new ArrayList();
 730  0
         DocumentTypeService docTypeService = (DocumentTypeService) KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_TYPE_SERVICE);
 731  0
         DocumentType docType = docTypeService.findByName(documentType);
 732  0
         while (docType != null) {
 733  0
             docTypeList.add(docType.getName());
 734  0
             docType = docType.getParentDocType();
 735  
         }
 736  0
         return docTypeList;
 737  
     }
 738  
 
 739  
     private Integer getNextVersionNumber(RuleBaseValues currentRule) {
 740  0
         List candidates = new ArrayList();
 741  0
         candidates.add(currentRule.getVersionNbr());
 742  0
         List pendingRules = ruleDAO.findByPreviousRuleId(currentRule.getId());
 743  0
         for (Iterator iterator = pendingRules.iterator(); iterator.hasNext();) {
 744  0
             RuleBaseValues pendingRule = (RuleBaseValues) iterator.next();
 745  0
             candidates.add(pendingRule.getVersionNbr());
 746  0
         }
 747  0
         Collections.sort(candidates);
 748  0
         Integer maxVersionNumber = (Integer) candidates.get(candidates.size() - 1);
 749  0
         if (maxVersionNumber == null) {
 750  0
             return Integer.valueOf(0);
 751  
         }
 752  0
         return Integer.valueOf(maxVersionNumber.intValue() + 1);
 753  
     }
 754  
 
 755  
     /**
 756  
      * Determines if the given rule is locked for routing.
 757  
      *
 758  
      * In the case of a root rule edit, this method will take the rule id of the rule being edited.
 759  
      *
 760  
      * In the case of a new delegate rule or a delegate rule edit, this method will take the id of it's parent.
 761  
      */
 762  
     public String isLockedForRouting(String currentRuleBaseValuesId) {
 763  
         // checks for any other versions of the given rule, essentially, if this is a rule edit we want to see how many other
 764  
         // pending edits are out there
 765  0
         List pendingRules = ruleDAO.findByPreviousRuleId(currentRuleBaseValuesId);
 766  0
         boolean isDead = true;
 767  0
         for (Iterator iterator = pendingRules.iterator(); iterator.hasNext();) {
 768  0
             RuleBaseValues pendingRule = (RuleBaseValues) iterator.next();
 769  
 
 770  0
             if (pendingRule.getDocumentId() != null && StringUtils.isNotBlank(pendingRule.getDocumentId())) {
 771  0
                 DocumentRouteHeaderValue routeHeader = getRouteHeaderService().getRouteHeader(pendingRule.getDocumentId());
 772  
                 // the pending edit is considered dead if it's been disapproved or cancelled and we are allowed to proceed with our own edit
 773  0
                 isDead = routeHeader.isDisaproved() || routeHeader.isCanceled();
 774  0
                 if (!isDead) {
 775  0
                     return pendingRule.getDocumentId();
 776  
                 }
 777  
             }
 778  
 
 779  0
             for (Object element : pendingRule.getRuleResponsibilities()) {
 780  0
                 RuleResponsibilityBo responsibility = (RuleResponsibilityBo) element;
 781  0
                 for (Object element2 : responsibility.getDelegationRules()) {
 782  0
                     RuleDelegationBo delegation = (RuleDelegationBo) element2;
 783  0
                     List pendingDelegateRules = ruleDAO.findByPreviousRuleId(delegation.getDelegationRule().getId());
 784  0
                     for (Iterator iterator3 = pendingDelegateRules.iterator(); iterator3.hasNext();) {
 785  0
                         RuleBaseValues pendingDelegateRule = (RuleBaseValues) iterator3.next();
 786  0
                         if (pendingDelegateRule.getDocumentId() != null && StringUtils.isNotBlank(pendingDelegateRule.getDocumentId())) {
 787  0
                             DocumentRouteHeaderValue routeHeader = getRouteHeaderService().getRouteHeader(pendingDelegateRule.getDocumentId());
 788  0
                             isDead = routeHeader.isDisaproved() || routeHeader.isCanceled();
 789  0
                             if (!isDead) {
 790  0
                                 return pendingDelegateRule.getDocumentId();
 791  
                             }
 792  
                         }
 793  0
                     }
 794  0
                 }
 795  0
             }
 796  0
         }
 797  0
         return null;
 798  
     }
 799  
 
 800  
     public RuleBaseValues getParentRule(RuleBaseValues rule) {
 801  0
         if (rule == null || rule.getId() == null) {
 802  0
             throw new IllegalArgumentException("Rule must be non-null with non-null id: " + rule);
 803  
         }
 804  0
         if (!Boolean.TRUE.equals(rule.getDelegateRule())) {
 805  0
             return null;
 806  
         }
 807  0
         return getRuleDAO().getParentRule(rule.getId());
 808  
     }
 809  
 
 810  
     /**
 811  
      * This configuration is currently stored in a system parameter named "CUSTOM_DOCUMENT_TYPES ",
 812  
      * long term we should come up with a better solution.  The format of this constant is a comma-separated
 813  
      * list of entries of the following form:
 814  
      *
 815  
      * <<name of doc type on rule>>:<<rule template name on rule>>:<<type of rule>>:<<name of document type to use for rule routing>>
 816  
      *
 817  
      * Rule type indicates either main or delegation rules.  A main rule is indicated by the character 'M' and a
 818  
      * delegate rule is indicated by the character 'D'.
 819  
      *
 820  
      * So, if you wanted to route "main" rules made for the "MyDocType" document with the rule template name
 821  
      * "MyRuleTemplate" using the "MyMainRuleDocType" doc type, it would be specified as follows:
 822  
      *
 823  
      * MyDocType:MyRuleTemplate:M:MyMainRuleDocType
 824  
      *
 825  
      * If you also wanted to route "delegate" rules made for the "MyDocType" document with rule template name
 826  
      * "MyDelegateTemplate" using the "MyDelegateRuleDocType", you would then set the constant as follows:
 827  
      *
 828  
      * MyDocType:MyRuleTemplate:M:MyMainRuleDocType,MyDocType:MyDelegateTemplate:D:MyDelegateRuleDocType
 829  
      *
 830  
      * TODO this method ended up being a mess, we should get rid of this as soon as we can
 831  
      */
 832  
     public String getRuleDocumentTypeName(List rules) {
 833  0
         if (rules.size() == 0) {
 834  0
             throw new IllegalArgumentException("Cannot determine rule DocumentType for an empty list of rules.");
 835  
         }
 836  0
         String ruleDocTypeName = null;
 837  0
         RuleRoutingConfig config = RuleRoutingConfig.parse();
 838  
         // There are 2 cases here
 839  0
         RuleBaseValues firstRule = (RuleBaseValues)rules.get(0);
 840  0
         if (Boolean.TRUE.equals(firstRule.getDelegateRule())) {
 841  
             // if it's a delegate rule then the list will contain only 2 elements, the first is the delegate rule,
 842  
             // the second is the parent rule.  In this case just look at the custom routing process for the delegate rule.
 843  0
             ruleDocTypeName = config.getDocumentTypeName(firstRule);
 844  
         } else {
 845  
             // if this is a list of parent rules being routed, look at all configued routing types and verify that they are
 846  
             // all the same, if not throw an exception
 847  0
             String parentRulesDocTypeName = null;
 848  0
             for (Iterator iterator = rules.iterator(); iterator.hasNext();) {
 849  0
                 RuleBaseValues rule = (RuleBaseValues) iterator.next();
 850  
                 // if it's a delegate rule just skip it
 851  0
                 if  (Boolean.TRUE.equals(rule.getDelegateRule())) {
 852  0
                     continue;
 853  
                 }
 854  0
                 String currentDocTypeName = config.getDocumentTypeName(rule);
 855  0
                 if (parentRulesDocTypeName == null) {
 856  0
                     parentRulesDocTypeName = currentDocTypeName;
 857  
                 } else {
 858  0
                     if (!ObjectUtils.equals(currentDocTypeName, parentRulesDocTypeName)) {
 859  0
                         throw new RuntimeException("There are multiple rules being routed and they have different document type definitions!  " + parentRulesDocTypeName + " and " + currentDocTypeName);
 860  
                     }
 861  
                 }
 862  0
             }
 863  0
             ruleDocTypeName = parentRulesDocTypeName;
 864  
         }
 865  0
         if (ruleDocTypeName == null) {
 866  0
             ruleDocTypeName = KewApiConstants.DEFAULT_RULE_DOCUMENT_NAME;
 867  
         }
 868  0
         return ruleDocTypeName;
 869  
     }
 870  
 
 871  
     public void setRuleDAO(RuleDAO ruleDAO) {
 872  0
         this.ruleDAO = ruleDAO;
 873  0
     }
 874  
 
 875  
     public RuleDAO getRuleDAO() {
 876  0
         return ruleDAO;
 877  
     }
 878  
 
 879  
     public void deleteRuleResponsibilityById(String ruleResponsibilityId) {
 880  0
         getRuleResponsibilityDAO().delete(ruleResponsibilityId);
 881  0
     }
 882  
 
 883  
     public RuleResponsibilityBo findByRuleResponsibilityId(String ruleResponsibilityId) {
 884  0
         return getRuleResponsibilityDAO().findByRuleResponsibilityId(ruleResponsibilityId);
 885  
     }
 886  
 
 887  
     public List findRuleBaseValuesByResponsibilityReviewer(String reviewerName, String type) {
 888  0
         return getRuleDAO().findRuleBaseValuesByResponsibilityReviewer(reviewerName, type);
 889  
     }
 890  
 
 891  
     public List findRuleBaseValuesByResponsibilityReviewerTemplateDoc(String ruleTemplateName, String documentType, String reviewerName, String type) {
 892  0
         return getRuleDAO().findRuleBaseValuesByResponsibilityReviewerTemplateDoc(ruleTemplateName, documentType, reviewerName, type);
 893  
     }
 894  
 
 895  
     public RuleTemplateService getRuleTemplateService() {
 896  0
         return (RuleTemplateService) KEWServiceLocator.getService(KEWServiceLocator.RULE_TEMPLATE_SERVICE);
 897  
     }
 898  
 
 899  
     public DocumentTypeService getDocumentTypeService() {
 900  0
         return (DocumentTypeService) KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_TYPE_SERVICE);
 901  
     }
 902  
 
 903  
     public GroupService getGroupService() {
 904  0
         return KimApiServiceLocator.getGroupService();
 905  
     }
 906  
 
 907  
     public ActionRequestService getActionRequestService() {
 908  0
         return (ActionRequestService) KEWServiceLocator.getService(KEWServiceLocator.ACTION_REQUEST_SRV);
 909  
     }
 910  
 
 911  
     private ResponsibilityIdService getResponsibilityIdService() {
 912  0
         return (ResponsibilityIdService) KEWServiceLocator.getService(KEWServiceLocator.RESPONSIBILITY_ID_SERVICE);
 913  
     }
 914  
 
 915  
     private RuleDelegationService getRuleDelegationService() {
 916  0
         return (RuleDelegationService) KEWServiceLocator.getService(KEWServiceLocator.RULE_DELEGATION_SERVICE);
 917  
     }
 918  
 
 919  
     private RouteHeaderService getRouteHeaderService() {
 920  0
         return (RouteHeaderService) KEWServiceLocator.getService(KEWServiceLocator.DOC_ROUTE_HEADER_SRV);
 921  
     }
 922  
 
 923  
     /**
 924  
      * A comparator implementation which compares RuleBaseValues and puts all delegate rules first.
 925  
      */
 926  0
     public class RuleDelegationSorter implements Comparator {
 927  
         public int compare(Object arg0, Object arg1) {
 928  0
             RuleBaseValues rule1 = (RuleBaseValues) arg0;
 929  0
             RuleBaseValues rule2 = (RuleBaseValues) arg1;
 930  
 
 931  0
             Integer rule1Value = new Integer((rule1.getDelegateRule().booleanValue() ? 0 : 1));
 932  0
             Integer rule2Value = new Integer((rule2.getDelegateRule().booleanValue() ? 0 : 1));
 933  0
             int value = rule1Value.compareTo(rule2Value);
 934  0
             return value;
 935  
         }
 936  
     }
 937  
 
 938  
 
 939  
     public void loadXml(InputStream inputStream, String principalId) {
 940  0
         RuleXmlParser parser = new RuleXmlParser();
 941  
         try {
 942  0
             parser.parseRules(inputStream);
 943  0
         } catch (Exception e) { //any other exception
 944  0
             LOG.error("Error loading xml file", e);
 945  0
             WorkflowServiceErrorException wsee = new WorkflowServiceErrorException("Error loading xml file", new WorkflowServiceErrorImpl("Error loading xml file", XML_PARSE_ERROR));
 946  0
             wsee.initCause(e);
 947  0
             throw wsee;
 948  0
         }
 949  0
     }
 950  
 
 951  
     public Element export(ExportDataSet dataSet) {
 952  0
         RuleXmlExporter exporter = new RuleXmlExporter(XmlConstants.RULE_NAMESPACE);
 953  0
         return exporter.export(dataSet);
 954  
     }
 955  
     
 956  
     @Override
 957  
         public boolean supportPrettyPrint() {
 958  0
                 return true;
 959  
         }
 960  
 
 961  
     protected List<RuleBaseValues> loadRules(List<String> ruleIds) {
 962  0
         List<RuleBaseValues> rules = new ArrayList<RuleBaseValues>();
 963  0
         for (String ruleId : ruleIds) {
 964  0
             RuleBaseValues rule = KEWServiceLocator.getRuleService().findRuleBaseValuesById(ruleId);
 965  0
             rules.add(rule);
 966  0
         }
 967  0
         return rules;
 968  
     }
 969  
 
 970  
     /**
 971  
      * If a rule has been modified and is no longer current since the original request was made, we need to
 972  
      * be sure to NOT update the rule.
 973  
      */
 974  
     protected boolean shouldChangeRuleInvolvement(String documentId, RuleBaseValues rule) {
 975  0
         if (!rule.getCurrentInd()) {
 976  0
             LOG.warn("Rule requested for rule involvement change by document " + documentId + " is no longer current.  Change will not be executed!  Rule id is: " + rule.getId());
 977  0
             return false;
 978  
         }
 979  0
         String lockingDocumentId = KEWServiceLocator.getRuleService().isLockedForRouting(rule.getId());
 980  0
         if (lockingDocumentId != null) {
 981  0
             LOG.warn("Rule requested for rule involvement change by document " + documentId + " is locked by document " + lockingDocumentId + " and cannot be modified.  " +
 982  
                     "Change will not be executed!  Rule id is: " + rule.getId());
 983  0
             return false;
 984  
         }
 985  0
         return true;
 986  
     }
 987  
 
 988  
     protected RuleDelegationBo getRuleDelegationForDelegateRule(RuleBaseValues rule) {
 989  0
         if (Boolean.TRUE.equals(rule.getDelegateRule())) {
 990  0
             List delegations = getRuleDelegationService().findByDelegateRuleId(rule.getId());
 991  0
             for (Iterator iterator = delegations.iterator(); iterator.hasNext();) {
 992  0
                 RuleDelegationBo ruleDelegation = (RuleDelegationBo) iterator.next();
 993  0
                 RuleBaseValues parentRule = ruleDelegation.getRuleResponsibility().getRuleBaseValues();
 994  0
                 if (Boolean.TRUE.equals(parentRule.getCurrentInd())) {
 995  0
                     return ruleDelegation;
 996  
                 }
 997  0
             }
 998  
         }
 999  0
         return null;
 1000  
     }
 1001  
 
 1002  
     protected void hookUpDelegateRuleToParentRule(RuleBaseValues newParentRule, RuleBaseValues newDelegationRule, RuleDelegationBo existingRuleDelegation) {
 1003  
         // hook up parent rule to new rule delegation
 1004  0
         boolean foundDelegation = false;
 1005  0
         outer:for (RuleResponsibilityBo responsibility : (List<RuleResponsibilityBo>)newParentRule.getRuleResponsibilities()) {
 1006  0
             for (RuleDelegationBo ruleDelegation : (List<RuleDelegationBo>)responsibility.getDelegationRules()) {
 1007  0
                 if (ruleDelegation.getDelegationRule().getId().equals(existingRuleDelegation.getDelegationRule().getId())) {
 1008  0
                     ruleDelegation.setDelegationRule(newDelegationRule);
 1009  0
                     foundDelegation = true;
 1010  0
                     break outer;
 1011  
                 }
 1012  
             }
 1013  
         }
 1014  0
         if (!foundDelegation) {
 1015  0
             throw new WorkflowRuntimeException("Failed to locate the existing rule delegation with id: " + existingRuleDelegation.getDelegationRule().getId());
 1016  
         }
 1017  
 
 1018  0
     }
 1019  
 
 1020  
     protected RuleBaseValues createNewRuleVersion(RuleBaseValues existingRule, String documentId) throws Exception {
 1021  0
         RuleBaseValues rule = new RuleBaseValues();
 1022  0
         PropertyUtils.copyProperties(rule, existingRule);
 1023  0
         rule.setPreviousVersion(existingRule);
 1024  0
         rule.setPreviousRuleId(existingRule.getId());
 1025  0
         rule.setId(null);
 1026  0
         rule.setActivationDate(null);
 1027  0
         rule.setDeactivationDate(null);
 1028  0
         rule.setVersionNumber(0L);
 1029  0
         rule.setDocumentId(documentId);
 1030  
 
 1031  
         // TODO: FIXME: need to copy the rule expression here too?
 1032  
 
 1033  0
         rule.setRuleResponsibilities(new ArrayList());
 1034  0
         for (RuleResponsibilityBo existingResponsibility : (List<RuleResponsibilityBo>)existingRule.getRuleResponsibilities()) {
 1035  0
             RuleResponsibilityBo responsibility = new RuleResponsibilityBo();
 1036  0
             PropertyUtils.copyProperties(responsibility, existingResponsibility);
 1037  0
             responsibility.setRuleBaseValues(rule);
 1038  0
             responsibility.setRuleBaseValuesId(null);
 1039  0
             responsibility.setId(null);
 1040  0
             responsibility.setVersionNumber(0L);
 1041  0
             rule.getRuleResponsibilities().add(responsibility);
 1042  
 //            responsibility.setDelegationRules(new ArrayList());
 1043  
 //            for (RuleDelegation existingDelegation : (List<RuleDelegation>)existingResponsibility.getDelegationRules()) {
 1044  
 //                RuleDelegation delegation = new RuleDelegation();
 1045  
 //                PropertyUtils.copyProperties(delegation, existingDelegation);
 1046  
 //                delegation.setRuleDelegationId(null);
 1047  
 //                delegation.setRuleResponsibility(responsibility);
 1048  
 //                delegation.setRuleResponsibilityId(null);
 1049  
 //                delegation.setVersionNumber(0L);
 1050  
 //                // it's very important that we do NOT recurse down into the delegation rules and reversion those,
 1051  
 //                // this is important to how rule versioning works
 1052  
 //                responsibility.getDelegationRules().add(delegation);
 1053  
 //            }
 1054  0
         }
 1055  0
         rule.setRuleExtensions(new ArrayList());
 1056  0
         for (RuleExtensionBo existingExtension : (List<RuleExtensionBo>)existingRule.getRuleExtensions()) {
 1057  0
             RuleExtensionBo extension = new RuleExtensionBo();
 1058  0
             PropertyUtils.copyProperties(extension, existingExtension);
 1059  0
             extension.setVersionNumber(new Long(0));
 1060  0
             extension.setRuleBaseValues(rule);
 1061  0
             extension.setRuleBaseValuesId(null);
 1062  0
             extension.setRuleExtensionId(null);
 1063  0
             rule.getRuleExtensions().add(extension);
 1064  0
             extension.setExtensionValues(new ArrayList<RuleExtensionValue>());
 1065  0
             for (RuleExtensionValue existingExtensionValue : extension.getExtensionValues()) {
 1066  0
                 RuleExtensionValue extensionValue = new RuleExtensionValue();
 1067  0
                 PropertyUtils.copyProperties(extensionValue, existingExtensionValue);
 1068  0
                 extensionValue.setExtension(extension);
 1069  0
                 extensionValue.setRuleExtensionId(null);
 1070  0
                 extensionValue.setLockVerNbr(0);
 1071  0
                 extensionValue.setRuleExtensionValueId(null);
 1072  0
                 extension.getExtensionValues().add(extensionValue);
 1073  0
             }
 1074  0
         }
 1075  0
         return rule;
 1076  
     }
 1077  
 
 1078  0
     private static class RuleVersion {
 1079  
         public RuleBaseValues rule;
 1080  
         public RuleBaseValues parent;
 1081  
         public RuleDelegationBo delegation;
 1082  
     }
 1083  
 
 1084  0
     private static class RuleRoutingConfig {
 1085  0
         private List configs = new ArrayList();
 1086  
         public static RuleRoutingConfig parse() {
 1087  0
             RuleRoutingConfig config = new RuleRoutingConfig();
 1088  0
             String constant = CoreFrameworkServiceLocator.getParameterService().getParameterValueAsString(KewApiConstants.KEW_NAMESPACE, KRADConstants.DetailTypes.RULE_DETAIL_TYPE, KewApiConstants.RULE_CUSTOM_DOC_TYPES);
 1089  0
             if (!StringUtils.isEmpty(constant)) {
 1090  0
                 String[] ruleConfigs = constant.split(",");
 1091  0
                 for (String ruleConfig : ruleConfigs) {
 1092  0
                     String[] configElements = ruleConfig.split(":");
 1093  0
                     if (configElements.length != 4) {
 1094  0
                         throw new RuntimeException("Found incorrect number of config elements within a section of the custom rule document types config.  There should have been four ':' delimited sections!  " + ruleConfig);
 1095  
                     }
 1096  0
                     config.configs.add(configElements);
 1097  
                 }
 1098  
             }
 1099  0
             return config;
 1100  
         }
 1101  
         public String getDocumentTypeName(RuleBaseValues rule) {
 1102  0
             for (Iterator iterator = configs.iterator(); iterator.hasNext();) {
 1103  0
                 String[] configElements = (String[]) iterator.next();
 1104  0
                 String docTypeName = configElements[0];
 1105  0
                 String ruleTemplateName = configElements[1];
 1106  0
                 String type = configElements[2];
 1107  0
                 String ruleDocTypeName = configElements[3];
 1108  0
                 if (rule.getDocTypeName().equals(docTypeName) && rule.getRuleTemplateName().equals(ruleTemplateName)) {
 1109  0
                     if (type.equals("M")) {
 1110  0
                         if (Boolean.FALSE.equals(rule.getDelegateRule())) {
 1111  0
                             return ruleDocTypeName;
 1112  
                         }
 1113  0
                     } else if (type.equals("D")) {
 1114  0
                         if (Boolean.TRUE.equals(rule.getDelegateRule())) {
 1115  0
                             return ruleDocTypeName;
 1116  
                         }
 1117  
                     } else {
 1118  0
                         throw new RuntimeException("Bad rule type '" + type + "' in rule doc type routing config.");
 1119  
                     }
 1120  
                 }
 1121  0
             }
 1122  0
             return null;
 1123  
         }
 1124  
     }
 1125  
 
 1126  
     public String getDuplicateRuleId(RuleBaseValues rule) {
 1127  
 
 1128  
             // TODO: this method is extremely slow, if we could implement a more optimized query here, that would help tremendously
 1129  0
         Rule baseRule = RuleBaseValues.to(rule);
 1130  0
             List<RuleResponsibility> responsibilities = baseRule.getRuleResponsibilities();
 1131  0
             List<RuleExtension> extensions = baseRule.getRuleExtensions();
 1132  0
             String docTypeName = baseRule.getDocTypeName();
 1133  0
             String ruleTemplateName = baseRule.getRuleTemplateName();
 1134  
         //use api service to take advantage of caching
 1135  0
         List<Rule> rules = KewApiServiceLocator.getRuleService().getRulesByTemplateNameAndDocumentTypeName(
 1136  
                 ruleTemplateName, docTypeName);
 1137  0
         for (Rule r : rules) {
 1138  0
             if (ObjectUtils.equals(rule.isActive(), r.isActive()) &&
 1139  
                         ObjectUtils.equals(docTypeName, r.getDocTypeName()) &&
 1140  
                     ObjectUtils.equals(ruleTemplateName, r.getRuleTemplateName()) &&
 1141  
                     CollectionUtils.collectionsEquivalent(responsibilities, r.getRuleResponsibilities()) &&
 1142  
                     CollectionUtils.collectionsEquivalent(extensions, r.getRuleExtensions())) {
 1143  
 
 1144  0
                 if (ObjectUtils.equals(baseRule.getRuleExpressionDef(), r.getRuleExpressionDef()) ||
 1145  
                     (baseRule.getRuleExpressionDef() != null && r.getRuleExpressionDef() != null) &&
 1146  
                       ObjectUtils.equals(baseRule.getRuleExpressionDef().getType(), r.getRuleExpressionDef().getType()) &&
 1147  
                       ObjectUtils.equals(baseRule.getRuleExpressionDef().getExpression(), r.getRuleExpressionDef().getExpression())) {
 1148  
                 // we have a duplicate
 1149  0
                     return r.getId();
 1150  
                 }
 1151  
             }
 1152  
         }
 1153  0
         return null;
 1154  
     }
 1155  
 
 1156  
     private void generateRuleNameIfNeeded(RuleBaseValues rule) {
 1157  0
         if (StringUtils.isBlank(rule.getName())) {
 1158  0
                 rule.setName(UUID.randomUUID().toString());
 1159  
         }
 1160  0
     }
 1161  
 
 1162  
     private void assignResponsibilityIds(RuleBaseValues rule) {
 1163  0
             for (RuleResponsibilityBo responsibility : rule.getRuleResponsibilities()) {
 1164  0
                     if (responsibility.getResponsibilityId() == null) {
 1165  0
                             responsibility.setResponsibilityId(KEWServiceLocator.getResponsibilityIdService().getNewResponsibilityId());
 1166  
                     }
 1167  
             }
 1168  0
     }
 1169  
 
 1170  
     public RuleBaseValues saveRule(RuleBaseValues rule, boolean isRetroactiveUpdatePermitted) {
 1171  0
             rule.setPreviousRuleId(rule.getId());
 1172  0
                 rule.setPreviousVersion(null);
 1173  0
                 rule.setId(null);
 1174  0
                 makeCurrent(rule, isRetroactiveUpdatePermitted);
 1175  0
                 return rule;
 1176  
     }
 1177  
 
 1178  
     public List<RuleBaseValues> saveRules(List<RuleBaseValues> rulesToSave, boolean isRetroactiveUpdatePermitted) {
 1179  0
             List<RuleBaseValues> savedRules = new ArrayList<RuleBaseValues>();
 1180  0
             for (RuleBaseValues rule : rulesToSave) {
 1181  0
                     rule = saveRule(rule, isRetroactiveUpdatePermitted);
 1182  0
                     savedRules.add(rule);
 1183  
             }
 1184  0
             return savedRules;
 1185  
     }
 1186  
 
 1187  
     public RuleDelegationBo saveRuleDelegation(RuleDelegationBo ruleDelegation, boolean isRetroactiveUpdatePermitted) {
 1188  0
             RuleBaseValues rule = ruleDelegation.getDelegationRule();
 1189  0
                 rule.setPreviousRuleId(rule.getId());
 1190  0
                 rule.setPreviousVersion(null);
 1191  0
                 rule.setId(null);
 1192  0
                 ruleDelegation.setRuleDelegationId(null);
 1193  0
                 makeCurrent(ruleDelegation, isRetroactiveUpdatePermitted);
 1194  0
                 return ruleDelegation;
 1195  
     }
 1196  
 
 1197  
     public List<RuleDelegationBo> saveRuleDelegations(List<RuleDelegationBo> ruleDelegationsToSave, boolean isRetroactiveUpdatePermitted) {
 1198  0
             List<RuleDelegationBo> savedRuleDelegations = new ArrayList<RuleDelegationBo>();
 1199  0
             for (RuleDelegationBo ruleDelegation : ruleDelegationsToSave) {
 1200  0
                     ruleDelegation = saveRuleDelegation(ruleDelegation, isRetroactiveUpdatePermitted);
 1201  0
                     savedRuleDelegations.add(ruleDelegation);
 1202  
             }
 1203  0
             return savedRuleDelegations;
 1204  
     }
 1205  
 
 1206  
     public String findResponsibilityIdForRule(String ruleName, String ruleResponsibilityName, String ruleResponsibilityType) {
 1207  0
             return getRuleDAO().findResponsibilityIdForRule(ruleName, ruleResponsibilityName, ruleResponsibilityType);
 1208  
     }
 1209  
 
 1210  
     protected String getRuleByTemplateAndDocTypeCacheKey(String ruleTemplateName, String docTypeName) {
 1211  0
         return "'templateName=' + " + ruleTemplateName +" '|' + 'documentTypeName=' + " + docTypeName;
 1212  
     }
 1213  
 
 1214  
 }