Professional Documents
Culture Documents
November 2005
Niels Peter Strandberg
ITU
060570-1841
Teacher: Prof. Henning Christiansen
1 of 8
2 of 8
}
} else {
// even more business logic
}
Source: www.onjava.com/pub/a/onjava/2005/08/03/drools.html?page=1
This above example shows that rules is hard to program and maintain in Java. Another
problem is that of role. What if a businessperson wants to change the B203 into a B204?
Should the programmer be involved every time a business rule changes? This is not
sustainable. By having the rules separated from the source code, the businessperson can
actually read and understand the rules, and change them to reflect changes in business.
3 of 8
4 of 8
The XML file can include many rules. The parameter tag <parameter
identifier="cart"> is a named reference to an actual Java class. The reference is used in
the <java:condition> tag. The method cart.getGrossCost() is actually called by this
condition. All conditions has to be met for the <java:consequence> to be executed.
This is how you load the rules:
RuleBase ruleBase = RuleBaseLoader.loadFromReader(new
FileReader(abc.drl));
After the rules are loaded, we create a WorkingMemory. It is where all knowledge or
facts is kept.
WorkingMemory workingMemory = ruleBase.newWorkingMemory();
The WorkingMemory can be manipulated in various ways. You can add (assertObject),
modify (modifyObject) and remove (retractObject) facts from the WorkingMemory. In this
example we will only add facts to the WorkingMemory.
We add the shopping cart as a fact, so that the engine is aware of it existence.
workingMemory.assertObject(cart);
Now that we have loaded the rules and facts, let us fire all the rules.
workingMemory.fireAllRules();
that's it ;-)
5 of 8
Drools of cause offers more features that I have described in this short report. But it will get
you started.
Conflict Resolution
A common problem is if several rules have been activated, what rule should be fired first.
Drools offer several strategies [5] to solve this problem. I will not describe them all, but the
on PetShop uses. The solution used in the PetShop is Salience. Salience is a kind of
priority. You can specify a priority for each rule in the XML file. You add an attribute to the
rule tag:
<rule name="Apply 2% Sales Discount" salience="-5">
It has to be an Integer value. The higher the number the higher priority the rule has. In this
example, it is important that this rule fires last after all the other rules. So this rule has to have
the lowest salience.
The following rule:
<rule name="Explode Cart" salience="20">
<parameter identifier="cart">
<class>org.drools.examples.petstore.ShoppingCart</class>
</parameter>
<java:condition>cart.getState( "Exploded" ) == false</java:condition>
<java:consequence>
import java.util.Iterator;
System.out.println( "Examining each item in the shopping cart." );
Iterator itemIter = cart.getItems().iterator();
while ( itemIter.hasNext() )
{
drools.assertObject( itemIter.next() );
}
cart.setState( "Exploded", true);
drools.modifyObject( cart );
</java:consequence>
</rule>
It has the highest priority (20), since the other rules will fail if this rule has not been fired first.
6 of 8
Conclusion
I believe that the separation of rules and code is important when you are building application
that contain many rules. And that makes Drools are a very interesting application. Drools has
been adopted by JBoss as the rule engine for their J2EE application server, so that properly
means that we will hear more about Drools, and that it will be in continuous development. I
will certainly try to use rule engines after experimenting with Drools.
References
[1] Why Use Rules, http://drools.org/Why+Use+Rules
[2] Page 35, 2.6, Artificial Intelligence, Michael Negnevitsky.
[3] Drools, http://drools.org
[4] Rete algorithm, http://en.wikipedia.org/wiki/Rete_algorithm
[5] Conflict Resolution Strategies, http://drools.org/Conflict+Resolution
Appendix
This appendix will only include the extension I have made to the original PetShop example.
The PetShop example can be downloaded from http://drools.org/Project+Downloads.
If you would the PetShop project as an Eclipse project, please send me an email at
nielspeter@npstrandberg.com. And I will send it to you, including my extension to the
PetShop.
Addition to the rule XML file:
<!-- ************************************************* -->
<!-- Give 2% Sales month discount -->
<!-- ************************************************* -->
<rule name="Apply 2% Sales Discount" salience="-5">
<parameter identifier="sales">
<class>org.drools.examples.petstore.SalesMonthDiscount</class>
</parameter>
<parameter identifier="cart">
<class>org.drools.examples.petstore.ShoppingCart</class>
</parameter>
<java:condition>cart.getGrossCost() > 0.00</java:condition>
<java:condition>sales.getSales(11) == true</java:condition>
7 of 8
<java:consequence>
System.out.println( "Applying 2% Month Sales discount to cart" );
cart.setDiscount( 0.02 );
</java:consequence>
</rule>
SalesMonthDiscount.java source:
package org.drools.examples.petstore;
import java.util.Calendar;
import java.util.GregorianCalendar;
public class SalesMonthDiscount {
public boolean getSales(int month) {
month = month -1;
GregorianCalendar gc1 = new GregorianCalendar(2005,
Calendar.JANUARY, 1);
GregorianCalendar gc2 = new GregorianCalendar(2005,
Calendar.JANUARY, 30);
Calendar today = new GregorianCalendar();
gc1.set(GregorianCalendar.MONTH, month);
gc2.set(GregorianCalendar.MONTH, month);
if (today.after(gc1) && today.before(gc2)) {
return true;
} else {
return false;
}
}
}
8 of 8