Search in sources :

Example 6 with UnaryTest

use of org.kie.dmn.feel.runtime.UnaryTest in project drools by kiegroup.

the class DecisionTableFunction method invoke.

/**
 *     @param inputExpressionList a list of the N>=0 input expressions in display order
 *     @param inputValuesList * a list of N input values, corresponding to the input expressions. Each
 *     list element is a unary tests literal (see below).
 *     @param outputs * a name (a string matching grammar rule 27) or a list of M>0 names
 *     @param outputValues * if outputs is a list, then output values is a list of lists of values, one list
 *     per output; else output values is a list of values for the one output.
 *     Each value is a string.
 *     @param ruleList a list of R>0 rules. A rule is a list of N input entries followed by M
 *     output entries. An input entry is a unary tests literal. An output entry is
 *     an expression represented as a string.
 *     @param hitPolicy * one of: "U", "A", “P”, “F”, "R", "O", "C", "C+", "C#", "C<", “C>”
 *     (default is "U")
 *     @param defaultOutputValue * if outputs is a list, then default output value is a context with entries
 *     composed of outputs and output values; else default output value is one
 *     of the output values.
 */
public Object invoke(@ParameterName("ctx") EvaluationContext ctx, @ParameterName("outputs") Object outputs, @ParameterName("input expression list") Object inputExpressionList, @ParameterName("input values list") List<?> inputValuesList, @ParameterName("output values") Object outputValues, @ParameterName("rule list") List<List> ruleList, @ParameterName("hit policy") String hitPolicy, @ParameterName("default output value") Object defaultOutputValue) {
    // input expression list can have a single element or be a list
    // TODO isn't ^ conflicting with the specs page 136 "input expression list: a LIST of the"
    List<String> inputExpressions = inputExpressionList instanceof List ? (List) inputExpressionList : Collections.singletonList((String) inputExpressionList);
    List<DTInputClause> inputs;
    if (inputValuesList != null) {
        List<UnaryTest> inputValues = inputValuesList.stream().map(o -> toUnaryTest(ctx, o)).collect(Collectors.toList());
        if (inputValues.size() != inputExpressions.size()) {
        // TODO handle compilation error
        }
        // zip inputExpression with its inputValue
        inputs = IntStream.range(0, inputExpressions.size()).mapToObj(i -> new DTInputClause(inputExpressions.get(i), inputValuesList.toString(), Collections.singletonList(inputValues.get(i)), null)).collect(Collectors.toList());
    } else {
        inputs = inputExpressions.stream().map(ie -> new DTInputClause(ie, null, null, null)).collect(Collectors.toList());
    }
    List<String> parseOutputs = outputs instanceof List ? (List) outputs : Collections.singletonList((String) outputs);
    List<DTOutputClause> outputClauses;
    if (outputValues != null) {
        if (parseOutputs.size() == 1) {
            outputClauses = new ArrayList<>();
            List<UnaryTest> outputValuesCompiled = objectToUnaryTestList(ctx, Collections.singletonList((List<Object>) outputValues)).get(0);
            outputClauses.add(new DTOutputClause(parseOutputs.get(0), outputValuesCompiled));
        } else {
            List<List<UnaryTest>> listOfList = objectToUnaryTestList(ctx, (List<List<Object>>) outputValues);
            // zip inputExpression with its inputValue
            outputClauses = IntStream.range(0, parseOutputs.size()).mapToObj(i -> new DTOutputClause(parseOutputs.get(i), listOfList.get(i))).collect(Collectors.toList());
        }
    } else {
        outputClauses = parseOutputs.stream().map(out -> new DTOutputClause(out, null)).collect(Collectors.toList());
    }
    // TODO parse default output value.
    FEEL feel = FEEL.newInstance();
    List<DTDecisionRule> decisionRules = IntStream.range(0, ruleList.size()).mapToObj(index -> toDecisionRule(ctx, feel, index, ruleList.get(index), inputExpressions.size())).collect(Collectors.toList());
    // TODO is there a way to avoid UUID and get from _evaluation_ ctx the name of the wrapping context?
    // TODO also in this case it is using an ad-hoc created FEEL instance instead of the "hosted" one.
    DecisionTableImpl dti = new DecisionTableImpl(UUID.randomUUID().toString(), inputExpressions, inputs, outputClauses, decisionRules, HitPolicy.fromString(hitPolicy), FEEL.newInstance());
    return new DTInvokerFunction(dti);
}
Also used : IntStream(java.util.stream.IntStream) FEEL(org.kie.dmn.feel.FEEL) FEELEventBase(org.kie.dmn.feel.runtime.events.FEELEventBase) FEELEventListener(org.kie.dmn.api.feel.runtime.events.FEELEventListener) UnaryTest(org.kie.dmn.feel.runtime.UnaryTest) Logger(org.slf4j.Logger) DTOutputClause(org.kie.dmn.feel.runtime.decisiontables.DTOutputClause) HitPolicy(org.kie.dmn.feel.runtime.decisiontables.HitPolicy) LoggerFactory(org.slf4j.LoggerFactory) DTInputClause(org.kie.dmn.feel.runtime.decisiontables.DTInputClause) UUID(java.util.UUID) Collectors(java.util.stream.Collectors) Range(org.kie.dmn.feel.runtime.Range) ArrayList(java.util.ArrayList) List(java.util.List) CompiledExpression(org.kie.dmn.feel.lang.CompiledExpression) FEELEvent(org.kie.dmn.api.feel.runtime.events.FEELEvent) EvaluationContext(org.kie.dmn.feel.lang.EvaluationContext) DTDecisionRule(org.kie.dmn.feel.runtime.decisiontables.DTDecisionRule) Msg(org.kie.dmn.feel.util.Msg) DecisionTableImpl(org.kie.dmn.feel.runtime.decisiontables.DecisionTableImpl) Collections(java.util.Collections) FEEL(org.kie.dmn.feel.FEEL) DecisionTableImpl(org.kie.dmn.feel.runtime.decisiontables.DecisionTableImpl) DTOutputClause(org.kie.dmn.feel.runtime.decisiontables.DTOutputClause) UnaryTest(org.kie.dmn.feel.runtime.UnaryTest) DTDecisionRule(org.kie.dmn.feel.runtime.decisiontables.DTDecisionRule) DTInputClause(org.kie.dmn.feel.runtime.decisiontables.DTInputClause) ArrayList(java.util.ArrayList) List(java.util.List)

