2011-01-28 58 views
3

可以使用Drools規則引擎將本地變量創建爲本地規則定義?使用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

從Drools 5起,不可能在條件中聲明任意變量。您可以綁定變量,以事實和屬性:

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

我問了,因爲我需要在不同的Map實例上查找同一個鍵。而且,我有一些結構相同的規則。感謝您的幫助! – apast 2011-01-28 17:05:36

2

Drools的5只能定義局部變量是事實或事實字段規則:

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

但是,您可以模擬任意本地變量(即不由埃德森的答案提出一個事實或事實性質)通過使用地圖:

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(); 
    } 
}