Java - Generic Drools rule

折月煮酒 提交于 2020-07-10 10:28:04

问题


I would like to create my rule more Generic format which mean it should be validate the fields and values. Following my POJO structure.

 public class RulesModel
private String field;
private List<String> values;
// other stuff  

And my rule

rule "sample"
when
    $rule : RulesModel( field == "source", values contains "facebook", values contains "youtube", value not contains "instagram" )  
then
    // actions
end  

It's working fine to validate single field, but i want to validate the multiple fields of RulesModel. So i desire to create the POJO

public class RulesModelList {

    private List<RulesModel> ruleList;
    // Getter & Setter
}

So now when i pass the list of RulesModel by using RulesModelList class the rule should be validate like below

$rule : RulesModel( field == "source", values contains "facebook") && $rule : RulesModel( field == "createdBy", values contains "admin")

How to validate that in Drools?

Thanks in advance.


回答1:


If all you want to do is verify that those two (or three or however many) RulesModels are in the list, it's quite simple:

// Example from question
rule "Verify Facebook source and admin createdBy"
when
  RulesModelList( $list: ruleList)
  exists(RulesModel( field == "source", values contains "facebook") from $list)
  exists(RulesModel( field == "createdBy", values contains "admin") from $list)
then
  // do something
end

Basically I get the list of RulesModel out of the RulesModelList input and assign to $list. Then I verify that there exists a RulesModel instance that matches my 'source' criteria, and then one that matches the 'createdBy' criteria.

In the example I used exists() instead of assigning a variable because my sample rule doesn't need to make use of the RulesModel instance on the right hand side. If you do need to do something with the RulesModel instance, simply replace exists() with an assignment like this:

$source: RulesModel( field == "source", values contains "facebook") from $list
$createdBy: RulesModel( field == "createdBy", values contains "admin") from $list

There is no need to do an accumulate unless you're trying to iterate over the list and find things that match a certain criteria. For example, let's say that one of the "field" values is "updatedBy", and there can be multiple RulesModel instances with that field name. To get the subset of the RulesModel instances with field name "updatedBy", you'd use accumulate, as Mykhaylo demonstrated in his answer.

But if all you want to do is verify that a list contains an object that meets your criteria, accumulate is overkill and this here is the appropriate solution.




回答2:


You can use java methods in when block, for example CollectionUtils.intersection

import static org.apache.commons.collections4.CollectionUtils.intersection;
...
$rule : RulesModel( field == "source", !intersection(values, valuesToCheck).isEmpty())



回答3:


You can analyze collection of elements using forAll and accumulate

RulesModelList($ruleList: ruleList)
$matchingList: List() from accumulate (
    $model: RulesModel(field == "source", values contains "facebook", values contains "youtube", value not contains "instagram") from $ruleList,
    accumulateList($model)
)


来源:https://stackoverflow.com/questions/62056120/java-generic-drools-rule

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!