Skip Headers
Oracle® Business Rules User's Guide
10g (10.1.3.1.0)

Part Number B28965-02
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Index
Index
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
View PDF

6 Using Oracle Business Rules SDK

Oracle Business Rules SDK (Rules SDK) provides APIs that a developer can use to write customized applications that access, create, or modify rules and data models (and all the information stored in an Oracle Business Rules dictionary). Using Rules SDK APIs, you can create, modify, and access dictionary data using well-defined interfaces, and you can use the APIs to build customized rule-enabled applications.

You can use the Rules SDK APIs in a rule-enabled application to access existing rules and then run Rules Engine, or in an application that you write to access, create, or edit rules and data model information.

This chapter introduces the Oracle Business Rules SDK APIs.

This chapter includes the following sections:

6.1 Rules SDK Building Blocks

The top level Rules SDK package, oracle.rules.sdk, includes the following packages:

The Rules SDK interface follows the JavaBeans model and includes getters and setters for each bean property. For example, setName("somevalue") sets the name property of the individual instance.

In addition to bean interfaces, the Rules SDK provides a hash get and put style interface. The bean interfaces are generally useful, but the HashMap style is necessary for at least one GUI framework.

6.2 Working with a Repository and a Dictionary

Oracle Business Rules dictionaries are stored in a repository. Prior to accessing a dictionary, access to its repository must be established. This requires specifying the type of repository to access and the initialization parameters required by that specific repository type. As shipped, Rule Author supports a WebDAV (Web Distributed Authoring and Versioning) repository and a file repository.

Table 6-1 shows the initialization parameter keys for a WebDAV repository. The repository type key is oracle.rules.sdk.store.webdav.

Table 6-1 WebDAV Repository Type Parameter Initialization Keys

Parameter Key Description

URL

oracle.rules.sdk.store.webdav.url

The URL for the desired WebDAV rule repository. This parameter is required.

Proxy Host

oracle.rules.sdk.store.webdav.proxyHost

The host name of the proxy server. This is only required if you have a proxy server between the server on which Rule Author is running and the WebDAV server.

Proxy Port

oracle.rules.sdk.store.webdav.proxyPort

The port to use for the proxy server. This is only required if you have a proxy server between the server on which Rule Author is running and the WebDAV server.


Table 6-2 shows the initialization parameter keys for a file repository. The repository type key is oracle.rules.sdk.store.jar.

Table 6-2 File Repository Type Parameter Initialization Key

Parameter Key Description

File Path

oracle.rules.sdk.store.webdav.path

The path to the file that contains the rule repository. This parameter is required.


6.2.1 Establishing Contact with a WebDAV Repository

Example 6-1 shows how to establish access to a WebDAV repository.

Example 6-1 Establishing Access to a WebDAV Repository

String url;     // the URL for the WebDAV repository
Locale locale;  // the desired Locale

// The following code assumes that the url and locale have been set appropriately
RepositoryType rt =
   RepositoryManager.getRegisteredRepositoryType("oracle.rules.sdk.store.webdav");
RuleRepository repos = RepositoryManager.createRuleRepositoryInstance(rt);
RepositoryContext rc = new RepositoryContext();
rc.setLocale(locale);
rc.setProperty("oracle.rules.sdk.store.webdav.url", url);
repos.init(rc);

If the WebDAV repository has been configured to require authentication, then the following must be performed:

  • Configure a wallet with the required user name(s) and password(s).

  • Create an instance of the oracle.rules.sdk.callbacks.WalletCallback class and set it in the RepositoryContext prior to calling the init method.

In Example 6-2, /wallets/rules_wallet is the path to the wallet configured with the credentials for WebDAV authentication:

Example 6-2 Configuring a Wallet for Authentication

WalletCallback callback = new WalletCallback("/wallets/rules_wallet", null);
rc.setSensitiveDataCallback(callback);

6.2.2 Establishing Contact with a File Repository

Example 6-3 shows how to establish access to a file repository.

Example 6-3 Establishing Access to a File Repository

String path;     // the path to the file repository
Locale locale;  // the desired Locale

// The following code assumes that the path and locale have been set appropriately
RepositoryType rt =
   RepositoryManager.getRegisteredRepositoryType("oracle.rules.sdk.store.jar");
RuleRepository repos = RepositoryManager.createRuleRepositoryInstance(rt);
RepositoryContext rc = new RepositoryContext();
rc.setLocale(locale);
rc.setProperty("oracle.rules.sdk.store.jar.path", path);
repos.init(rc);

6.2.3 Loading a Dictionary

Now, a dictionary may be loaded either by specifying the dictionary name, in which case, the default version of the dictionary is loaded with:

RuleDictionary dictionary = repos.loadDictionary(dictionaryName);

or by specifying both the dictionary name and version with:

