可以使用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";
答案 0 :(得分:4)
从Drools 5开始,无法在条件中声明任意变量。您可以将变量绑定到事实和属性:
when
Person( $name : name )
then
// $name is bound to each name of each person in the working memory
end
答案 1 :(得分:2)
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();
}
}