Search in sources :

Example 1 with DMNBaseNode

use of org.kie.dmn.core.ast.DMNBaseNode in project drools by kiegroup.

the class DMNEvaluatorCompiler method compileDecisionTable.

private DMNExpressionEvaluator compileDecisionTable(DMNCompilerContext ctx, DMNModelImpl model, DMNBaseNode node, String dtName, DecisionTable dt) {
    java.util.List<DTInputClause> inputs = new ArrayList<>();
    int index = 0;
    for (InputClause ic : dt.getInput()) {
        index++;
        String inputExpressionText = ic.getInputExpression().getText();
        String inputValuesText = Optional.ofNullable(ic.getInputValues()).map(UnaryTests::getText).orElse(null);
        java.util.List<UnaryTest> inputValues = null;
        if (inputValuesText != null) {
            inputValues = textToUnaryTestList(ctx, inputValuesText, model, ic, Msg.ERR_COMPILING_FEEL_EXPR_ON_DT_INPUT_CLAUSE_IDX, inputValuesText, node.getIdentifierString(), index);
        } else if (ic.getInputExpression().getTypeRef() != null) {
            QName inputExpressionTypeRef = ic.getInputExpression().getTypeRef();
            BaseDMNTypeImpl typeRef = (BaseDMNTypeImpl) model.getTypeRegistry().resolveType(resolveNamespaceForTypeRef(inputExpressionTypeRef, ic.getInputExpression()), inputExpressionTypeRef.getLocalPart());
            inputValues = typeRef.getAllowedValuesFEEL();
        }
        CompiledExpression compiledInput = feel.compileFeelExpression(ctx, inputExpressionText, model, dt, Msg.ERR_COMPILING_FEEL_EXPR_ON_DT_INPUT_CLAUSE_IDX, inputExpressionText, dtName, index);
        inputs.add(new DTInputClause(inputExpressionText, inputValuesText, inputValues, compiledInput));
    }
    java.util.List<DTOutputClause> outputs = new ArrayList<>();
    index = 0;
    boolean hasOutputValues = false;
    for (OutputClause oc : dt.getOutput()) {
        String outputName = oc.getName();
        if (outputName != null) {
            DMNCompilerHelper.checkVariableName(model, node.getSource(), outputName);
        }
        String id = oc.getId();
        String outputValuesText = Optional.ofNullable(oc.getOutputValues()).map(UnaryTests::getText).orElse(null);
        String defaultValue = oc.getDefaultOutputEntry() != null ? oc.getDefaultOutputEntry().getText() : null;
        BaseDMNTypeImpl typeRef = (BaseDMNTypeImpl) DMNTypeRegistry.UNKNOWN;
        java.util.List<UnaryTest> outputValues = null;
        if (oc.getTypeRef() != null) {
            QName outputExpressionTypeRef = oc.getTypeRef();
            typeRef = (BaseDMNTypeImpl) model.getTypeRegistry().resolveType(resolveNamespaceForTypeRef(outputExpressionTypeRef, oc), outputExpressionTypeRef.getLocalPart());
            if (typeRef == null) {
                typeRef = (BaseDMNTypeImpl) DMNTypeRegistry.UNKNOWN;
            }
        } else if (dt.getOutput().size() == 1 && (dt.getParent() instanceof Decision || dt.getParent() instanceof BusinessKnowledgeModel || dt.getParent() instanceof ContextEntry)) {
            QName inferredTypeRef = recurseUpToInferTypeRef(model, oc, dt);
            // if inferredTypeRef is null, a std err will have been reported
            if (inferredTypeRef != null) {
                typeRef = (BaseDMNTypeImpl) model.getTypeRegistry().resolveType(resolveNamespaceForTypeRef(inferredTypeRef, oc), inferredTypeRef.getLocalPart());
            }
        }
        if (outputValuesText != null) {
            outputValues = textToUnaryTestList(ctx, outputValuesText, model, oc, Msg.ERR_COMPILING_FEEL_EXPR_ON_DT_OUTPUT_CLAUSE_IDX, outputValuesText, node.getIdentifierString(), ++index);
        } else if (typeRef != DMNTypeRegistry.UNKNOWN) {
            outputValues = typeRef.getAllowedValuesFEEL();
        }
        if (outputValues != null && !outputValues.isEmpty()) {
            hasOutputValues = true;
        }
        outputs.add(new DTOutputClause(outputName, id, outputValues, defaultValue, typeRef.getFeelType(), typeRef.isCollection()));
    }
    if (dt.getHitPolicy().equals(HitPolicy.PRIORITY) && !hasOutputValues) {
        MsgUtil.reportMessage(logger, DMNMessage.Severity.ERROR, dt.getParent(), model, null, null, Msg.MISSING_OUTPUT_VALUES, dt.getParent());
    }
    java.util.List<DTDecisionRule> rules = new ArrayList<>();
    index = 0;
    for (DecisionRule dr : dt.getRule()) {
        DTDecisionRule rule = new DTDecisionRule(index);
        for (UnaryTests ut : dr.getInputEntry()) {
            final java.util.List<UnaryTest> tests;
            if (ut == null || ut.getText() == null || ut.getText().isEmpty()) {
                tests = Collections.emptyList();
                MsgUtil.reportMessage(logger, DMNMessage.Severity.ERROR, ut, model, null, null, Msg.DTABLE_EMPTY_ENTRY, dt.getRule().indexOf(dr) + 1, dr.getInputEntry().indexOf(ut) + 1, dt.getParentDRDElement().getIdentifierString());
            } else {
                tests = textToUnaryTestList(ctx, ut.getText(), model, dr, Msg.ERR_COMPILING_FEEL_EXPR_ON_DT_RULE_IDX, ut.getText(), node.getIdentifierString(), index + 1);
            }
            rule.getInputEntry().add((c, x) -> tests.stream().anyMatch(t -> {
                Boolean result = t.apply(c, x);
                return result != null && result == true;
            }));
        }
        for (LiteralExpression le : dr.getOutputEntry()) {
            String expressionText = le.getText();
            CompiledExpression compiledExpression = feel.compileFeelExpression(ctx, expressionText, model, dr, Msg.ERR_COMPILING_FEEL_EXPR_ON_DT_RULE_IDX, expressionText, dtName, index + 1);
            rule.getOutputEntry().add(compiledExpression);
        }
        rules.add(rule);
        index++;
    }
    String policy = dt.getHitPolicy().value() + (dt.getAggregation() != null ? " " + dt.getAggregation().value() : "");
    org.kie.dmn.feel.runtime.decisiontables.HitPolicy hp = org.kie.dmn.feel.runtime.decisiontables.HitPolicy.fromString(policy);
    java.util.List<String> parameterNames = new ArrayList<>();
    if (node instanceof BusinessKnowledgeModelNode) {
        // need to break this statement down and check for nulls
        parameterNames.addAll(((BusinessKnowledgeModelNode) node).getBusinessKnowledModel().getEncapsulatedLogic().getFormalParameter().stream().map(f -> f.getName()).collect(toList()));
    } else {
        parameterNames.addAll(node.getDependencies().keySet());
    }
    // creates a FEEL instance which will be used by the invoker/impl (s)
    FEEL feelInstance = feel.newFEELInstance();
    DecisionTableImpl dti = new DecisionTableImpl(dtName, parameterNames, inputs, outputs, rules, hp, feelInstance);
    DTInvokerFunction dtf = new DTInvokerFunction(dti);
    DMNDTExpressionEvaluator dtee = new DMNDTExpressionEvaluator(node, feelInstance, dtf);
    return dtee;
}
Also used : InformationItem(org.kie.dmn.model.v1_1.InformationItem) DMNMessage(org.kie.dmn.api.core.DMNMessage) ContextEntry(org.kie.dmn.model.v1_1.ContextEntry) OutputClause(org.kie.dmn.model.v1_1.OutputClause) FunctionDefinition(org.kie.dmn.model.v1_1.FunctionDefinition) LoggerFactory(org.slf4j.LoggerFactory) LiteralExpression(org.kie.dmn.model.v1_1.LiteralExpression) DMNExpressionEvaluator(org.kie.dmn.core.api.DMNExpressionEvaluator) DTDecisionRule(org.kie.dmn.feel.runtime.decisiontables.DTDecisionRule) EvaluatorResult(org.kie.dmn.core.api.EvaluatorResult) Binding(org.kie.dmn.model.v1_1.Binding) UnaryTest(org.kie.dmn.feel.runtime.UnaryTest) DMNModelInstrumentedBase(org.kie.dmn.model.v1_1.DMNModelInstrumentedBase) BaseDMNTypeImpl(org.kie.dmn.core.impl.BaseDMNTypeImpl) DMNModelImpl(org.kie.dmn.core.impl.DMNModelImpl) DecisionTable(org.kie.dmn.model.v1_1.DecisionTable) DMNRelationEvaluator(org.kie.dmn.core.ast.DMNRelationEvaluator) Collectors(java.util.stream.Collectors) BusinessKnowledgeModelNode(org.kie.dmn.api.core.ast.BusinessKnowledgeModelNode) Context(org.kie.dmn.model.v1_1.Context) List(java.util.List) DMNDTExpressionEvaluator(org.kie.dmn.core.ast.DMNDTExpressionEvaluator) CompiledExpression(org.kie.dmn.feel.lang.CompiledExpression) Invocation(org.kie.dmn.model.v1_1.Invocation) Optional(java.util.Optional) QName(javax.xml.namespace.QName) DMNLiteralExpressionEvaluator(org.kie.dmn.core.ast.DMNLiteralExpressionEvaluator) BusinessKnowledgeModel(org.kie.dmn.model.v1_1.BusinessKnowledgeModel) DMNElement(org.kie.dmn.model.v1_1.DMNElement) FEEL(org.kie.dmn.feel.FEEL) MsgUtil(org.kie.dmn.core.util.MsgUtil) DMNType(org.kie.dmn.api.core.DMNType) DMNContextEvaluator(org.kie.dmn.core.ast.DMNContextEvaluator) DTOutputClause(org.kie.dmn.feel.runtime.decisiontables.DTOutputClause) EvaluatorResultImpl(org.kie.dmn.core.ast.EvaluatorResultImpl) DTInputClause(org.kie.dmn.feel.runtime.decisiontables.DTInputClause) ArrayList(java.util.ArrayList) HitPolicy(org.kie.dmn.model.v1_1.HitPolicy) Relation(org.kie.dmn.model.v1_1.Relation) DecisionNode(org.kie.dmn.api.core.ast.DecisionNode) FEELFunction(org.kie.dmn.feel.runtime.FEELFunction) DMNBaseNode(org.kie.dmn.core.ast.DMNBaseNode) DecisionRule(org.kie.dmn.model.v1_1.DecisionRule) UnaryTests(org.kie.dmn.model.v1_1.UnaryTests) Expression(org.kie.dmn.model.v1_1.Expression) DMNInvocationEvaluator(org.kie.dmn.core.ast.DMNInvocationEvaluator) Logger(org.slf4j.Logger) DMNListEvaluator(org.kie.dmn.core.ast.DMNListEvaluator) DTInvokerFunction(org.kie.dmn.feel.runtime.functions.DTInvokerFunction) Decision(org.kie.dmn.model.v1_1.Decision) Collectors.toList(java.util.stream.Collectors.toList) DMNFunctionDefinitionEvaluator(org.kie.dmn.core.ast.DMNFunctionDefinitionEvaluator) InputClause(org.kie.dmn.model.v1_1.InputClause) Msg(org.kie.dmn.core.util.Msg) DecisionTableImpl(org.kie.dmn.feel.runtime.decisiontables.DecisionTableImpl) Collections(java.util.Collections) BaseFEELFunction(org.kie.dmn.feel.runtime.functions.BaseFEELFunction) FEEL(org.kie.dmn.feel.FEEL) ArrayList(java.util.ArrayList) BusinessKnowledgeModelNode(org.kie.dmn.api.core.ast.BusinessKnowledgeModelNode) UnaryTest(org.kie.dmn.feel.runtime.UnaryTest) CompiledExpression(org.kie.dmn.feel.lang.CompiledExpression) ContextEntry(org.kie.dmn.model.v1_1.ContextEntry) DTDecisionRule(org.kie.dmn.feel.runtime.decisiontables.DTDecisionRule) DecisionRule(org.kie.dmn.model.v1_1.DecisionRule) DTDecisionRule(org.kie.dmn.feel.runtime.decisiontables.DTDecisionRule) DTInputClause(org.kie.dmn.feel.runtime.decisiontables.DTInputClause) DTInputClause(org.kie.dmn.feel.runtime.decisiontables.DTInputClause) InputClause(org.kie.dmn.model.v1_1.InputClause) QName(javax.xml.namespace.QName) DecisionTableImpl(org.kie.dmn.feel.runtime.decisiontables.DecisionTableImpl) LiteralExpression(org.kie.dmn.model.v1_1.LiteralExpression) DTOutputClause(org.kie.dmn.feel.runtime.decisiontables.DTOutputClause) DMNDTExpressionEvaluator(org.kie.dmn.core.ast.DMNDTExpressionEvaluator) BaseDMNTypeImpl(org.kie.dmn.core.impl.BaseDMNTypeImpl) Decision(org.kie.dmn.model.v1_1.Decision) OutputClause(org.kie.dmn.model.v1_1.OutputClause) DTOutputClause(org.kie.dmn.feel.runtime.decisiontables.DTOutputClause) BusinessKnowledgeModel(org.kie.dmn.model.v1_1.BusinessKnowledgeModel) DTInvokerFunction(org.kie.dmn.feel.runtime.functions.DTInvokerFunction) UnaryTests(org.kie.dmn.model.v1_1.UnaryTests)

