|






















|
|
Rule Project "ExternalRulesFromJava"
Step 1.
Setting Up Rule Templates
Step 2. Defining Rule
Tables in Java
Step
3. Executing External Rules from a Java Program
The OpenRulesEngine can be created with additional
parameter of the predefined type ExternalRules allowing to bring into
consideration rule tables defined as Java objects.
The
project "ExternalRulesFromDJava" demonstrates different ways of
defining external rules in Java. For simplicity
this project intends to produce
simple greetings like "Good Morning" based on the current time
of the day.
Step 1. Setting Up Rule
Templates
►top
The business logic for producing greetings is presented in the Excel file HelloTemplates.xls. The template
| Rules void defineGreeting(Request
request, Response response) |
| C1 |
A1 |
| min <= request.hour && request.hour <= max |
response.result = greeting; |
| int min |
int max |
String greeting |
| Hour From |
Hour To |
Set Greeting |
| |
|
How are you (default greeting) |
specifies how to define different greetings (Good
Morning, Good Afternoon, etc.) based on the hour of the day. The current
hour is expected to be an attribute if the object request that comes as
the first parameter. The resulting greeting is expected to be saved
inside the second parameter Response. If the
"hour" belongs to the interval [min;max] then a concrete
rule that defines this interval will be satisfied. If no rules are satisfied, this multi-hit table
will use the default greeting "How are you (default greeting)".
The second template
| Rules void defineGreetingHorizontal(Request
request, Response response) |
| C1 |
min <= request.hour && request.hour <= max |
int min |
Hour From |
|
| int max |
Hour To |
|
| A1 |
response.result = greeting; |
String greeting |
Set Greeting |
How are you (horizontal default greeting) |
demonstrates how external rules deal with horizontal
vs vertical rule tables.
Step 2.
Defining Rule Tables in Java ►top
All Java classes are typical for basic rule projects.
There is a special
constructor
OpenRulesEngine(String excelFileName,
ExternalRules rules)
that has an additional parameter of the predefined
Java type ExternalRules. You may create an object of this type like
ExternalRules externalRules = new ExternalRules();
and then add different rule tables using the method:
addRuleTable(String ruleTableName,
String ruleTemplateName,
Object[][] ruleGrid);
The complete API is described at
OpenRules API.
In this project the main Java class RunExternalRules
shows different ways for adding rule tables to the external rules. Here
is the first rule table:
externalRules.addRuleTable(
"ExternalSummerGreeting", //table name
"defineGreeting", //template name
new String[][] { //rules
new String[] {"0","11","Good Morning Summer"},
new String[] {"12","17","Good Afternoon Summer"},
new String[] {"18","21","Good Evening Summer"},
new String[] {"22","24","Good Night Summer"}
}
);
|
The first parameter specifies the rule table name. The
second parameter specifies the template based on which this table will
be created. The third parameter defines a grid that is two-dimensional
array Object[][] containing actual rules. This grid corresponds to the
template "defineGreeting" - see above. The first rule in the grid states
that IF Hour From is "0" AND Hour To is "11" THEN Set Greeting as "Good
Morning Summer", etc.
The second rule table
externalRules.addRuleTable(
"ExternalWinterrGreeting", //table name
"defineGreeting", //template name
new String[][] { //rules
new String[] {"0","12","Good Morning Winter"},
new String[] {"13","16","Good Afternoon Winter"},
new String[] {"17","22","Good Evening Winter"},
new String[] {"23","24","Good Night Winter"}
}
);
|
is very similar to the first one but defines greeting
rules for a winter season.
The second rule table
externalRules.addRuleTable(
"ExternalWinterrGreeting", //table name
"defineGreeting", //template name
new String[][] { //rules
new String[] {"0","12","Good Morning Winter"},
new String[] {"13","16","Good Afternoon Winter"},
new String[] {"17","22","Good Evening Winter"},
new String[] {"23","24","Good Night Winter"}
}
);
|
is very similar to the first one but defines greeting
rules for winter.
The third rule table
externalRules.addRuleTable(
"ExternalGreetingHorizontal", //table name
"defineGreetingHorizontal", //template name
new String[][] { //rules
new String[] {"0","11","Good Morning"},
new String[] {"12","16","Good Afternoon"},
new String[] {"17","22","Good Evening"},
new String[] {"23","24","Good Night"}
}
);
|
shows that you may use a horizontal template "ExternalGreetingHorizontal"
and still use the same vertical structure of your rules.
The fourth rule table
externalRules.addRuleTable(
"ExternalGreetingReverseOrder", //table name
"defineGreeting", //template name
new String[] { "A1","C1" }, //labels order differs from template order
new Object[][] { // not all cells contains strings but other objects
new Object[] { "Good Morning", new Integer(0),new Integer(11) },
new Object[] { "Good Afternoon", new Integer(12),new Integer(17) },
new Object[] { "Good Evening", new Integer(18), new Integer(21) },
new Object[] { "Good Night", new Integer(22),new Integer(24)}
}
);
|
shows several additional flavors that could be added
to the ExternalRules object. First of all, you can use all optional
rules and conditions along with other features available for "normal"
rules and templates - as described
here.
The array of Strings
new String[] { "A1","C1" }
placed just before the grid informs OpenRules Engine that this rule table
starts with the action A1 following by the condition C1, thus
violating the default column order in the template. The grid
Object[][]
demonstrates an ability to specify not only String but any
Java objects as long as they correspond to the types of parameters
specified in the template.
If the type of objects inside rule tables do not
correspond to the templates the proper error will be produced. For
example, if you make a mistake in the first rule table:
externalRules.addRuleTable(
"ExternalSummerGreeting", //table name
"defineGreeting", //template name
new String[][] { //rules
new String[] {"O","11","Good Morning Summer"}, //letter "O" instead of "0"
new String[] {"12","17","Good Afternoon Summer"},
new String[] {"18","21","Good Evening Summer"},
new String[] {"22","24","Good Night Summer"}
}
);
|
you will receive a compilation error that will look
like this:
org.openl.syntax.SyntaxErrorException :
Error: For input string: "O" :
java.lang.NumberFormatException
at ExternalRules#ExternalSummerGreeting?row=0&column=0&openl=
java.lang.NumberFormatException:
For input string: "O"
The error message points you to the name of the
invalid external table (ExternalRules#ExternalSummerGreeting) and
to the coordinates of the invalid cells inside the grid (row=0&column=0).
Step
3. Executing External Rules from a Java Program
►top
The main file HelloCustomer.xls defines the
Environment of our rule project as follows:
| Environment |
| import.java |
hello.* |
| include |
../include/HelloTemplates.xls |
This application uses two simple Java beans:
Request.java:
int
hour;
Response.java:
String result;
The main Java class RunExternalRules creates and
executes an
OpenRulesEngine in the standard way:
String fileName = "file:rules/main/HelloCustomer.xls";
OpenRulesEngine engine = new OpenRulesEngine(fileName,externalRules);
System.out.println(
"\n=====================================================\n" +
"OpenRulesEngine: " + fileName +
"\n=====================================================\n");
Response response = new Response();
Request request = new Request();
request.setHour(Calendar.getInstance().get(Calendar.HOUR_OF_DAY));
Object[] params = new Object[] { request, response };
for (int i = 0; i < externalRules.getRuleTables().size(); i++) {
RuleTable rules = (RuleTable)externalRules.getRuleTables().get(i);
System.out.println(rules);
engine.run(rules.getTableName(), params);
System.out.println("Greeting generated by rules '" + rules.getTableName() +
"' for hour " +request.hour +": " + response.result );
System.out.println();
}
|
To run the project you may double-click on the file "run.bat".
Here is an expected output:
INITIALIZE OPENRULES ENGINE 5.3.0 (build 03092009) for [file:rules/main/HelloCustomer.xls]
External rules table: ExternalSummerGreeting
External rules table: ExternalWinterGreeting
External rules table: ExternalGreetingHorizontal
External rules table: ExternalGreetingReverseOrder
IMPORT.JAVA=hello.*
INCLUDE=../include/HelloTemplates.xls
[../include/HelloTemplates.xls] has been resolved to [file:<...>/rules/include/HelloTemplates.xls]
=====================================================
OpenRulesEngine: file:rules/main/HelloCustomer.xls
=====================================================
ExternalRules ExternalSummerGreeting template defineGreeting
0 11 Good Morning Summer
12 17 Good Afternoon Summer
18 21 Good Evening Summer
22 24 Good Night Summer
Greeting generated by rules 'ExternalSummerGreeting' for hour 16: Good Afternoon Summer
ExternalRules ExternalWinterGreeting template defineGreeting
0 12 Good Morning Winter
13 16 Good Afternoon Winter
17 22 Good Evening Winter
23 24 Good Night
Greeting generated by rules 'ExternalWinterGreeting' for hour 16: Good Afternoon Winter
ExternalRules ExternalGreetingHorizontal template defineGreetingHorizontal
0 11 Good Morning
12 16 Good Afternoon
17 22 Good Evening
23 24 Good Night
Greeting generated by rules 'ExternalGreetingHorizontal' for hour 16: Good Afternoon
ExternalRules ExternalGreetingReverseOrder template defineGreeting
Good Morning 0 11
Good Afternoon 12 17
Good Evening 18 21
Good Night 22 24
Greeting generated by rules 'ExternalGreetingReverseOrder' for hour 16: Good Afternoon
|
►top
|
|

|