RuleDictionary dictionary = repos.loadDictionary(dictionaryName,
                                                 dictionaryVersion);

These examples are applicable to both file and WebDAV repositories.

6.3 Working with a Data Model

The Rules SDK data model contains the fact types, internal variables, constraints, and functions that you use to create rules. The fact types from the data model can be reasoned on in corresponding rules. Oracle Business Rules variables contain information that rules share. Oracle Business Rules functions provide for logic reuse for rules. Constraints limit the set of valid values for rule customization.

Note:

To import existing Java classes or XML schemas, the Rule Author application must be used. After the classes or schemas are imported with Rule Author, the repository may be used by the SDK. Future versions of the SDK will have extensions to allow for Java classes and XML schemas to be imported directly.

After you use a repository to create or open a RuleDictionary object, you can use the Rules SDK to create a data model in the dictionary. A RuleDictionary object can access the internal data structures necessary to create a DataModel instance.

The data model shown in the examples is this chapter includes the Java FactTypes that are imported from a sample package named email. The email package was imported using Rule Author. The classes and properties shown in Table 6-3 were populated by importing email.jar.

Table 6-3 Sample email Package Classes

Name Description Type

email.ElectronicMessage

Represents the occurrence of a message

Java FactType

email.EmailAddress

Represents an e-mail address

Java FactType

email.EmailAddressList

Represents a list of e-mail addresses

Java FactType


In the data model for the spam processing example, using the email package, the data model supports inferencing by creating an RLFact object named SpamFound. To contain a global count, we create a variable named spamCounter, and the constant String variable indicates spam. A function named killSpam provides an action when the rules detect that an e-mail message is spam. Table 6-4 shows these data model components.

Table 6-4 Sample Data Model Types for Handling the E-mail Package

Name Description Type

SpamFound

Asserted when an e-mail message is determined to be spam

RL FactType

spamCounter

Accumulates count of spam messages

variable

SpecialOffer_CONST

Constant containing the String "Special Offer"

constant variable

fKillSpam

Called when spam found to delete spam

RL function


6.3.1 Creating a Data Model

After you create and open a RuleDictionary object, you can use Rules SDK to create an editor.DataModel instance. The RuleDictionary object can access the internal data structures necessary to create a DataModel instance.

For example,

eDM = new oracle.rules.sdk.editor.datamodel.DataModel(m_dict);

The basis of the DataModel type system is the FactType object. A FactType object is defined as a primitive, Java, XML, or RL FactType. A Primitive FactType is fixed, and includes Java primitives (for example: String, int, or double). Rules SDK automatically creates primitive types when you create a RuleDictionary. You create Java and XML FactTypes when you import classes from jar file, a class, or a schema file. You can create RL FactTypes directly using the Rules SDK. The Java, XML, and RL FactTypes define classes and may have associated properties, which represent the JavaBeans defined properties, and methods.

6.3.2 Creating Data Model Components

You create each part of the data model using the appropriate ModelComponentTable object. The sequence required to create a new instance (Function, FactType, Variable, or Constraint) is the same:

  • Instantiate the appropriate table in the data model.

  • Invoke the table instance add() method.

Example 6-4 shows how you create a Function instance:

Example 6-4 Creating a Function Instance

FunctionTable ft = eDM.getFunctionTable();
Function fKillSpam = ft.add();

To import existing Java classes or XML schemas, the Rule Author application must be used. After the classes or schemas are imported with Rule Author, the repository may be used by the SDK. Future versions of the SDK will have extensions to allow for Java classes and XML schemas to be imported directly.

6.3.3 Creating a Function Argument List

In Rules SDK you create argument lists for functions using a FormalParameterTable object. Each FormalParameter entry represents a parameter. The first parameter is the first (zero) entry in the FormalParameterTable, the second parameter is the second entry, and so on. Variables may be constants, which may not be assigned a value after the original initialization. The setFinal() method controls the constant behavior. Each FormalParameter object has a type and a name. The type of a FormalParameter is selected from the available FactTypes.

The code in Example 6-5 creates a FormalParameterTable object for the email sample.

Example 6-5 Creating a FormalParameterTable

// define the parms of the function
// basically just an instance of ElectronicMessage
// and a String to explain what triggered this
FormalParameterTable fKillSpamParmTable = fKillSpam.getFormalParameterTable();
FormalParameter fp1 = fKillSpamParmTable.add();
FormalParameter fp2 = fKillSpamParmTable.add();
fp1.setName("emsg");
fp1.setAlias("Email Message");

// use the alias for the email.ElectronicMessage fact type
// will be in the getType_Options list
fp1.setType("email.ElectronicMessage");
fp2.setName("reason");
fp2.setAlias("reason");

 // use the primitive type for String
 // will be in the getType_Options list
fp2.setType("String");

6.3.4 Creating an Initializing Expression