Example 2 with DMNBaseNode

use of org.kie.dmn.core.ast.DMNBaseNode in project drools by kiegroup.

the class DMNRuntimeImpl method evaluateBKM.

private void evaluateBKM(DMNContext context, DMNResultImpl result, BusinessKnowledgeModelNode b, boolean typeCheck) {
    BusinessKnowledgeModelNodeImpl bkm = (BusinessKnowledgeModelNodeImpl) b;
    if (isNodeValueDefined(result, bkm)) {
        // TODO: do we need to check if the defined variable is a function as it should?
        return;
    }
    // TODO: do we need to check/resolve dependencies?
    if (bkm.getEvaluator() == null) {
        MsgUtil.reportMessage(logger, DMNMessage.Severity.WARN, bkm.getSource(), result, null, null, Msg.MISSING_EXPRESSION_FOR_BKM, getIdentifier(bkm));
        return;
    }
    try {
        DMNRuntimeEventManagerUtils.fireBeforeEvaluateBKM(eventManager, bkm, result);
        for (DMNNode dep : bkm.getDependencies().values()) {
            if (typeCheck && !checkDependencyValueIsValid(dep, result)) {
                MsgUtil.reportMessage(logger, DMNMessage.Severity.ERROR, ((DMNBaseNode) dep).getSource(), result, null, null, Msg.ERROR_EVAL_NODE_DEP_WRONG_TYPE, getIdentifier(bkm), getIdentifier(dep), MsgUtil.clipString(result.getContext().get(dep.getName()).toString(), 50), ((DMNBaseNode) dep).getType());
                return;
            }
            if (!isNodeValueDefined(result, dep)) {
                if (dep instanceof BusinessKnowledgeModelNode) {
                    evaluateBKM(context, result, (BusinessKnowledgeModelNode) dep, typeCheck);
                } else {
                    MsgUtil.reportMessage(logger, DMNMessage.Severity.ERROR, bkm.getSource(), result, null, null, Msg.REQ_DEP_NOT_FOUND_FOR_NODE, getIdentifier(dep), getIdentifier(bkm));
                    return;
                }
            }
        }
        EvaluatorResult er = bkm.getEvaluator().evaluate(this, result);
        if (er.getResultType() == EvaluatorResult.ResultType.SUCCESS) {
            FEELFunction resultFn = (FEELFunction) er.getResult();
            if (bkm.getModelNamespace().equals(result.getModel().getNamespace())) {
                // TODO check of the return type will need calculation/inference of function return type.
                result.getContext().set(bkm.getBusinessKnowledModel().getVariable().getName(), resultFn);
            } else {
                DMNModelImpl model = (DMNModelImpl) result.getModel();
                Optional<String> importAlias = model.getImportAliasFor(bkm.getModelNamespace(), bkm.getModelName());
                Map<String, Object> aliasContext = (Map) result.getContext().getAll().computeIfAbsent(importAlias.get(), x -> new LinkedHashMap<>());
                aliasContext.put(bkm.getBusinessKnowledModel().getVariable().getName(), resultFn);
            }
        }
    } catch (Throwable t) {
        MsgUtil.reportMessage(logger, DMNMessage.Severity.ERROR, bkm.getSource(), result, t, null, Msg.ERROR_EVAL_BKM_NODE, getIdentifier(bkm), t.getMessage());
    } finally {
        DMNRuntimeEventManagerUtils.fireAfterEvaluateBKM(eventManager, bkm, result);
    }
}
Also used : ResourceTypePackage(org.kie.api.internal.io.ResourceTypePackage) MsgUtil(org.kie.dmn.core.util.MsgUtil) DMNPackage(org.kie.dmn.api.core.DMNPackage) DMNMessage(org.kie.dmn.api.core.DMNMessage) DMNResult(org.kie.dmn.api.core.DMNResult) LoggerFactory(org.slf4j.LoggerFactory) ResourceType(org.kie.api.io.ResourceType) DMNOption(org.kie.dmn.core.compiler.DMNOption) EVALUATING(org.kie.dmn.api.core.DMNDecisionResult.DecisionEvaluationStatus.EVALUATING) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) DMNModel(org.kie.dmn.api.core.DMNModel) DecisionNode(org.kie.dmn.api.core.ast.DecisionNode) FEELFunction(org.kie.dmn.feel.runtime.FEELFunction) DMNBaseNode(org.kie.dmn.core.ast.DMNBaseNode) Map(java.util.Map) EvaluatorResult(org.kie.dmn.core.api.EvaluatorResult) DMNRuntime(org.kie.dmn.api.core.DMNRuntime) InputDataNodeImpl(org.kie.dmn.core.ast.InputDataNodeImpl) DMNProfile(org.kie.dmn.core.compiler.DMNProfile) InternalKnowledgePackage(org.drools.core.definitions.InternalKnowledgePackage) DMNRuntimeEventListener(org.kie.dmn.api.core.event.DMNRuntimeEventListener) DMNFactory(org.kie.dmn.core.api.DMNFactory) Logger(org.slf4j.Logger) DMNNode(org.kie.dmn.api.core.ast.DMNNode) BusinessKnowledgeModelNodeImpl(org.kie.dmn.core.ast.BusinessKnowledgeModelNodeImpl) SKIPPED(org.kie.dmn.api.core.DMNDecisionResult.DecisionEvaluationStatus.SKIPPED) Collection(java.util.Collection) Set(java.util.Set) FAILED(org.kie.dmn.api.core.DMNDecisionResult.DecisionEvaluationStatus.FAILED) BusinessKnowledgeModelNode(org.kie.dmn.api.core.ast.BusinessKnowledgeModelNode) RuntimeTypeCheckOption(org.kie.dmn.core.compiler.RuntimeTypeCheckOption) List(java.util.List) KieRuntime(org.kie.api.runtime.KieRuntime) DMNContext(org.kie.dmn.api.core.DMNContext) Optional(java.util.Optional) InputDataNode(org.kie.dmn.api.core.ast.InputDataNode) Msg(org.kie.dmn.core.util.Msg) DMNDecisionResult(org.kie.dmn.api.core.DMNDecisionResult) DecisionNodeImpl(org.kie.dmn.core.ast.DecisionNodeImpl) EvaluatorResult(org.kie.dmn.core.api.EvaluatorResult) FEELFunction(org.kie.dmn.feel.runtime.FEELFunction) BusinessKnowledgeModelNode(org.kie.dmn.api.core.ast.BusinessKnowledgeModelNode) LinkedHashMap(java.util.LinkedHashMap) DMNNode(org.kie.dmn.api.core.ast.DMNNode) BusinessKnowledgeModelNodeImpl(org.kie.dmn.core.ast.BusinessKnowledgeModelNodeImpl) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map)

