First Previous Next Last

Rules Guide  

Chapter 2   Rule Development Basics

This chapter describes basic rule development concepts. It has these sections:

 
Top of page

How rules work

A rule is a combination of conditions and actions that return a value. You define rules in the Workbench Rule Editor, and then access rules and handle the results in your Director application code. Using rules is a three-step process:

  1. Using the Rule Editor, you create a rule by selecting conditions and actions and setting their properties. For example, you might select the CheckDay condition and set the property to When today is Thursday, then select the ReturnResponsePhrase action and enter an appropriate phrase.

  2. From the appropriate point in your application code, you fire the rule using one of the available methods. For example:

      fireRule(Thursdays)
    
  3. You handle the result of the rule in your application. For example, if the rule returns a certain response phrase when today is Thursday and another phrase otherwise, you set the result in your application.

Here is how rules are processed in the Director application environment:

reProcessing

Term in the diagram

Description

Component or JSP page

You can fire rules in your application from a component or directly from a JSP page. You instantiate an EbiContext or an EbiRuleManager to access the requisite methods. In many cases you will want to instantiate both of these objects.

EbiContext

EbiContext provides access to the whiteboard and has methods for firing rules, validating pipelines, and handling rule results.

EbiRuleManager

EbiRuleManager provides alternative methods for firing rules and accessing rules associated with rule owners. Owners, defined in the Rule Editor, allow you to organize rules by application or other criteria.

Rule

A rule defines a set of conditions and actions that you configure in the Rule Editor. The rule definition is saved as an XML descriptor. The descriptor is used by the Rule subsystem to execute rules and return a value to the caller.

Conditions and actions

Conditions and actions are Java classes (typically JavaBeans) with properties you can set using the Rule Editor. These properties can include session and object values accessed from the whiteboard.

Whiteboard

The whiteboard is an area where session values and specified objects can be stored. The whiteboard is accessed from the context object (EbiContext).

 
Top of section

Rule samples

The Rule subsystem installation includes these rule samples:

Sample rule

Description

For more information

FireRule

Shows how to use a portal component parameter to fire a rule

See the chapter on installed components in Samples

ContentQuery

Shows how to use a component and the installed Query action to query the Content Management database

See the chapter on the Content Query Application in Samples

 
Top of page

Working with conditions and actions

You use the Rule Editor in Workbench to create rules by selecting installed (prebuilt) conditions and actions.

NOTE   Before creating rules you should become familiar with the Rule Editor tool. For more information, see Rule and Macro Editors.

There are several ways you can set up your business logic. Some setup can be done in the rule itself, and other setup needs to be done in application code before the application fires the rule. Here are some techniques for using the installed conditions and actions to set up values and build results:

Technique

How to implement it

Getting, setting, and removing whiteboard values

  • Use one of the several Save To Whiteboard conditions or actions. The data on the whiteboard is then available to other conditions and actions via !valueOf templates.

  • Check whether a whiteboard key exists (Check Whiteboard condition) and if not, use Save To Whiteboard to create it.

Saving cookies on the client

  • Check for the existence of a cookie with the Check For Cookie condition.

  • Use the Save Cookies To Whiteboard action to make cookies available as whiteboard keys.

  • Use the Set Cookie Value action to create cookies that the application or rule needs.

Building a response phrase

  • Use the several Return Response and Return HTML actions to put data in the response phrase.

  • Select the Append check box (when available in an action property sheet) to incrementally build a response from several actions.

Setting response status

  • Use the Return True, Return False, or Set Response Status action.

For more information    For details about these and other installed conditions and actions, see Installed Conditions and Installed Actions.

 
Top of section

Using whiteboard values

A Director session includes a whiteboard where you can store values needed for your business logic. You give each whiteboard value a key that you use to retrieve the value. You can access the whiteboard from installed conditions and actions in the Rule Editor as well as from your component code.Whiteboard values are accessed in a condition or action property sheet in the Rule Editor.

Using the !valueOf template

For some properties, you can either enter the actual value or specify a whiteboard key that holds the value. You can also specify a key that holds the name of another key.

