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:
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
If you like this post, then consider subscribing to the full feed RSS.
For readability, I added some comments to the original rule:
rule 'Rank accomodation name'For my solution, I created two POJOs, tester class DSL and DSLR files. The following is my DSL:
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
[when]AccomodationBaseObj = $accBase: AccomodationBase()and this is the DSLR file:
[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);
package net.javabeansdotasia.casestudy;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.
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
package net.javabeansdotasia.casestudy.utils;Below is my Tester class:
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;
}
}
package net.javabeansdotasia.casestudy.test;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.
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();
}
}
}
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
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
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.
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.

















