droolsdrools-guvnordrools-fusiondrools-flow

Drools check if one list contains all elements of another list


How to check whether list of facts contains the list of parameters or attributes present. We want a Rule where The Fact is List of Variables and the attributes which we are passing it is also list of variables. We want to check whether the the Facts contains all the variables present in the List of Attributes . And if it has all the variables matching the Fact then should execute the Action part

    when
          variable:Fact(names contains( ${names}))
    then
          System.out.println($listOfNames);
    end

This is the example which I have tried. Here the Fact class has the Variable name which is List of String. And ${names} is the attribute which we are passing it as the List of String. So basically we want is that when we pass the list of names in fact it shold see whether it has the variable present from ${names} if yes then should execute. But when we pass list to attribute it gives error which is

11:21:00.868 [main] ERROR o.d.c.k.b.impl.AbstractKieProject.buildKnowledgePackages:276 - Unable to build KieBaseModel:defaultKieBase
Unable to Analyse Expression names contains ( [TaskSpecification3, TaskSpecification4]):
[Error: unable to resolve method using strict-mode: com.drool.example.Fact.TaskSpecification3()]
[Near : {... names contains ( [TaskSpecification3, TaskSpecif ....}]
                               ^ : [Rule name='Rule1_1']

It is not able to rectify bracket, when we pass attributes in the list form it gets print with brackets which gives error.

Is there any way we can Compare that One list contains the parameters from the other List.


Solution

  • template header
    salience
    names
    namedTags
    
    import com.drool.example.Fact;
    import java.util.Map;
    import java.util.List;
    global java.util.List list;
    
    function Boolean toCompareList(List targetList, List blackList){
    
        Boolean flag = false;
        for(Object obj: targetList){
            if(blackList.contains(obj)){
                flag = true;
                break;
            }
        }
        return flag;
    }
    
    template "DataWithoutNull"
    
    rule "Rule1_@{row.rowNumber}"
     salience @{salience}
     dialect "java"
    when
      $names: Fact($listOfNames:${names})
      variable:Fact(toCompareList(names,$listOfNames))
    then
      System.out.println($names);
    end
    

    This is the Drt which I have used. Here we have written a function to check if onle list contains all the element in other function and that function is used in the Condition part where we pass facts and parameters to that function and then it evaluate it and give the result in true or false.

    If its true then the action part will be executed or will look for other condition and if false will not execute the action part.

    Is this the right way to do it or is there any other method. But this works absolutely fine as we expected. If there is any other method please let me know.