Example 3 with DMNBaseNode

use of org.kie.dmn.core.ast.DMNBaseNode in project drools by kiegroup.

the class DMNEvaluatorCompiler method compileFunctionDefinition.

private DMNExpressionEvaluator compileFunctionDefinition(DMNCompilerContext ctx, DMNModelImpl model, DMNBaseNode node, String functionName, FunctionDefinition expression) {
    FunctionDefinition funcDef = expression;
    String kindStr = funcDef.getAdditionalAttributes().get(FunctionDefinition.KIND_QNAME);
    FunctionDefinition.Kind kind = kindStr != null ? FunctionDefinition.Kind.determineFromString(kindStr) : FunctionDefinition.Kind.FEEL;
    if (kind == null) {
        // unknown function kind
        MsgUtil.reportMessage(logger, DMNMessage.Severity.ERROR, funcDef, model, null, null, Msg.FUNC_DEF_INVALID_KIND, kindStr, node.getIdentifierString());
        return new DMNFunctionDefinitionEvaluator(node.getName(), funcDef);
    } else if (kind.equals(FunctionDefinition.Kind.FEEL)) {
        ctx.enterFrame();
        try {
            DMNFunctionDefinitionEvaluator func = new DMNFunctionDefinitionEvaluator(node.getName(), funcDef);
            for (InformationItem p : funcDef.getFormalParameter()) {
                DMNCompilerHelper.checkVariableName(model, p, p.getName());
                DMNType dmnType = compiler.resolveTypeRef(model, node, p, p, p.getTypeRef());
                func.addParameter(p.getName(), dmnType);
                ctx.setVariable(p.getName(), dmnType);
            }
            DMNExpressionEvaluator eval = compileExpression(ctx, model, node, functionName, funcDef.getExpression());
            if (eval instanceof DMNLiteralExpressionEvaluator && ((DMNLiteralExpressionEvaluator) eval).isFunctionDefinition()) {
                // we need to resolve the function and eliminate the indirection
                CompiledExpression fexpr = ((DMNLiteralExpressionEvaluator) eval).getExpression();
                FEELFunction feelFunction = feel.evaluateFunctionDef(ctx, fexpr, model, funcDef, Msg.FUNC_DEF_COMPILATION_ERR, functionName, node.getIdentifierString());
                DMNInvocationEvaluator invoker = new DMNInvocationEvaluator(node.getName(), node.getSource(), functionName, new Invocation(), (fctx, fname) -> feelFunction, // feel can be null as anyway is hardcoded to `feelFunction`
                null);
                for (InformationItem p : funcDef.getFormalParameter()) {
                    invoker.addParameter(p.getName(), func.getParameterType(p.getName()), (em, dr) -> new EvaluatorResultImpl(dr.getContext().get(p.getName()), EvaluatorResult.ResultType.SUCCESS));
                }
                eval = invoker;
            }
            func.setEvaluator(eval);
            return func;
        } finally {
            ctx.exitFrame();
        }
    } else if (kind.equals(FunctionDefinition.Kind.JAVA)) {
        if (funcDef.getExpression() instanceof Context) {
            // proceed
            Context context = (Context) funcDef.getExpression();
            String clazz = null;
            String method = null;
            for (ContextEntry ce : context.getContextEntry()) {
                if (ce.getVariable() != null && ce.getVariable().getName() != null && ce.getExpression() != null && ce.getExpression() instanceof LiteralExpression) {
                    if (ce.getVariable().getName().equals("class")) {
                        clazz = stripQuotes(((LiteralExpression) ce.getExpression()).getText().trim());
                    } else if (ce.getVariable().getName().equals("method signature")) {
                        method = stripQuotes(((LiteralExpression) ce.getExpression()).getText().trim());
                    }
                }
            }
            if (clazz != null && method != null) {
                String params = funcDef.getFormalParameter().stream().map(p -> p.getName()).collect(Collectors.joining(","));
                String expr = String.format("function(%s) external { java: { class: \"%s\", method signature: \"%s\" }}", params, clazz, method);
                try {
                    FEELFunction feelFunction = feel.evaluateFunctionDef(ctx, expr, model, funcDef, Msg.FUNC_DEF_COMPILATION_ERR, functionName, node.getIdentifierString());
                    if (feelFunction != null) {
                        ((BaseFEELFunction) feelFunction).setName(functionName);
                    }
                    DMNInvocationEvaluator invoker = new DMNInvocationEvaluator(node.getName(), node.getSource(), functionName, new Invocation(), (fctx, fname) -> feelFunction, // feel can be null as anyway is hardcoded to `feelFunction`
                    null);
                    DMNFunctionDefinitionEvaluator func = new DMNFunctionDefinitionEvaluator(node.getName(), funcDef);
                    for (InformationItem p : funcDef.getFormalParameter()) {
                        DMNCompilerHelper.checkVariableName(model, p, p.getName());
                        DMNType dmnType = compiler.resolveTypeRef(model, node, p, p, p.getTypeRef());
                        func.addParameter(p.getName(), dmnType);
                        invoker.addParameter(p.getName(), dmnType, (em, dr) -> new EvaluatorResultImpl(dr.getContext().get(p.getName()), EvaluatorResult.ResultType.SUCCESS));
                    }
                    func.setEvaluator(invoker);
                    return func;
                } catch (Throwable e) {
                    MsgUtil.reportMessage(logger, DMNMessage.Severity.ERROR, expression, model, e, null, Msg.FUNC_DEF_COMPILATION_ERR, functionName, node.getIdentifierString(), "Exception raised: " + e.getClass().getSimpleName());
                }
            } else {
                MsgUtil.reportMessage(logger, DMNMessage.Severity.ERROR, expression, model, null, null, Msg.FUNC_DEF_MISSING_ENTRY, functionName, node.getIdentifierString());
            }
        } else {
            // error, java function definitions require a context
            MsgUtil.reportMessage(logger, DMNMessage.Severity.ERROR, funcDef, model, null, null, Msg.FUNC_DEF_BODY_NOT_CONTEXT, node.getIdentifierString());
        }
    } else if (kind.equals(FunctionDefinition.Kind.PMML)) {
        MsgUtil.reportMessage(logger, DMNMessage.Severity.WARN, funcDef, model, null, null, Msg.FUNC_DEF_PMML_NOT_SUPPORTED, node.getIdentifierString());
    } else {
        MsgUtil.reportMessage(logger, DMNMessage.Severity.ERROR, funcDef, model, null, null, Msg.FUNC_DEF_INVALID_KIND, kindStr, node.getIdentifierString());
    }
    return new DMNFunctionDefinitionEvaluator(node.getName(), funcDef);
}
Also used : InformationItem(org.kie.dmn.model.v1_1.InformationItem) DMNMessage(org.kie.dmn.api.core.DMNMessage) ContextEntry(org.kie.dmn.model.v1_1.ContextEntry) OutputClause(org.kie.dmn.model.v1_1.OutputClause) FunctionDefinition(org.kie.dmn.model.v1_1.FunctionDefinition) LoggerFactory(org.slf4j.LoggerFactory) LiteralExpression(org.kie.dmn.model.v1_1.LiteralExpression) DMNExpressionEvaluator(org.kie.dmn.core.api.DMNExpressionEvaluator) DTDecisionRule(org.kie.dmn.feel.runtime.decisiontables.DTDecisionRule) EvaluatorResult(org.kie.dmn.core.api.EvaluatorResult) Binding(org.kie.dmn.model.v1_1.Binding) UnaryTest(org.kie.dmn.feel.runtime.UnaryTest) DMNModelInstrumentedBase(org.kie.dmn.model.v1_1.DMNModelInstrumentedBase) BaseDMNTypeImpl(org.kie.dmn.core.impl.BaseDMNTypeImpl) DMNModelImpl(org.kie.dmn.core.impl.DMNModelImpl) DecisionTable(org.kie.dmn.model.v1_1.DecisionTable) DMNRelationEvaluator(org.kie.dmn.core.ast.DMNRelationEvaluator) Collectors(java.util.stream.Collectors) BusinessKnowledgeModelNode(org.kie.dmn.api.core.ast.BusinessKnowledgeModelNode) Context(org.kie.dmn.model.v1_1.Context) List(java.util.List) DMNDTExpressionEvaluator(org.kie.dmn.core.ast.DMNDTExpressionEvaluator) CompiledExpression(org.kie.dmn.feel.lang.CompiledExpression) Invocation(org.kie.dmn.model.v1_1.Invocation) Optional(java.util.Optional) QName(javax.xml.namespace.QName) DMNLiteralExpressionEvaluator(org.kie.dmn.core.ast.DMNLiteralExpressionEvaluator) BusinessKnowledgeModel(org.kie.dmn.model.v1_1.BusinessKnowledgeModel) DMNElement(org.kie.dmn.model.v1_1.DMNElement) FEEL(org.kie.dmn.feel.FEEL) MsgUtil(org.kie.dmn.core.util.MsgUtil) DMNType(org.kie.dmn.api.core.DMNType) DMNContextEvaluator(org.kie.dmn.core.ast.DMNContextEvaluator) DTOutputClause(org.kie.dmn.feel.runtime.decisiontables.DTOutputClause) EvaluatorResultImpl(org.kie.dmn.core.ast.EvaluatorResultImpl) DTInputClause(org.kie.dmn.feel.runtime.decisiontables.DTInputClause) ArrayList(java.util.ArrayList) HitPolicy(org.kie.dmn.model.v1_1.HitPolicy) Relation(org.kie.dmn.model.v1_1.Relation) DecisionNode(org.kie.dmn.api.core.ast.DecisionNode) FEELFunction(org.kie.dmn.feel.runtime.FEELFunction) DMNBaseNode(org.kie.dmn.core.ast.DMNBaseNode) DecisionRule(org.kie.dmn.model.v1_1.DecisionRule) UnaryTests(org.kie.dmn.model.v1_1.UnaryTests) Expression(org.kie.dmn.model.v1_1.Expression) DMNInvocationEvaluator(org.kie.dmn.core.ast.DMNInvocationEvaluator) Logger(org.slf4j.Logger) DMNListEvaluator(org.kie.dmn.core.ast.DMNListEvaluator) DTInvokerFunction(org.kie.dmn.feel.runtime.functions.DTInvokerFunction) Decision(org.kie.dmn.model.v1_1.Decision) Collectors.toList(java.util.stream.Collectors.toList) DMNFunctionDefinitionEvaluator(org.kie.dmn.core.ast.DMNFunctionDefinitionEvaluator) InputClause(org.kie.dmn.model.v1_1.InputClause) Msg(org.kie.dmn.core.util.Msg) DecisionTableImpl(org.kie.dmn.feel.runtime.decisiontables.DecisionTableImpl) Collections(java.util.Collections) BaseFEELFunction(org.kie.dmn.feel.runtime.functions.BaseFEELFunction) Context(org.kie.dmn.model.v1_1.Context) BaseFEELFunction(org.kie.dmn.feel.runtime.functions.BaseFEELFunction) DMNExpressionEvaluator(org.kie.dmn.core.api.DMNExpressionEvaluator) FEELFunction(org.kie.dmn.feel.runtime.FEELFunction) BaseFEELFunction(org.kie.dmn.feel.runtime.functions.BaseFEELFunction) Invocation(org.kie.dmn.model.v1_1.Invocation) DMNLiteralExpressionEvaluator(org.kie.dmn.core.ast.DMNLiteralExpressionEvaluator) LiteralExpression(org.kie.dmn.model.v1_1.LiteralExpression) InformationItem(org.kie.dmn.model.v1_1.InformationItem) CompiledExpression(org.kie.dmn.feel.lang.CompiledExpression) ContextEntry(org.kie.dmn.model.v1_1.ContextEntry) DMNFunctionDefinitionEvaluator(org.kie.dmn.core.ast.DMNFunctionDefinitionEvaluator) FunctionDefinition(org.kie.dmn.model.v1_1.FunctionDefinition) EvaluatorResultImpl(org.kie.dmn.core.ast.EvaluatorResultImpl) DMNInvocationEvaluator(org.kie.dmn.core.ast.DMNInvocationEvaluator) DMNType(org.kie.dmn.api.core.DMNType)

