开发者

Declare local rule variable using Drools

开发者 https://www.devze.com 2023-02-07 02:06 出处:网络
It\'s possible to create a loc开发者_如何学Cal variable into a local rule definition using Drools rule engine?

It's possible to create a loc开发者_如何学Cal variable into a local rule definition using Drools rule engine?

I wrote an example code, but it's not compiling. This example is just to expose the idea about local declaration (I know that it's wrong)

/*...*/
    rule "Test local Variable"
        when
            String $departmentName = "Music";
        then
            System.out.println($departmentName);
    end
/*...*/

The error message is:

org.drools.CheckedDroolsException: There were errors in the rule source: [ERR 101] Line 25:2 no viable alternative at input 'String' in rule "Test local Variable"

The position [25,2] is defined by line:

String $departmentName = "Music";


As of Drools 5, it is not possible to declare arbitrary variables in conditions. You can bind variables to facts and attributes:

when
   Person( $name : name )
then
   // $name is bound to each name of each person in the working memory
end


Drools 5 can only define local variables for rules that are Facts or Fact fields:

when
    $city : City()               // a Fact
    Person ($name : firstName)   // a Fact property
then
    System.out.println("city="+$city+", name="+$name);
end

However, you can emulate arbitrary local variable (i.e. not a Fact or Fact property) by using a map as suggested by Edson's answer:

when
    $myParamList : eval(DroolsRuleLocalVariable.setVariable("myParamList", Arrays.asList(1,2,3) ))
    // warn: you must use eval() and not a Drools condition because the Drools condition will be cached so the setVariable method will not be called
then
    System.out.println("myParamList="+(List<Integer>)DroolsRuleLocalVariable.getVariable("myParamList"));

    // remember to cleanup the variables for the next rule to be executed
    DroolsRuleLocalVariable.clear(); 
end

The DroolsRuleLocalVariable class is the following:

package com.mypackage;

import java.util.HashMap;
import java.util.Map;

/**
 * Manage Drools rule local variables.
 * A local variable can be read/written in the "when" (CONDITION) and in the "then" (consequence/ACTION) parts.
 * The "then" part must cleanup the local variables otherwise they are available for the next executed rule.
 * 
 * Note: Drools 5 cannot create rule local variables, see
 * http://stackoverflow.com/questions/4830117/declare-local-rule-variable-using-drools
 * 
 *
 */
public class DroolsRuleLocalVariable {
    private static Map<String,Object> ruleLocalVariables = new HashMap<>();

    /**
     * Sets the variable variableName to the variableValue value. If the
     * variable is not defined, create a new variable.
     * The method returns true in order to be evaluated in Drools CONDITION, e.g.:
     *  
     *  eval(DroolsRuleLocalVariable.setVariable("myParamList", Arrays.asList($param) ))
     * 
     * @see #clear() the clear method should be called in the ACTION of the decision table
     * @param variableName the variable name
     * @param variableValue the variable value
     * @return always true
     */
    public static boolean setVariable(String variableName, Object variableValue) {
        ruleLocalVariables.put(variableName, variableValue);
        return true;
    }

    /**
     * Returns the variable value or null if the variable is not defined.
     * The variable must be casted to the original type.
     * Usage:
     *  eval(DroolsRuleLocalVariable.getVariable("myParamList"))
     * 
     * @param variableValue
     * @return
     */
    public static Object getVariable(String variableName) {
        Object value = ruleLocalVariables.get(variableName);
        return value;
    }

    /**
     * Clears the local variables. This method MUST be called in the ACTION part of the decision table.
     */
    public static void clear() {
        ruleLocalVariables.clear();
    }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号