Example 7 with UnaryTest

use of org.kie.dmn.feel.runtime.UnaryTest in project drools by kiegroup.

the class FEELImpl method evaluateUnaryTests.

@Override
public List<UnaryTest> evaluateUnaryTests(String expression, Map<String, Type> variableTypes) {
    // DMN defines a special case where, unless the expressions are unary tests
    // or ranges, they need to be converted into an equality test unary expression.
    // This way, we have to compile and check the low level AST nodes to properly
    // deal with this case
    CompilerContext ctx = newCompilerContext();
    for (Map.Entry<String, Type> e : variableTypes.entrySet()) {
        ctx.addInputVariableType(e.getKey(), e.getValue());
    }
    CompiledExpressionImpl compiledExpression = (CompiledExpressionImpl) compileExpressionList(expression, ctx);
    if (compiledExpression != null) {
        ListNode listNode = (ListNode) compiledExpression.getExpression();
        List<BaseNode> tests = new ArrayList<>();
        for (BaseNode o : listNode.getElements()) {
            if (o == null) {
                // not much we can do, so just skip it. Error was reported somewhere else
                continue;
            } else if (o instanceof UnaryTestNode || o instanceof DashNode) {
                tests.add(o);
            } else if (o instanceof RangeNode || o instanceof ListNode) {
                tests.add(new UnaryTestNode("in", o));
            } else {
                tests.add(new UnaryTestNode("=", o));
            }
        }
        listNode.setElements(tests);
        compiledExpression.setExpression(listNode);
        // now we can evaluate the expression to build the list of unary tests
        List<UnaryTest> uts = (List<UnaryTest>) evaluate(compiledExpression, FEELImpl.EMPTY_INPUT);
        return uts;
    }
    return Collections.emptyList();
}
Also used : UnaryTestNode(org.kie.dmn.feel.lang.ast.UnaryTestNode) CompilerContext(org.kie.dmn.feel.lang.CompilerContext) BaseNode(org.kie.dmn.feel.lang.ast.BaseNode) ArrayList(java.util.ArrayList) ListNode(org.kie.dmn.feel.lang.ast.ListNode) UnaryTest(org.kie.dmn.feel.runtime.UnaryTest) Type(org.kie.dmn.feel.lang.Type) ArrayList(java.util.ArrayList) List(java.util.List) DashNode(org.kie.dmn.feel.lang.ast.DashNode) HashMap(java.util.HashMap) Map(java.util.Map) RangeNode(org.kie.dmn.feel.lang.ast.RangeNode)

Aggregations

UnaryTest (org.kie.dmn.feel.runtime.UnaryTest)7 ArrayList (java.util.ArrayList)3 List (java.util.List)3 Collections (java.util.Collections)2 HashMap (java.util.HashMap)2 Map (java.util.Map)2 Collectors (java.util.stream.Collectors)2 DMNType (org.kie.dmn.api.core.DMNType)2 FEELEvent (org.kie.dmn.api.feel.runtime.events.FEELEvent)2 BaseDMNTypeImpl (org.kie.dmn.core.impl.BaseDMNTypeImpl)2 FEEL (org.kie.dmn.feel.FEEL)2 CompiledExpression (org.kie.dmn.feel.lang.CompiledExpression)2 EvaluationContext (org.kie.dmn.feel.lang.EvaluationContext)2 Type (org.kie.dmn.feel.lang.Type)2 FEELFunction (org.kie.dmn.feel.runtime.FEELFunction)2 UnaryTests (org.kie.dmn.model.v1_1.UnaryTests)2 Optional (java.util.Optional)1 UUID (java.util.UUID)1 Collectors.toList (java.util.stream.Collectors.toList)1 IntStream (java.util.stream.IntStream)1