Example 4 with DMNBaseNode

use of org.kie.dmn.core.ast.DMNBaseNode in project drools by kiegroup.

the class DMNRuntimeImpl method evaluateDecision.

private boolean evaluateDecision(DMNContext context, DMNResultImpl result, DecisionNode d, boolean typeCheck) {
    DecisionNodeImpl decision = (DecisionNodeImpl) d;
    if (result.getContext().isDefined(decision.getName())) {
        // already resolved
        return true;
    } else {
        // check if the decision was already evaluated before and returned error
        DMNDecisionResult.DecisionEvaluationStatus status = result.getDecisionResultById(decision.getId()).getEvaluationStatus();
        if (FAILED == status || SKIPPED == status || EVALUATING == status) {
            return false;
        }
    }
    try {
        DMNRuntimeEventManagerUtils.fireBeforeEvaluateDecision(eventManager, decision, result);
        boolean missingInput = false;
        DMNDecisionResultImpl dr = (DMNDecisionResultImpl) result.getDecisionResultById(decision.getId());
        dr.setEvaluationStatus(DMNDecisionResult.DecisionEvaluationStatus.EVALUATING);
        for (DMNNode dep : decision.getDependencies().values()) {
            try {
                if (typeCheck && !checkDependencyValueIsValid(dep, result)) {
                    missingInput = true;
                    DMNMessage message = MsgUtil.reportMessage(logger, DMNMessage.Severity.ERROR, ((DMNBaseNode) dep).getSource(), result, null, null, Msg.ERROR_EVAL_NODE_DEP_WRONG_TYPE, getIdentifier(decision), getIdentifier(dep), MsgUtil.clipString(result.getContext().get(dep.getName()).toString(), 50), ((DMNBaseNode) dep).getType());
                    reportFailure(dr, message, DMNDecisionResult.DecisionEvaluationStatus.SKIPPED);
                }
            } catch (Exception e) {
                MsgUtil.reportMessage(logger, DMNMessage.Severity.ERROR, ((DMNBaseNode) dep).getSource(), result, e, null, Msg.ERROR_CHECKING_ALLOWED_VALUES, getIdentifier(dep), e.getMessage());
            }
            if (!result.getContext().isDefined(dep.getName())) {
                if (dep instanceof DecisionNode) {
                    if (!evaluateDecision(context, result, (DecisionNode) dep, typeCheck)) {
                        missingInput = true;
                        DMNMessage message = MsgUtil.reportMessage(logger, DMNMessage.Severity.ERROR, decision.getSource(), result, null, null, Msg.UNABLE_TO_EVALUATE_DECISION_REQ_DEP, getIdentifier(decision), getIdentifier(dep));
                        reportFailure(dr, message, DMNDecisionResult.DecisionEvaluationStatus.SKIPPED);
                    }
                } else if (dep instanceof BusinessKnowledgeModelNode) {
                    evaluateBKM(context, result, (BusinessKnowledgeModelNode) dep, typeCheck);
                } else {
                    missingInput = true;
                    DMNMessage message = MsgUtil.reportMessage(logger, DMNMessage.Severity.ERROR, decision.getSource(), result, null, null, Msg.REQ_DEP_NOT_FOUND_FOR_NODE, getIdentifier(dep), getIdentifier(decision));
                    reportFailure(dr, message, DMNDecisionResult.DecisionEvaluationStatus.SKIPPED);
                }
            }
        }
        if (missingInput) {
            return false;
        }
        if (decision.getEvaluator() == null) {
            DMNMessage message = MsgUtil.reportMessage(logger, DMNMessage.Severity.WARN, decision.getSource(), result, null, null, Msg.MISSING_EXPRESSION_FOR_DECISION, getIdentifier(decision));
            reportFailure(dr, message, DMNDecisionResult.DecisionEvaluationStatus.SKIPPED);
            return false;
        }
        try {
            EvaluatorResult er = decision.getEvaluator().evaluate(this, result);
            if (er.getResultType() == EvaluatorResult.ResultType.SUCCESS) {
                Object value = er.getResult();
                if (!decision.getResultType().isCollection() && value instanceof Collection && ((Collection) value).size() == 1) {
                    // spec defines that "a=[a]", i.e., singleton collections should be treated as the single element
                    // and vice-versa
                    value = ((Collection) value).toArray()[0];
                }
                try {
                    if (typeCheck && !d.getResultType().isAssignableValue(value)) {
                        DMNMessage message = MsgUtil.reportMessage(logger, DMNMessage.Severity.ERROR, decision.getSource(), result, null, null, Msg.ERROR_EVAL_NODE_RESULT_WRONG_TYPE, getIdentifier(decision), decision.getResultType(), value);
                        reportFailure(dr, message, DMNDecisionResult.DecisionEvaluationStatus.FAILED);
                        return false;
                    }
                } catch (Exception e) {
                    MsgUtil.reportMessage(logger, DMNMessage.Severity.ERROR, decision.getSource(), result, e, null, Msg.ERROR_CHECKING_ALLOWED_VALUES, getIdentifier(decision), e.getMessage());
                    return false;
                }
                result.getContext().set(decision.getDecision().getVariable().getName(), value);
                dr.setResult(value);
                dr.setEvaluationStatus(DMNDecisionResult.DecisionEvaluationStatus.SUCCEEDED);
            } else {
                dr.setEvaluationStatus(DMNDecisionResult.DecisionEvaluationStatus.FAILED);
                return false;
            }
        } catch (Throwable t) {
            DMNMessage message = MsgUtil.reportMessage(logger, DMNMessage.Severity.ERROR, decision.getSource(), result, t, null, Msg.ERROR_EVAL_DECISION_NODE, getIdentifier(decision), t.getMessage());
            reportFailure(dr, message, DMNDecisionResult.DecisionEvaluationStatus.FAILED);
        }
        return true;
    } finally {
        DMNRuntimeEventManagerUtils.fireAfterEvaluateDecision(eventManager, decision, result);
    }
}
Also used : EvaluatorResult(org.kie.dmn.core.api.EvaluatorResult) DecisionNode(org.kie.dmn.api.core.ast.DecisionNode) BusinessKnowledgeModelNode(org.kie.dmn.api.core.ast.BusinessKnowledgeModelNode) DecisionNodeImpl(org.kie.dmn.core.ast.DecisionNodeImpl) DMNMessage(org.kie.dmn.api.core.DMNMessage) DMNBaseNode(org.kie.dmn.core.ast.DMNBaseNode) DMNDecisionResult(org.kie.dmn.api.core.DMNDecisionResult) Collection(java.util.Collection) DMNNode(org.kie.dmn.api.core.ast.DMNNode)

