[jboss-svn-commits] JBL Code SVN: r25807 - labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Quick_Start.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Tue Mar 24 20:54:05 EDT 2009


Author: mark.proctor at jboss.com
Date: 2009-03-24 20:54:05 -0400 (Tue, 24 Mar 2009)
New Revision: 25807

Removed:
   labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Quick_Start/Chapter-Quick_Start.html
Log:
remvong .html, should never have been committed

Deleted: labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Quick_Start/Chapter-Quick_Start.html
===================================================================
--- labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Quick_Start/Chapter-Quick_Start.html	2009-03-25 00:53:19 UTC (rev 25806)
+++ labs/jbossrules/trunk/drools-docs/drools-docs-expert/src/main/docbook/en-US/Chapter-Quick_Start/Chapter-Quick_Start.html	2009-03-25 00:54:05 UTC (rev 25807)
@@ -1,590 +0,0 @@
-<html><head>
-      <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
-   <title>Chapter&nbsp;1.&nbsp;Quick Start</title><meta name="generator" content="DocBook XSL-NS Stylesheets V1.74.3-pre"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="chapter" lang="en"><div class="titlepage"><div><div><h2 class="title"><a name="d0e1"></a>Chapter&nbsp;1.&nbsp;Quick Start</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#d0e4">The Basics</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e7">Stateless Knowledge Session</a></span></dt><dt><span class="section"><a href="#d0e73">Stateful Knowledge Session</a></span></dt></dl></dd><dt><span class="section"><a href="#d0e159">A Little Theory</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e162">Methods versus Rules</a></span></dt><dt><span class="section"><a href="#d0e188">Cross Products</a></span></dt><dt><span class="section"><a href="#d0e207">Execution Control</a></span></dt!
 ></dl></dd></dl></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d0e4"></a>The Basics</h2></div></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="d0e7"></a>Stateless Knowledge Session</h3></div></div></div><p>So where do we get started, there are so many use cases and so much functionality in a
