コード例 #1
0
  /**
   * Tests that an exception is thrown if you try to execute a "route" command on an already routed
   * document.
   */
  @Test
  public void testRouteAlreadyRoutedDocument() throws Exception {
    WorkflowDocument document =
        WorkflowDocumentFactory.createDocument(getPrincipalIdForName("user1"), DOCUMENT_TYPE_NAME);
    document.route("");

    assertTrue("Document should be ENROUTE.", document.isEnroute());
    assertFalse("There should not be a request to ewestfal.", document.isApprovalRequested());

    // verify that only 1 action taken has been performed
    Collection<ActionTakenValue> actionTakens =
        KEWServiceLocator.getActionTakenService().findByDocumentId(document.getDocumentId());
    assertEquals("There should be only 1 action taken.", 1, actionTakens.size());

    // now try and route the document again, an exception should be thrown
    try {
      document.route("");
      fail("A WorkflowException should have been thrown.");
    } catch (InvalidActionTakenException e) {
      e.printStackTrace();
    }

    // verify that there is still only 1 action taken (the transaction above should have rolled
    // back)
    actionTakens =
        KEWServiceLocator.getActionTakenService().findByDocumentId(document.getDocumentId());
    assertEquals("There should still be only 1 action taken.", 1, actionTakens.size());
  }
コード例 #2
0
  private RuleTemplateBo parseRuleTemplate(Element element, List<RuleTemplateBo> ruleTemplates)
      throws XmlException {
    String name = element.getChildText(NAME, RULE_TEMPLATE_NAMESPACE);
    String description = element.getChildText(DESCRIPTION, RULE_TEMPLATE_NAMESPACE);
    Attribute allowOverwriteAttrib = element.getAttribute("allowOverwrite");

    boolean allowOverwrite = false;
    if (allowOverwriteAttrib != null) {
      allowOverwrite = Boolean.valueOf(allowOverwriteAttrib.getValue()).booleanValue();
    }
    if (org.apache.commons.lang.StringUtils.isEmpty(name)) {
      throw new XmlException("RuleTemplate must have a name");
    }
    if (org.apache.commons.lang.StringUtils.isEmpty(description)) {
      throw new XmlException("RuleTemplate must have a description");
    }

    // look up the rule template by name first
    RuleTemplateBo ruleTemplate =
        KEWServiceLocator.getRuleTemplateService().findByRuleTemplateName(name);

    if (ruleTemplate == null) {
      // if it does not exist create a new one
      ruleTemplate = new RuleTemplateBo();
    } else {
      // if it does exist, update it, only if allowOverwrite is set
      if (!allowOverwrite) {
        throw new RuntimeException(
            "Attempting to overwrite template " + name + " without allowOverwrite set");
      }

      // the name should be equal if one was actually found
      assert (name.equals(ruleTemplate.getName()))
          : "Existing template definition name does not match incoming definition name";
    }

    // overwrite simple properties
    ruleTemplate.setName(name);
    ruleTemplate.setDescription(description);

    // update the delegation template
    updateDelegationTemplate(element, ruleTemplate, ruleTemplates);

    // update the attribute relationships
    updateRuleTemplateAttributes(element, ruleTemplate);

    // save the rule template first so that the default/template rule that is generated
    // in the process of setting defaults is associated properly with this rule template
    ruleTemplate = KEWServiceLocator.getRuleTemplateService().save(ruleTemplate);

    // update the default options
    updateRuleTemplateDefaultOptions(element, ruleTemplate);

    ruleTemplate = KEWServiceLocator.getRuleTemplateService().save(ruleTemplate);

    return ruleTemplate;
  }
コード例 #3
0
  /** This method converts everything except for the parent and child requests */
  private static void populateActionRequest(
      ActionRequestValue actionRequestBo,
      ActionRequest actionRequest,
      RouteNodeInstanceLoader routeNodeInstanceLoader) {

    actionRequestBo.setActionRequested(actionRequest.getActionRequested().getCode());
    if (!StringUtils.isBlank(actionRequest.getId())) {
      actionRequestBo.setActionRequestId(actionRequest.getId());
    }

    if (actionRequest.getActionTaken() != null) {
      // actionRequestBo.setActionTaken(ActionTakenValue.from(actionRequest.getActionTaken()));
      if (!StringUtils.isBlank(actionRequest.getActionTaken().getId())) {
        actionRequestBo.setActionTaken(
            KEWServiceLocator.getActionTakenService()
                .findByActionTakenId(actionRequest.getActionTaken().getId()));
      }
    }
    actionRequestBo.setAnnotation(actionRequest.getAnnotation());
    if (actionRequest.getRequestPolicy() != null) {
      actionRequestBo.setApprovePolicy(actionRequest.getRequestPolicy().getCode());
    }
    actionRequestBo.setCreateDate(new Timestamp(actionRequest.getDateCreated().getMillis()));
    actionRequestBo.setCurrentIndicator(actionRequest.isCurrent());
    if (actionRequest.getDelegationType() != null) {
      actionRequestBo.setDelegationType(actionRequest.getDelegationType());
    }
    // actionRequestBo.setDocVersion(actionRequest.?);
    actionRequestBo.setForceAction(actionRequest.isForceAction());
    actionRequestBo.setPriority(actionRequest.getPriority());
    actionRequestBo.setRouteLevel(actionRequest.getRouteLevel());
    actionRequestBo.setQualifiedRoleName(actionRequest.getQualifiedRoleName());
    actionRequestBo.setQualifiedRoleNameLabel(actionRequest.getQualifiedRoleNameLabel());
    actionRequestBo.setRecipientTypeCd(actionRequest.getRecipientType().getCode());
    actionRequestBo.setResponsibilityDesc(actionRequest.getResponsibilityDescription());
    if (!StringUtils.isBlank(actionRequest.getResponsibilityId())) {
      actionRequestBo.setResponsibilityId(actionRequest.getResponsibilityId());
    }
    actionRequestBo.setRoleName(actionRequest.getRoleName());
    String documentId = actionRequest.getDocumentId();
    if (documentId != null) {
      actionRequestBo.setDocumentId(documentId);
      actionRequestBo.setRouteHeader(
          KEWServiceLocator.getRouteHeaderService().getRouteHeader(documentId));
    }

    actionRequestBo.setStatus(actionRequest.getStatus().getCode());
    actionRequestBo.setPrincipalId(actionRequest.getPrincipalId());
    actionRequestBo.setGroupId(actionRequest.getGroupId());

    if (routeNodeInstanceLoader != null
        && !StringUtils.isBlank(actionRequest.getRouteNodeInstanceId())) {
      actionRequestBo.setNodeInstance(
          routeNodeInstanceLoader.load(actionRequest.getRouteNodeInstanceId()));
    }
  }
