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();
}
}
精彩评论