-        rule engine such as Drools that it becomes beguiling. Have no fear my intrepid adventurer,
-        the complexity is layered and you can ease yourself into with simple use cases.</p><p>Stateless session, not utilising inference, forms the simplest of use case. A stateless
-        session can be called like a function passing it some data and then receiving some results
-        back. Some common use cases for stateless sessions are, but not limited to:</p><div class="itemizedlist"><ul type="disc"><li><p>Validation</p><div class="itemizedlist"><ul type="circle"><li><p>Is this person legible for a mortgage</p></li></ul></div></li><li><p>Calculation</p><div class="itemizedlist"><ul type="circle"><li><p>Mortgage premium</p></li></ul></div></li><li><p>Routing/Filtering</p><div class="itemizedlist"><ul type="circle"><li><p>Filtering incoming messages, such as emails, into folders</p></li><li><p>Sending incoming message to a destinatino</p></li></ul></div></li></ul></div><p>So lets start with a very simple example using a driving license application.</p><pre class="programlisting">public class Applicant {
-    private String name;
-    private int age;
-    private boolean valid;
-    // getter and setter methods here
-}
-</pre><p>Now we have our data model we can write our first rule, we assume the application starts
-        off valid and rules would be used to disqualify the application. As this is a simple
-        validation use case we will add a single rule to disqualify the applicant if they are
-        younger than 18.</p><pre class="programlisting">package com.company.license
-
-rule "Is of valid age"
-when
-    $a : Applicant( age &lt; 18 )
-then
-    $a.setValid( false );
-end</pre><p>To make the engine aware of data, so it can be processed against the rules, we have to
-        "insert" the data, much like with a database. When the Applicant instance is inserted into
-        the engine it is evaluated against the constraints of the rules, in this case just two
-        constraint for one rule. We say two because the type Applicant is the first object type
-        constraint, and the "age &lt; 18" is the second field constraint. An object type constraint
-        plus it's zero or more field constraints is referred to as a pattern. When an inserted
-        instance satisfies both the object type constraint and all the field constraints, it is said
-        to be matched. The "$a" is a binding and allows the matched object to be referenced in the
-        consquence, so it's properties can be updated, the $ is optional, but it helps to
-        differentiate the variables from the fields. This part of the engine is often referred to as
-        pattern matchin, i.e. the matching of patterns against the inserted data.</p><p>Let's assume that the rules are in the same folder as the classes, so we can use the
-        classpath resource loader to build our first KnowledgeBase. A KnowledgeBase is what we call
-        our collection of compiled rules, which are compiled using the KnowledgeBuilder.</p><pre class="programlisting">KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
-kbuilder.add( ResourceFactory.newClasspathResource( "licenseApplication.drl", getClass() ),
-              ResourceType.DRL );
-if ( kbuilder.hasErrors() ) {
-    System.err.println( builder.getErrors().toString() );
-}  </pre><p>The above looks on the classpath for the "licenseApplication.drl" file, using the given
-        classes getResource() method. The ResourceType here is DRL, short for "Drools Rule
-        Language". Once the drl has be added we can check the KnowledgeBuilder for any errors. If
-        there are no errors, we are now ready to build our session and execute against some
-        data:</p><pre class="programlisting">StatelessKnowledgeSession ksession = kbase.newStatelessKnowledgeSession();
-Applicant applicant = new Applicant( "Mr John Smith", 16 );
-assertTrue( applicant.isValid() );
-ksession.execute( applicant );
-assertFalse( applicant.isValid() );
-</pre><p>The above executes the data against the rules, the applicant is under the age of 18, so
-        it marked invalid.</p><p>So far we've only used a single instance, but what if want to use more than one? We can
-        also execute against an Iterable, such a a collection. Lets add another class called
-        Application, which has the date of the application and we'll move the boolean valid field to
-        the Application class.</p><pre class="programlisting">public class Applicant {
-    private String name;
-    private int age;
-    // getter and setter methods here
-}
-
-
-public class Application {
-    private Date dateApplied;
-    private boolean valid;
-    // getter and setter methods here
-}</pre><p>And we can also add another rule, that validates the Application was made within a
-        period of time.</p><pre class="programlisting">package com.company.license
-
-rule "Is of valid age"
-when
-    Applicant( age &lt; 18 )
-    $a : Application()     
-then
-    $a.setValid( false );
-end
-
-rule "Application was made this year"
-when
-    $a : Application( dateApplied &gt; "01-jan-2009" )     
-then
-    $a.setValid( false );
-end
-</pre><p>Unfortunately in java an array does not implement h the Iterable interface, so we have
-        to use the JDK converter, asList(...). So code below executes against an Iterable, where
-        each of the collection elements are inserted before any matched rules are fired.</p><pre class="programlisting">StatelessKnowledgeSession ksession = kbase.newStatelessKnowledgeSession();
-Applicant applicant = new Applicant( "Mr John Smith", 16 );
-Application application = new Application();
-assertTrue( application() );
-ksession.execute( Arrays.asList( new Object[] { application, applicant } ) );
-assertFalse( application() );
-</pre><p>The two execute methods execute(Object object ) and execute(Iterable objects) are
-        actually convenience methods for the interface BatchExecutor's method execute(Command
-        command). This allows for more than just fact insertion, and also handles "out" parameters
-        and results.</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="d0e73"></a>Stateful Knowledge Session</h3></div></div></div><p>Stateful sessions are longer lived and allow iterative changes over time. Some common
-        use cases for stateful sessions are, but not limited to:</p><div class="itemizedlist"><ul type="disc"><li><p>Monitoring</p><div class="itemizedlist"><ul type="circle"><li><p>Stock market monitorig and analysis for semi-automatic buying.</p></li></ul></div></li><li><p>Diagnostics</p><div class="itemizedlist"><ul type="circle"><li><p>fault finding, medical diagnostics</p></li></ul></div></li><li><p>Logistics</p><div class="itemizedlist"><ul type="circle"><li><p>parcel tracking and delivery provisioning</p></li></ul></div></li><li><p>Compliance</p><div class="itemizedlist"><ul type="circle"><li><p>Validation of legality for market trades.</p></li></ul></div></li></ul></div><p>We can use a fire alarm example to explore the monitoring use case. The simple example
-        has just 4 classes. We are monitoring the rooms in a house, each room has one sprinkler. If
-        a fire starts in a room, we represent that with a single Fire instance.</p><pre class="programlisting">public class Room {
-    private String name
-    // getter and setter methods here
-}
-public classs Sprinkler {
-    private Room room;
-    private boolean on;
-    // getter and setter methods here
-}
-public class Fire {
-    private room room;
-    // getter and setter methods here
-}
-public class Alarm {
-}
-</pre><p>In the previous section on stateless sessions the concepts of inserting and matching
-        against data was introduced. That example assumed only a single instance of each object type
-        was ever inserted and thus only used literal constraints. However a house has many rooms, so
-        rules have the need to express joins that constraint to the desired objects, this can be
-        done using a binding as a variable constraint in a pattern. This join process results in
-        what is called cross products, which are covered in the next section.</p><p>When a fire occurs an instance of the Fire class is created, for that room, and insert
-        it. The rule uses a binding on the room field of the Fire to constrain to the Sprinkler for
-        that room, which is currently off. When this rule fires and the consequence is executed the
-        sprinkler is turned on</p><pre class="programlisting">rule "When there is a fire turn on the sprinkler"
-when
-    Fire($room : room)
-    $sprinkler : Sprinkler( room == $room, on == false )
-then
-    modify( $sprinkler ) { setOn( true ) };
-    System.out.println( "Turn off the sprinkler for room " + $room.getName() );
-end</pre><p>Where as the stateless session used standard java syntax to modify a field, in the above
-        rule we use the modify keyword, which acts as a sort of with statement, that contains a
-        series of comma separated java expressions. Stateless sessions do not have inference, so the
-        engine does not need to be aware of changes to data, however a stateful session does. The
-        modify keyword allows the setters to modify the data, while make the engine aware of those
-        changes so it can reason over them, this process is called inference.</p><p>So far we have rules that tell us when matching data exists, but what about when it
-        doesn't exist? What about when there stops being a Fire? Previously the constraints have
-        been propositional logic where the engine is constraining against individual intances,
-        Drools also has support for first order logic that allows you to look at sets of data. The
-        'not' keyword matches when something does not exist. So for a Room with a Sprinkler that is
-        on when the Fire for that room stops existing we can turn off the sprinkler.</p><pre class="programlisting">rule "When the fire is gone turn on the sprinkler"
-when
-    $room : Room( )
-    $sprinkler : Sprinkler( room == $room, on == true )
-    not Fire( room == $room )
-then
-    modify( $sprinkler ) { setOn( false ) };
-    System.out.println( "Turn off the sprinkler for room " + $room.getName() );
-end</pre><p>While there is a Sprinkler per room, there is just a single Alarm for the building. An
-        Alarm is created when a Fire is occurs, but only one Alarm is needed for the entire
-        building, no matter how many Fires occur. Previously 'not' was introduced, the compliment to
-        ths is 'exists' which matches for one or more of something.</p><pre class="programlisting">rule "Raise the alarm when we have one or more fires"
-when
-    exists Fire()
-then
-    insert( new Alarm() );
-    System.out.println( "Raise the alarm" );
-end</pre><p>Likewise when there are no Fires we want to remove the alarm, so the 'not' keyword can
-        be used again.</p><pre class="programlisting">rule "Lower the alarm when all the fires have gone"
-when
-    not Fire()
-    $alarm : Alarm()
-then
-    retract( $alarm );
-    System.out.println( "Lower the alarm" );
-end
-
-</pre><p>Finally there is a general health status message, that is printed when the application
-        first starts and after the Alarm is removed and all Sprinklers have been turned off.</p><pre class="programlisting">rule "Status output when things are ok"
-when
-    not Alarm()
-    not Sprinkler( on === true ) 
-then
-    System.out.println( "Everything is ok" );
-end</pre><p>The above rules should be placed in a single drl file and saved to the classpath using
-        the file name "fireAlarm.drl", as per the stateless session example. We can then build a
-        KnowledgeBase as before, just using the new name "fireAlarm.drl". The difference is this
-        time we create a stateful session from the kbase, where as before we created a stateless
-        session.</p><pre class="programlisting">KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
-kbuilder.add( ResourceFactory.newClasspathResource( "fireAlarm.drl", getClass() ),
-              ResourceType.DRL );
-if ( kbuilder.hasErrors() ) {
-    System.err.println( builder.getErrors().toString() );
-}  
-StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();</pre><p>With the session created it is now possible to iteratvely work with it over time. Four
-        Rooms are created and inserted, a Sprinkler for each room is also inserted. At this point
-        the engine has done all it's matching, but no rules have fired. calling "fireAllRules" on
-        the ksession allows the matched rules to fire, currently that is just the health
-        message.</p><pre class="programlisting">Room kitchen = new Room( "kitchen" );
-Room bedroom = new Room( "bedroom" );
-Room office = new Room( "office" );
-Room livingRoom = new Room( "livingroom" );
-
-ksession.insert( kitchen );
-ksession.insert( bedroom );
-ksession.insert( office );
-ksession.insert( livingRoom );
-
-Sprinkler kitchenSprinkler = new Sprinkler( kitchen );
-Sprinkler bedroomSprinkler = new Sprinkler( bedroom );
-Sprinkler officeSprinkler = new Sprinkler( office );
-Sprinkler livingRoomSprinkler = new Sprinkler( livingRoom );
-
-
-ksession.insert( kitchenSprinkler );
-ksession.insert( bedroomSprinkler );
-ksession.insert( officeSprinkler );
-ksession.insert( livingRoomSprinkler );
-
-ksession.fireAllRules()
-</pre><pre class="programlisting">&gt; Everything is ok</pre><p>We now create two fires and insert them, this time a referenced is kept for the returned
-        FactHandle. The FactHandle is an internal engine reference to the inserted instance and
-        allows that instance to be retracted or modified at a later point in time. With the Fires
-        now in the engine, once "fireAllRules" is called, the Alarm is raised and the respectively
-        Sprinklers are turned on.</p><pre class="programlisting">Fire kitchenFire = new Fire( kitchen );
-Fire officeFire = new Fire( office );
-
-FactHandle kitchenFireHandle = kession.insert( kitchenFire );
-FactHandle officeFireHandle = ksession.insert( officeFire );
-
-ksession.fireAllRules();</pre><pre class="programlisting">&gt; Raise the alarm
-&gt; Turn on the sprinkler for room kitchen
-&gt; Turn on the sprinkler for room office</pre><p>After a while the fires will be put out and the Fire intances are retracted. This
-        results in the Sprinklers being turned off, the Alarm being lowered and eventually the
-        health message is printed again.</p><pre class="programlisting">ksession.retract( kitchenFire );
-ksession.retract( officeFire );
-
-ksession.fireAllRules();</pre><pre class="programlisting">&gt; Turn on the sprinkler for room office
-&gt; Turn on the sprinkler for room kitchen
-&gt; Lower the alarm
-&gt; Everything is ok</pre><p>Every one still with me? That wasn't so hard and already I'm hoping you can start to see
-        the value and power of a declarative rule system.</p></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d0e159"></a>A Little Theory</h2></div></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="d0e162"></a>Methods versus Rules</h3></div></div></div><p>People often confuse methods and rules, and new rule users regular ask, "how do I call a
-        rule?". After the last section, you are now feeling like a rule expert and the answer to
-        that is obvsious, but just to summarise.</p><pre class="programlisting">public void helloWorld(Person person) {
-    if ( person.getName().equals( &#8220;Chuck&#8221; ) ) {
-        System.out.println( &#8220;Hello Chuck&#8221; );
-    }
-}</pre><div class="itemizedlist"><ul type="disc"><li><p>Methods are called directly.</p></li><li><p>Specific instances are passed.</p></li></ul></div><pre class="programlisting">rule &#8220;Hello World&#8221;
-    when
-        Person( name == &#8220;Chuck&#8221; )
-    then
-        System.out.println( &#8220;Hello Chuck&#8221; );
-        end</pre><div class="itemizedlist"><ul type="disc"><li><p>Rules execute by matching against data inserted into the engine.</p></li><li><p>Rules can never be called directly.</p></li><li><p>Specific instances cannot be passed to a rule.</p></li></ul></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="d0e188"></a>Cross Products</h3></div></div></div><p>Earlier the term "cross product" was mentioned, which is the result of a join. Imagine
-        for a moment when using the previous data the following rules where used, with no field
-        constraints:</p><pre class="programlisting">rule
-when
-    $room : Room()
-    $sprinkler : Sprinkler()
-then
-    System.out.println( "room:" + $room.getName() + " sprinkler:" + $sprinkler.getRoom().getName() );
-end</pre><p>In SQL terms this would be like doing "select * from Room, Sprinkler" and every row in
-        the Room table would be joined with every row in the Sprinkler table resulting in the
-        following output:</p><pre class="programlisting">room:office sprinker:office
-room:office sprinker:kitchen
-room:office sprinker:livingroom
-room:office sprinker:bedroom
-room:kitchen sprinker:office
-room:kitchen sprinker:kitchen
-room:kitchen sprinker:livingroom
-room:kitchen sprinker:bedroom
-room:livingroom sprinker:office
-room:livingroom sprinker:kitchen
-room:livingroom sprinker:livingroom
-room:livingroom sprinker:bedroom
-room:bedroom sprinker:office
-room:bedroom sprinker:kitchen
-room:bedroom sprinker:livingroom
-room:bedroom sprinker:bedroom</pre><p>These cross products can obviously become huge as well as returning potentially
-        incorrect data. The size of cross products is often source of performance problems for new
-        rule authors. From this it can be seen that it's always desirable to constrain the cross
-        products, which is done with the variable constriant.</p><pre class="programlisting">rule
-when
-    $room : Room()
-    $sprinkler : Sprinkler( room == $room )
-then
-    System.out.println( "room:" + $room.getName() + " sprinkler:" + $sprinkler.getRoom().getName() );
-end</pre><p>Resulting in just for rows of data, with the correct Sprinkler for the Room. In SQL
-        (actually HQL) terms that is like "select * from Room, Sprinkler where Room ==
-        Sprinkler.room"</p><pre class="programlisting">room:office sprinker:office
-room:kitchen sprinker:kitchen
-room:livingroom sprinker:livingroom
-room:bedroom sprinker:bedroom</pre></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="d0e207"></a>Execution Control</h3></div></div></div><p></p><pre class="programlisting">public class Cashflow {
-    private Date   date;
-    private double amount;
-    private int    type;
-    long           accountNo;
-    // getter and setter methods here
-}
-
-public class Account {
-    private long   accountNo;
-    private double balance;
-    // getter and setter methods here
-}
-
-public AccountPeriod {
-    private Date start;
-    private Dte end
-    // getter and setter methods here
-}</pre><p>By now you already know how to create KnowledgeBases and how to instantiate facts to
-        populate the StatefulKnowledgeSession, so tables will be used to show the state of the
-        inserted data, as it makes things clearer for illustration purposes. The tables below show a
-        single fact was inserted for the Account and a series of debit's and credit's as Cashflows
-        over two quarters for that Account were inserted.</p><table border="0" id="d0e215"><tbody><tr>
-            <td align="left" valign="top">
-              <table border="1" cellpadding="3" ccellspacing="0" style="border-style:solid; border-spacing:0; border-collapse:collapse" id="d0e221"><thead><tr>
-                    <th colspan="2" align="left" valign="top">Account</th>
-                  </tr><tr align="center">
-                    <th>accountNo</th>
-                    <th>balance</th>
-                  </tr></thead><tbody><tr>
-                    <td>1</td>
-                    <td>0</td>
-                  </tr></tbody></table>
-            </td>
-            <td align="left" valign="top">
-              <table border="1" cellpadding="3" ccellspacing="0" style="border-style:solid; border-spacing:0; border-collapse:collapse" id="d0e249"><thead><tr>
-                    <th colspan="4" align="left">Cashflow</th>
-                  </tr><tr align="center">
-                    <th>date</th>
-                    <th>amount</th>
-                    <th>type</th>
-                    <th>accountNo</th>
-                  </tr></thead><tbody><tr>
-                    <td>12-jan-09</td>
-                    <td>100</td>
-                    <td>CREDIT</td>
-                    <td>1</td>
-                  </tr><tr>
-                    <td>2-feb-09</td>
-                    <td>200</td>
-                    <td>DEBIT</td>
-                    <td>1</td>
-                  </tr><tr>
-                    <td>18-may-09</td>
-                    <td>50</td>
-                    <td>CREDIT</td>
-                    <td>1</td>
-                  </tr><tr>
-                    <td>09-mar-09</td>
-                    <td>75</td>
-                    <td>CREDIT</td>
-                    <td>1</td>
-                  </tr></tbody></table>
-            </td>
-          </tr></tbody></table><p>Two rules can be used to determine the debit and credit for that quarter and update the
-        Account balance. The two rules below constraint the Cashflows for an Account for a given
-        time period. Notice the "&amp;&amp;" which use short cut syntax to avoid repeating the field
-        name twice.</p><table frame="void"><tbody><tr>
-            <td align="left" valign="top">
-              <pre class="programlisting">rule &#8220;increase balance for AccountPeriod Credits&#8221;
-when
-    ap : AccountPeriod()
-    acc : Account( $accountNo : accountNo )
-    CashFlow( type == CREDIT,
-              accountNo == $accountNo,
-              date &gt;= ap.start &amp;&amp; &lt;= ap.end,
-              $ammount : ammount )
-then
-    acc.balance  += $amount;
-end</pre>
-            </td>
-            <td align="left" valign="top">
-              <pre class="programlisting">rule &#8220;decrease balance for AccountPeriod Debits&#8221; 
-when 
-    ap : AccountPeriod() 
-    acc : Account( $accountNo : accountNo ) 
-    CashFlow( type == DEBIT, 
-              accountNo == $accountNo,
-              date &gt;= ap.start &amp;&amp; &lt;= ap.end, 
-              $ammount : ammount ) 
-then 
-    acc.balance -= $amount; 
-end</pre>
-            </td>
-          </tr></tbody></table><p>If the AccountPeriod is set to the first quarter we constraint the &#8220;increase balance for
-        AccountPeriod Credits&#8221; to two rows of data and &#8220;decrease balance for AccountPeriod Debits&#8221;
-        to one row of data.</p><table border="0px" id="d0e349"><tbody><tr>
-            <td align="left" valign="top">
-              <table border="1" cellpadding="3" ccellspacing="0" style="border-style:solid; border-spacing:0; border-collapse:collapse" id="d0e355"><thead><tr>
-                    <th colspan="2" align="left">AccountPeriod</th>
-                  </tr><tr align="center">
-                    <th>start</th>
-                    <th>end</th>
-                  </tr></thead><tbody><tr>
-                    <td>01-jan-09</td>
-                    <td>31-mar-09</td>
-                  </tr></tbody></table>
-            </td>
-          </tr></tbody></table><table border="0px" id="d0e381"><tbody><tr>
-            <td align="left" valign="top">
-              <table border="1" cellpadding="3" ccellspacing="0" style="border-style:solid; border-spacing:0; border-collapse:collapse" id="d0e387"><thead><tr>
-                    <th colspan="3" align="left">Cashflow</th>
-                  </tr><tr align="center">
-                    <th>date</th>
-                    <th>amount</th>
-                    <th>type</th>
-                  </tr></thead><tbody><tr>
-                    <td>12-jan-09</td>
-                    <td>100</td>
-                    <td>CREDIT</td>
-                  </tr><tr>
-                    <td>09-mar-09</td>
-                    <td>75</td>
-                    <td>CREDIT</td>
-                  </tr></tbody></table>
-            </td>
-            <td align="left" valign="top">
-              <table border="1" cellpadding="3" ccellspacing="0" style="border-style:solid; border-spacing:0; border-collapse:collapse" id="d0e432"><thead><tr>
-                    <th colspan="3" align="left">Cashflow</th>
-                  </tr><tr align="center">
-                    <th>date</th>
-                    <th>amount</th>
-                    <th>type</th>
-                  </tr></thead><tbody><tr>
-                    <td>02-feb-09</td>
-                    <td>200</td>
-                    <td>DEBIT</td>
-                  </tr></tbody></table>
-            </td>
-          </tr></tbody></table><p>The two Cashflow tables above represent the matched data for the two rules, the data is
-        matched during the insertion stage and as you found in the previous chapter does not fire
-        straight away, until fireAllRules() is called. Intstead the rule plus it's matched data is
-        placed on the Agenda and referred to as an Activation. The Agenda is a table of Activations
-        that are able to fire and have their consequences executed, when fireAllRules() is called.
-        Each of the Activations on the Agneda are executed in turn. Notice that the order of
-        execution so far is considered arbitrary.</p><table border="0px" id="d0e466"><tbody><tr>
-            <td align="left" valign="top">
-              <table border="1" cellpadding="3" ccellspacing="0" style="border-style:solid; border-spacing:0; border-collapse:collapse" id="d0e472"><thead><tr>
-                    <th colspan="3" align="left">Agenda</th>
-                  </tr></thead><tbody><tr>
-                    <td>1</td>
-                    <td>increase balance</td>
-                    <td rowspan="3">arbitrary</td>
-                  </tr><tr>
-                    <td>2</td>
-                    <td>decrease balance</td>
-                  </tr><tr>
-                    <td>3</td>
-                    <td>increase balance</td>
-                  </tr></tbody></table>
-            </td>
-          </tr></tbody></table><p>After each of the above activations are fired, the Account has a balance of -25.</p><table border="0px" id="d0e511"><tbody><tr>
-            <td align="left" valign="top">
-              <table border="1" cellpadding="3" ccellspacing="0" style="border-style:solid; border-spacing:0; border-collapse:collapse" id="d0e517"><thead><tr>
-                    <th colspan="2" align="left">Account</th>
-                  </tr><tr align="center">
-                    <th>accountNo</th>
-                    <th>balance</th>
-                  </tr></thead><tbody><tr>
-                    <td>1</td>
-                    <td>-25</td>
-                  </tr></tbody></table>
-            </td>
-          </tr></tbody></table><p>If the AccountPeriod is updated to Q2, we have just a single matched row of data, and
-        thus just a single Activation on the Agenda.</p><table border="0px" id="d0e545"><tbody><tr>
-            <td align="left" valign="top">
-              <table border="1" cellpadding="3" ccellspacing="0" style="border-style:solid; border-spacing:0; border-collapse:collapse" id="d0e551"><thead><tr>
-                    <th colspan="2" align="left">AccountPeriod</th>
-                  </tr><tr align="center">
-                    <th>start</th>
-                    <th>end</th>
-                  </tr></thead><tbody><tr>
-                    <td>01-apr-09</td>
-                    <td>30-jun-09</td>
-                  </tr></tbody></table>
-            </td>
-          </tr></tbody></table><table border="0px" id="d0e577"><tbody><tr>
-            <td align="left" valign="top">
-              <table border="1" cellpadding="3" ccellspacing="0" style="border-style:solid; border-spacing:0; border-collapse:collapse" id="d0e583"><thead><tr>
-                    <th colspan="3" align="left">Cashflow</th>
-                  </tr><tr align="center">
-                    <th>date</th>
-                    <th>amount</th>
-                    <th>type</th>
-                  </tr></thead><tbody><tr>
-                    <td>18-may-09</td>
-                    <td>50</td>
-                    <td>CREDIT</td>
-                  </tr></tbody></table>
-            </td>
-            <td align="left" valign="top">
-              <table border="1" cellpadding="3" ccellspacing="0" style="border-style:solid; border-spacing:0; border-collapse:collapse" id="d0e617"><thead><tr>
-                    <th colspan="3" align="left">Cashflow</th>
-                  </tr><tr align="center">
-                    <th>date</th>
-                    <th>amount</th>
-                    <th>type</th>
-                  </tr></thead><tbody><tr>
-                    <td></td>
-                    <td></td>
-                    <td></td>
-                  </tr></tbody></table>
-            </td>
-          </tr></tbody></table><p>The firing of that Activation results in a balance of 50.</p><table border="0px" id="d0e648"><tbody><tr>
-            <td align="left" valign="top">
-              <table border="1" cellpadding="3" ccellspacing="0" style="border-style:solid; border-spacing:0; border-collapse:collapse" id="d0e654"><thead><tr>
-                    <th colspan="2" align="left">Account</th>
-                  </tr><tr align="center">
-                    <th>accountNo</th>
-                    <th>balance</th>
-                  </tr></thead><tbody><tr>
-                    <td>1</td>
-                    <td>50</td>
-                  </tr></tbody></table>
-            </td>
-          </tr></tbody></table><p>So what happens if you don't want the order of Activation execution to be arbitrary?
-        When there is one or more Activations on the Agenda they are said to be in conflict, and a
-        conflict resolver strategy is used to determine the order of execution. At the simplest
-        level the default strategy uses salience to determine rule priority. Each rule has a default
-        value of 0, the higher the value the higher the priority. To illustrate this a rule to print
-        the Account balance can be added, we want this rule to be executed after all the debit's and
-        credit's have been applied for this rule, by setting the rule to have a salience of below 0
-        we ensure it fires afterwards.</p><table border="0px" id="d0e682"><tbody><tr>
-            <td>
-              <pre class="programlisting">rule &#8220;Print blance for AccountPeriod&#8221;
-        salience -50
-    when
-        ap : AccountPeriod()
-        acc : Account( )        
-    then
-        System.out.println( acc.accountNo + &#8220; : &#8220; acc.balance );    
-end</pre>
-            </td>
-          </tr></tbody></table><p>The table below shows the resulting Agenda, the 3 debit and credit rules are shown to be
-        arbitrary order, while the print rule is shown to execute aftwards.</p><table border="0px" id="d0e694"><tbody><tr>
-            <td align="left" valign="top">
-              <table border="1" cellpadding="3" ccellspacing="0" style="border-style:solid; border-spacing:0; border-collapse:collapse" id="d0e700"><thead><tr>
-                    <th colspan="3" align="left">Agenda</th>
-                  </tr></thead><tbody><tr>
-                    <td>1</td>
-                    <td>increase balance</td>
-                    <td rowspan="3">arbitrary</td>
-                  </tr><tr>
-                    <td>2</td>
-                    <td>decrease balance</td>
-                  </tr><tr>
-                    <td>3</td>
-                    <td>increase balance</td>
-                  </tr><tr>
-                    <td>4</td>
-                    <td>print balance</td>
-                    <td></td>
-                  </tr></tbody></table>
-            </td>
-          </tr></tbody></table><p>Earlier we showed how rules would equate to SQL, which can often be helpful for people
-        with an SQL background when understanding rules. The two ruels above can be represented with
-        two views and a trigger for each view, as below:</p><table border="0px" id="d0e749"><tbody><tr>
-            <td align="left" valign="top">
-              <pre class="programlisting">select * from Account acc, Cashflow cf, AccountPeriod ap      
-where acc.accountNo == cf.accountNo and 
-      cf.type == CREDIT cf.date &gt;= ap.start and 
-      cf.date &lt;= ap.end</pre>
-            </td>
-            <td align="left" valign="top">
-              <pre class="programlisting">select * from Account acc, Cashflow cf, AccountPeriod ap 
-where acc.accountNo == cf.accountNo and 
-      cf.type == DEBIT cf.date &gt;= ap.start and 
-      cf.date &lt;= ap.end</pre>
-            </td>
-          </tr><tr>
-            <td align="left" valign="top">
-              <pre class="programlisting">trigger : acc.balance += cf.amount</pre>
-            </td>
-            <td align="left" valign="top">
-              <pre class="programlisting">trigger : acc.balance -= cf.amount</pre>
-            </td>
-          </tr></tbody></table><p>Drools also features ruleflow-group attributes which allows workflow diagrams to
-        declaratively specify when rules are allowed to fire. The screenshot below is taken from
-        Eclipse using the Drools plugin. It has two ruleflow-group nodes that ensures the
-        calculation rules are executed before the reporting rules.</p><div class="mediaobject"><img src="images/Chapter-Quick_Start/ruleflow.png"></div><p>The use of the ruleflow-group attribute in a rule is shown below.</p><table border="0px" id="d0e786"><tbody><tr>
-            <td align="left" valign="top">
-              <pre class="programlisting">rule &#8220;increase balance for AccountPeriod Credits&#8221;
-     ruleflow-group &#8220;calculation&#8221;
-when
-    ap : AccountPeriod()
-    acc : Account( $accountNo : accountNo )
-    CashFlow( type == CREDIT,
-              accountNo == $accountNo,
-              date &gt;= ap.start &amp;&amp; &lt;= ap.end,
-              $ammount : ammount )
-then
-    acc.balance  += $amount;
-end</pre>
-            </td>
-            <td align="left" valign="top">
-              <pre class="programlisting">rule &#8220;Print blance for AccountPeriod&#8221;
-        ruleflow-group &#8220;report&#8221;
-    when
-        ap : AccountPeriod()
-        acc : Account( )        
-    then
-        System.out.println( acc.accountNo + &#8220; : &#8220; acc.balance );    
-end</pre>
-            </td>
-          </tr></tbody></table></div></div></div></body></html>
\ No newline at end of file




More information about the jboss-svn-commits mailing list