In the Rule Editor, if a condition or action property has a caret (^) as part of its name, you can use the special code !valueOf.whiteboardkey, where whiteboardkey is the name of the key whose value you want. The rule substitutes the key's value for the special code.

To specify a whiteboard key, use this format:

  !valueOf.keyname

where keyname is a key that exists on the whiteboard when the application runs the rule.

NOTE   keyname is case sensitive.

Using built-in whiteboard values

There are several built-in constants you can use like whiteboard keys in !valueOf expressions. They provide information about the logged-in user, the rule that is being run, and the current date and time:

Constant

Description

userID

The ID for the user logged in to the application. If the user is not logged in, the userID is anonymous. If the user's session times out, the userID reverts to anonymous.

today

The current date. The value is returned as a string using the date format appropriate for the user's locale.

now

The current time as a number, returned as a string. The time value is the difference (measured in milliseconds) between the current time and midnight on January 1, 1970 UTC (Coordinated Universal Time).

response

The text stored in the response phrase of the context object. Many rule actions assign a value to the response phrase.

ruleID

The ID of the rule currently being run.

ruleDesc

The description of the rule currently being run.

uri

A reference to the content currently set in the browser.

Example of !valueOf

In the following panel, the ReturnResponseWithDefault action has a Default property for a message to the user. In the message, you can refer to values on the whiteboard. This sample text uses the system whiteboard value userID and a key called appname, created by the application:

  The current user !valueOf.userID is authorized to get more data from the application !valueOf.appname.

reValueOf

Accessing object attributes from the whiteboard

If an item on the whiteboard is a programming object rather than plain text, you can access any attributes (instance variables) associated with the object. You can refer to object attributes on the whiteboard with this format:

  !valueOf.whiteboardkey^attributename

For example, if your application puts an EbiUser object on the whiteboard, you can get the user's last name this way:

  !valueOf.myUser^lastName

Accessing whiteboard values

The context object provides several methods for accessing values stored on the whiteboard.

For more information    For more information, see Context methods for accessing the whiteboard.

Removing values from the whiteboard

You can use an eraser to remove a whiteboard key at a designated time or after a specified number of accesses. An eraser has the same name as the whiteboard key it will erase. You can use the installed actions AddEraser and RemoveEraser to manage erasers. You can also access eraser methods from the com.sssw.fw.api.EbiWhiteboard class.

 
Top of page

Accessing and firing rules

When you fire a rule, the Rule subsystem evaluates the conditions for a decision node (the When section in the Rule Editor) and if true, executes the node's actions (Do section). If no decision node evaluates to true, it executes the default actions, if any (Otherwise Do section). The result of the action is then returned to the application.

NOTE   You can fire rules from an EbiContext object or from an EbiRuleManager. The rule manager provides additional methods for firing and accessing rules and is the recommended implementation for applications that use rules extensively.

 
Top of section

Methods for firing rules

Here are the context and rule manager methods for firing rules:

Method

In class

When to use

fireRule()

EbiContext

EbiRuleManager

When you have defined and saved a rule in the Rule Editor.

fireTemporaryRule()

EbiContext

EbiRuleManager

When you have a rule definition as an XML string. This allows you to fire a rule by providing the entire XML rule definition, rather than a rule ID defined in the Rule Editor in Workbench.

For more information    See Firing temporary rules.

isTrue()

EbiRuleManager

When a rule defined in Workbench sets the response status to a true or false value. The isFalse() method fires the specified rule and reports whether the rule returned a true value.

isFalse()

EbiRuleManager

When a rule defined in Workbench sets the response status to a true or false value. The isFalse() method fires the specified rule and reports whether the rule returned a false value.

 
Top of section

Firing rules from the context object

