Home | About the author | Resume | << JBoss Security - JMX Console | Drools 5 - Complex Event Processing >>
SMS Bundle - Mobile Marketing Solutions
SMS Bundle is an Australian-based service for sending marketing SMS and MMS

Drools 5 Case Study 1- Writing DSL for DRL rule

A small real life case study from one of the blog readers

One of the blog readers, who posted a comment in my previous post Drools - tutorial on writing DSL template asked to me to help him with creating DSL for the following rule, so I decided to use his example as a small case study:

For readability, I added some comments to the original rule:
rule 'Rank accomodation name'
salience 90
when
/*
Matches every AccomodationBase
*/
$accBase: AccomodationBase()

/*
Uses inline eval to evaluate that there is
no AccomodationBase of type AccomodationRank
in the session.

To remind: inline eval evaluated only once
and then it is cached by Drools.
*/
not AccomodationBase(eval($accBase
instanceof AccomodationRank))

/*
Matches every AccomodationRank that has the same
level and the description as the AccomodationBase
*/
$accRank: AccomodationRank(
level == $accBase.level,
description == $accBase.description)
then
/*
Increments the score
*/
$accRank.setScore($accRank.getScore()+1);
end
For my solution, I created two POJOs, tester class DSL and DSLR files. The following is my DSL:
[when]AccomodationBaseObj = $accBase: AccomodationBase()
[when]There is Accomodation base object of type Accomodation rank = eval($accBase instanceof AccomodationRank)
[when]AccomodationRankObj = $accRank: AccomodationRank(level == $accBase.level, description == $accBase.description)
[then]IncrementScore = $accRank.setScore($accRank.score+1);
[then]PrintScore = System.out.println("Rank score: " + $accRank.score);
[then]PrintLevel = System.out.println("Base level: " + $accBase.level);
and this is the DSLR file:
package net.javabeansdotasia.casestudy;

expander accomodation.dsl

import net.javabeansdotasia.casestudy.pojo.AccomodationBase;
import net.javabeansdotasia.casestudy.pojo.AccomodationRank;

rule "Rank"
dialect "mvel"
when
AccomodationBaseObj
not (There is Accomodation base object of type Accomodation rank)
AccomodationRankObj
then
IncrementScore
PrintScore
PrintLevel
end
In the following class I load DSL and DSLR files in to the KnowledgeBuilder and get a KnowledgeBase object. Once I have the KnowledgeBase object, I can get StatefulKnowledgeSession or StatelessKnowledgeSession, depends on what I want to do.
package net.javabeansdotasia.casestudy.utils;

import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderError;
import org.drools.builder.KnowledgeBuilderErrors;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.io.ResourceFactory;

public class MyKnowledgeBaseFactory {
public static KnowledgeBase
createKnowledgeBaseFromDSL(String dslr,
String dsl) throws Exception {

KnowledgeBuilder builder =
KnowledgeBuilderFactory
.newKnowledgeBuilder();

//Attention!!!!
//Add DSL BEFORE DSLR
builder.add(
ResourceFactory.newClassPathResource(dsl),
ResourceType.DSL);

builder.add(
ResourceFactory.newClassPathResource(dslr),
ResourceType.DSLR);

KnowledgeBuilderErrors errors = builder.getErrors();

if (errors.size() > 0) {
for (KnowledgeBuilderError error : errors) {
System.err.println(error);
}
throw new IllegalArgumentException("Could not parse knowledge.");
}
KnowledgeBase knowledgeBase =
KnowledgeBaseFactory.newKnowledgeBase();
knowledgeBase.addKnowledgePackages(
builder.getKnowledgePackages());
return knowledgeBase;
}
}
Below is my Tester class:
package net.javabeansdotasia.casestudy.test;

import net.javabeansdotasia.casestudy.pojo.AccomodationBase;
import net.javabeansdotasia.casestudy.pojo.AccomodationRank;
import net.javabeansdotasia.casestudy.utils.MyKnowledgeBaseFactory;

import org.drools.KnowledgeBase;
import org.drools.runtime.StatefulKnowledgeSession;

public class Test {

public static final void main(String[] args) {
try {
KnowledgeBase kbase =
MyKnowledgeBaseFactory
.createKnowledgeBaseFromDSL(
"accomodation.dslr",
"accomodation.dsl");
StatefulKnowledgeSession ksession =
kbase.newStatefulKnowledgeSession();
AccomodationBase accomBase =
new AccomodationBase(9, "Just Demo");
AccomodationRank accomRank =
new AccomodationRank(9, "Just Demo");
ksession.insert(accomBase);
ksession.insert(accomRank);
ksession.fireAllRules();
} catch (Throwable t) {
t.printStackTrace();
}
}
}
As you may have noticed, in Drools 5 the process of loading the rule files (DSL and DSLR) and getting a working session is different to Drools 4. In Drools 5 there is a whole new set of APIs. Basically, main change is that Drools now is knowledge oriented, instead of rule oriented. It was a real step forward in order to support other forms of logic, such as workflow and event processing. You can read about it in Drools 5.0 docs.

That it. Please note that the above example was tested by me and its working fine. I also included source files for the above example as Eclipse project. You can simply create a new Java project from this existing Ant build.xml file.

Also, I wanted to point out that in my Eclipse project setup my Drools binaries located under JAVA_HOME/lib/drools-5.0-bin/ (have a look at the build.xml)

Cheers
Categories : drools
Technorati Tags : , , , ,
Social Bookmarks :  Add this post to Slashdot    Add this post to Digg    Add this post to Reddit    Add this post to Delicious    Add this post to Stumble it    Add this post to Google    Add this post to Technorati    Add this post to Bloglines    Add this post to Facebook    Add this post to Furl    Add this post to Windows Live    Add this post to Yahoo!

Related Posts
Drools 5 Case Study 2 - Complex Event Processing
Rule Engine Stress Testing
Brainteaser Drools: Testing Objects
Feedback by the Drools Team
Drools 5 - Complex Event Processing
Drools - tutorial on writing DSL template
Drools - Stop executing current agenda group and all rules
Drools - working with Stateless session




If you like this post, then consider subscribing to the full feed RSS.



Re: Drools 5 Case Study 1- Writing DSL for DRL rule

Alex ,

Is there any way we can iterate through a list or define a for loop inside a DSL file?

Thanks,
Bala

Re: Drools 5 Case Study 1- Writing DSL for DRL rule

Hi Bala, I do not think you can define for loop inside a DSL, since its only a template.

But, I think it is possible to iterate through a collection. Refer to the following, I took it from the Drools Expert doco, a small DRL example:

<pre class="programlisting"><a id="d0e5490">for ( QueryResultsRow row : results ) {
Person person = ( Person ) row.get( "person" );
System.out.println( person.getName() + "\n" );
} You can try and create a mapping for DSL rule and the for loop function.

Actually, you can create a function, and try to pass your collection as a parameter. Then you can create a DSL mapping to that function and use the mapping inside your DRL.

Re: Drools 5 Case Study 1- Writing DSL for DRL rule

Hey Alex,

Thanks for the quick reply (as everytime).

Sorry for the delayed reply..was caught up with loads of work.

Bala

Re: Drools 5 Case Study 1- Writing DSL for DRL rule

Always a pleasure

Add a comment    Send a TrackBack