Rules Guide

CHAPTER 2

How You Use Rules

This chapter describes how you use rules in your applications. It has these sections:

 
Top of page

How rules work

As stated in the first chapter, a rule is a combination of conditions and actions that return a value. You define rules in the exteNd Director Rule Editor, and then access rules and handle the results in your exteNd Director application code.

 
Top of section

Basic process

Using rules is a three-step process:

  1. In 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.

 
Top of section

Rule application components

These are the components for building rules:

Component

Description

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, which 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 EbiContext (the context object).

 
Top of page

Working with conditions and actions

You use the exteNd Director's Rule Editor to create rules by selecting installed (prebuilt) conditions and actions.

NOTE:   Before creating rules, you should become familiar with the Rule Editor. 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

An exteNd 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 application 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 section

Accessing scoped paths

The ^ template field in conditions and actions also supports substitution syntax for scoped paths. Scoped paths allow you to access different types of data in your exteNd Director applications, such as documents in the resource set and the Content Management subsystem.

You can specify a scoped path using this format:

  ${spath}

For more information    For more information, see the chapter on working with scoped paths and XPaths in Developing exteNd Director Applications.

 
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, the Rule subsystem executes the default actions (Otherwise Do section— if any. 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 exteNd Director.

For more information    See Firing temporary rules.

isTrue()

EbiRuleManager

When a rule defined in exteNd Director 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 exteNd Director 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 an exteNd Director portlet or a JSP page. First you need to instantiate a rule context object using this method:

  public static EbiContext createEbiContext(HttpServletRequest
   request, HttpServletResponse response, ServletContext 
     servletContext) 
  throws EboFactoryException

You can get the request and response objects from an EbiContext object, which you can instantiate using another factory method.

Here is sample code showing how to fire a rule from a portlet's doView() method; where myapp is the (optional) rule owner and access rule is the rule ID:

  public void doView( RenderRequest req, RenderResponse res ) {
   try{
  // get an EbiContext from the RenderRequest
    com.sssw.fw.api.EbiContext context =
     com.sssw.fw.factory.EboFactory.createEbiContext( req, res, 
        GenericPortlet.getPortletContext() );
  // Get the rule context    
    reContext = com.sssw.re.factory.EboFactory.createEbiContext(
      context );
  // Fire the rule
      reContext.fireRule("myapp.accessRule");
  // handle the result...
  // Catch excepions ...

 
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 in a portlet:

  public void doView( RenderRequest req, RenderResponse res ) {
   try{
    {
      // If a rule owner exicts
      EbiRuleManager rm = com.sssw.re.factory.EboFactory. 
        createRuleManager( "myapp" );
    /** For rules with no owner
     EbiRuleManager rm = 
        com.sssw.re.factory.EboFactory.createRuleManager();
    */
    // get an EbiContext from the RenderRequest
    com.sssw.fw.api.EbiContext context =
     com.sssw.fw.factory.EboFactory.createEbiContext( req, res, 
        GenericPortlet.getPortletContext() );
  // Get the rule context    
    reContext = com.sssw.re.factory.EboFactory.createEbiContext(
      context );
     rm.fireRule("myRule", reContext);
  // handle the result...
  // Catch excepions ...

NOTE:   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", reContext);

 
Top of section

Firing rules from a JSP page

You can also get a rule manager 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 portlet:

  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 exteNd Director Rule Editor, where they are saved to a known location in your exteNd 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().

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

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

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

  rm.fireTemporaryRule(xmlrule, reContext);

 
Top of page

Handling the result of a rule

This section describes methods you can use 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

This table lists 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 application code.

Typically, actions set a response phrase by calling setResponsePhrase(); the application code 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 application code 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 table lists 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 code.

Example of a rule that returns a boolean

This code shows a portlet that 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 code determines what to do with those results:

  public void doView(RenderRequest req, RenderResponse res) {
   try {
     //get the context
     com.sssw.fw.api.EbiContext context =
       com.sssw.fw.factory.EboFactory.createEbiContext(req,
         res, GenericPortlet.getPortletContext());
     // Get the rule manager
     EbiRuleManager rm =
       com.sssw.re.factory.EboFactory.createRuleManager("sample" );
     // Get the rule context
     com.sssw.re.api.EbiContext reContext =  
        com.sssw.re.factory.EboFactory.createEbiContext(context);
    // nitialize bonus
     Double bonusAmount = null;
     
   // Fire rule to determine bonus.
    if (rm.ruleExists( "bonus" ) ) 
    {
      if (rm.isTrue( "bonus", reContext ))
       bonusAmount = new Double(100000.00);
      else
       bonusAmount = new Double(1.00);
    }
    else
     bonusAmount = new Double(0.00);
   } 
  catch (Exception e) 
   {
   // ..exception handling ...  
    }
  }

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.

Before firing the rule, you 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.fw.api.EbiContext context =
    com.sssw.fw.factory.EboFactory.createEbiContext(req,
       res, GenericPortlet.getPortletContext());
  com.sssw.re.api.EbiContext reContext =  
    com.sssw.re.factory.EboFactory.createEbiContext(context);
  
  // 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", reContext );
     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 Do 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 as shown 
  // in previous example.
  
  // Fire rule to determine bonus.
  if ( rm.ruleExists( "bonus" ) ) 
  {
     rm.fireRule( "bonus", reContext );
     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 exteNd Director's Pipeline and Binding Editors.

For more information    For information about setting up pipelines in exteNd Director, 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.

Enhanced 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 you can push more of your business logic out of your portlet or JSP page, which can be used to handle presentation.

Enhanced 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 application code. 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();}


Copyright © 2004 Novell, Inc. All rights reserved. Copyright © 1997, 1998, 1999, 2000, 2001, 2002, 2003 SilverStream Software, LLC. All rights reserved.  more ...