How to define variable and add values to it inside DRL file that can be used between the rules as a static resource.
I tried to use global keyword but when add I add values to it i will not be effected inside Working Memory as it mentioned in documentation. And in my case i conn't add it from Application side.
Example :
global java.util.List myList;
function java.util.List initMyList() {
List list = new ArrayList();
list.add(1);
return list;
}
rule "initListRule"
salience 1001
when
eval(myList == null)
then
myList = initMyList();
end
rule "checkIfListIsStillEmptyRule"
salience 1000
when
eval(myList != null)
then
System.out.println("MyList is Not null");
end
as global are not stored in woking memory then myList will be always null as it is not provided from Application side. is there any alternative to define variables and fill them in DRL ?
A DRL global is not evaluated dynamically and therefore your rule "checkIfListIsStillEmptyRule" will not fire.
You can do
rule "initListFact"
when
not List()
then
insert( new ArrayList() );
end
rule "checkThatThereIsAnEmptyList"
when
$list: List( size == 0 )
then
modify( $list ){ add( "something" ) }
end
If you don't need to observe changes of a global you can initialize it in a rule with very high salience. It will be available as a resource but you cannot base rule conditions on its state.
global list myList
rule "initListRule"
salience 9999999999
when
then
myList = new ArrayList();
end
You can use more than one global:
global List myListOne
global List myListTwo
rule "initListsRule"
salience 9999999999
when
then
myListOne = new ArrayList();
myListTwo = new ArrayList();
end
If you need to react to changes, there's no way around facts.
declare NamedList
name: String
list: ArrayList
end
rule createListOne
when
not NamedList( name == "one" )
then
insert( new NamedList( "one", new ArrayList() ) );
end
rule "checkIfListOneIsStillEmpty"
when
$nl: NamedList( name == "one", eval( list.size() == 0 ) )
then
modify( $nl ){vgetList().add( "something" ) }
end
Related
global java.util.List rules;
global java.util.Map ruleParamsMap;
global java.util.List invoiceRowIds;
function BigDecimal sum(List invoiceRowIdsValue, String docType) {
return RuleHelper.sum(invoiceRowIdsValue, docType);
}
rule "example"
when
Boolean(booleanValue == true) from rules contains "TestedValue"
$amount : Integer() from ruleParamsMap.get("amount")
$sum : BigDecimal() from sum(invoiceRowIds, "IV")
Boolean(booleanValue == true) from $sum.compareTo(BigDecimal.valueOf($amount)) <= 0
then
System.out.println("RUN");
end
Here is my rule and for some reason, it prints RUN twice.
Any ideas why?
I have created two different rules, which belong to two different agenda-groups.
First one:
rule "32-30-33.32"
dialect "java"
salience 0
agenda-group "32-30"
when
map : Map((this["Product Name"].toUpperCase().contains("PREMIUM ADPRODUCT")) && ((this["Size Length"] != 5) || (this["Size"].toUpperCase() not contains "300X600") || (this["Size"].toUpperCase() not contains "280X130") || (this["Size"].toUpperCase() not contains "300X250") || (this["Size"].toUpperCase() not contains "970X250") || (this["Size"].toUpperCase() not contains "320X50")));
then
JSONObject jObject = new JSONObject("{\"error34\":\"Premium Adproduct doesn't contain required Creative size!\"}");
Iterator<?> keys = jObject.keys();
while(keys.hasNext()) {
String key = (String)keys.next();
Object value = jObject.get(key);
map.put(key, value);
}
debug(drools);
end
Another rule, in another agenda group:
rule "47-37-1.0"
dialect "java"
salience 0
agenda-group "47-37"
when
map : Map((this["OrderName"] == null));
then
JSONObject jObject = new JSONObject("{\"error1\":\"OrderName should not be null \"}");
Iterator<?> keys = jObject.keys();
while(keys.hasNext()) {
String key = (String)keys.next();
Object value = jObject.get(key);
map.put(key, value);
}
debug(drools);
end
After this, I set focus to the group "47-37",
kieSession.getAgenda().getAgendaGroup("47-37").setFocus();
All rules within the group "32-30" are also getting evaluated. I'm using Drools 7.0.0. How can I control execution of rules only within the focused group?
I'm trying to collect some objects in drools using this code:
rule "Evalua Anexo 10" salience 300 when
jul: ArchJuliano()
reg551: Registro551( fraccAne10 : getFraccion() ) from jul.getListReg551()
exists ( Anexo10( getFraccion() == fraccAne10 ) from jul.getListFraccAne10() )
then
// get pojo reg551
end
The above rule will fire once for each Registro551 when fraccAne10 exists in jul.getListFraccAne10. However, I want to get a list of Registro551 instead only the object.
rule "Evalua Anexo 10" salience 300 when
jul: ArchJuliano()
listOfReg551: List() from collect (
Registro551( fraccAne10 : getFraccion() ) from jul.getListReg551()
exists ( Anexo10( getFraccion() == fraccAne10 ) from jul.getListFraccAne10() )
)
then
// trying to get List<Registro551>
// fires error: mismatched input 'exists' in rule name-of-rule
end
facts:
public class Anexo10 {
private String fraccion;
// getters and setters
public class Registro551 {
private String fraccion;
// getters and setters
public class ArchJuliano {
private List<Anexo10> listFraccAne10;
private List<Registro551> listReg551;
// getters and setters
thank you very much.
rule "Evalua Anexo 10"
when
jul: ArchJuliano( $lAne: listFraccAne10, $lReg: listReg551 )
accumulate( Anexo10( $fA: fraccion ) from $lAne;
$fraccionsA: collectSet($fA) )
accumulate( Registro551( $fR: fraccion memberOf $fraccionsA ) from $lReg;
$fraccionsR: collectList($fR) )
then
...List<Registro551> $fraccionsR...
end
(I haven't tested this.)
facing problem with List iteration in drools
GoodsShipment has the list of GoodsItems and
GoodsItem has the list of Documents
my requirement is, need to check atleast one document is available or no.
iam tried this
but failed
writen a class to checking purpose
public class CheckDocument {
public boolean flag = false;
public CheckPreviousDocument() {
}
public boolean getPreviousDocument(GoodsShipment goodsshipment) {
List<GoodsItem> list = goodsshipment.getGoodsItems();
Iterator<GoodsItem> itr = list.iterator();
while (itr.hasNext()) {
GovernmentAgencyGoodsItem document = itr.next();
if (document.getDocuments().size() > 0) {
flag = true;
break;
}
}
return flag;
}
}
rule "previousDocuments minimum 1"
when
$o: GoodsShipment()
%x: CheckPreviousDocuments(previousDocuments($o) == false)
then
insert(-------------)
end
can anyone please help me..
thanks in advance
Your code is somewhat unusual, but thus rule should do. Note that I have used Document as the type for the elements in the list returned by GovernmentAgencyGoodsItem.getDocuments().
rule atLeastOne
when
$gs: GoodsShipment()
List( size > 0 )
from accumulate ( $gi: GoodsItem() from $gs.getGoodsItems() and
$d: Document() from $gi.getDocuments();
collectList( $d ) )
then
// $gs contains at least one Document
end
The the following logic:
if (order.getPrice()<200 ) {
order.setPrice(order.getPrice()-10);
} else {
order.setPrice(order.getPrice()-20);
if (order.getPrice()<200 ) {
//do nothing
}else {
order.setFreeShip("true");
}
}
for above logic, if I want to implement in drools rule.
rule "rule 1"
when
$o:Order ( amount<200);
then
$o.setPrice($o.getPrice()-10);
end
rule "rule 2"
when
$o:Order (amount>200);
then
$o.setPrice($o.getPrice()-20);
end
If the fact's price is 210, the rule2 is activated then the rule1 will be fired. That is not expected. I don't want to retract(). So is there any better solution for this issue?
And can I specify the sequential rule once a rule is executed like a token mechanism.
Thanks.
No, you can't specify sequential for just one rule or group of rules. You'll need to create a flag and use it as a guard, for example:
rule "rule 1"
when
$o:Order ( amount<200);
not: Flag(object=$o)
then
$o.setPrice($o.getPrice()-10);
insert( new Flag($o) );
end
rule "rule 2"
when
$o:Order (amount>200);
not: Flag(object=$o)
then
$o.setPrice($o.getPrice()-20);
insert( new Flag($o) );
end
and
public class Flag {
private final Object object;
public Flag(Object o) {
this.object = o;
}
//add getter for object
//delegate equals and hashcode to object
}
rule "NYuser_Rule"
no-loop true
ruleflow-group "EvalLoopcondition"
when
m:HelloProcessModel(userlocation in ("NewYorkUser"), count < 4)
then
m.setLoopcondition(6);update(m);
end
rule "ChileUser_Rule"
no-loop true
ruleflow-group "EvalLoopcondition"
when
m:HelloProcessModel(userlocation in ("ChileUser"), count < 3)
then
m.setLoopcondition(5);update(m);
end
Something like this can help you out.