Reputation: 6176
How can I pass a parameter to set the comparing value of age(18 should be dynamic) in the below drools rule
package com.rule.models
import com.rule.models.User
rule "AgeCheck"
when
$user: User( age < 18 )
then
System.out.println("Warning, "+$user.getName()+" is below age!");
end
Upvotes: 6
Views: 12636
Reputation: 9490
For a bit of fun I thought I'd knock up a little example DRL demonstrating how this might be done by inserting AgeLimit
facts.
declare AgeLimit
country: String
age: int
end
declare Bar
country: String
revellers: java.util.Collection
end
declare Person
age: int
end
declare ThrowOutOfTheBar
person: Person
bar: Bar
end
rule "UK drinking age" salience 1000 when then
insertLogical( new AgeLimit( 'uk', 18 ) );
end
rule "US drinking age" salience 1000 when then
insertLogical( new AgeLimit( 'us', 21 ) );
end
rule "Can I buy a beer?" when
$p: Person()
$bar: Bar( revellers contains $p )
AgeLimit( country == $bar.country, age > $p.age )
then
insertLogical( new ThrowOutOfTheBar($p, $bar) );
end
To reduce the amount of hand-cranked DRL further, you could insert those AgeLimit
facts using the API. For example, you could maintain a database table of national age limits and at the start of your session you could insert them all into working memory as facts. Alternatively, you could create a decision table which generates those same age limit insertions rules behind the scenes. This is likely to be a good way to manage things if for example, you wish to maintain an age limit for every country.
Furthering these ends of keeping hard-coded values out of key rules, it would be worth reading up on inference and truth maintenance. This could lead to a rule such as:
rule "Can I buy a beer?" when
$p: Person()
$bar: Bar( revellers contains $p )
IsUnderAge( person == $p, country == $bar.country )
then
insertLogical( new ThrowOutOfTheBar($p, $bar) );
end
This has the benefit of encapsulating the rules around age limits and providing some re-use potential. However to achieve it in the example above involves inserting IsUnderAge
facts for every person for every country in which they are under age. Working out whether that would be a good thing was leading me into all sorts of off-topic thinking, so I left it out. :)
Upvotes: 7
Reputation: 31300
For rules in Drools, there is nothing comparable to "parameter passing". Data used in rules must come from facts in Working Memory or from global variables.
Using the first technique would look like this:
rule "AgeCheck"
when
Parameter( $ageLimit: ageLimit )
$user: User( age < $ageLimit )
then ... end
A single fact of class Parameter
must be inserted initially; it may contain more than one parameter.
Using a global variable is also possible:
global my.app.Parameter parameter
rule "AgeCheck"
when
$user: User( age < parameter.getAgeLimit() )
then ... end
See the Expert manual for details about how to install a global.
Upvotes: 10