Объявите локальную переменную правила, используя Drools - PullRequest
3 голосов
/ 28 января 2011

Можно создать локальную переменную в определении локального правила, используя механизм правил 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";

Ответы [ 2 ]

4 голосов
/ 28 января 2011

Начиная с Drools 5, невозможно объявить произвольные переменные в условиях. Вы можете привязать переменные к фактам и атрибутам:

when
   Person( $name : name )
then
   // $name is bound to each name of each person in the working memory
end
2 голосов
/ 10 июня 2016

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
 * /2842241/obyavite-lokalnuy-peremennuy-pravila-ispolzuya-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();
    }
}
...