コード例 #4
0
 /* (non-Javadoc)
  * @see org.kuali.rice.kew.actions.ActionTakenEvent#isActionCompatibleRequest(java.util.List)
  */
 @Override
 public String validateActionRules() {
   return validateActionRules(
       getActionRequestService().findAllPendingRequests(routeHeader.getDocumentId()),
       KEWServiceLocator.getRouteNodeService()
           .getActiveRouteNodeNames(getRouteHeader().getDocumentId()));
 }
コード例 #5
0
  /**
   * verifies that rule exports are the same regardless of whether the rule is ready for render, or
   * for persistance.
   */
  protected void assertRuleBaseValuesStateIndependence() throws Exception {
    for (Object o : KEWServiceLocator.getRuleService().fetchAllRules(true)) {
      RuleBaseValues rule = (RuleBaseValues) o;
      KewExportDataSet dataSet = new KewExportDataSet();
      dataSet.getRules().add(rule);

      // first, do a conversion in the just-loaded state:
      byte[] saveXmlBytes =
          CoreApiServiceLocator.getXmlExporterService().export(dataSet.createExportDataSet());
      String saveStr = new String(saveXmlBytes);

      // now, convert for render:
      WebRuleUtils.populateRuleMaintenanceFields(rule);

      // do another conversion in the ready-for-render state:
      byte[] loadXmlBytes =
          CoreApiServiceLocator.getXmlExporterService().export(dataSet.createExportDataSet());
      String loadStr = new String(loadXmlBytes);

      // check that the results are identical:
      assertTrue(
          "The load/render state of the RuleBaseValues shouldn't effect the export: \n"
              + saveStr
              + "\n\n != \n\n"
              + loadStr,
          StringUtils.equals(saveStr, loadStr));
    }
  }
コード例 #6
0
  /**
   * Tests that an exception is not thrown if you try to execute a "route" command on a document you
   * did not initiate.
   */
  @Test
  public void testRouteDocumentAsNonInitiatorUser() throws Exception {
    WorkflowDocument firstDocument =
        WorkflowDocumentFactory.createDocument(
            getPrincipalIdForName("user1"), DOCUMENT_TYPE_POLICY_TEST_NAME);
    WorkflowDocument document =
        WorkflowDocumentFactory.loadDocument(
            getPrincipalIdForName("user2"), firstDocument.getDocumentId());
    try {
      document.route("");
    } catch (Exception e) {
      e.printStackTrace();
      fail(
          "Exception thrown but should not have have been... Exception was of type "
              + e.getClass().getName()
              + " and message was "
              + e.getMessage());
    }
    document =
        WorkflowDocumentFactory.loadDocument(
            getPrincipalIdForName("user1"), firstDocument.getDocumentId());
    assertEquals(
        "Document should be in Enroute status.", DocumentStatus.ENROUTE, document.getStatus());

    // verify that there is 1 action taken
    Collection<ActionTakenValue> actionTakens =
        KEWServiceLocator.getActionTakenService().findByDocumentId(document.getDocumentId());
    assertEquals("There should be 1 action taken.", 1, actionTakens.size());
  }
コード例 #7
0
 @Override
 public String validateActionRules(List<ActionRequestValue> actionRequests) {
   return validateActionRules(
       actionRequests,
       KEWServiceLocator.getRouteNodeService()
           .getActiveRouteNodeNames(getRouteHeader().getDocumentId()));
 }
コード例 #8
0
  /** Clears out KIM cache by calling flush methods on role and identity services */
  protected void clearKIMCache() {
    LOG.info("clearing KIM role & identity service cache ...");

    roleManagementService.flushRoleCaches();
    identityManagementService.flushAllCaches();
    KEWServiceLocator.getCacheAdministrator().flushGroup("ResponsibilityImpl");
  }
コード例 #9
0
  @Override
  public List<String> buildListForFYI(AwardDocument awardDocument) throws WorkflowException {

    WorkflowDocument document = awardDocument.getDocumentHeader().getWorkflowDocument();
    RoutingReportCriteria reportCriteria =
        RoutingReportCriteria.Builder.createByDocumentId(document.getDocumentId()).build();
    // gather the IDs for action requests that predate the simulation
    DocumentRouteHeaderValue routeHeader =
        KEWServiceLocator.getRouteHeaderService().getRouteHeader(document.getDocumentId());
    Set<String> preexistingActionRequestIds = getActionRequestIds(routeHeader);

    // run the simulation via WorkflowUtility
    DocumentDetail documentDetail = workflowUtility.executeSimulation(reportCriteria);

    // fabricate our ActionRequestValueS from the results
    List<ActionRequestValue> actionRequests =
        reconstituteActionRequestValues(documentDetail, preexistingActionRequestIds);

    List<String> actionIds = new ArrayList<String>();
    for (ActionRequestValue request : actionRequests) {
      if (request.isGroupRequest()) {
        actionIds.addAll(
            KimApiServiceLocator.getGroupService().getMemberPrincipalIds(request.getGroupId()));
      }
      if (request.isUserRequest()) {
        actionIds.add(request.getPrincipalId());
      }
    }
    return actionIds;
  }