Aggregations

DMNMessage (org.kie.dmn.api.core.DMNMessage)4 BusinessKnowledgeModelNode (org.kie.dmn.api.core.ast.BusinessKnowledgeModelNode)4 DecisionNode (org.kie.dmn.api.core.ast.DecisionNode)4 EvaluatorResult (org.kie.dmn.core.api.EvaluatorResult)4 DMNBaseNode (org.kie.dmn.core.ast.DMNBaseNode)4 ArrayList (java.util.ArrayList)3 List (java.util.List)3 Optional (java.util.Optional)3 Msg (org.kie.dmn.core.util.Msg)3 MsgUtil (org.kie.dmn.core.util.MsgUtil)3 FEELFunction (org.kie.dmn.feel.runtime.FEELFunction)3 Collection (java.util.Collection)2 Collections (java.util.Collections)2 Collectors (java.util.stream.Collectors)2 Collectors.toList (java.util.stream.Collectors.toList)2 QName (javax.xml.namespace.QName)2 DMNDecisionResult (org.kie.dmn.api.core.DMNDecisionResult)2 DMNType (org.kie.dmn.api.core.DMNType)2 DMNNode (org.kie.dmn.api.core.ast.DMNNode)2 DMNExpressionEvaluator (org.kie.dmn.core.api.DMNExpressionEvaluator)2