Typically, you fire rules from a Director component or from a component in a JSP page. First you need to instantiate a rule context object. When you create a component using the Portal Component Wizard in Workbench, the code template passes an EbiPortalContext object to the getComponentData() method.

  public void getComponentData(com.sssw.portal.api.EbiPortalContext context, java.util.Map params)
   {

You use this context object to get the rule EbiContext. Here is the code needed to fire a rule:

       com.sssw.re.api.EbiContext ctx = 
         com.sssw.re.factory.EboFactory.createEbiContext(
         context.getEbiRequest().getHttpServletRequest(),
         context.getEbiResponse().getHttpServletResponse(),
         context.getServletContext());
              
     ctx.fireRule("myapp.accessRule");
  // handle the result...

where myapp is the rule owner and access rule is the rule ID. If the rule does not have an owner, just specify the rule ID.

 
Top of section

Firing rules from a rule manager

A rule manager allows you to fire rules without specifying the owner each time. You can invoke a rule manager for a particular owner and fire rules by specifying the rule ID.

This code instantiates a rule manager for the owner myapp and fires a rule. Specifying the owner is not necessary:

  public void getComponentData(com.sssw.portal.api.EbiPortalContext context, java.util.Map params)
    {
      EbiRuleManager rm = com.sssw.re.factory.EboFactory. 
        createRuleManager( "myapp" );
    /** For rules with no owner
     EbiRuleManager rm = com.sssw.re.factory.EboFactory.createRuleManager();
    */
     com.sssw.re.api.EbiContext ctx = 
         com.sssw.re.factory.EboFactory.createEbiContext(
         context.getEbiRequest().getHttpServletRequest(),
         context.getEbiResponse().getHttpServletResponse(),
         context.getServletContext());
     rm.fireRule("myRule", ctx);

Regardless of the owner you used to instantiate a rule manager, you can fire any rule as you would from the context object by specifying an owner:

  rm.fireRule("secondApp.contentRule", ctx);

 
Top of section

Firing rules from a JSP page

You can also get a rule manager outside a component directly from a JSP page or a servlet. In this case you need to get a class that extends HttpServlet and call getServletContext(). Then you can get the rule manager and fire the rule the same way you would from a component:

  public class reTester extends HttpServlet
  {
     ServletContext m_servletContext = null; 
      public void init( ServletConfig config )
          throws ServletException
       {
         super.init( config );
          // Initialize any instance variables...
          m_servletContext = config.getServletContext();
       }
     // Create a rule manager and fire the rule
     EbiRuleManager rm = com.sssw.re.factory.EboFactory. 
        createRuleManager();
     com.sssw.re.api.EbiContext ctx = 
         com.sssw.re.factory.EboFactory.createEbiContext(
         m_servletContext.getEbiRequest().getHttpServletRequest(),
         m_servletContext.getEbiResponse().getHttpServletResponse(),
         m_servletContext.getServletContext());
     rm.fireRule(myRule, ctx);

 
Top of section

Firing temporary rules

Typically you define rules in the Workbench Rule Editor, where they are saved to a known location in your Director project resource set. This is what allows you to reference rules by rule name. Temporary rules are XML strings that can be referenced directly. You can get the XML for a rule by defining it in the Rule Editor and exporting the XML using EbiRuleManager.toXMLString(). You can also specify the XML by following the rule XML DTD.

For more information    For more information, see the rule DTD and sample XML in your Director project source directory at:

library/RuleService/RuleService-conf/DTD/rule_3_0.dtd

library/RuleService/RuleService-conf/DTD/rule-basicRule_3_0_sample.xml

Here is how you fire a temporary rule from the component context object:

  string xmlrule =...;
  cxt.fireTemporarayRule(xmlrule);

Here is how you fire a temporary rule from the rule manager:

  rm.fireTemporaryRule(xmlrule, ctx);

 
Top of page

Handling the result of a rule

This section describes methods you can use in your component to handle HTTP response values and whiteboard values returned from a rule, and includes some code examples.

 
Top of section

Context methods for accessing HTTP response values

Here are the methods available on the rule EbiContext to handle HTTP response values:

Accessor method

Usage

get/setResponsePhrase()

Accesses an HTTP response phrase. A response phrase can be used to pass data between an action and the firing component.

Typically, actions set a response phrase by calling setResponsePhrase(); the firing component can then retrieve the data by calling getResponsePhrase(). When your action sets a response phrase, it should also set a response type by calling the setResponseType() method.

get/setResponseStatus()

Accesses an HTTP response status code. A response status code tells the calling object the status of the return value. For example, the action Return True returns the status code 200. Return False returns 412. HTTP status codes are defined in EbiResponse.

Typically, actions set the status code by calling setResponseStatus(); the firing component calls getResponseStatus() to retrieve the code.

NOTE   If a rule action returns true or false, use the isTrue() or isFalse() method to fire the rule. For more information, see Methods for firing rules.

get/setResponseType()

Accesses the type of value associated with the response phrase. Response types are defined in EbiResponse as CONTENT, HTML, TEXT, and URL.

 
Top of section

Context methods for accessing the whiteboard

This section describes some EbiContext methods to store and retrieve session and object values from the whiteboard.

Method

Description

get/setValue()

Gets the Object associated with a specified whiteboard key. Use these methods for values that need to persist during the session.

get/setTemporaryValue()

Gets the Object associated with a specified whiteboard key. Use these methods for values that do not need to persist beyond the initiating request.

get/setValueNames()

Gets an array of the whiteboard keys that are defined in the session.

hasValue()

Checks whether the specified key has a value on the whiteboard.

merge()

Processes text that contains !valueOf expressions. The merge() method finds !valueOf expressions in the passed template, gets the keyname associated with it, and gets the value of that key from the whiteboard.

removeValue()

Removes a value associated with the specified key from the whiteboard.

removeValues()

Removes all values and their keys from the whiteboard.

 
Top of section

Examples of handling return values

This section provides some code examples for handling values returned by rules in your application components.

Example of a rule that returns a boolean

This code from the Human Resources sample component fires a rule called bonus whose owner is sample.

The bonus is based on this rule: "If today is a weekday, display the value the bonus is $100,000; otherwise, display $1."

The rule's actions return true or false by setting the response status to 200 for true and 412 for false. The component code determines what to do with those results.

  try 
  {
    // get a rule manager and context objects
     EbiRuleManager rm = com.sssw.re.factory.EboFactory. 
       createRuleManager();
     com.sssw.re.api.EbiContext ctx = 
        com.sssw.re.factory.EboFactory.createEbiContext(
        context.getEbiRequest().getHttpServletRequest(),
        context.getEbiResponse().getHttpServletResponse(),
        context.getServletContext());
  
     Double bonusAmount = null;
  
     // fire rule to determine bonus
     if ( rm.ruleExists( "bonus" ) ) 
     {
        if (rm.isTrue( "bonus", context ))
           bonusAmount = new Double(100000.00);
        else
           bonusAmount = new Double(1.00);
     }
     else
        bonusAmount = new Double(0.00);
  } 
  catch (Exception e) 
  {
     e.printStackTrace();
     System.out.println(
        "\nHR (getComponentData) Failed to instantiate the rule\n");
  }

Example of a rule that returns data

Building on the preceding example, suppose the rule returns a bonus amount instead of true or false. Both the Do and Otherwise Do actions are ReturnContentFromData, rather than ReturnTrue and ReturnFalse. Do gets the value bonus1 and Otherwise Do gets bonus2 from the whiteboard. The selected action returns the value as a response phrase, which is available from the context object by calling getResponsePhrase().

Before firing the rule, a component must get the values (from a company database, for example) and call EbiContext.setValue() to set the values for the whiteboard keys bonus1 and bonus2 in this user's session:

  String bonusString = "0";
  Double bonusAmount = null;
  
  // get a rule manager and context objects
  EbiRuleManager rm = com.sssw.re.factory.EboFactory. 
    createRuleManager();
  com.sssw.re.api.EbiContext ctx = 
     com.sssw.re.factory.EboFactory.createEbiContext(
     context.getEbiRequest().getHttpServletRequest(),
     context.getEbiResponse().getHttpServletResponse(),
     context.getServletContext());
  
  // fire rule to determine bonus
  if ( rm.ruleExists( "bonus" ) ) 
  {
     context.setValue("bonus1", ...); // retrieve value from db
     context.setValue("bonus2", ...); // retrieve value from db
     rm.fireRule( "bonus", context );
     bonusString = context.getResponsePhrase();
     bonusAmount = Double.valueOf(bonusString);
  }

Example of a rule that uses a whiteboard value

Again using the bonus example, suppose instead that the bonus value is set in the Rule Editor. The Do and Otherwise sections both use the installed action Return Response, where the bonus amounts are specified:

  String bonusString = "0";
  Double bonusAmount = null;
  
  // get a rule manager and context objects
  EbiRuleManager rm = com.sssw.re.factory.EboFactory. 
    createRuleManager();
  com.sssw.re.api.EbiContext ctx = 
     com.sssw.re.factory.EboFactory.createEbiContext(
     context.getEbiRequest().getHttpServletRequest(),
     context.getEbiResponse().getHttpServletResponse(),
     context.getServletContext());
  
  // fire rule to determine bonus
  if ( rm.ruleExists( "bonus" ) ) 
  {
     rm.fireRule( "bonus", context );
     bonusString = context.getResponsePhrase();
     bonusAmount = Double.valueOf(bonusString);

 
Top of page

Using pipelines

A pipeline is a mechanism for binding a rule or set of rules to a known user or group, or for firing a set of rules in a specified order as a unit.

You set up a pipeline using the Pipeline and Binding Editors in Workbench.

For more information    For information about setting up pipelines in Workbench, see Pipeline and Binding Editors.

 
Top of section

Benefits of pipelines

Pipelines enhance the power of rules by providing a higher level of logical encapsulation and reusability, while maintaining the benefits of tool-based maintenance and the hot deployment capability. Here is a summary of some of the benefits:

Benefit of pipelines

Details

Easy to organize and maintain complex logic

Pipelines are especially useful for applications with complex logic that depends on one or more top-level conditions. This is especially relevant with user and group bindings.

For example, a corporate Web site might be driven primarily by user or organizational group. You might have rules that stop processing under certain conditions, or whose actions fire other rules under other conditions. It would be much easier to maintain this kind of logic in a single pipeline, especially if the logic needs to be updated frequently.

Enhances separation of logic and presentation

When you validate a pipeline, the application does not need to know what rules will be fired—only what value will be returned.

For example, you can avoid firing rules in case statements and let the pipeline handle this higher-level logic. This means that you can push more of your business logic out of your component or JSP page, which can be used to handle presentation.

Enhances rule reusability

Pipelines are reusable, just like rules. You might have two or more applications that share logic that can be built into pipelines.

 
Top of section

How pipelines work

When you create a pipeline, you can associate it with one or more binders, of which there are three types:

Binder type

When to use

User

To fire rules associated with a specified user. The rules will fire only when this user is in the application session.

Group

To fire rules associated with a specified group. The rules will fire only when a member of this group is in the application session.

Pipeline

To fire rules associated with the specified pipeline.

Here is how a pipeline is processed:

rePipeline

After you create a pipeline, you use the appropriate Binding Editor to select a rule or rules and specify the order in which you want them to fire. Then you use the validate() method to execute the pipeline in your component. You handle the result of the pipeline the same way you handle the result of a rule.

For more information    For more information, see Handling the result of a rule.

 
Top of section

Validating a pipeline

Firing the rules in a pipeline is called validating the pipeline. You use the validate() method on the EbiContext object.

First you need to get the EbiContext, as shown in Firing rules from the context object.

This code validates the pipeline you specify:

  ctx.validate("CheckAllAccessRestrictions");

This code sets a pipeline ID in the EbiContext object and validates it:

  ctx.setPipelineID("CheckAllAccessRestrictions");
  ctx.validate();}


    First Previous Next Last

Rules Guide  

Copyright © 2002, SilverStream Software, LLC, a wholly owned subsidiary of Novell, Inc. All rights reserved.