コード例 #10
0
 /**
  * Parses a rule template attribute
  *
  * @param element the attribute XML element
  * @param ruleTemplate the ruleTemplate to update
  * @return a parsed rule template attribute
  * @throws XmlException if the attribute does not exist
  */
 private RuleTemplateAttributeBo parseRuleTemplateAttribute(
     Element element, RuleTemplateBo ruleTemplate) throws XmlException {
   String attributeName = element.getChildText(NAME, RULE_TEMPLATE_NAMESPACE);
   String requiredValue = element.getChildText(REQUIRED, RULE_TEMPLATE_NAMESPACE);
   String activeValue = element.getChildText(ACTIVE, RULE_TEMPLATE_NAMESPACE);
   if (org.apache.commons.lang.StringUtils.isEmpty(attributeName)) {
     throw new XmlException("Attribute name must be non-empty");
   }
   boolean required = DEFAULT_ATTRIBUTE_REQUIRED;
   if (requiredValue != null) {
     required = Boolean.parseBoolean(requiredValue);
   }
   boolean active = DEFAULT_ATTRIBUTE_ACTIVE;
   if (activeValue != null) {
     active = Boolean.parseBoolean(activeValue);
   }
   RuleAttribute ruleAttribute =
       KEWServiceLocator.getRuleAttributeService().findByName(attributeName);
   if (ruleAttribute == null) {
     throw new XmlException("Could not locate rule attribute for name '" + attributeName + "'");
   }
   RuleTemplateAttributeBo templateAttribute = new RuleTemplateAttributeBo();
   templateAttribute.setRuleAttribute(ruleAttribute);
   templateAttribute.setRuleAttributeId(ruleAttribute.getId());
   templateAttribute.setRuleTemplate(ruleTemplate);
   templateAttribute.setRequired(Boolean.valueOf(required));
   templateAttribute.setActive(Boolean.valueOf(active));
   templateAttribute.setDisplayOrder(new Integer(templateAttributeCounter++));
   return templateAttribute;
 }
コード例 #11
0
 public List<ActionItem> getActionItems() {
   if (this.simulatedActionItems == null || this.simulatedActionItems.isEmpty()) {
     return (List<ActionItem>)
         KEWServiceLocator.getActionListService().findByActionRequestId(actionRequestId);
   } else {
     return this.simulatedActionItems;
   }
 }
コード例 #12
0
 private RuleDelegationBo getDefaultDelegationValues(RuleBaseValues defaultRuleValues) {
   List ruleDelegations =
       KEWServiceLocator.getRuleDelegationService()
           .findByDelegateRuleId(defaultRuleValues.getId());
   if (ruleDelegations.size() > 1) {
     LOG.warn("The rule defaults has more than one associated delegation defaults.");
   }
   return (ruleDelegations.isEmpty() ? null : (RuleDelegationBo) ruleDelegations.get(0));
 }
コード例 #13
0
 public RuleTemplateBo getRuleTemplate() {
   if (ruleTemplate == null) {
     RuleTemplateService ruleTemplateService =
         (RuleTemplateService)
             KEWServiceLocator.getService(KEWServiceLocator.RULE_TEMPLATE_SERVICE);
     ruleTemplate = ruleTemplateService.findByRuleTemplateName(getRouteMethodName());
   }
   return ruleTemplate;
 }
コード例 #14
0
 private void exportDefaults(Element parent, RuleTemplateBo ruleTemplate) {
   RuleBaseValues defaultRuleValues =
       KEWServiceLocator.getRuleService().findDefaultRuleByRuleTemplateId(ruleTemplate.getId());
   if (defaultRuleValues != null) {
     RuleDelegationBo defaultDelegationValues = getDefaultDelegationValues(defaultRuleValues);
     Element defaultsElement = renderer.renderElement(parent, RULE_DEFAULTS);
     if (defaultDelegationValues != null) {
       renderer.renderTextElement(
           defaultsElement,
           DELEGATION_TYPE,
           defaultDelegationValues.getDelegationType().getCode());
     }
     renderer.renderTextElement(defaultsElement, DESCRIPTION, defaultRuleValues.getDescription());
     if (defaultRuleValues.getFromDateValue() != null) {
       renderer.renderDateElement(
           defaultsElement, FROM_DATE, defaultRuleValues.getFromDateValue());
     }
     if (defaultRuleValues.getToDateValue() != null) {
       renderer.renderDateElement(defaultsElement, TO_DATE, defaultRuleValues.getToDateValue());
     }
     renderer.renderBooleanElement(
         defaultsElement, FORCE_ACTION, defaultRuleValues.isForceAction(), false);
     renderer.renderBooleanElement(defaultsElement, ACTIVE, defaultRuleValues.isActive(), true);
     if (defaultDelegationValues == null) {
       RuleTemplateOptionBo defaultActionOption = ruleTemplate.getDefaultActionRequestValue();
       RuleTemplateOptionBo supportsComplete = ruleTemplate.getComplete();
       RuleTemplateOptionBo supportsApprove = ruleTemplate.getApprove();
       RuleTemplateOptionBo supportsAck = ruleTemplate.getAcknowledge();
       RuleTemplateOptionBo supportsFYI = ruleTemplate.getFyi();
       if (defaultActionOption != null) {
         String defaultActionValue =
             (defaultActionOption == null ? null : defaultActionOption.getValue());
         renderer.renderTextElement(defaultsElement, DEFAULT_ACTION_REQUESTED, defaultActionValue);
       }
       if (supportsComplete != null) {
         String supportsCompleteValue = supportsComplete.getValue();
         renderer.renderTextElement(defaultsElement, SUPPORTS_COMPLETE, supportsCompleteValue);
       }
       if (supportsApprove != null) {
         String supportsApproveValue = supportsApprove.getValue();
         renderer.renderTextElement(defaultsElement, SUPPORTS_APPROVE, supportsApproveValue);
       }
       if (supportsAck != null) {
         String supportsAckValue = supportsAck.getValue();
         renderer.renderTextElement(defaultsElement, SUPPORTS_ACKNOWLEDGE, supportsAckValue);
       }
       if (supportsFYI != null) {
         String supportsFYIValue = supportsFYI.getValue();
         renderer.renderTextElement(defaultsElement, SUPPORTS_FYI, supportsFYIValue);
       }
     }
   }
 }
