Oracle® Business Rules User's Guide 10g (10.1.3.1.0) Part Number B28965-02 |
|
|
View PDF |
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:
The top level Rules SDK package, oracle.rules.sdk,
includes the following packages:
oracle.rules.sdk.repository
oracle.rules.sdk.dictionary
oracle.rules.sdk.editor.datamodel
oracle.rules.sdk.editor.ruleset
oracle.rules.sdk.exception
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.
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 |
|
The URL for the desired WebDAV rule repository. This parameter is required. |
Proxy Host |
|
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 |
|
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 |
|
The path to the file that contains the rule repository. This parameter is required. |
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-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);
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.
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 |
---|---|---|
|
Represents the occurrence of a message |
Java FactType |
|
Represents an e-mail address |
Java FactType |
|
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 |
---|---|---|
|
Asserted when an e-mail message is determined to be spam |
RL FactType |
|
Accumulates count of spam messages |
variable |
|
Constant containing the |
constant variable |
|
Called when spam found to delete spam |
RL function |
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.
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.
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");
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.
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).
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 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.
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.
Generally, the sequence you use to create a RuleComponent
object is:
Create a RuleSet
instance by use of a RuleSet
constructor.
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.
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.
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.
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\"");
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());
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()
.