Open Your Business Rules!
Rules-based
Operational Decision Services
External Rules Coming from Java
Rule Project "ExternalRulesFromJava"
Step 1. Setting Up Rule Templates
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( "ExternalWinterGreeting", //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 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:
: Error: For input string: "O" : java.lang.NumberFormatExceptionorg.openl.syntax.SyntaxErrorException
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" with
an integer attribute "hour" and "Response" with a String attribute "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 |