コード例 #15
0
  /**
   * Updates the rule template delegation template with the one specified in the XML (if any)
   *
   * @param ruleTemplateElement the XML ruleTemplate element
   * @param updatedRuleTemplate the rule template to update
   * @param parsedRuleTemplates the rule templates parsed in this parsing run
   * @throws XmlException if a delegation template was specified but could not be found
   */
  protected void updateDelegationTemplate(
      Element ruleTemplateElement,
      RuleTemplateBo updatedRuleTemplate,
      List<RuleTemplateBo> parsedRuleTemplates)
      throws XmlException {
    String delegateTemplateName =
        ruleTemplateElement.getChildText(DELEGATION_TEMPLATE, RULE_TEMPLATE_NAMESPACE);

    if (delegateTemplateName != null) {
      // if a delegateTemplate was set in the XML, then look it up and set it on the RuleTemplate
      // object
      // first try looking up an existing delegateTemplate in the system
      RuleTemplateBo delegateTemplate =
          KEWServiceLocator.getRuleTemplateService().findByRuleTemplateName(delegateTemplateName);

      // if not found, try the list of templates currently parsed
      if (delegateTemplate == null) {
        for (RuleTemplateBo rt : parsedRuleTemplates) {
          if (delegateTemplateName.equalsIgnoreCase(rt.getName())) {
            // set the expected next rule template id on the target delegateTemplate
            String ruleTemplateId =
                KEWServiceLocator.getRuleTemplateService().getNextRuleTemplateId();
            rt.setId(ruleTemplateId);
            delegateTemplate = rt;
            break;
          }
        }
      }

      if (delegateTemplate == null) {
        throw new XmlException("Cannot find delegation template " + delegateTemplateName);
      }

      updatedRuleTemplate.setDelegationTemplateId(delegateTemplate.getDelegationTemplateId());
      updatedRuleTemplate.setDelegationTemplate(delegateTemplate);
    } else {
      // the previously referenced template is left in the system
    }
  }
コード例 #16
0
  /**
   * Note that the assertion here will fail if you have multiple rules with the same description.
   */
  protected void assertExport() throws Exception {
    // export all existing rules and their dependencies (document types, rule templates, rule
    // attributes)
    List oldRules = KEWServiceLocator.getRuleService().fetchAllRules(true);
    assertAllRulesHaveUniqueNames(oldRules);
    List oldRuleDelegations =
        KEWServiceLocator.getRuleDelegationService().findAllCurrentRuleDelegations();
    assertAllRuleDelegationsHaveUniqueNames(oldRuleDelegations);

    KewExportDataSet dataSet = new KewExportDataSet();
    dataSet.getRules().addAll(oldRules);
    dataSet.getRuleDelegations().addAll(oldRuleDelegations);
    dataSet.getDocumentTypes().addAll(KEWServiceLocator.getDocumentTypeService().findAllCurrent());
    dataSet.getRuleTemplates().addAll(KEWServiceLocator.getRuleTemplateService().findAll());
    dataSet.getRuleAttributes().addAll(KEWServiceLocator.getRuleAttributeService().findAll());
    byte[] xmlBytes =
        CoreApiServiceLocator.getXmlExporterService().export(dataSet.createExportDataSet());
    assertTrue("XML should be non empty.", xmlBytes != null && xmlBytes.length > 0);

    // now clear the tables
    ClearDatabaseLifecycle clearLifeCycle = new ClearDatabaseLifecycle();
    clearLifeCycle.getTablesToClear().add("KREW_RULE_T");
    clearLifeCycle.getTablesToClear().add("KREW_RULE_RSP_T");
    clearLifeCycle.getTablesToClear().add("KREW_DLGN_RSP_T");
    clearLifeCycle.getTablesToClear().add("KREW_RULE_ATTR_T");
    clearLifeCycle.getTablesToClear().add("KREW_RULE_TMPL_T");
    clearLifeCycle.getTablesToClear().add("KREW_DOC_TYP_T");
    clearLifeCycle.start();
    new ClearCacheLifecycle().stop();

    // import the exported xml
    loadXmlStream(new BufferedInputStream(new ByteArrayInputStream(xmlBytes)));

    List newRules = KEWServiceLocator.getRuleService().fetchAllRules(true);
    assertEquals("Should have same number of old and new Rules.", oldRules.size(), newRules.size());
    for (Iterator iterator = oldRules.iterator(); iterator.hasNext(); ) {
      RuleBaseValues oldRule = (RuleBaseValues) iterator.next();
      boolean foundRule = false;
      for (Iterator iterator2 = newRules.iterator(); iterator2.hasNext(); ) {
        RuleBaseValues newRule = (RuleBaseValues) iterator2.next();
        if (oldRule.getDescription().equals(newRule.getDescription())) {
          assertRuleExport(oldRule, newRule);
          foundRule = true;
        }
      }
      assertTrue(
          "Could not locate the new rule for description " + oldRule.getDescription(), foundRule);
    }

    List newRuleDelegations =
        KEWServiceLocator.getRuleDelegationService().findAllCurrentRuleDelegations();
    assertDelegations(oldRuleDelegations, newRuleDelegations);
  }
コード例 #17
0
  public SimpleResult process(RouteContext context, RouteHelper helper) throws Exception {

    LOG.debug("processing FYIByUniversityId node");
    Element rootElement =
        getRootElement(new StandardDocumentContent(context.getDocument().getDocContent()));
    Collection<Element> fieldElements = XmlHelper.findElements(rootElement, "field");
    Iterator<Element> elementIter = fieldElements.iterator();
    while (elementIter.hasNext()) {
      Element field = (Element) elementIter.next();
      Element version = field.getParentElement();
      if (version.getAttribute("current").getValue().equals("true")) {
        LOG.debug("Looking for studentUid field:  " + field.getAttributeValue("name"));
        if (field.getAttribute("name") != null
            && field.getAttributeValue("name").equals("studentUid")) {
          String employeeId = field.getChildText("value");
          LOG.debug("Should send an FYI to employee ID:  " + employeeId);
          if (!StringUtils.isBlank(employeeId)) {
            Person person = KimApiServiceLocator.getPersonService().getPerson(employeeId);

            if (person == null) {
              throw new WorkflowRuntimeException(
                  "Failed to locate a Person with the given employee ID: " + employeeId);
            }
            if (!context.isSimulation()) {
              KEWServiceLocator.getWorkflowDocumentService()
                  .adHocRouteDocumentToPrincipal(
                      person.getPrincipalId(),
                      context.getDocument(),
                      KewApiConstants.ACTION_REQUEST_FYI_REQ,
                      null,
                      null,
                      "Notification Request",
                      person.getPrincipalId(),
                      "Notification Request",
                      true,
                      null);
            }
            // wfDoc.adHocRouteDocumentToPrincipal(KewApiConstants.ACTION_REQUEST_FYI_REQ,
            // "Notification Request", new EmplIdVO(field.getChildText("value")), "Notification
            // Request", true);
            LOG.debug(
                "Sent FYI using the adHocRouteDocumentToPrincipal function to UniversityID:  "
                    + person.getEmployeeId());
            break;
          }
        }
      }
    }
    return super.process(context, helper);
  }
