IBM BPM, V8.0.1, All platforms > Programming IBM BPM > Business rule management programming > Examples
Example 12: Modify a template in a decision table by changing a parameter value and then publish
In this example, a condition and action, both defined with templates, are modified in a decision table by changing the parameter values before it is published.
The easiest way to modify conditions and actions in a decision table is to use unique names for the templates at each condition level and for each action. The unique names can be searched for and then changes can be made to template instances defined with the template. When changes are made to a template instance of a particular template, all of the condition values defined with that template at that level will be updated. For action expressions, each instance is unique and a change to one does not change others.
For this example, there are a number of additional methods that were created to simplify the locating of a specific case edge for update, finding the specific parameter value, and finding the action expression defined with a specific template.
package com.ibm.websphere.sample.brules.mgmt; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Vector; import com.ibm.wbiserver.brules.mgmt.BusinessRule; import com.ibm.wbiserver.brules.mgmt.BusinessRuleGroup; import com.ibm.wbiserver.brules.mgmt.BusinessRuleManagementException; import com.ibm.wbiserver.brules.mgmt.BusinessRuleManager; import com.ibm.wbiserver.brules.mgmt.Operation; import com.ibm.wbiserver.brules.mgmt.ParameterValue; import com.ibm.wbiserver.brules.mgmt.Template; import com.ibm.wbiserver.brules.mgmt.dtable.ActionNode; import com.ibm.wbiserver.brules.mgmt.dtable.CaseEdge; import com.ibm.wbiserver.brules.mgmt.dtable.ConditionNode; import com.ibm.wbiserver.brules.mgmt.dtable.DecisionTable; import com.ibm.wbiserver.brules.mgmt.dtable.TemplateInstanceExpression; import com.ibm.wbiserver.brules.mgmt.dtable.TreeAction; import com.ibm.wbiserver.brules.mgmt.dtable.TreeBlock; import com.ibm.wbiserver.brules.mgmt.dtable.TreeConditionValueDefinition; import com.ibm.wbiserver.brules.mgmt.dtable.TreeNode; import com.ibm.wbiserver.brules.mgmt.query.QueryOperator; public class Example12 { static Formatter out = new Formatter(); static public String executeExample12() { try { out.clear(); // Retrieve a business rule group by target namespace and name List<BusinessRuleGroup> brgList = BusinessRuleManager .getBRGsByTNSAndName( "http://BRSamples/com/ibm/websphere /sample/brules", QueryOperator.EQUAL, "ConfigurationValues", QueryOperator.EQUAL, 0, 0); if (brgList.size() > 0) { // Get the first business rule group from the list // This should be the only business rule group in the list as // the combination of target namespace and name are unique BusinessRuleGroup brg = brgList.get(0); // Get the operation of the business rule group that // has the business rule that will be modified as // the business rules are associated with a specific // operation Operation op = brg.getOperation("getMessages"); // Get all business rules available for this operation List<BusinessRule> ruleList = op.getAvailableTargets(); // For this operation there is only 1 business rule and // it is the business that we want to update DecisionTable decisionTable = (DecisionTable) ruleList.get(0); out.println(""); out.printlnBold("Decision table before publish:"); out .print(RuleArtifactUtility .printDecisionTable(decisionT able));The init rule and condition and actions are contained in a tree block. With the tree block, the root node can be retrieved.
// Get the tree block that contains all of the conditions // and actions for the decision table TreeBlock treeBlock = decisionTable.getTreeBlock(); // From the tree block, get the tree node which is the // starting point for navigating through the decision table TreeNode treeNode = treeBlock.getRootNode();The condition to be updated was defined with a template by the name of “Condition Value Template 2.1”. The method getCaseEdge will recursively search from the TreeNode down to the appropriate case edge to find the case edge where the template is defined. The method expects that the level at which the template is defined is known as well as the current level. This method can be used to find the case edge with a template by a specific name in case the same name is used at multiple case edges.
// Find the case edge at level 1 below the root with // specific template with a parameter value that has // a specific name. Since we are starting at the top, // the current depth is 0 CaseEdge caseEdge = getCaseEdge(treeNode, "param0", "Condition Value Template 2.1", 1, 0);With the case edge found, the ConditionValueTemplateInstance for the condition can be retrieved.
if (caseEdge != null) { // Case edge was found. Get the value definition of the // case edge TreeConditionValueDefinition condition = caseEdge .getValueDefinition(); // Get the condition expression defined with a template TemplateInstanceExpression conditionExpression = condition .getConditionValueTemplateInstance( );With the ConditionValueTemplateInstance , the appropriate parameter value can be retrieve and then updated with the getParameterValue method.
// Get the template for the expression Template conditionTemplate = conditionExpression .getTemplate(); // Check that template is correct as it is possible to have // multiple templates for a condition value, but only one // applied if (conditionTemplate.getName().equals( "Condition Value Template 2.1")) { // Get the parameter value ParameterValue parameterValue = getParameterValue("param0", conditionExpression); // Set the new parameter value parameterValue.setValue("info"); }The different action expressions defined with templates that need to be updated can then be retrieved. The getActionExpressions method will return all actions that are defined with the template by name Action Value Template 1.
ConditionNode conditionNode = (ConditionNode) treeNode; // Get the case edges tree node ListCaseEdge> caseEdges = conditionNode.getCaseEdges(); // Create a list to hold all of the action expressions that // also need to be updated. Because every action is // independent of other action even though the template is // shared, all must be updated. List<TemplateInstanceExpression> expressions = new Vector<TemplateInstanceExpression>(); // Retrieve all of the expressions for (CaseEdge edge : caseEdges) { getActionExpressions("Action Value Template 1", edge, expressions); }With the list of action expressions, each item can be updated. For action expressions defined with templates the correct parameter value can be updated.
// Update the correct parameter in each expression for (TemplateInstanceExpression expression expressions) { for (ParameterValue parameterValue : expression .getParameterValues()) { // Check for correct parameter although there is // only one paramater in our template if (parameterValue.getParameter().getN ame().equals("param0")) { String value = parameterValue.getValue(); parameterValue.setValue("Info " + value.substring(value. indexOf(":"), value.length())); } } } // With the condition value and actions updated, the // business rule group can be published. // Use the original list or create a new list // of business rule groups List<BusinessRuleGroup> publishList = new ArrayList<BusinessRuleGroup>(); // Add the changed business rule group to the list publishList.add(brg); // Publish the list with the updated business rule group BusinessRuleManager.publish(publishList, true); out.println(""); // Retrieve the business rule groups again to verify the // changes were published out.printlnBold("Decision table after publish:"); brgList = BusinessRuleManager.getBRGsByTNSAndName( "http://BRSamples/com/ibm/websphere /sample/brules", QueryOperator.EQUAL, "ConfigurationValues", QueryOperator.EQUAL, 0, 0); brg = brgList.get(0); op = brg.getOperation("getMessages"); ruleList = op.getAvailableTargets(); decisionTable = (DecisionTable) ruleList.get(0); out.print(RuleArtifactUtility .printDecisionTable(decisionTable)) ; } } } catch (BusinessRuleManagementException e) { e.printStackTrace(); out.println(e.getMessage()); } return out.toString();} /* Method to recursively navigate through a decision table and locate a case edge that has a template with a specific name and contains a specific parameter to change. This method assumes that the level(depth) in the decesion table of the value that is to be changed is known and the current level(currentDepth) is tracked * */ static private CaseEdge getCaseEdge(TreeNode node, String pName, String templateName, int depth, int currentDepth) { // Check if the current node is an action. This is an indication // that this branch of the decision table has been exhausted // looking for the case edge if (node instanceof ActionNode) { return null; } // Get the case edges for this node List<CaseEdge> caseEdges = ((ConditionNode) node).getCaseEdges(); for (CaseEdge caseEdge : caseEdges) { // Check if the correct level has been reached if (currentDepth < depth) { // Move down one level and then call getCaseEdge again // to process that level currentDepth++; return getCaseEdge(caseEdge.getChildNode(), pName, templateName, depth, currentDepth); } else { // The correct level has been reached. Get the condition in // order to check the templates on that condition on whether // they match the template sought TreeConditionValueDefinition condition = caseEdge .getValueDefinition(); // Get the expression for the condition which has been defined // with a template TemplateInstanceExpression expression = condition .getConditionValueTemplateInstance(); // Get the template from the expression Template template = expression.getTemplate(); // Check if this is the template sought if (template.getName().equals(templateName)) { // The template is found to match return caseEdge; } else caseEdge = null; } } return null;} /* This method will check the different parameter values for an expression and if the correct one is found, return that parameter value. */ private static ParameterValue getParameterValue(String pName, TemplateInstanceExpression expression) { // Check that the expression is not null as null would indicate // that the expression that was passed in was probably not defined // with a template and does not have any parameters to check. if (expression != null) { // Get the parameter values for the expression List<ParameterValue> parameterValues = expression .getParameterValues(); for (ParameterValue parameterValue : parameterValues) { // For the different parameters, check that it matches the // parameter value sought if (parameterValue.getParameter().getName().equals(pName )) { // Return the parameter value that matched return parameterValue; } } } return null;} /* This method finds all of the action expressions that are defined with a specific template. It recursively works through a case edge and adds action expressions that match to the expressions parameter. */ private static void getActionExpressions(String templateName, CaseEdge next, List<TemplateInstanceExpression> expressions) { ActionNode actionNode = null; TreeNode treeNode = next.getChildNode(); // Check if the current node is at the action node level if (treeNode instanceof ConditionNode) { List<CaseEdge> caseEdges = ((ConditionNode) treeNode) .getCaseEdges(); Iterator<CaseEdge> caseEdgesIterator = caseEdges.iterator(); // Work through all case edges to find the action // expressions while (caseEdgesIterator.hasNext()) { getActionExpressions(templateName, caseEdgesIterator.next(), expressions); } } else { // ActionNode found actionNode = (ActionNode) treeNode; List<TreeAction> treeActions = actionNode.getTreeActions(); // Check that there is at least one treeAction specified for // the expression and work through the expressions checking // if the expressions have been created with the specific // template. if (!treeActions.isEmpty()) { Iterator<TreeAction> iterator = treeActions.iterator(); while (iterator.hasNext()) { TreeAction treeAction = iterator.next(); TemplateInstanceExpression expression = treeAction .getValueTemplateInstance(); Template template = expression.getTemplate(); if (template.getName().equals(templateName)) { // Expression found with matching template expressions.add(expression); } } } } } }
Example
Web browser output for example 12.
Executing example12 Rule set before publish: Decision Table Name: getMessages Namespace: http://BRSamples/com/ibm/websphere/sample/brules Decision table after publish: Decision Table Name: getMessages Namespace: http://BRSamples/com/ibm/websphere/sample/brules