3

可以使用 Drools 规则引擎将局部变量创建到局部规则定义中吗?

我写了一个示例代码,但它没有编译。这个例子只是为了暴露关于局部声明的想法(我知道它是错误的)

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

错误信息是:

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"

位置 [25,2] 由以下行定义:

String $departmentName = "Music";
4

2 回答 2

6

从 Drools 5 开始,不能在条件中声明任意变量。您可以将变量绑定到事实和属性:

when
   Person( $name : name )
then
   // $name is bound to each name of each person in the working memory
end
于 2011-01-28T15:53:11.987 回答
3

Drools 5 只能为 Facts 或 Fact 字段的规则定义局部变量:

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

但是,您可以使用 Edson 的回答所建议的映射来模拟任意局部变量(即不是 Fact 或 Fact 属性):

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

DroolsRuleLocalVariable 类如下:

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();
    }
}
于 2016-06-10T11:36:08.377 回答