コード例 #18
0
  /**
   * Tests that the document route past the join properly when there are parallel branches that
   * don't generate requests. This was coded in response to a bug found while testing with ERA in
   * order to track it down and fix it.
   */
  @Test
  public void testEmptyParallelBranches() throws Exception {

    WorkflowDocument document =
        WorkflowDocumentFactory.createDocument(
            getPrincipalIdForName("ewestfal"), PARALLEL_EMPTY_DOCUMENT_TYPE_NAME);
    document.saveDocumentData();
    assertTrue("Document should be initiated", document.isInitiated());
    assertEquals("Should be no action requests.", 0, document.getRootActionRequests().size());
    Collection<? extends Object> nodeInstances =
        KEWServiceLocator.getRouteNodeService().getActiveNodeInstances(document.getDocumentId());
    assertEquals("Wrong number of active nodes.", 1, nodeInstances.size());
    document.route("");

    // should have generated a request to "bmcgough"
    document =
        WorkflowDocumentFactory.loadDocument(
            getPrincipalIdForName("bmcgough"), document.getDocumentId());
    assertTrue("Document should be enroute", document.isEnroute());
    List<ActionRequestValue> actionRequests =
        KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getDocumentId());
    assertEquals("Incorrect pending action requests.", 1, actionRequests.size());
    ActionRequestValue bRequest = actionRequests.get(0);
    assertNotNull("Should have been routed through node instance.", bRequest.getNodeInstance());
    assertTrue(document.isApprovalRequested());

    document.approve("");

    // now the document should have split, passed through nodes in each branch which didn't generate
    // requests,
    // and then passed the join node and generated requests at WorkflowDocumentFinal
    document =
        WorkflowDocumentFactory.loadDocument(
            getPrincipalIdForName("xqi"), document.getDocumentId());
    assertTrue("Document should be enroute", document.isEnroute());
    assertTrue(document.isApprovalRequested());
  }
コード例 #19
0
  protected void assertExport() throws Exception {
    // export all existing rule templates and their dependencies (rule attributes)
    List oldRuleTemplates = KEWServiceLocator.getRuleTemplateService().findAll();
    KewExportDataSet dataSet = new KewExportDataSet();
    dataSet.getRuleTemplates().addAll(oldRuleTemplates);
    dataSet.getRuleAttributes().addAll(KEWServiceLocator.getRuleAttributeService().findAll());
    byte[] xmlBytes =
        CoreApiServiceLocator.getXmlExporterService().export(dataSet.createExportDataSet());
    assertTrue("XML should be non empty.", xmlBytes != null && xmlBytes.length > 0);

    // now clear the tables
    new ClearDatabaseLifecycle(getPerTestTablesToClear(), getPerTestTablesNotToClear()).start();

    // import the exported xml
    loadXmlStream(new BufferedInputStream(new ByteArrayInputStream(xmlBytes)));

    List newRuleTemplates = KEWServiceLocator.getRuleTemplateService().findAll();
    assertEquals(
        "Should have same number of old and new RuleTemplates.",
        oldRuleTemplates.size(),
        newRuleTemplates.size());
    for (Iterator iterator = oldRuleTemplates.iterator(); iterator.hasNext(); ) {
      RuleTemplateBo oldRuleTemplate = (RuleTemplateBo) iterator.next();
      boolean foundTemplate = false;
      for (Iterator iterator2 = newRuleTemplates.iterator(); iterator2.hasNext(); ) {
        RuleTemplateBo newRuleTemplate = (RuleTemplateBo) iterator2.next();
        if (oldRuleTemplate.getName().equals(newRuleTemplate.getName())) {
          assertRuleTemplateExport(oldRuleTemplate, newRuleTemplate);
          foundTemplate = true;
        }
      }
      assertTrue(
          "Could not locate the new rule template for name " + oldRuleTemplate.getName(),
          foundTemplate);
    }
  }
コード例 #20
0
  /** Copied from org.kuali.rice.kew.routelog.web.RouteLogAction. */
  @SuppressWarnings("unchecked")
  private Set<String> getActionRequestIds(DocumentRouteHeaderValue document) {
    Set<String> actionRequestIds = new HashSet<String>();

    List<ActionRequestValue> actionRequests =
        KEWServiceLocator.getActionRequestService()
            .findAllActionRequestsByDocumentId(document.getDocumentId());

    if (actionRequests != null) {
      for (ActionRequestValue actionRequest : actionRequests) {
        if (actionRequest.getActionRequestId() != null) {
          actionRequestIds.add(actionRequest.getActionRequestId());
        }
      }
    }
    return actionRequestIds;
  }
コード例 #21
0
 /**
  * Creates a KualiMaintenanceForm with the given rule template inside of its RuleBaseValues
  * instance.
  *
  * @param rtName The rule template to use.
  */
 private void createNewKualiMaintenanceForm(String rtName) {
   // Initialize the required variables.
   final KualiMaintenanceForm kmForm = new KualiMaintenanceForm();
   final MaintenanceDocument maintDoc = new MaintenanceDocumentBase();
   final Maintainable oldMaint = new RoutingRuleMaintainable();
   final Maintainable newMaint = new RoutingRuleMaintainable();
   final RuleBaseValues rbValues = new RuleBaseValues();
   // Setup the rule base and the maintainables.
   rbValues.setRuleTemplate(
       KEWServiceLocator.getRuleTemplateService().findByRuleTemplateName(rtName));
   oldMaint.setBusinessObject(rbValues);
   oldMaint.setBoClass(rbValues.getClass());
   newMaint.setBusinessObject(rbValues);
   newMaint.setBoClass(rbValues.getClass());
   // Setup the maintenance document and the maintenance form.
   maintDoc.setOldMaintainableObject(oldMaint);
   maintDoc.setNewMaintainableObject(newMaint);
   maintDoc.getDocumentHeader().setDocumentDescription("This is a rule template test");
   kmForm.setDocument(maintDoc);
   KNSGlobalVariables.setKualiForm(kmForm);
 }
コード例 #22
0
  public String getRouteLevelName() {
    // this is for backward compatibility of requests which have not been converted
    if (CompatUtils.isRouteLevelRequest(this)) {
      int routeLevelInt = getRouteLevel();
      if (routeLevelInt == KewApiConstants.EXCEPTION_ROUTE_LEVEL) {
        return "Exception";
      }

      List<RouteNode> routeLevelNodes =
          CompatUtils.getRouteLevelCompatibleNodeList(
              KEWServiceLocator.getRouteHeaderService()
                  .getRouteHeader(documentId)
                  .getDocumentType());
      if (!(routeLevelInt < routeLevelNodes.size())) {
        return "Not Found";
      }
      return ((RouteNode) routeLevelNodes.get(routeLevelInt)).getRouteNodeName();
    } else {
      return (nodeInstance == null ? "Exception" : nodeInstance.getName());
    }
  }
