Drools - Using “from” in decision table

2019-06-05 03:39发布

问题:

I'm having some trouble getting a rule that I know works in .drl form, to work in a decision table.

Here is my rule in drl form:

rule = "slider1"
    dialect "mvel"
    when
        $person: Person()
        ArrayList( size >= 2 )
            from collect( TestResult( name in ("TestA","TestB"), result == "high" )
                           from $person.getLabResults()
                        )
    then
        $person.setString("It worked");
end

Here is what I am trying in the spreadsheet:

CONDITION
-------------------
$person:Person()
-------------------
ArrayList( size >= 1 ) 
    from collect( TestResult( name in $param, result == 'high' ) 
       from $person.getLabResults() ) 
-------------------
Lab Names
-------------------
"TestA","TestB"

When I try to run the rule from the spread sheet, I am getting this error:

Error while creating KieBase[Message [id=1, level=ERROR, path=com/creo/drools/decisiontables/sample-decision-table.xls, line=11, column=0
text=[ERR 102] Line 11:53 mismatched input 'from' in rule "Young safe package 1"], Message [id=2, level=ERROR, path=com/creo/drools/decisiontables/sample-decision-table.xls, line=0, column=0
text=Parser returned a null Package]]

It seems like something isn't working correctly with the from clause, but I have no idea why. I have tried numerous google searches and this is the only thing I could find: http://drools-moved.46999.n3.nabble.com/Question-on-excel-decision-table-with-quot-variable-Type-from-collection-quot-td1186138.html

Any ideas? It's driving me crazy why this won't work in the spread sheet.

回答1:

The pattern format you want to have is not possible with the Drools spreadsheet compiler. If you read the documentation, it will say that the cell under CONDITION provides the pattern CE, typically a class name, and the next cell below specifies a constraint, i.e., an expression that must fit between the pair of parentheses added to the pattern above. The placeholder $param will then repeatedly be replaced by cell values further down the column.

Adding the missing parentheses, your condition expands into (invalid) DRL code:

$person:Person( ArrayList( size >= 1 ) 
from collect( TestResult( name in ("TestA","TestB"), result == 'high' ) 
   from $person.getLabResults() ) )

This causes just the error message you've reported, due to the misplaced from.

I have this snippet of code lying around, and if you can import class SpreadsheetCompiler from wherever it is, a call will display the generated DRL, right or wrong.

private void testSpreadsheet(String dtPath){
  File dtf = new File( dtPath );
  InputStream is;
  try {
    is = new FileInputStream( dtf );
    SpreadsheetCompiler ssComp = new SpreadsheetCompiler();
    String s = ssComp.compile( is, InputType.XLS );
    System.out.println( "=== Begin generated DRL ===" );
    System.out.println( s );
    System.out.println( "=== End generated DRL ===" );
  } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  }
}

If you need to generate lots of rules with lists of test results you should look into Drools templates. With this technique, parameter insertion into arbitrary rule text is possible. Other workarounds may also be viable, e.g., a combination of DRL and spreadsheet rules.