[jboss-svn-commits] JBL Code SVN: r20477 - in labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples: Section-BankingExample and 3 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Fri Jun 13 21:56:17 EDT 2008
Author: mark.proctor at jboss.com
Date: 2008-06-13 21:56:17 -0400 (Fri, 13 Jun 2008)
New Revision: 20477
Added:
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-BankingExample/
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-BankingExample/Section-BankingExample.xml
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-FibonacciExample/
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-FibonacciExample/Section-FibonacciExample.xml
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-FibonacciExample/fibonacci1.jpg
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-FibonacciExample/fibonacci2.jpg
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-FibonacciExample/fibonacci3.jpg
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-FibonacciExample/fibonacci4.jpg
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-FibonacciExample/fibonacci5.jpg
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-HelloWorldExample/
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-HelloWorldExample/Section-HelloWorldExample.xml
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-HelloWorldExample/helloworld_agenda1.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-HelloWorldExample/helloworld_agenda2.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-HelloWorldExample/helloworld_auditview1.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-StateExample/
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-StateExample/state_example_agenda1.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-StateExample/state_example_audit1.png
Removed:
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/fibonacci1.jpg
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/fibonacci1.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/fibonacci2.jpg
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/fibonacci2.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/fibonacci3.jpg
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/fibonacci3.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/fibonacci4.jpg
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/fibonacci4.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/fibonacci5.jpg
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/fibonacci5.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/fibonacci_agenda1.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/fibonacci_agenda2.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/helloworld_agenda1.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/helloworld_agenda2.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/helloworld_auditview1.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/state_example_agenda1.png
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/state_example_audit1.png
Modified:
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/
labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-Examples.xml
Log:
JBRULES-1643
-trying to move images to section folders for better grouping
Property changes on: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples
___________________________________________________________________
Name: svn:ignore
+ Thumbs.db
Added: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-BankingExample/Section-BankingExample.xml
===================================================================
--- labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-BankingExample/Section-BankingExample.xml (rev 0)
+++ labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-BankingExample/Section-BankingExample.xml 2008-06-14 01:56:17 UTC (rev 20477)
@@ -0,0 +1,592 @@
+<?xml version="1.0" encoding="UTF-8"?>
+ <section xml:base="../">
+ <title>Banking Tutorial</title>
+
+ <screen><emphasis role="bold">Name:</emphasis> BankingTutorial
+<emphasis role="bold">Main class:</emphasis> org.drools.tutorials.banking.*
+<emphasis role="bold">Type:</emphasis> java application
+<emphasis role="bold">Rules file:</emphasis> org.drools.tutorials.banking.*
+<emphasis role="bold">Objective:</emphasis> tutorial that builds up knowledge of pattern matching, basic sorting and calculation rules.</screen>
+
+ <para>This tutorial will demonstrate the process of developing a complete personal banking application that will handle credits, debits, currencies and that will use a set of design patterns that have been created for the process. In order to make the examples documented here clear and modular, I will try and steer away from re-visiting existing code to add new functionality, and will instead extend and inject where appropriate.</para>
+
+ <para>The RuleRunner class is a simple harness to execute one or more drls against a set of data. It compiles the Packages and creates the RuleBase for each execution, this allows us to easy execute each scenario and see the outputs. In reality this is not a good solution for a production system where the RuleBase should be built just once and cached, but for the purposes of this tutorial it shall suffice.</para>
+
+ <example>
+ <title>Banking Tutorial : RuleRunner</title>
+
+ <programlisting>public class RuleRunner {
+
+ public RuleRunner() {
+ }
+
+ public void runRules(String[] rules,
+ Object[] facts) throws Exception {
+
+ RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+ PackageBuilder builder = new PackageBuilder();
+
+ for ( int i = 0; i < rules.length; i++ ) {
+ String ruleFile = rules[i];
+ System.out.println( "Loading file: " + ruleFile );
+ builder.addPackageFromDrl(new InputStreamReader( RuleRunner.class.getResourceAsStream( ruleFile ) ) );
+ }
+
+ Package pkg = builder.getPackage();
+ ruleBase.addPackage( pkg );
+ WorkingMemory workingMemory = ruleBase.newStatefulSession();
+
+ for ( int i = 0; i < facts.length; i++ ) {
+ Object fact = facts[i];
+ System.out.println( "Inserting fact: " + fact );
+ workingMemory.insert( fact );
+ }
+
+ workingMemory.fireAllRules();
+ }
+}</programlisting>
+ </example>
+
+ <para>This is our first Example1.java class it loads and executes a single drl file "Example.drl" but inserts no data.</para>
+
+ <example>
+ <title>Banking Tutorial : Java Example1</title>
+
+ <programlisting>public class Example1 {
+ public static void main(String[] args) throws Exception {
+ new RuleRunner().runRules( new String[] { "Example1.drl" },
+ new Object[0] );
+ }
+}</programlisting>
+ </example>
+
+ <para>And this is the first simple rule to execute. It has a single "eval" condition that will alway be true, thus this rul will always match and fire.</para>
+
+ <example>
+ <title>Banking Tutorial : Rule Example1</title>
+
+ <programlisting>rule "Rule 01"
+ when
+ eval (1==1)
+ then
+ System.out.println("Rule 01 Works");
+endh</programlisting>
+ </example>
+
+ <para>The output for the rule is below, the rule matches and executes the single print statement.</para>
+
+ <example>
+ <title>Banking Tutorial : Output Example1</title>
+
+ <programlisting>Loading file: Example1.drl
+Rule 01 Works</programlisting>
+ </example>
+
+ <para>The next step is to assert some simple facts and print them out. </para>
+
+ <example>
+ <title>Banking Tutorial : Java Example2</title>
+
+ <programlisting>public class Example2 {
+ public static void main(String[] args) throws Exception {
+ Number[] numbers = new Number[] {wrap(3), wrap(1), wrap(4), wrap(1), wrap(5)};
+ new RuleRunner().runRules( new String[] { "Example2.drl" },
+ numbers );
+ }
+
+ private static Integer wrap(int i) {
+ return new Integer(i);
+ }
+}</programlisting>
+ </example>
+
+ <para>This doesn’t use any specific facts but instead asserts a set of java.lang.Integer’s. This is not considered "best practice" as a number of a collection is not a fact, it is not a thing. A Bank acount has a number, its balance, thus the Account is the fact; but to get started asserting Integers shall suffice for demonstration purposes as the complexity is built up.</para>
+
+ <para>Now we will create a simple rule to print out these numbers.</para>
+
+ <example>
+ <title>Banking Tutorial : Rule Example2</title>
+
+ <programlisting>rule "Rule 02"
+ when
+ Number( $intValue : intValue )
+ then
+ System.out.println("Number found with value: " + $intValue);
+end</programlisting>
+ </example>
+
+ <para>Once again, this rule does nothing special. It identifies any facts that are Numbers and prints out the values. Notice the user of interfaces here, we inserted Integers but the pattern matching engine is able to match the interfaces and super classes of the asserted objects.</para>
+
+ <para>The output shows the drl being loaded, the facts inserted and then the matched and fired rules. We can see that each inserted number is matched and fired and thus printed.</para>
+
+ <example>
+ <title>Banking Tutorial : Output Example2</title>
+
+ <programlisting>Loading file: Example2.drl
+Inserting fact: 3
+Inserting fact: 1
+Inserting fact: 4
+Inserting fact: 1
+Inserting fact: 5
+Number found with value: 5
+Number found with value: 1
+Number found with value: 4
+Number found with value: 1
+Number found with value: 3
+</programlisting>
+ </example>
+
+ <para>here are probably a hundred and one better ways to sort numbers; but we will need to apply some cashflows in date order when we start looking at banking rules so let’s look at a simple rule based example.</para>
+
+ <example>
+ <title>Banking Tutorial : Java Example3</title>
+
+ <programlisting>public class Example3 {
+ public static void main(String[] args) throws Exception {
+ Number[] numbers = new Number[] {wrap(3), wrap(1), wrap(4), wrap(1), wrap(5)};
+ new RuleRunner().runRules( new String[] { "Example3.drl" },
+ numbers );
+ }
+
+ private static Integer wrap(int i) {
+ return new Integer(i);
+ }
+}</programlisting>
+ </example>
+
+ <para>Again we insert our Integers as before, this time the rule is slightly different:</para>
+
+ <example>
+ <title>Banking Tutorial : Rule Example3</title>
+
+ <programlisting>rule "Rule 03"
+ when
+ $number : Number( )
+ not Number( intValue < $number.intValue )
+ then
+ System.out.println("Number found with value: " + $number.intValue() );
+ retract( $number );
+end</programlisting>
+ </example>
+
+ <para>The first line of the rules identifies a Number and extracts the value. The second line ensures that there does not exist a smaller number than the one found. By executing this rule, we might expect to find only one number - the smallest in the set. However, the retraction of the number after it has been printed, means that the smallest number has been removed, revealing the next smallest number, and so on. </para>
+
+ <para>So, the output we generate is, notice the numbers are now sorted numerically.</para>
+
+ <example>
+ <title>Banking Tutorial : Output Example3</title>
+
+ <programlisting>Loading file: Example3.drl
+Inserting fact: 3
+Inserting fact: 1
+Inserting fact: 4
+Inserting fact: 1
+Inserting fact: 5
+Number found with value: 1
+Number found with value: 1
+Number found with value: 3
+Number found with value: 4
+Number found with value: 5
+</programlisting>
+ </example>
+
+ <para>Now we want to start moving towards our personal accounting rules. The first step is to create a Cashflow POJO.</para>
+
+ <example>
+ <title>Banking Tutoria : Class Cashflow</title>
+
+ <programlisting>public class Cashflow {
+ private Date date;
+ private double amount;
+
+ public Cashflow() {
+ }
+
+ public Cashflow(Date date,
+ double amount) {
+ this.date = date;
+ this.amount = amount;
+ }
+
+ public Date getDate() {
+ return date;
+ }
+
+ public void setDate(Date date) {
+ this.date = date;
+ }
+
+ public double getAmount() {
+ return amount;
+ }
+
+ public void setAmount(double amount) {
+ this.amount = amount;
+ }
+
+ public String toString() {
+ return "Cashflow[date=" + date + ",amount=" + amount + "]";
+ }
+}</programlisting>
+ </example>
+
+ <para>The Cashflow has two simple attributes, a date and an amount. I have added a toString method to print it and overloaded the constructor to set the values. The Example4 java code inserts 5 Cashflow objecst with varying dates and amounts.</para>
+
+ <example>
+ <title>Banking Tutorial : Java Example4</title>
+
+ <programlisting>public class Example4 {
+ public static void main(String[] args) throws Exception {
+ Object[] cashflows = {
+ new Cashflow(new SimpleDate("01/01/2007"), 300.00),
+ new Cashflow(new SimpleDate("05/01/2007"), 100.00),
+ new Cashflow(new SimpleDate("11/01/2007"), 500.00),
+ new Cashflow(new SimpleDate("07/01/2007"), 800.00),
+ new Cashflow(new SimpleDate("02/01/2007"), 400.00),
+ };
+
+ new RuleRunner().runRules( new String[] { "Example4.drl" },
+ cashflows );
+ }
+}</programlisting>
+ </example>
+
+ <para>SimpleDate is a simple class that extends Date and takes a String as input. It allows for pre-formatted Data classes, for convienience. The code is listed below</para>
+
+ <example>
+ <title>Banking Tutorial : Java SimpleDate</title>
+
+ <programlisting>public class SimpleDate extends Date {
+ private static final SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
+
+ public SimpleDate(String datestr) throws Exception {
+ setTime(format.parse(datestr).getTime());
+ }
+}</programlisting>
+ </example>
+
+ <para>Now, let’s look at rule04.drl to see how we print the sorted Cashflows:</para>
+
+ <example>
+ <title>Banking Tutorial : Rule Example4</title>
+
+ <programlisting>rule "Rule 04"
+ when
+ $cashflow : Cashflow( $date : date, $amount : amount )
+ not Cashflow( date < $date)
+ then
+ System.out.println("Cashflow: "+$date+" :: "+$amount);
+ retract($cashflow);
+end</programlisting>
+ </example>
+
+ <para>Here, we identify a Cashflow and extract the date and the amount. In the second line of the rules we ensure that there is not a Cashflow with an earlier date than the one found. In the consequences, we print the Cashflow that satisfies the rules and then retract it, making way for the next earliest Cashflow. So, the output we generate is:</para>
+
+ <example>
+ <title>Banking Tutorial : Output Example4</title>
+
+ <programlisting>Loading file: Example4.drl
+Inserting fact: Cashflow[date=Mon Jan 01 00:00:00 GMT 2007,amount=300.0]
+Inserting fact: Cashflow[date=Fri Jan 05 00:00:00 GMT 2007,amount=100.0]
+Inserting fact: Cashflow[date=Thu Jan 11 00:00:00 GMT 2007,amount=500.0]
+Inserting fact: Cashflow[date=Sun Jan 07 00:00:00 GMT 2007,amount=800.0]
+Inserting fact: Cashflow[date=Tue Jan 02 00:00:00 GMT 2007,amount=400.0]
+Cashflow: Mon Jan 01 00:00:00 GMT 2007 :: 300.0
+Cashflow: Tue Jan 02 00:00:00 GMT 2007 :: 400.0
+Cashflow: Fri Jan 05 00:00:00 GMT 2007 :: 100.0
+Cashflow: Sun Jan 07 00:00:00 GMT 2007 :: 800.0
+Cashflow: Thu Jan 11 00:00:00 GMT 2007 :: 500.0
+</programlisting>
+ </example>
+
+ <para>Here we extend our Cashflow to give a TypedCashflow which can be CREDIT or DEBIT. Ideally, we would just add this to the Cashflow type, but so that we can keep all the examples simple, we will go with the extensions.</para>
+
+ <example>
+ <title>Banking Tutoria : Class TypedCashflow</title>
+
+ <programlisting>public class TypedCashflow extends Cashflow {
+ public static final int CREDIT = 0;
+ public static final int DEBIT = 1;
+
+ private int type;
+
+ public TypedCashflow() {
+ }
+
+ public TypedCashflow(Date date,
+ int type,
+ double amount) {
+ super( date,
+ amount );
+ this.type = type;
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public void setType(int type) {
+ this.type = type;
+ }
+
+ public String toString() {
+ return "TypedCashflow[date=" + getDate() + ",type=" + (type == CREDIT ? "Credit" : "Debit") + ",amount=" + getAmount() + "]";
+ }
+}</programlisting>
+ </example>
+
+ <para>There are lots of ways to improve this code, but for the sake of the example this will do.</para>
+
+ <para>Nows lets create the Example5 runner.</para>
+
+ <example>
+ <title>Banking Tutorial : Java Example5</title>
+
+ <programlisting>public class Example5 {
+ public static void main(String[] args) throws Exception {
+ Object[] cashflows = {
+ new TypedCashflow(new SimpleDate("01/01/2007"),
+ TypedCashflow.CREDIT, 300.00),
+ new TypedCashflow(new SimpleDate("05/01/2007"),
+ TypedCashflow.CREDIT, 100.00),
+ new TypedCashflow(new SimpleDate("11/01/2007"),
+ TypedCashflow.CREDIT, 500.00),
+ new TypedCashflow(new SimpleDate("07/01/2007"),
+ TypedCashflow.DEBIT, 800.00),
+ new TypedCashflow(new SimpleDate("02/01/2007"),
+ TypedCashflow.DEBIT, 400.00),
+ };
+
+ new RuleRunner().runRules( new String[] { "Example5.drl" },
+ cashflows );
+ }
+}</programlisting>
+ </example>
+
+ <para>Here, we simply create a set of Cashflows which are either CREDIT or DEBIT Cashflows and supply them and rule05.drl to the RuleEngine. </para>
+
+ <para>Now, let’s look at rule0 Example5.drl to see how we print the sorted Cashflows:</para>
+
+ <example>
+ <title>Banking Tutorial : Rule Example5</title>
+
+ <programlisting>rule "Rule 05"
+ when
+ $cashflow : TypedCashflow( $date : date,
+ $amount : amount,
+ type == TypedCashflow.CREDIT )
+ not TypedCashflow( date < $date,
+ type == TypedCashflow.CREDIT )
+ then
+ System.out.println("Credit: "+$date+" :: "+$amount);
+ retract($cashflow);
+end</programlisting>
+ </example>
+
+ <para>Here, we identify a Cashflow with a type of CREDIT and extract the date and the amount. In the second line of the rules we ensure that there is not a Cashflow of type CREDIT with an earlier date than the one found. In the consequences, we print the Cashflow that satisfies the rules and then retract it, making way for the next earliest Cashflow of type CREDIT.</para>
+
+ <para>So, the output we generate is</para>
+
+ <example>
+ <title>Banking Tutorial : Output Example5</title>
+
+ <screen>Loading file: Example5.drl
+Inserting fact: TypedCashflow[date=Mon Jan 01 00:00:00 GMT 2007,type=Credit,amount=300.0]
+Inserting fact: TypedCashflow[date=Fri Jan 05 00:00:00 GMT 2007,type=Credit,amount=100.0]
+Inserting fact: TypedCashflow[date=Thu Jan 11 00:00:00 GMT 2007,type=Credit,amount=500.0]
+Inserting fact: TypedCashflow[date=Sun Jan 07 00:00:00 GMT 2007,type=Debit,amount=800.0]
+Inserting fact: TypedCashflow[date=Tue Jan 02 00:00:00 GMT 2007,type=Debit,amount=400.0]
+Credit: Mon Jan 01 00:00:00 GMT 2007 :: 300.0
+Credit: Fri Jan 05 00:00:00 GMT 2007 :: 100.0
+Credit: Thu Jan 11 00:00:00 GMT 2007 :: 500.0
+</screen>
+ </example>
+
+ <para>Here we are going to process both CREDITs and DEBITs on 2 bank accounts to calculate the account balance. In order to do this, I am going to create two separate Account Objects and inject them into the Cashflows before passing them to the Rule Engine. The reason for this is to provide easy access to the correct Bank Accounts without having to resort to Helper classes. Let’s take a look at the Account class first. This is a simple POJO with an account number and balance:</para>
+
+ <example>
+ <title>Banking Tutoria : Class Account</title>
+
+ <programlisting>public class Account {
+ private long accountNo;
+ private double balance = 0;
+
+ public Account() {
+ }
+
+ public Account(long accountNo) {
+ this.accountNo = accountNo;
+ }
+
+ public long getAccountNo() {
+ return accountNo;
+ }
+
+ public void setAccountNo(long accountNo) {
+ this.accountNo = accountNo;
+ }
+
+ public double getBalance() {
+ return balance;
+ }
+
+ public void setBalance(double balance) {
+ this.balance = balance;
+ }
+
+ public String toString() {
+ return "Account[" + "accountNo=" + accountNo + ",balance=" + balance + "]";
+ }
+}</programlisting>
+ </example>
+
+ <para>Now let’s extend our TypedCashflow to give AllocatedCashflow (allocated to an account).</para>
+
+ <example>
+ <title>Banking Tutoria : Class AllocatedCashflow</title>
+
+ <programlisting>public class AllocatedCashflow extends TypedCashflow {
+ private Account account;
+
+ public AllocatedCashflow() {
+ }
+
+ public AllocatedCashflow(Account account,
+ Date date,
+ int type,
+ double amount) {
+ super( date,
+ type,
+ amount );
+ this.account = account;
+ }
+
+ public Account getAccount() {
+ return account;
+ }
+
+ public void setAccount(Account account) {
+ this.account = account;
+ }
+
+ public String toString() {
+ return "AllocatedCashflow[" + "account=" + account + ",date=" + getDate() +
+ ",type=" + (getType() == CREDIT ? "Credit" : "Debit") +
+ ",amount=" + getAmount() + "]";
+ }
+}</programlisting>
+ </example>
+
+ <para>Now, let’s java code for Example5 execution. Here we create two Account objects and inject one into each cashflow as appropriate. For simplicity I have simply included them in the constructor.</para>
+
+ <example>
+ <title>Banking Tutorial : Java Example5</title>
+
+ <programlisting>public class Example6 {
+ public static void main(String[] args) throws Exception {
+ Account acc1 = new Account(1);
+ Account acc2 = new Account(2);
+
+ Object[] cashflows = {
+ new AllocatedCashflow(acc1,new SimpleDate("01/01/2007"),
+ TypedCashflow.CREDIT, 300.00),
+ new AllocatedCashflow(acc1,new SimpleDate("05/02/2007"),
+ TypedCashflow.CREDIT, 100.00),
+ new AllocatedCashflow(acc2,new SimpleDate("11/03/2007"),
+ TypedCashflow.CREDIT, 500.00),
+ new AllocatedCashflow(acc1,new SimpleDate("07/02/2007"),
+ TypedCashflow.DEBIT, 800.00),
+ new AllocatedCashflow(acc2,new SimpleDate("02/03/2007"),
+ TypedCashflow.DEBIT, 400.00),
+ new AllocatedCashflow(acc1,new SimpleDate("01/04/2007"),
+ TypedCashflow.CREDIT, 200.00),
+ new AllocatedCashflow(acc1,new SimpleDate("05/04/2007"),
+ TypedCashflow.CREDIT, 300.00),
+ new AllocatedCashflow(acc2,new SimpleDate("11/05/2007"),
+ TypedCashflow.CREDIT, 700.00),
+ new AllocatedCashflow(acc1,new SimpleDate("07/05/2007"),
+ TypedCashflow.DEBIT, 900.00),
+ new AllocatedCashflow(acc2,new SimpleDate("02/05/2007"),
+ TypedCashflow.DEBIT, 100.00)
+ };
+
+ new RuleRunner().runRules( new String[] { "Example6.drl" },
+ cashflows );
+ }
+}</programlisting>
+ </example>
+
+ <para>Now, let’s look at rule Example06.drl to see how we apply each cashflow in date order and calculate and print the balance. </para>
+
+ <example>
+ <title>Banking Tutorial : Rule Example6</title>
+
+ <programlisting>rule "Rule 06 - Credit"
+ when
+ $cashflow : AllocatedCashflow( $account : account,
+ $date : date, $amount : amount,
+ type==TypedCashflow.CREDIT )
+ not AllocatedCashflow( account == $account, date < $date)
+ then
+ System.out.println("Credit: " + $date + " :: " + $amount);
+ $account.setBalance($account.getBalance()+$amount);
+ System.out.println("Account: " + $account.getAccountNo() +
+ " - new balance: " + $account.getBalance());
+ retract($cashflow);
+end
+
+rule "Rule 06 - Debit"
+ when
+ $cashflow : AllocatedCashflow( $account : account,
+ $date : date, $amount : amount,
+ type==TypedCashflow.DEBIT )
+ not AllocatedCashflow( account == $account, date < $date)
+ then
+ System.out.println("Debit: " + $date + " :: " + $amount);
+ $account.setBalance($account.getBalance() - $amount);
+ System.out.println("Account: " + $account.getAccountNo() +
+ " - new balance: " + $account.getBalance());
+ retract($cashflow);
+end</programlisting>
+ </example>
+
+ <para>Here, we have separate rules for CREDITs and DEBITs, however we do not specify a type when checking for earlier cashflows. This is so that all cashflows are applied in date order regardless of which type of cashflow type they are. In the rule section we identify the correct account to work with and in the consequences we update it with the cashflow amount.</para>
+
+ <example>
+ <title>Banking Tutorial : Output Example6</title>
+
+ <programlisting>Loading file: Example6.drl
+Inserting fact: AllocatedCashflow[account=Account[accountNo=1,balance=0.0],date=Mon Jan 01 00:00:00 GMT 2007,type=Credit,amount=300.0]
+Inserting fact: AllocatedCashflow[account=Account[accountNo=1,balance=0.0],date=Mon Feb 05 00:00:00 GMT 2007,type=Credit,amount=100.0]
+Inserting fact: AllocatedCashflow[account=Account[accountNo=2,balance=0.0],date=Sun Mar 11 00:00:00 GMT 2007,type=Credit,amount=500.0]
+Inserting fact: AllocatedCashflow[account=Account[accountNo=1,balance=0.0],date=Wed Feb 07 00:00:00 GMT 2007,type=Debit,amount=800.0]
+Inserting fact: AllocatedCashflow[account=Account[accountNo=2,balance=0.0],date=Fri Mar 02 00:00:00 GMT 2007,type=Debit,amount=400.0]
+Inserting fact: AllocatedCashflow[account=Account[accountNo=1,balance=0.0],date=Sun Apr 01 00:00:00 BST 2007,type=Credit,amount=200.0]
+Inserting fact: AllocatedCashflow[account=Account[accountNo=1,balance=0.0],date=Thu Apr 05 00:00:00 BST 2007,type=Credit,amount=300.0]
+Inserting fact: AllocatedCashflow[account=Account[accountNo=2,balance=0.0],date=Fri May 11 00:00:00 BST 2007,type=Credit,amount=700.0]
+Inserting fact: AllocatedCashflow[account=Account[accountNo=1,balance=0.0],date=Mon May 07 00:00:00 BST 2007,type=Debit,amount=900.0]
+Inserting fact: AllocatedCashflow[account=Account[accountNo=2,balance=0.0],date=Wed May 02 00:00:00 BST 2007,type=Debit,amount=100.0]
+Debit: Fri Mar 02 00:00:00 GMT 2007 :: 400.0
+Account: 2 - new balance: -400.0
+Credit: Sun Mar 11 00:00:00 GMT 2007 :: 500.0
+Account: 2 - new balance: 100.0
+Debit: Wed May 02 00:00:00 BST 2007 :: 100.0
+Account: 2 - new balance: 0.0
+Credit: Fri May 11 00:00:00 BST 2007 :: 700.0
+Account: 2 - new balance: 700.0
+Credit: Mon Jan 01 00:00:00 GMT 2007 :: 300.0
+Account: 1 - new balance: 300.0
+Credit: Mon Feb 05 00:00:00 GMT 2007 :: 100.0
+Account: 1 - new balance: 400.0
+Debit: Wed Feb 07 00:00:00 GMT 2007 :: 800.0
+Account: 1 - new balance: -400.0
+Credit: Sun Apr 01 00:00:00 BST 2007 :: 200.0
+Account: 1 - new balance: -200.0
+Credit: Thu Apr 05 00:00:00 BST 2007 :: 300.0
+Account: 1 - new balance: 100.0
+Debit: Mon May 07 00:00:00 BST 2007 :: 900.0
+Account: 1 - new balance: -800.0
+</programlisting>
+ </example>
+
+ </section>
\ No newline at end of file
Modified: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-Examples.xml
===================================================================
--- labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-Examples.xml 2008-06-13 22:34:41 UTC (rev 20476)
+++ labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-Examples.xml 2008-06-14 01:56:17 UTC (rev 20477)
@@ -8,10 +8,10 @@
<para>Make sure the Drools Eclipse plugin is installed, which needs GEF dependency installed first. Then download and extract the drools-examples zip file, which includes an already created Eclipse project. Import that project into a new Eclipse workspace. The rules all have example classes that execute the rules. If you want to try the examples in another project (or another IDE) then you will need to setup the dependencies by hand of course. Many, but not all of the examples are documented below, enjoy :)</para>
</section>
- <xi:include href="Section-HelloWorldExample.xml" />
- <xi:include href="Section-StateExample.xml" />
- <xi:include href="Section-FibonacciExample.xml" />
- <xi:include href="Section-BankingExample.xml" />
+ <xi:include href="Section-HelloWorldExample/Section-HelloWorldExample.xml" />
+ <xi:include href="Section-StateExample/Section-StateExample.xml" />
+ <xi:include href="Section-FibonacciExample/Section-FibonacciExample.xml" />
+ <xi:include href="Section-BankingExample/Section-BankingExample.xml" />
<section>
<title>Golfing Example</title>
Added: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-FibonacciExample/Section-FibonacciExample.xml
===================================================================
--- labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-FibonacciExample/Section-FibonacciExample.xml (rev 0)
+++ labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-FibonacciExample/Section-FibonacciExample.xml 2008-06-14 01:56:17 UTC (rev 20477)
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="UTF-8"?>
+ <section xml:base="../">
+ <title>Fibonacci Example</title>
+
+ <screen><emphasis role="bold">Name:</emphasis> Fibonacci
+<emphasis role="bold">Main class:</emphasis> org.drools.examples.FibonacciExample
+<emphasis role="bold">Type:</emphasis> java application
+<emphasis role="bold">Rules file:</emphasis> Fibonacci.drl
+<emphasis role="bold">Objective:</emphasis> Demonsrates Recursion, 'not' CEs and Cross Product Matching</screen>
+
+ <para>The Fibonacci Numbers, <ulink url="http://en.wikipedia.org/wiki/Fibonacci_number">http://en.wikipedia.org/wiki/Fibonacci_number</ulink>, invented by Leonardo of Pisa, <ulink url="http://en.wikipedia.org/wiki/Fibonacci">http://en.wikipedia.org/wiki/Fibonacci</ulink>, are obtained by starting with 0 and 1, and then produce the next Fibonacci number by adding the two previous Fibonacci numbers. The first Fibonacci numbers for n = 0, 1,... are: * 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946... The Fibonacci Example demonstrates recursion and conflict resolution with Salience values.</para>
+
+ <para>A single fact Class is used in this example, Fibonacci. It has two fields, sequence and value. The sequence field is used to indicate the position of the object in the Fibonacci number sequence and the value field shows the value of that Fibonacci object for that sequence position.</para>
+
+ <example>
+ <title>Fibonacci Class</title>
+
+ <programlisting>public static class Fibonacci {
+ private int sequence;
+ private long value;
+
+ ... setters and getters go here...
+}</programlisting>
+ </example>
+
+ <para>Execute the example:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>Open the class <classname>org.drools.examples.FibonacciExample</classname> in your Eclipse IDE</para>
+ </listitem>
+
+ <listitem>
+ <para>Right-click the class an select "Run as..." -> "Java application"</para>
+ </listitem>
+ </orderedlist>
+
+ <para>And Eclipse shows the following output in its console, "...snip..." shows repeated bits removed to save space:</para>
+
+ <example>
+ <title>Fibonacci Example Console Output</title>
+
+ <programlisting>recurse for 50
+recurse for 49
+recurse for 48
+recurse for 47
+...snip...
+recurse for 5
+recurse for 4
+recurse for 3
+recurse for 2
+1 == 1
+2 == 1
+3 == 2
+4 == 3
+5 == 5
+6 == 8
+...snip...
+47 == 2971215073
+48 == 4807526976
+49 == 7778742049
+50 == 12586269025
+</programlisting>
+ </example>
+
+ <para>To kick this off from java we only insert a single Fibonacci object, with a sequence of 50, a recurse rule is then used to insert the other 49 Fibonacci objects. This example doesn't use PropertyChangeSupport and uses the MVEL dialect, this means we can use the <emphasis role="bold">modify</emphasis> keyword, which allows a block setter action which also notifies the engine of changes.</para>
+
+ <example>
+ <title>Fibonacci Example Execution</title>
+
+ <programlisting>session.insert( new Fibonacci( 50 ) );
+session.fireAllRules();</programlisting>
+ </example>
+
+ <para>The recurse rule is very simple, it matches each asserted Fibonacci object with a value of -1, it then creates and asserts a new Fibonacci object with a sequence of one less than the currently matched object. Each time a Fibonacci object is added, as long as one with a "sequence == 1" does not exist, the rule re-matches again and fires; causing the recursion. The 'not' conditional element is used to stop the rule matching once we have all 50 Fibonacci objects in memory. The rule also has a salience value, this is because we need to have all 50 Fibonacci objects asserted before we execute the Bootstrap rule.</para>
+
+ <example>
+ <title>Fibonacci Example : Rule "Recurse"</title>
+
+ <programlisting>rule Recurse
+ salience 10
+ when
+ f : Fibonacci ( value == -1 )
+ not ( Fibonacci ( sequence == 1 ) )
+ then
+ insert( new Fibonacci( f.sequence - 1 ) );
+ System.out.println( "recurse for " + f.sequence );
+end</programlisting>
+ </example>
+
+ <para>The audit view shows the original assertion of the Fibonacci object with a sequence of 50, this was done from Java land. From there the audit view shows the continual recursion of the rule, each asserted Fibonacci causes the "Recurse" rule to become activate again, which then fires.</para>
+
+ <figure>
+ <title>Fibonacci Example "Recurse" Audit View 1</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="fibonacci1.png" />
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>When a Fibonacci with a sequence of 2 is asserted the "Bootstrap" rule is matched and activated along with the "Recurse" rule.</para>
+
+ <example>
+ <title>Fibonacci Example : Rule "Bootstrap"</title>
+
+ <programlisting>rule Bootstrap
+ when
+ f : Fibonacci( sequence == 1 || == 2, value == -1 ) // this is a multi-restriction || on a single field
+ then
+ modify ( f ){ value = 1 };
+ System.out.println( f.sequence + " == " + f.value );
+end</programlisting>
+ </example>
+
+ <para>At this point the Agenda looks like the figure shown below. However the "Bootstrap" rule does not fire as the "Recurse" rule has a higher salience.</para>
+
+ <figure>
+ <title>Fibonacci Example "Recurse" Agenda View 1</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="fibonacci_agenda1.png" />
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>When a Fibonacci with a sequence of 1 is asserted the "Bootstrap" rule is matched again, causing two activations for this rule; note that the "Recurse" rule does not match and activate because the 'not conditional element stops the rule matching when a Fibonacci with a sequence of 1 exists.</para>
+
+ <figure>
+ <title>Fibonacci Example "Recurse" Agenda View 2</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="fibonacci_agenda2.png" />
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>Once we have two Fibonacci objects both with values not equal to -1 the "calculate" rule is able to match; remember it was the "Bootstrap" rule that set the Fibonacci's with sequences 1 and 2 to values of 1. At this point we have 50 Fibonacci objects in the Working Memory and we some how need to select the correct ones to calculate each of their values in turn. With three Fibonacci patterns in a rule with no field constriants to correctly constrain the available cross products we have 50x50x50 possible permutations, thats 125K possible rule firings. The "Calculate" rule uses the field constraints to correctly constraint the thee Fibonacci patterns and in the correct order; this technique is called "cross product matching". The first pattern finds any Fibonacci with a value != -1 and binds both the pattern and the field. The second Fibonacci does too but it adds an additional field constraint to make sure that its sequence is one greater than the Fibonacci bound to f!
1. When this rule first fires we know that only sequences 1 and 2 have values of 1 and the two constraints ensure that f1 references sequence 1 and f2 references sequence2. The final pattern finds the Fibonacci of a value == -1 with a sequence one greater than f2. At this point we have three Fibonacci objects correctly selected from the available cross products and we can do the maths calculating the value for Fibonacci sequence = 3.</para>
+
+ <example>
+ <title>Fibonacci Example : Rule "Calculate"</title>
+
+ <programlisting>rule Calculate
+ when
+ f1 : Fibonacci( s1 : sequence, value != -1 ) // here we bind sequence
+ f2 : Fibonacci( sequence == (s1 + 1 ), value != -1 ) // here we don't, just to demonstrate the different way bindings can be used
+ f3 : Fibonacci( s3 : sequence == (f2.sequence + 1 ), value == -1 )
+ then
+ modify ( f3 ) { value = f1.value + f2.value };
+ System.out.println( s3 + " == " + f3.value ); // see how you can access pattern and field bindings
+end
+</programlisting>
+ </example>
+
+ <para>The MVEL modify keyword updated the value of the Fibonacci object bound to f3, this means we have a new Fibonacci object with a value != -1, this allows the "Calculate" rule to rematch and calculate the next Fibonacci number. The Audit view below shows the how the firing of the last "Bootstrap" modifies the Fibonacci object enabling the "Calculate" rule to match, which then modifies another Fibonacci object allowing the "Calculate" rule to rematch. This continues till the value is set for all Fibonacci objects.</para>
+
+ <figure>
+ <title>Fibonacci Example "Bootstrap" Audit View 1</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="fibonacci4.png" />
+ </imageobject>
+ </mediaobject>
+ </figure>
+ </section>
\ No newline at end of file
Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-FibonacciExample/fibonacci1.jpg (from rev 20476, labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/fibonacci1.jpg)
===================================================================
(Binary files differ)
Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-FibonacciExample/fibonacci2.jpg (from rev 20476, labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/fibonacci2.jpg)
===================================================================
(Binary files differ)
Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-FibonacciExample/fibonacci3.jpg (from rev 20476, labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/fibonacci3.jpg)
===================================================================
(Binary files differ)
Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-FibonacciExample/fibonacci4.jpg (from rev 20476, labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/fibonacci4.jpg)
===================================================================
(Binary files differ)
Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-FibonacciExample/fibonacci5.jpg (from rev 20476, labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/fibonacci5.jpg)
===================================================================
(Binary files differ)
Added: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-HelloWorldExample/Section-HelloWorldExample.xml
===================================================================
--- labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-HelloWorldExample/Section-HelloWorldExample.xml (rev 0)
+++ labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-HelloWorldExample/Section-HelloWorldExample.xml 2008-06-14 01:56:17 UTC (rev 20477)
@@ -0,0 +1,285 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<section>
+ <title>Hello World</title>
+
+ <screen><emphasis role="bold">Name:</emphasis> Hello World
+<emphasis role="bold">Main class:</emphasis> org.drools.examples.HelloWorldExample
+<emphasis role="bold">Type:</emphasis> java application
+<emphasis role="bold">Rules file:</emphasis> HelloWorld.drl
+<emphasis role="bold">Objective:</emphasis> demonstrate basic rules in use</screen>
+
+ <para>The "Hello World" example shows a simple example of rules usage, and
+ both the MVEL and Java dialects.</para>
+
+ <para>In this example it will be shown how to build rulebases and sessions
+ and how to add audit logging and debug outputs, this information is ommitted
+ from other examples as it's all very similar. PackageBuilder is used to turn
+ a drl source file into Package objects which the RuleBase can consume,
+ addPackageFromDrl takes a Reader interface as the parameter. Reader can be
+ used to retrieve a source drl file from various locations, in this case the
+ drl file is being retrieved from the classpath as an InputStream which we
+ turn into a Reader by wrapping it with InputStreamReader; but it could come
+ the disk or a url. The use of the Reader interface means that Drools does
+ not have to care. In this case we only add a single drl source file, but
+ multiple drl files can be added and all are merged into a single Package.
+ All drl files added to the PackageBuilder must declare themselves in the
+ same package namespace, if you wish to build a Package in a different
+ namespace a new instance of PackageBuilder must be created; multiple
+ packages of differerent namespaces can be added to the same RuleBase. When
+ all the drl files have been added we should check the builder for errors;
+ while the RuleBase will validate the packge it will only have access to the
+ error information as a String, so if you wish to debug the error information
+ you should do it on the builder instance. Once we know the builder is error
+ free get the Package, instantiate a RuleBase from the RuleBaseFactory and
+ add the package.</para>
+
+ <example>
+ <title>HelloWorld example: Creating the RuleBase and Session</title>
+
+ <programlisting>//read in the source
+Reader source = new InputStreamReader( HelloWorldExample.class.getResourceAsStream( "HelloWorld.drl" ) );
+
+PackageBuilder builder = new PackageBuilder();
+
+//this will parse and compile in one step
+builder.addPackageFromDrl( source );
+
+// Check the builder for errors
+if ( builder.hasErrors() ) {
+ System.out.println( builder.getErrors().toString() );
+ throw new RuntimeException( "Unable to compile \"HelloWorld.drl\".");
+}
+
+//get the compiled package (which is serializable)
+Package pkg = builder.getPackage();
+
+//add the package to a rulebase (deploy the rule package).
+RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+ruleBase.addPackage( pkg );
+
+StatefulSession session = ruleBase.newStatefulSession();</programlisting>
+ </example>
+
+ <para>Drools has an event model that exposes much of what's happening
+ internally, two default debug listeners are supplied
+ DebugAgendaEventListener and DebugWorkingMemoryEventListener which print out
+ debug event information to the err console, adding listeners to a session is
+ trivial and shown below. The WorkingMemoryFileLogger provides execution
+ auditing which can be viewed in a graphical viewer; it's actually a
+ specialised implementation built on the agenda and working memory listeners,
+ when the engine has finished executing logger.writeToDisk() must be
+ called.</para>
+
+ <para>Most of the examples use the Audit logging features of Drools to
+ record execution flow for later inspection.</para>
+
+ <example>
+ <title>HelloWorld example: Event logging and Auditing</title>
+
+ <programlisting>// setup the debug listeners
+session.addEventListener( new DebugAgendaEventListener() );
+session.addEventListener( new DebugWorkingMemoryEventListener() );
+
+// setup the audit logging
+WorkingMemoryFileLogger logger = new WorkingMemoryFileLogger( session );
+logger.setFileName( "log/helloworld" ); </programlisting>
+ </example>
+
+ <para>The single class used in this example is very simple, it has two
+ fields: the message, which is a String and the status which can be either
+ the int HELLO or the int GOODBYE.</para>
+
+ <example>
+ <title>HelloWorld example: Message Class</title>
+
+ <programlisting>public static class Message {
+ public static final int HELLO = 0;
+ public static final int GOODBYE = 1;
+
+ private String message;
+ private int status;
+ ...
+}</programlisting>
+ </example>
+
+ <para>A single Message object is created with the message "Hello World" and
+ status HELLO and then inserted into the engine, at which point
+ fireAllRules() is executed. Remember all the network evaluation is done
+ during the insert time, by the time the program execution reaches the
+ fireAllRules() method it already knows which rules are fully matches and
+ able to fire.</para>
+
+ <example>
+ <title>HelloWorld example: Execution</title>
+
+ <programlisting>Message message = new Message();
+message.setMessage( "Hello World" );
+message.setStatus( Message.HELLO );
+session.insert( message );
+
+session.fireAllRules();
+
+logger.writeToDisk();
+
+session.dispose(); </programlisting>
+ </example>
+
+ <para>To execute the example from Java.</para>
+
+ <orderedlist>
+ <listitem>
+ <para>Open the class org.drools.examples.FibonacciExample in your
+ Eclipse IDE</para>
+ </listitem>
+
+ <listitem>
+ <para>Right-click the class an select "Run as..." -> "Java
+ application"</para>
+ </listitem>
+ </orderedlist>
+
+ <para>If we put a breakpoint on the fireAllRules() method and select the
+ session variable we can see that the "Hello World" view is already activated
+ and on the Agenda, showing that all the pattern matching work was already
+ done during the insert.</para>
+
+ <figure>
+ <title>Hello World : fireAllRules Agenda View</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="helloworld_agenda1.png" />
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>The may application print outs go to to System.out while the debug
+ listener print outs go to System.err.</para>
+
+ <example>
+ <title>HelloWorld example: Console.out</title>
+
+ <programlisting>Hello World
+Goodbye cruel world</programlisting>
+ </example>
+
+ <example>
+ <title>HelloWorld example: Console.err</title>
+
+ <programlisting>==>[ActivationCreated(0): rule=Hello World;
+ tuple=[fid:1:1:org.drools.examples.HelloWorldExample$Message at 17cec96]]
+[ObjectInserted: handle=[fid:1:1:org.drools.examples.HelloWorldExample$Message at 17cec96];
+ object=org.drools.examples.HelloWorldExample$Message at 17cec96]
+[BeforeActivationFired: rule=Hello World;
+ tuple=[fid:1:1:org.drools.examples.HelloWorldExample$Message at 17cec96]]
+==>[ActivationCreated(4): rule=Good Bye;
+ tuple=[fid:1:2:org.drools.examples.HelloWorldExample$Message at 17cec96]]
+[ObjectUpdated: handle=[fid:1:2:org.drools.examples.HelloWorldExample$Message at 17cec96];
+ old_object=org.drools.examples.HelloWorldExample$Message at 17cec96;
+ new_object=org.drools.examples.HelloWorldExample$Message at 17cec96]
+[AfterActivationFired(0): rule=Hello World]
+[BeforeActivationFired: rule=Good Bye;
+ tuple=[fid:1:2:org.drools.examples.HelloWorldExample$Message at 17cec96]]
+[AfterActivationFired(4): rule=Good Bye] </programlisting>
+ </example>
+
+ <para>The <emphasis role="bold">LHS (when)</emphasis> section of the rule
+ states that it will be activated for each <emphasis>Message</emphasis>
+ object inserted into the working memory whose <emphasis>status</emphasis> is
+ <emphasis>Message.HELLO</emphasis>. Besides that, two variable binds are
+ created: "<emphasis>message</emphasis>" variable is bound to the
+ <emphasis>message</emphasis> attribute and "<emphasis>m</emphasis>" variable
+ is bound to the <emphasis>object matched pattern</emphasis> itself.</para>
+
+ <para>The <emphasis role="bold">RHS (consequence, then)</emphasis> section
+ of the rule is written using the MVEL expression language, as declared by
+ the rule's attribute <emphasis>dialect</emphasis>. After printing the
+ content of the <emphasis>message</emphasis> bound variable to the default
+ console, the rule changes the values of the <emphasis>message</emphasis> and
+ <emphasis>status</emphasis> attributes of the <emphasis>m</emphasis> bound
+ variable; using MVEL's 'modify' keyword which allows you to apply a block of
+ setters in one statement, with the engine being automatically notified of
+ the changes at the end of the block.</para>
+
+ <example>
+ <title>HelloWorld example: rule "Hello World"</title>
+
+ <programlisting>rule "Hello World"
+ dialect "mvel"
+ when
+ m : Message( status == Message.HELLO, message : message )
+ then
+ System.out.println( message );
+ modify ( m ) { message = "Goodbyte cruel world",
+ status = Message.GOODBYE };
+end</programlisting>
+ </example>
+
+ <para>We can add a break point into the DRL for when modify is called during
+ the execution of the "Hello World" consequence and inspect the Agenda view
+ again. Notice this time we "Debug As" a "Drools application" and not a "Java
+ application".</para>
+
+ <orderedlist>
+ <listitem>
+ <para>Open the class org.drools.examples.FibonacciExample in your
+ Eclipse IDE</para>
+ </listitem>
+
+ <listitem>
+ <para>Right-click the class an select "Debug as..." -> "Drools
+ application"</para>
+ </listitem>
+ </orderedlist>
+
+ <para>Now we can see that the other rule "Good Bye" which uses the java
+ dialect is activated and placed on the agenda.</para>
+
+ <figure>
+ <title>Hello World : rule "Hello World" Agenda View</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="helloworld_agenda2.png" />
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>The "Good Bye" rule is similar to the "Hello World" rule but matches
+ Message objects whose status is Message.GOODBYE instead, printing its
+ message to the default console, it specifies the "java" dialect.</para>
+
+ <example>
+ <title>HelloWorld example: rule "Good Bye"</title>
+
+ <programlisting>rule "Good Bye"
+ dialect "java"
+ when
+ Message( status == Message.GOODBYE, message : message )
+ then
+ System.out.println( message );
+end</programlisting>
+ </example>
+
+ <para>If you remember at the start of this example in the java code we
+ created a WorkingMemoryFileLogger and called logger.writeToDisk() at the
+ end, this created an audit log file that can be shown in the Audit view. We
+ use the audit view in many of the examples to try and understand the example
+ execution flow. In the view below we can see the object is inserted which
+ creates an activation for the "Hello World" rule, the activation is then
+ executed which updated the Message object causing the "Good Bye" rule to
+ activate, the "Good Bye" rule then also executes. When an event in the Audit
+ view is select it highlights the origin event in green, so below the
+ Activation created event is highlighted in greed as the origin of the
+ Activation executed event.</para>
+
+ <figure>
+ <title>Hello World : Audit View</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="helloworld_auditview1.png" />
+ </imageobject>
+ </mediaobject>
+ </figure>
+</section>
\ No newline at end of file
Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-HelloWorldExample/helloworld_agenda1.png (from rev 20476, labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/helloworld_agenda1.png)
===================================================================
(Binary files differ)
Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-HelloWorldExample/helloworld_agenda2.png (from rev 20476, labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/helloworld_agenda2.png)
===================================================================
(Binary files differ)
Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-HelloWorldExample/helloworld_auditview1.png (from rev 20476, labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/helloworld_auditview1.png)
===================================================================
(Binary files differ)
Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-StateExample/state_example_agenda1.png (from rev 20476, labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/state_example_agenda1.png)
===================================================================
(Binary files differ)
Copied: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/Section-StateExample/state_example_audit1.png (from rev 20476, labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/state_example_audit1.png)
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/fibonacci1.jpg
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/fibonacci1.png
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/fibonacci2.jpg
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/fibonacci2.png
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/fibonacci3.jpg
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/fibonacci3.png
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/fibonacci4.jpg
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/fibonacci4.png
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/fibonacci5.jpg
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/fibonacci5.png
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/fibonacci_agenda1.png
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/fibonacci_agenda2.png
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/helloworld_agenda1.png
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/helloworld_agenda2.png
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/helloworld_auditview1.png
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/state_example_agenda1.png
===================================================================
(Binary files differ)
Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/en/Chapter-Examples/state_example_audit1.png
===================================================================
(Binary files differ)
More information about the jboss-svn-commits
mailing list