コード例 #23
0
  private boolean notifyExternalActionList(String actionType, String actionItemId) {
    LOG.info("actionType: " + actionType + "   actionItemId: " + actionItemId);
    ActionItem actionItem = null;

    // Get the action item unless it was deleted
    if (actionType.toString().equalsIgnoreCase(KewApiConstants.ACTION_ITEM_INSERTED)
        || (actionType.toString().equalsIgnoreCase(KewApiConstants.ACTION_ITEM_UPDATED))) {
      actionItem = KEWServiceLocator.getActionListService().findByActionItemId(actionItemId);
    }

    if (actionType.toString().equalsIgnoreCase(KewApiConstants.ACTION_ITEM_INSERTED)) {
      LOG.info("Code to INSERT into external action list goes here");
    } else if (actionType.toString().equalsIgnoreCase(KewApiConstants.ACTION_ITEM_UPDATED)) {
      LOG.info("Code to UPDATE external action list goes here");
    } else if (actionType.toString().equalsIgnoreCase(KewApiConstants.ACTION_ITEM_DELETED)) {
      LOG.info("Code to DELETE from external action list goes here");
    }

    // Currently always return true to indicate successful processing.
    // This may change once the above code is implemented.
    return true;
  }
コード例 #24
0
  public void recordAction() throws InvalidActionTakenException {
    MDC.put("docId", getRouteHeader().getDocumentId());
    updateSearchableAttributesIfPossible();
    LOG.debug(
        "Moving document "
            + getRouteHeader().getDocumentId()
            + " to point: "
            + displayMovePoint(movePoint)
            + ", annotation: "
            + annotation);

    List actionRequests =
        getActionRequestService()
            .findAllValidRequests(
                getPrincipal().getPrincipalId(),
                getDocumentId(),
                KewApiConstants.ACTION_REQUEST_COMPLETE_REQ);
    Collection activeNodes =
        KEWServiceLocator.getRouteNodeService()
            .getActiveNodeInstances(getRouteHeader().getDocumentId());
    String errorMessage = validateActionRules(actionRequests, activeNodes);
    if (!org.apache.commons.lang.StringUtils.isEmpty(errorMessage)) {
      throw new InvalidActionTakenException(errorMessage);
    }

    RouteNodeInstance startNodeInstance = determineStartNode(activeNodes, movePoint);

    LOG.debug("Record the move action");
    Recipient delegator = findDelegatorForActionRequests(actionRequests);
    ActionTakenValue actionTaken = saveActionTaken(delegator);
    getActionRequestService().deactivateRequests(actionTaken, actionRequests);
    notifyActionTaken(actionTaken);

    // TODO this whole bit is a bit hacky at the moment
    if (movePoint.getStepsToMove() > 0) {
      Set<String> targetNodeNames = new HashSet<String>();
      targetNodeNames.add(determineFutureNodeName(startNodeInstance, movePoint));

      final boolean shouldIndex =
          getRouteHeader().getDocumentType().hasSearchableAttributes()
              && RouteContext.getCurrentRouteContext().isSearchIndexingRequestedForContext();
      String applicationId = routeHeader.getDocumentType().getApplicationId();
      DocumentOrchestrationQueue orchestrationQueue =
          KewApiServiceLocator.getDocumentOrchestrationQueue(
              routeHeader.getDocumentId(), applicationId);
      org.kuali.rice.kew.api.document.OrchestrationConfig orchestrationConfig =
          org.kuali.rice.kew.api.document.OrchestrationConfig.create(
              actionTaken.getActionTakenId(), targetNodeNames);
      DocumentProcessingOptions options =
          DocumentProcessingOptions.create(true, shouldIndex, false);
      orchestrationQueue.orchestrateDocument(
          routeHeader.getDocumentId(),
          getPrincipal().getPrincipalId(),
          orchestrationConfig,
          options);
    } else {
      String targetNodeName = determineReturnNodeName(startNodeInstance, movePoint);
      ReturnToPreviousNodeAction returnAction =
          new ReturnToPreviousNodeAction(
              KewApiConstants.ACTION_TAKEN_MOVE_CD,
              getRouteHeader(),
              getPrincipal(),
              annotation,
              targetNodeName,
              false);

      returnAction.recordAction();
    }
  }
コード例 #25
0
 public Principal getPrincipal() {
   if (getPrincipalId() == null) {
     return null;
   }
   return KEWServiceLocator.getIdentityHelperService().getPrincipal(getPrincipalId());
 }
コード例 #26
0
 private RuleServiceInternal getRuleService() {
   return (RuleServiceInternal) KEWServiceLocator.getService(KEWServiceLocator.RULE_SERVICE);
 }
