The Drools Rules Language

then RHS end What might sample LHS and RHS statements look like? Drools rules reference POJOs “Plain Old Java Objects” in both the LHS matching expressions and RHS actions. If you use the Eclipse Drools Workbench and create a new demo project, the Workbench will automatically create for you: • Sample.drl – a sample rule file. • com.sample.DroolsTest.java – defines: a simple Java POJO class M essage that is used in the Sample.drl rule file, a utility method for loading rules, and a main method that loads rules and creates an instance of the M essage class that “fires” the first rule in Sample.drl. Even if you decide not to use the Eclipse Drools Workbench, I include these two auto-generated files in the ZIP file for this book and we will use these files to intro- duce both the syntax of rues and using rules and Drools in Java applications in the next section. Here is the Sample.drl file: package com.sample import com.sample.DroolsTest.Message; rule Hello World when m : Messagestatus == Message.HELLO, message : message then System.out.printlnmessage; m.setMessageGoodbye cruel world; m.setStatusMessage.GOODBYE; updatem; end rule GoodBye no-loop true when m : Messagestatus == Message.GOODBYE, message : message then System.out.printlnmessage; 76 m.setMessagemessage; end This example rule file defines which Java package it has visibility in; we will see in the next section that the Java code that defines the POJO M essage class and code that uses these rules will be in the same Java package. This class has private data with public accessor methods using Java Bean protocol for attributes “status” and “message.” Another thing that might surprise you in this example is the direct calls to the static Java method System.out.println: this is a hint that Drools will end up compil- ing these rules into Java byte code. When Drools sees a reference to the class M essage, since there are no Java import statements in this example rule file, the class M essage must be in the package com.sample. On the LHS of both rules, any instance of class M essage that matches and thus allows the rule to “fire” sets a reference to the matched object to the local variable m that can then be used on the RHS of the rule. In the first rule, the attribute message is also stored in a local variable perhaps confusingly also called message. Note that the public attribute accessor methods like setM essage are used to change the state of a matched M essage object. We will see later that the first step in writing a Drools based expert system is mod- eling as Java classes the data required to represent problem states. After you have defined these POJO classes you can then proceed with defining some initial test cases and start writing rules to handle the test cases. Drools development of non- trivial projects will involve an iterative process of adding new test cases, writing new rules or generalizing previously written rules, and making sure that both the original and newer test cases work. There is a complete reference description of the Drools rule syntax on the Drools documentation wiki. The material in this chapter is tutorial in nature: new features of the rule language and how to use Drools will be introduced as needed for the examples.

5.3 Using Drools in Java Applications

We looked at the sample rules file Sample.drl in the last section which is generated automatically when creating a demo project with the Eclipse Drools Workbench. We will use the other generated file DroolsTest.java as an illustrative example in this section. The file DroolsTest.java is almost 100 lines long so I will list it in small fragments followed by an explanation of each code fragment. The first thing to note is that the Java client code is in the same package as the rules file: 77 package com.sample; import java.io.InputStreamReader; import java.io.Reader; import org.drools.RuleBase; import org.drools.RuleBaseFactory; import org.drools.WorkingMemory; import org.drools.compiler.PackageBuilder; import org.drools.rule.Package; This main function is an example showing how to use a rule package defined in a rule source file. We will see the definition of the utility method readRule that opens a rule file and returns an instance of class RuleBase shortly. After creating an instance of RuleBase we create an instance of the M essage class and add it to open memory: public class DroolsTest { public static final void mainString[] args { try { RuleBase ruleBase = readRule; WorkingMemory workingMemory = ruleBase.newStatefulSession; Message message = new Message; message.setMessage Hello World ; message.setStatus Message.HELLO ; workingMemory.insert message ; workingMemory.fireAllRules; } catch Throwable t { t.printStackTrace; } } The main method creates a new rule base and working memory. Working memory is responsible for maintaining the “facts” in the system – in this case facts are Plain Old Java Objects POJOs that are maintained in a collection. An instance of class M essage is created and its status is set to the constant value M essage.HELLO. We saw in the last section how the first example rule has a condition that allows the rule to “fire” if there is any instance of class M essage that has its status attribute set to this value. The method f ireAllRules will keep identifying rules that are eligible to fire, choos- ing a rule from this active set using algorithms we will discuss later, and then repeat- 78