In Rules SDK, variables contain state internal to a RuleSet. Each variable must have a type and an initializing Expression. The variable type of is chosen from the list of possible FactTypes (all FactTypes defined in the DataModel).

There are two types of expressions:

  • Expression

    This type of expression must follow the form:

    operand operator operand
    
    

    The operands and operators available for an Expression are more limited than than those for an AdvancedExpression. For example, an Expression does not allow an operand to be a function requiring parameters.

  • AdvancedExpression

    This type of expression allows for the full range of operands and operators.

It is recommended that you use an AdvancedExpression to initialize an expression. Example 6-6 shows how to set a variable's initial value.

Example 6-6 Setting a Variable's Initial Value

InitialValue iv = var.getValue();
AdvancedExpression adv = iv.getAdvancedExpression();
adv.insert(0, "\"FIXEDVALUE\"");

6.3.5 Creating RL Function Bodies

RL Function bodies are composed of strings of RL Language. They may refer to any of the Function parameters, or any global Variable. Enter function bodies as a String that must be syntactically correct RL Language (see Example 6-7).

Example 6-7 Creating a Function Body

//set the body of the function
// in this case just pretty print a message
fKillSpam.setBody(" println(\" email from: \" + emsg.getSender() + \"  because \" + reason)" );

6.4 Using Rule Sets and Creating and Modifying Rules

In Rules SDK, a rule is a conditional expression (referred to as a condition) and a set of actions that execute if the condition evaluates to true. A rule condition is composed of a set of patterns. A pattern delineates the match type and includes tests against that type and other types that appear in preceding patterns (order has meaning). Rule actions can be calls, assignments, retractions, and assertions.

Figure 6-1 shows the general container hierarchy for a RuleSet.

Figure 6-1 Rules SDK RuleSet Container Hierarchy

Rules SDK RuleSet Container Hierarchy
Description of "Figure 6-1 Rules SDK RuleSet Container Hierarchy"

Rules SDK provides classes that represent each of these objects; all classes descend from RuleComponent. For collections, for example rules in a rule set, patterns in a rule, or actions in a rule, Rules SDK provides a class that is descended from the RuleComponentTable to manage a specific collection (see Figure 6-2). The RuleComponentTable subclass provides a specialized add() method for the particular subclass that the table represents.

Figure 6-2 Rules SDK RuleComponents

Rule SDK RuleComponents
Description of "Figure 6-2 Rules SDK RuleComponents"

The Rules SDK components describing the XML schemas, Java classes, RL Global variables, and RL Functions are located in the data model (stored in the dictionary). Typically, RuleComponent instances refer to data model entities.

6.4.1 Creating a Rule Set

Generally, the sequence you use to create a RuleComponent object is:

  1. Create a RuleSet instance by use of a RuleSet constructor.

  2. Create any children of the RuleSet by add() methods on the appropriate table (PatternTable, ActionTable, ExpressionTable, SimpleTestTable).

The Rules SDK API provides classes that represent collections in a RuleSet. Each of these objects descend from RuleComponent. For collections, for example rules in a ruleset, or patterns in a rule or actions in a rule, the Rules SDK provides classes that are descended from RuleComponentTable class to manage a specific collection. The RuleComponentTable subclass provides a specialized add() method for the particular subclass represented by the table.

The code in Example 6-8 creates a RuleSet for the e-mail sample.

Example 6-8 Creating a RuleSet

oracle.rules.sdk.editor.ruleset.RuleSet rs = null;
  try
    {
      rs = new oracle.rules.sdk.editor.ruleset.RuleSet(m_dict);
      m_curBean = rs;
      rs.setName("SpamRuleSet");
    }
    catch (Exception e)
    {
      System.out.println(" create RuleSet FAILED");
      addException(e);
      return;
    }

6.4.2 Adding a Rule to a Rule Set

Rules SDK provides classes that represent the objects in a RuleSet. Each of these objects descend from RuleComponent object. For collections, for example rules in a ruleset, or patterns in a rule or actions in a rule, Rules SDK provides classes that are descended from RuleComponentTable class to manage a specific collection. The RuleComponentTable subclass provides a specialized add() method for the particular subclass represented by the table.

Several classes are not parts of collections. To access these classes, use the parent bean with the getter interface. For example, acquire the AdvancedExpression by invoking getAdvancedExpression() on the correct Pattern instance.

The code in Example 6-9 shows how to add a rule to a table in Rule Set.

Example 6-9 Adding a Rule to a Table in a Rule Set

//add rule to the table
oracle.rules.sdk.editor.ruleset.Rule r = rs.getRuleTable().add();
r.setName("DetectSpamRule");

6.4.3 Adding a Pattern to a Rule

The Rules SDK API provides the Pattern class that represents a pattern. The getPatternTable subclass provides a specialized add() method for adding a pattern object, as shown in Example 6-10.