コード例 #27
0
  @Test
  public void testParallelRoute() throws Exception {
    WorkflowDocument document =
        WorkflowDocumentFactory.createDocument(
            getPrincipalIdForName("ewestfal"), DOCUMENT_TYPE_NAME);
    document.saveDocumentData();
    assertTrue("Document should be initiated", document.isInitiated());
    assertEquals("Should be no action requests.", 0, document.getRootActionRequests().size());
    Collection<RouteNodeInstance> nodeInstances =
        KEWServiceLocator.getRouteNodeService().getActiveNodeInstances(document.getDocumentId());
    assertEquals("Wrong number of active nodes.", 1, nodeInstances.size());
    document.route("Routing for parallel");

    // should have generated a request to "bmcgough"
    document =
        WorkflowDocumentFactory.loadDocument(
            getPrincipalIdForName("bmcgough"), document.getDocumentId());
    assertTrue("Document should be enroute", document.isEnroute());
    List<ActionRequestValue> actionRequests =
        KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getDocumentId());
    assertEquals("Incorrect pending action requests.", 1, actionRequests.size());
    ActionRequestValue bRequest = actionRequests.get(0);
    assertNotNull("Should have been routed through node instance.", bRequest.getNodeInstance());
    assertTrue(document.isApprovalRequested());

    document.approve("Approving test");

    // document should split at this point and generate an ack to temay and approves to rkirkend and
    // pmckown
    document =
        WorkflowDocumentFactory.loadDocument(
            getPrincipalIdForName("rkirkend"), document.getDocumentId());
    assertTrue("Document should be enroute", document.isEnroute());
    actionRequests =
        KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getDocumentId());
    assertEquals("Incorrect pending action requests.", 3, actionRequests.size());
    boolean isToTemay = false;
    boolean isToPmckown = false;
    boolean isToRkirkend = false;
    for (Iterator iterator = actionRequests.iterator(); iterator.hasNext(); ) {
      ActionRequestValue actionRequest = (ActionRequestValue) iterator.next();
      if (actionRequest.getPrincipalId().equals(getPrincipalIdForName("temay"))) {
        isToTemay = true;
        assertEquals(
            "Request should be activated.",
            ActionRequestStatus.ACTIVATED.getCode(),
            actionRequest.getStatus());
        assertEquals(
            "Wrong action requested.",
            KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ,
            actionRequest.getActionRequested());
        assertNotNull(
            "Should have been routed through node instance.", actionRequest.getNodeInstance());
        assertEquals(
            "Invalid node.",
            ACKNOWLEDGE_1_NODE,
            actionRequest.getNodeInstance().getRouteNode().getRouteNodeName());
      }
      if (actionRequest.getPrincipalId().equals(getPrincipalIdForName("rkirkend"))) {
        isToRkirkend = true;
        assertEquals(
            "Request should be activated.",
            ActionRequestStatus.ACTIVATED.getCode(),
            actionRequest.getStatus());
        assertEquals(
            "Wrong action requested.",
            KewApiConstants.ACTION_REQUEST_APPROVE_REQ,
            actionRequest.getActionRequested());
        assertNotNull(
            "Should have been routed through node instance.", actionRequest.getNodeInstance());
        assertEquals(
            "Invalid node.",
            WORKFLOW_DOCUMENT_2_NODE,
            actionRequest.getNodeInstance().getRouteNode().getRouteNodeName());
      }
      if (actionRequest.getPrincipalId().equals(getPrincipalIdForName("pmckown"))) {
        isToPmckown = true;
        assertEquals(
            "Request should be activated.",
            ActionRequestStatus.ACTIVATED.getCode(),
            actionRequest.getStatus());
        assertEquals(
            "Wrong action requested.",
            KewApiConstants.ACTION_REQUEST_APPROVE_REQ,
            actionRequest.getActionRequested());
        assertNotNull(
            "Should have been routed through node instance.", actionRequest.getNodeInstance());
        assertEquals(
            "Invalid node.",
            WORKFLOW_DOCUMENT_3_NODE,
            actionRequest.getNodeInstance().getRouteNode().getRouteNodeName());
      }
    }
    assertTrue("No request to temay.", isToTemay);
    assertTrue("No request to pmckown.", isToPmckown);
    assertTrue("No request to rkirkend.", isToRkirkend);

    // check that we are at both nodes, one in each branch
    Set<String> nodeNames = document.getNodeNames();
    assertEquals("Wrong number of node names.", 2, nodeNames.size());
    boolean isNode2 = false;
    boolean isNode3 = false;
    for (String name : nodeNames) {
      if (name.equals(WORKFLOW_DOCUMENT_2_NODE)) {
        isNode2 = true;
      }
      if (name.equals(WORKFLOW_DOCUMENT_3_NODE)) {
        isNode3 = true;
      }
    }
    assertTrue("Not at node2.", isNode2);
    assertTrue("Not at node3.", isNode3);
    nodeInstances =
        KEWServiceLocator.getRouteNodeService().getActiveNodeInstances(document.getDocumentId());
    assertEquals("Wrong number of active nodes.", 2, nodeInstances.size());
    Iterator<RouteNodeInstance> iterator = nodeInstances.iterator();
    RouteNodeInstance instance1 = (RouteNodeInstance) iterator.next();
    RouteNodeInstance instance2 = (RouteNodeInstance) iterator.next();
    assertNotNull("Node should be in branch.", instance1.getBranch());
    assertNotNull("Node should be in branch.", instance2.getBranch());
    assertTrue(
        "Branches should be different.",
        !instance1.getBranch().getBranchId().equals(instance2.getBranch().getBranchId()));

    document =
        WorkflowDocumentFactory.loadDocument(
            getPrincipalIdForName("rkirkend"), document.getDocumentId());
    assertTrue("Should have request.", document.isApprovalRequested());
    document.approve("Git-r-dun");

    nodeInstances =
        KEWServiceLocator.getRouteNodeService().getActiveNodeInstances(document.getDocumentId());
    assertEquals("Wrong number of active nodes.", 2, nodeInstances.size());
    boolean isAtJoin = false;
    boolean isAtWD3 = false;
    for (RouteNodeInstance nodeInstance : nodeInstances) {
      if (nodeInstance.getRouteNode().getRouteNodeName().equals(JOIN_NODE)) {
        assertEquals(
            "Join branch should be split branch.",
            instance1.getBranch().getParentBranch().getBranchId(),
            nodeInstance.getBranch().getBranchId());
        isAtJoin = true;
      }
      if (nodeInstance.getRouteNode().getRouteNodeName().equals(WORKFLOW_DOCUMENT_3_NODE)) {
        isAtWD3 = true;
      }
    }
    assertTrue("Not at join", isAtJoin);
    assertTrue("Not at WD3", isAtWD3);

    document =
        WorkflowDocumentFactory.loadDocument(
            getPrincipalIdForName("pmckown"), document.getDocumentId());
    assertTrue("Should have request.", document.isApprovalRequested());
    document.approve("Do it.");

    nodeInstances =
        KEWServiceLocator.getRouteNodeService().getActiveNodeInstances(document.getDocumentId());
    assertEquals("Wrong number of active nodes.", 1, nodeInstances.size());
    boolean isAtWDF = false;
    for (RouteNodeInstance nodeInstance : nodeInstances) {
      if (nodeInstance.getRouteNode().getRouteNodeName().equals(WORKFLOW_DOCUMENT_FINAL_NODE)) {
        isAtWDF = true;
      }
    }
    assertTrue("Not at WDF", isAtWDF);

    document =
        WorkflowDocumentFactory.loadDocument(
            getPrincipalIdForName("xqi"), document.getDocumentId());
    assertTrue("Should still be enroute.", document.isEnroute());
    assertTrue("Should have request.", document.isApprovalRequested());
    document.approve("I'm the last approver");

    assertTrue("Document should be processed.", document.isProcessed());
    nodeInstances =
        KEWServiceLocator.getRouteNodeService().getActiveNodeInstances(document.getDocumentId());
    assertEquals(
        "The doc is processed so no node instances should be active", 0, nodeInstances.size());

    document =
        WorkflowDocumentFactory.loadDocument(
            getPrincipalIdForName("temay"), document.getDocumentId());
    assertTrue("Should have request.", document.isAcknowledgeRequested());
    document.acknowledge("");
    assertTrue(document.isFinal());
  }
コード例 #28
0
 public DocumentRouteHeaderValue getRouteHeader() {
   if (this.routeHeader == null && this.documentId != null) {
     this.routeHeader = KEWServiceLocator.getRouteHeaderService().getRouteHeader(this.documentId);
   }
   return this.routeHeader;
 }
コード例 #29
0
 protected Object getService(String serviceName) {
   return KEWServiceLocator.getService(serviceName);
 }
コード例 #30
0
  /**
   * Updates the default/template rule options with those in the defaults element
   *
   * @param defaultsElement the ruleDefaults element
   * @param updatedRuleTemplate the Rule Template being updated
   * @return whether this is a delegation rule template
   */
  protected boolean updateRuleDefaults(Element defaultsElement, RuleTemplateBo updatedRuleTemplate)
      throws XmlException {
    // NOTE: implementation detail: in contrast with the other options, the delegate template, and
    // the rule attributes,
    // we unconditionally blow away the default rule and re-create it (we don't update the existing
    // one, if there is one)
    if (updatedRuleTemplate.getId() != null) {
      RuleBaseValues ruleDefaults =
          KEWServiceLocator.getRuleService()
              .findDefaultRuleByRuleTemplateId(updatedRuleTemplate.getId());
      if (ruleDefaults != null) {
        List ruleDelegationDefaults =
            KEWServiceLocator.getRuleDelegationService().findByDelegateRuleId(ruleDefaults.getId());
        // delete the rule
        KEWServiceLocator.getRuleService().delete(ruleDefaults.getId());
        // delete the associated rule delegation defaults
        for (Iterator iterator = ruleDelegationDefaults.iterator(); iterator.hasNext(); ) {
          RuleDelegationBo ruleDelegation = (RuleDelegationBo) iterator.next();
          KEWServiceLocator.getRuleDelegationService().delete(ruleDelegation.getRuleDelegationId());
        }
      }
    }

    boolean isDelegation = false;

    if (defaultsElement != null) {
      String delegationTypeCode =
          defaultsElement.getChildText(DELEGATION_TYPE, RULE_TEMPLATE_NAMESPACE);
      DelegationType delegationType = null;
      isDelegation = !org.apache.commons.lang.StringUtils.isEmpty(delegationTypeCode);

      String description = defaultsElement.getChildText(DESCRIPTION, RULE_TEMPLATE_NAMESPACE);

      // would normally be validated via schema but might not be present if invoking RuleXmlParser
      // directly
      if (description == null) {
        throw new XmlException("Description must be specified in rule defaults");
      }

      String fromDate = defaultsElement.getChildText(FROM_DATE, RULE_TEMPLATE_NAMESPACE);
      String toDate = defaultsElement.getChildText(TO_DATE, RULE_TEMPLATE_NAMESPACE);
      // toBooleanObject ensures that if the value is null (not set) that the Boolean object will
      // likewise be null (will not default to a value)
      Boolean forceAction =
          BooleanUtils.toBooleanObject(
              defaultsElement.getChildText(FORCE_ACTION, RULE_TEMPLATE_NAMESPACE));
      Boolean active =
          BooleanUtils.toBooleanObject(
              defaultsElement.getChildText(ACTIVE, RULE_TEMPLATE_NAMESPACE));

      if (isDelegation) {
        delegationType = DelegationType.parseCode(delegationTypeCode);
        if (delegationType == null) {
          throw new XmlException(
              "Invalid delegation type '"
                  + delegationType
                  + "'."
                  + "  Expected one of: "
                  + DelegationType.PRIMARY.getCode()
                  + ","
                  + DelegationType.SECONDARY.getCode());
        }
      }

      // create our "default rule" which encapsulates the defaults for the rule
      RuleBaseValues ruleDefaults = new RuleBaseValues();

      // set simple values
      ruleDefaults.setRuleTemplate(updatedRuleTemplate);
      ruleDefaults.setRuleTemplateId(updatedRuleTemplate.getId());
      ruleDefaults.setDocTypeName(DUMMY_DOCUMENT_TYPE);
      ruleDefaults.setTemplateRuleInd(Boolean.TRUE);
      ruleDefaults.setCurrentInd(Boolean.TRUE);
      ruleDefaults.setVersionNbr(new Integer(0));
      ruleDefaults.setDescription(description);

      // these are non-nullable fields, so default them if they were not set in the defaults section
      ruleDefaults.setForceAction(Boolean.valueOf(BooleanUtils.isTrue(forceAction)));
      ruleDefaults.setActive(Boolean.valueOf(BooleanUtils.isTrue(active)));

      if (ruleDefaults.getActivationDate() == null) {
        ruleDefaults.setActivationDate(new Timestamp(System.currentTimeMillis()));
      }

      ruleDefaults.setFromDateValue(formatDate("fromDate", fromDate));
      ruleDefaults.setToDateValue(formatDate("toDate", toDate));

      // ok, if this is a "Delegate Template", then we need to set this other RuleDelegation object
      // which contains
      // some delegation-related info
      RuleDelegationBo ruleDelegationDefaults = null;
      if (isDelegation) {
        ruleDelegationDefaults = new RuleDelegationBo();
        ruleDelegationDefaults.setDelegationRule(ruleDefaults);
        ruleDelegationDefaults.setDelegationType(delegationType);
        ruleDelegationDefaults.setResponsibilityId(KewApiConstants.ADHOC_REQUEST_RESPONSIBILITY_ID);
      }

      // explicitly save the new rule delegation defaults and default rule
      KEWServiceLocator.getRuleTemplateService()
          .saveRuleDefaults(ruleDelegationDefaults, ruleDefaults);
    } else {
      // do nothing, rule defaults will be deleted if ruleDefaults element is omitted
    }

    return isDelegation;
  }