Example 6-10 Adding a Pattern to a Rule

//add pattern to the rule
oracle.rules.sdk.editor.ruleset.Pattern p = r.getPatternTable().add();

//set pattern
p.setVariable("xx");
p.setFactType( "email.ElectronicMessage");
p.setTestForm("Advanced");

The TestForm property defines the type of test associated with the pattern.

6.4.4 Adding a Test to a Pattern

Every Pattern may have tests associated with the Pattern. Tests may take the form of SimpleTest objects or AdvancedExpression objects A Pattern may have an unlimited number of tests.

The Rules SDK "ANDs" tests together when generating RL Language. For example, the test used for the e-mail example requires a function with parameters. This requires an AdvancedExpression object (see Example 6-11).

Example 6-11 Adding a Test to a Pattern

AdvancedExpression adv = (AdvancedExpression)p.get("AdvancedExpression");

// FUNCTION and Variable complex expression
adv.put("Function", "containsString");
adv.insert(0, adv.getFunctionDescription());

//System.out.println(" function is: <<" + adv.getFunctionDescription() + ">>");
//set the function parms
// normally the cursor position is set by user input actions
adv.setVariable("SPECIAL OFFER");
adv.replace(17, 57, adv.getVariable() );
adv.insert( ((String)adv.getValue()).length() , "," );
adv.setVariable("message.subject");
adv.insert( ((String)adv.getValue()).length() + 1,
adv.getVariable() );
adv.insert( ((String)adv.getValue()).length() , " )" );
//since boolean, this is a single operator no need for anything else

If the test is of the form:

operand operator operand

where neither operand is a function requiring parameters, then a SimpleTest may be used. For example, if the pattern variable name is "emsg" and the test is "emsg.sender == david@fun.com," a simple test would look like Example 6-12:

Example 6-12 A Simple Test

// use the simple form of tests
p1.put("TestForm", Pattern.TEST_FORM_SIMPLE);

//////////////////////////////////////////////////////////////////////
// add a SimpleTest to the Pattern
// emsg.sender == "david@fun.com"
//////////////////////////////////////////////////////////////////////

//create a simple test
SimpleTest simple = p1.getSimpleTestTable().add();

// 
// emsg.sender == "david@fun.com"

// set the left side
Expression lhs = simple.getLeft();
lhs.setForm(Expression.FORM_SINGLE_TERM);

lhs.setSingleTermValue("emsg.sender");

// set the operator 
simple.setOperator("==");

// set the right hand side
Expression rhs = simple.getRight();
rhs.setForm(Expression.FORM_ADVANCED);

AdvancedExpression radv = rhs.getAdvancedExpression();
radv.insert(0, "\"david@fun.com\"");

6.4.5 Adding an Action to a Rule

The Rules SDK supports the following types of Actions:

  • Assert New

  • Assert

  • Assign

  • Call

  • Retract

  • RL

The setting in the setForm property of an action defines the type of action. Add an action using the add() method of the getActionTable instance associated with a particular rule (see Example 6-13).

Example 6-13 Defining an Action Type

//////////////////////////////////////////////////////////////////////
// Add a action to retract the instance of SpamFound
//////////////////////////////////////////////////////////////////////
act = spamRule.getActionTable().add();
act.setForm(Action.FORM_RETRACT);
act.setTarget("spamMessage");  // see above setVariable

//////////////////////////////////////////////////////////////////////
// Add a action to call the kill spam function
//////////////////////////////////////////////////////////////////////
act = spamRule.getActionTable().add();
act.setForm(Action.FORM_CALL);
act.setTarget("kill spam");
//see the datamodel fn definitions, alias for fnKillSpam

Expression exp1 = act.getExpression(0);
Expression exp2 = act.getExpression(1);

exp1.setForm(Expression.FORM_ADVANCED);
exp2.setForm(Expression.FORM_ADVANCED);
AdvancedExpression adv1 = exp1.getAdvancedExpression();
AdvancedExpression adv2 = exp2.getAdvancedExpression();

adv1.setVariable("spamMessage.Spam Email");
adv1.insert(0, adv1.getVariable());

adv2.setVariable("spamMessage.Why is this spam");
adv2.insert(0, adv2.getVariable());

6.4.6 Notes for Adding RuleSets and Rules

The order in which you add components to a RuleSet is important. Use the parent object to create a required child object. For example, after you create a RuleSet instance, you can add rules the RuleTable instance for the RuleSet. After you create the RuleSet, then you can add a Rule to the RuleSet using the add() method for the RuleTable. In turn, then add a rule pattern to the rule using the PatternTable.add() method. Finally, to create a test in the Pattern access the AdvancedExpression using getAdvancedExpression(), or for standard mode tests, use SimpleTestTable.add().