diff --git a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/api/EvaluatorResult.java b/kie-dmn/kie-dmn-api/src/main/java/org/kie/dmn/api/core/EvaluatorResult.java similarity index 96% rename from kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/api/EvaluatorResult.java rename to kie-dmn/kie-dmn-api/src/main/java/org/kie/dmn/api/core/EvaluatorResult.java index 7ef00e8ac0b..078bac9ce08 100644 --- a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/api/EvaluatorResult.java +++ b/kie-dmn/kie-dmn-api/src/main/java/org/kie/dmn/api/core/EvaluatorResult.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.kie.dmn.core.api; +package org.kie.dmn.api.core; public interface EvaluatorResult { diff --git a/kie-dmn/kie-dmn-api/src/main/java/org/kie/dmn/api/core/event/AfterConditionalEvaluationEvent.java b/kie-dmn/kie-dmn-api/src/main/java/org/kie/dmn/api/core/event/AfterConditionalEvaluationEvent.java new file mode 100644 index 00000000000..06b4050772f --- /dev/null +++ b/kie-dmn/kie-dmn-api/src/main/java/org/kie/dmn/api/core/event/AfterConditionalEvaluationEvent.java @@ -0,0 +1,33 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.dmn.api.core.event; + +import org.kie.dmn.api.core.EvaluatorResult; + +/** + * Event fired after the then/else branches of an if condition are evaluated + * @see AfterEvaluateConditionalEvent + */ +public interface AfterConditionalEvaluationEvent { + + EvaluatorResult getEvaluatorResultResult(); + + String getExecutedId(); + +} diff --git a/kie-dmn/kie-dmn-api/src/main/java/org/kie/dmn/api/core/event/AfterEvaluateConditionalEvent.java b/kie-dmn/kie-dmn-api/src/main/java/org/kie/dmn/api/core/event/AfterEvaluateConditionalEvent.java new file mode 100644 index 00000000000..b0fb5f2c623 --- /dev/null +++ b/kie-dmn/kie-dmn-api/src/main/java/org/kie/dmn/api/core/event/AfterEvaluateConditionalEvent.java @@ -0,0 +1,33 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.dmn.api.core.event; + +import org.kie.dmn.api.core.EvaluatorResult; + +/** + * Event fired after the if if conditional is evaluated + * + */ +public interface AfterEvaluateConditionalEvent { + + EvaluatorResult getEvaluatorResultResult(); + + String getExecutedId(); + +} diff --git a/kie-dmn/kie-dmn-api/src/main/java/org/kie/dmn/api/core/event/DMNRuntimeEventListener.java b/kie-dmn/kie-dmn-api/src/main/java/org/kie/dmn/api/core/event/DMNRuntimeEventListener.java index ddb6e890938..258d3f8b6b8 100644 --- a/kie-dmn/kie-dmn-api/src/main/java/org/kie/dmn/api/core/event/DMNRuntimeEventListener.java +++ b/kie-dmn/kie-dmn-api/src/main/java/org/kie/dmn/api/core/event/DMNRuntimeEventListener.java @@ -47,4 +47,16 @@ default void afterInvokeBKM(AfterInvokeBKMEvent event) {} default void beforeEvaluateAll(BeforeEvaluateAllEvent event) {} default void afterEvaluateAll(AfterEvaluateAllEvent event) {} + + /** + * Fired after the if if conditional is evaluated + * + */ + default void afterEvaluateConditional(AfterEvaluateConditionalEvent event) {} + + /** + * Fired after the then/else branches of an if condition are evaluated + * + */ + default void afterConditionalEvaluation(AfterConditionalEvaluationEvent event) {} } diff --git a/kie-dmn/kie-dmn-core-jsr223/src/main/java/org/kie/dmn/core/jsr223/JSR223DTExpressionEvaluator.java b/kie-dmn/kie-dmn-core-jsr223/src/main/java/org/kie/dmn/core/jsr223/JSR223DTExpressionEvaluator.java index ff114e2eb44..afa8009e4d7 100644 --- a/kie-dmn/kie-dmn-core-jsr223/src/main/java/org/kie/dmn/core/jsr223/JSR223DTExpressionEvaluator.java +++ b/kie-dmn/kie-dmn-core-jsr223/src/main/java/org/kie/dmn/core/jsr223/JSR223DTExpressionEvaluator.java @@ -35,8 +35,8 @@ import org.kie.dmn.api.feel.runtime.events.FEELEvent; import org.kie.dmn.api.feel.runtime.events.FEELEventListener; import org.kie.dmn.core.api.DMNExpressionEvaluator; -import org.kie.dmn.core.api.EvaluatorResult; -import org.kie.dmn.core.api.EvaluatorResult.ResultType; +import org.kie.dmn.api.core.EvaluatorResult; +import org.kie.dmn.api.core.EvaluatorResult.ResultType; import org.kie.dmn.core.ast.DMNDTExpressionEvaluator; import org.kie.dmn.core.ast.DMNDTExpressionEvaluator.EventResults; import org.kie.dmn.core.ast.EvaluatorResultImpl; diff --git a/kie-dmn/kie-dmn-core-jsr223/src/main/java/org/kie/dmn/core/jsr223/JSR223LiteralExpressionEvaluator.java b/kie-dmn/kie-dmn-core-jsr223/src/main/java/org/kie/dmn/core/jsr223/JSR223LiteralExpressionEvaluator.java index 5b3a5302298..48630c6459e 100644 --- a/kie-dmn/kie-dmn-core-jsr223/src/main/java/org/kie/dmn/core/jsr223/JSR223LiteralExpressionEvaluator.java +++ b/kie-dmn/kie-dmn-core-jsr223/src/main/java/org/kie/dmn/core/jsr223/JSR223LiteralExpressionEvaluator.java @@ -21,8 +21,8 @@ import org.kie.dmn.api.core.DMNResult; import org.kie.dmn.api.core.event.DMNRuntimeEventManager; import org.kie.dmn.core.api.DMNExpressionEvaluator; -import org.kie.dmn.core.api.EvaluatorResult; -import org.kie.dmn.core.api.EvaluatorResult.ResultType; +import org.kie.dmn.api.core.EvaluatorResult; +import org.kie.dmn.api.core.EvaluatorResult.ResultType; import org.kie.dmn.core.ast.EvaluatorResultImpl; import org.kie.dmn.core.impl.DMNResultImpl; import org.slf4j.Logger; diff --git a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/api/DMNExpressionEvaluator.java b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/api/DMNExpressionEvaluator.java index c40ebcb323d..c6237641674 100644 --- a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/api/DMNExpressionEvaluator.java +++ b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/api/DMNExpressionEvaluator.java @@ -19,6 +19,7 @@ package org.kie.dmn.core.api; import org.kie.dmn.api.core.DMNResult; +import org.kie.dmn.api.core.EvaluatorResult; import org.kie.dmn.api.core.event.DMNRuntimeEventManager; /** diff --git a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNConditionalEvaluator.java b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNConditionalEvaluator.java index 7da9445a81a..8f89bb1fcbb 100644 --- a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNConditionalEvaluator.java +++ b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNConditionalEvaluator.java @@ -18,15 +18,20 @@ */ package org.kie.dmn.core.ast; +import java.util.HashMap; +import java.util.Map; + import org.kie.dmn.api.core.DMNMessage; import org.kie.dmn.api.core.DMNResult; import org.kie.dmn.api.core.event.DMNRuntimeEventManager; import org.kie.dmn.core.api.DMNExpressionEvaluator; -import org.kie.dmn.core.api.EvaluatorResult; -import org.kie.dmn.core.api.EvaluatorResult.ResultType; +import org.kie.dmn.api.core.EvaluatorResult; +import org.kie.dmn.api.core.EvaluatorResult.ResultType; import org.kie.dmn.core.impl.DMNResultImpl; +import org.kie.dmn.core.impl.DMNRuntimeEventManagerUtils; import org.kie.dmn.core.util.Msg; import org.kie.dmn.core.util.MsgUtil; +import org.kie.dmn.model.api.Conditional; import org.kie.dmn.model.api.DMNElement; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -40,6 +45,7 @@ public class DMNConditionalEvaluator implements DMNExpressionEvaluator { private DMNExpressionEvaluator elseEvaluator; private DMNElement node; private String name; + private final Map evaluatorIdMap = new HashMap<>(); public DMNConditionalEvaluator(String name, DMNElement node, DMNExpressionEvaluator ifEvaluator, DMNExpressionEvaluator thenEvaluator, DMNExpressionEvaluator elseEvaluator) { this.name = name; @@ -47,6 +53,14 @@ public DMNConditionalEvaluator(String name, DMNElement node, DMNExpressionEvalua this.ifEvaluator = ifEvaluator; this.thenEvaluator = thenEvaluator; this.elseEvaluator = elseEvaluator; + Conditional conditional = node.getChildren().stream() + .filter(c -> c instanceof Conditional) + .map(c -> (Conditional) c) + .findFirst() + .orElseThrow(() -> new RuntimeException("Missing Conditional element inside " + node)); + evaluatorIdMap.put(ifEvaluator, conditional.getIf().getId()); + evaluatorIdMap.put(thenEvaluator, conditional.getThen().getId()); + evaluatorIdMap.put(elseEvaluator, conditional.getElse().getId()); } @Override @@ -54,16 +68,12 @@ public EvaluatorResult evaluate(DMNRuntimeEventManager eventManager, DMNResult d DMNResultImpl result = (DMNResultImpl) dmnr; EvaluatorResult ifEvaluation = ifEvaluator.evaluate(eventManager, result); + String executedId = evaluatorIdMap.get(ifEvaluator); + DMNRuntimeEventManagerUtils.fireAfterEvaluateConditional(eventManager, ifEvaluation, executedId); if (ifEvaluation.getResultType().equals(ResultType.SUCCESS)) { Object ifResult = ifEvaluation.getResult(); - if (ifResult instanceof Boolean) { - if (((Boolean) ifResult).booleanValue()) { - return thenEvaluator.evaluate(eventManager, result); - } else { - return elseEvaluator.evaluate(eventManager, result); - } - } else if (ifResult == null) { - return elseEvaluator.evaluate(eventManager, result); + if (ifResult == null || ifResult instanceof Boolean) { + return manageBooleanOrNullIfResult((Boolean) ifResult, eventManager, result); } else { MsgUtil.reportMessage(logger, DMNMessage.Severity.ERROR, @@ -80,4 +90,13 @@ public EvaluatorResult evaluate(DMNRuntimeEventManager eventManager, DMNResult d return new EvaluatorResultImpl(null, ResultType.FAILURE); } + protected EvaluatorResult manageBooleanOrNullIfResult(Boolean booleanResult, DMNRuntimeEventManager eventManager, DMNResultImpl result) { + DMNExpressionEvaluator evaluatorToUse = booleanResult != null && booleanResult ? thenEvaluator : elseEvaluator; + + EvaluatorResult toReturn = evaluatorToUse.evaluate(eventManager, result); + String executedId = evaluatorIdMap.get(evaluatorToUse); + DMNRuntimeEventManagerUtils.fireAfterConditionalEvaluation(eventManager, toReturn, executedId); + return toReturn; + } + } diff --git a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNContextEvaluator.java b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNContextEvaluator.java index 4fbb5c0c649..cedf3e309a3 100644 --- a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNContextEvaluator.java +++ b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNContextEvaluator.java @@ -31,8 +31,8 @@ import org.kie.dmn.api.core.DMNType; import org.kie.dmn.api.core.event.DMNRuntimeEventManager; import org.kie.dmn.core.api.DMNExpressionEvaluator; -import org.kie.dmn.core.api.EvaluatorResult; -import org.kie.dmn.core.api.EvaluatorResult.ResultType; +import org.kie.dmn.api.core.EvaluatorResult; +import org.kie.dmn.api.core.EvaluatorResult.ResultType; import org.kie.dmn.core.impl.DMNResultImpl; import org.kie.dmn.core.impl.DMNRuntimeEventManagerUtils; import org.kie.dmn.core.impl.DMNRuntimeImpl; diff --git a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNDTExpressionEvaluator.java b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNDTExpressionEvaluator.java index 7432b3114c6..8293f82e672 100644 --- a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNDTExpressionEvaluator.java +++ b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNDTExpressionEvaluator.java @@ -19,7 +19,6 @@ package org.kie.dmn.core.ast; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; @@ -32,8 +31,8 @@ import org.kie.dmn.api.core.event.DMNRuntimeEventManager; import org.kie.dmn.api.feel.runtime.events.FEELEvent; import org.kie.dmn.core.api.DMNExpressionEvaluator; -import org.kie.dmn.core.api.EvaluatorResult; -import org.kie.dmn.core.api.EvaluatorResult.ResultType; +import org.kie.dmn.api.core.EvaluatorResult; +import org.kie.dmn.api.core.EvaluatorResult.ResultType; import org.kie.dmn.core.impl.DMNResultImpl; import org.kie.dmn.core.impl.DMNRuntimeEventManagerUtils; import org.kie.dmn.core.impl.DMNRuntimeImpl; diff --git a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNDecisionServiceEvaluator.java b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNDecisionServiceEvaluator.java index 63a6faf1a74..328ee461b02 100644 --- a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNDecisionServiceEvaluator.java +++ b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNDecisionServiceEvaluator.java @@ -33,8 +33,8 @@ import org.kie.dmn.api.core.ast.DecisionServiceNode; import org.kie.dmn.api.core.event.DMNRuntimeEventManager; import org.kie.dmn.core.api.DMNExpressionEvaluator; -import org.kie.dmn.core.api.EvaluatorResult; -import org.kie.dmn.core.api.EvaluatorResult.ResultType; +import org.kie.dmn.api.core.EvaluatorResult; +import org.kie.dmn.api.core.EvaluatorResult.ResultType; import org.kie.dmn.core.compiler.DMNCompilerImpl; import org.kie.dmn.core.impl.DMNDecisionResultImpl; import org.kie.dmn.core.impl.DMNResultImpl; diff --git a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNDecisionServiceFunctionDefinitionEvaluator.java b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNDecisionServiceFunctionDefinitionEvaluator.java index 21ee7e0af6a..00c2c0f50f0 100644 --- a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNDecisionServiceFunctionDefinitionEvaluator.java +++ b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNDecisionServiceFunctionDefinitionEvaluator.java @@ -31,8 +31,8 @@ import org.kie.dmn.api.core.ast.DecisionServiceNode; import org.kie.dmn.api.core.event.DMNRuntimeEventManager; import org.kie.dmn.core.api.DMNExpressionEvaluator; -import org.kie.dmn.core.api.EvaluatorResult; -import org.kie.dmn.core.api.EvaluatorResult.ResultType; +import org.kie.dmn.api.core.EvaluatorResult; +import org.kie.dmn.api.core.EvaluatorResult.ResultType; import org.kie.dmn.core.ast.DMNFunctionDefinitionEvaluator.FormalParameter; import org.kie.dmn.core.impl.DMNResultImpl; import org.kie.dmn.core.impl.DMNRuntimeImpl; diff --git a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNFilterEvaluator.java b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNFilterEvaluator.java index ccaddaac570..b0120fd57e5 100644 --- a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNFilterEvaluator.java +++ b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNFilterEvaluator.java @@ -28,8 +28,8 @@ import org.kie.dmn.api.core.DMNResult; import org.kie.dmn.api.core.event.DMNRuntimeEventManager; import org.kie.dmn.core.api.DMNExpressionEvaluator; -import org.kie.dmn.core.api.EvaluatorResult; -import org.kie.dmn.core.api.EvaluatorResult.ResultType; +import org.kie.dmn.api.core.EvaluatorResult; +import org.kie.dmn.api.core.EvaluatorResult.ResultType; import org.kie.dmn.core.impl.DMNResultImpl; import org.kie.dmn.core.util.IterableRange; import org.kie.dmn.core.util.Msg; diff --git a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNFunctionDefinitionEvaluator.java b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNFunctionDefinitionEvaluator.java index c7d6469aaca..902ff74556c 100644 --- a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNFunctionDefinitionEvaluator.java +++ b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNFunctionDefinitionEvaluator.java @@ -32,8 +32,8 @@ import org.kie.dmn.api.core.ast.DMNNode; import org.kie.dmn.api.core.event.DMNRuntimeEventManager; import org.kie.dmn.core.api.DMNExpressionEvaluator; -import org.kie.dmn.core.api.EvaluatorResult; -import org.kie.dmn.core.api.EvaluatorResult.ResultType; +import org.kie.dmn.api.core.EvaluatorResult; +import org.kie.dmn.api.core.EvaluatorResult.ResultType; import org.kie.dmn.core.impl.BaseDMNTypeImpl; import org.kie.dmn.core.impl.DMNContextFEELCtxWrapper; import org.kie.dmn.core.impl.DMNResultImpl; diff --git a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNInvocationEvaluator.java b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNInvocationEvaluator.java index ec42aa0f1ec..44e166bb221 100644 --- a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNInvocationEvaluator.java +++ b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNInvocationEvaluator.java @@ -32,8 +32,8 @@ import org.kie.dmn.api.core.event.DMNRuntimeEventManager; import org.kie.dmn.api.feel.runtime.events.FEELEvent; import org.kie.dmn.core.api.DMNExpressionEvaluator; -import org.kie.dmn.core.api.EvaluatorResult; -import org.kie.dmn.core.api.EvaluatorResult.ResultType; +import org.kie.dmn.api.core.EvaluatorResult; +import org.kie.dmn.api.core.EvaluatorResult.ResultType; import org.kie.dmn.core.impl.DMNModelImpl; import org.kie.dmn.core.impl.DMNResultImpl; import org.kie.dmn.core.util.Msg; diff --git a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNIteratorEvaluator.java b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNIteratorEvaluator.java index 1abbe18e518..1d73315edee 100644 --- a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNIteratorEvaluator.java +++ b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNIteratorEvaluator.java @@ -27,8 +27,8 @@ import org.kie.dmn.api.core.DMNResult; import org.kie.dmn.api.core.event.DMNRuntimeEventManager; import org.kie.dmn.core.api.DMNExpressionEvaluator; -import org.kie.dmn.core.api.EvaluatorResult; -import org.kie.dmn.core.api.EvaluatorResult.ResultType; +import org.kie.dmn.api.core.EvaluatorResult; +import org.kie.dmn.api.core.EvaluatorResult.ResultType; import org.kie.dmn.core.impl.DMNResultImpl; import org.kie.dmn.core.util.IterableRange; import org.kie.dmn.core.util.Msg; diff --git a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNListEvaluator.java b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNListEvaluator.java index f0156ddfa9c..0a85a479073 100644 --- a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNListEvaluator.java +++ b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNListEvaluator.java @@ -26,8 +26,8 @@ import org.kie.dmn.api.core.DMNResult; import org.kie.dmn.api.core.event.DMNRuntimeEventManager; import org.kie.dmn.core.api.DMNExpressionEvaluator; -import org.kie.dmn.core.api.EvaluatorResult; -import org.kie.dmn.core.api.EvaluatorResult.ResultType; +import org.kie.dmn.api.core.EvaluatorResult; +import org.kie.dmn.api.core.EvaluatorResult.ResultType; import org.kie.dmn.core.impl.DMNResultImpl; import org.kie.dmn.core.util.Msg; import org.kie.dmn.core.util.MsgUtil; diff --git a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNLiteralExpressionEvaluator.java b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNLiteralExpressionEvaluator.java index 5e42fbc420d..07d1f69390b 100644 --- a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNLiteralExpressionEvaluator.java +++ b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNLiteralExpressionEvaluator.java @@ -19,7 +19,6 @@ package org.kie.dmn.core.ast; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import org.kie.dmn.api.core.DMNMessage; @@ -29,8 +28,8 @@ import org.kie.dmn.api.feel.runtime.events.FEELEvent.Severity; import org.kie.dmn.api.feel.runtime.events.FEELEventListener; import org.kie.dmn.core.api.DMNExpressionEvaluator; -import org.kie.dmn.core.api.EvaluatorResult; -import org.kie.dmn.core.api.EvaluatorResult.ResultType; +import org.kie.dmn.api.core.EvaluatorResult; +import org.kie.dmn.api.core.EvaluatorResult.ResultType; import org.kie.dmn.core.impl.DMNResultImpl; import org.kie.dmn.core.util.Msg; import org.kie.dmn.core.util.MsgUtil; diff --git a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNRelationEvaluator.java b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNRelationEvaluator.java index 1bb21d824b7..6a971ffba15 100644 --- a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNRelationEvaluator.java +++ b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNRelationEvaluator.java @@ -28,8 +28,8 @@ import org.kie.dmn.api.core.DMNResult; import org.kie.dmn.api.core.event.DMNRuntimeEventManager; import org.kie.dmn.core.api.DMNExpressionEvaluator; -import org.kie.dmn.core.api.EvaluatorResult; -import org.kie.dmn.core.api.EvaluatorResult.ResultType; +import org.kie.dmn.api.core.EvaluatorResult; +import org.kie.dmn.api.core.EvaluatorResult.ResultType; import org.kie.dmn.core.impl.DMNResultImpl; import org.kie.dmn.core.util.Msg; import org.kie.dmn.core.util.MsgUtil; diff --git a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/EvaluatorResultImpl.java b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/EvaluatorResultImpl.java index 73b25ca012b..ed8eb063996 100644 --- a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/EvaluatorResultImpl.java +++ b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/EvaluatorResultImpl.java @@ -18,7 +18,7 @@ */ package org.kie.dmn.core.ast; -import org.kie.dmn.core.api.EvaluatorResult; +import org.kie.dmn.api.core.EvaluatorResult; public class EvaluatorResultImpl implements EvaluatorResult { private final Object result; diff --git a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/compiler/DMNEvaluatorCompiler.java b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/compiler/DMNEvaluatorCompiler.java index 9e4ad9d59e9..57b4bc8f12c 100644 --- a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/compiler/DMNEvaluatorCompiler.java +++ b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/compiler/DMNEvaluatorCompiler.java @@ -38,7 +38,7 @@ import org.kie.dmn.api.core.ast.DMNNode; import org.kie.dmn.api.core.ast.DecisionNode; import org.kie.dmn.core.api.DMNExpressionEvaluator; -import org.kie.dmn.core.api.EvaluatorResult; +import org.kie.dmn.api.core.EvaluatorResult; import org.kie.dmn.core.ast.DMNBaseNode; import org.kie.dmn.core.ast.DMNConditionalEvaluator; import org.kie.dmn.core.ast.DMNContextEvaluator; diff --git a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/compiler/alphanetbased/DMNAlphaNetworkEvaluatorImpl.java b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/compiler/alphanetbased/DMNAlphaNetworkEvaluatorImpl.java index 522eb377438..cbffc8b5c8e 100644 --- a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/compiler/alphanetbased/DMNAlphaNetworkEvaluatorImpl.java +++ b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/compiler/alphanetbased/DMNAlphaNetworkEvaluatorImpl.java @@ -27,7 +27,7 @@ import org.kie.dmn.api.core.event.DMNRuntimeEventManager; import org.kie.dmn.api.feel.runtime.events.FEELEvent; import org.kie.dmn.core.api.DMNExpressionEvaluator; -import org.kie.dmn.core.api.EvaluatorResult; +import org.kie.dmn.api.core.EvaluatorResult; import org.kie.dmn.core.ast.DMNBaseNode; import org.kie.dmn.core.ast.DMNDTExpressionEvaluator; import org.kie.dmn.core.ast.EvaluatorResultImpl; diff --git a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/AfterConditionalEvaluationEventImpl.java b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/AfterConditionalEvaluationEventImpl.java new file mode 100644 index 00000000000..5d3c8eb2464 --- /dev/null +++ b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/AfterConditionalEvaluationEventImpl.java @@ -0,0 +1,43 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.dmn.core.impl; + +import org.kie.dmn.api.core.EvaluatorResult; +import org.kie.dmn.api.core.event.AfterConditionalEvaluationEvent; + +public class AfterConditionalEvaluationEventImpl implements AfterConditionalEvaluationEvent { + + private final EvaluatorResult evaluatorResult; + private final String executedId; + + public AfterConditionalEvaluationEventImpl(EvaluatorResult evaluatorResult, String executedId) { + this.evaluatorResult = evaluatorResult; + this.executedId = executedId; + } + + @Override + public EvaluatorResult getEvaluatorResultResult() { + return evaluatorResult; + } + + @Override + public String getExecutedId() { + return executedId; + } +} diff --git a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/AfterEvaluateConditionalEventImpl.java b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/AfterEvaluateConditionalEventImpl.java new file mode 100644 index 00000000000..4aa97cec111 --- /dev/null +++ b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/AfterEvaluateConditionalEventImpl.java @@ -0,0 +1,43 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.dmn.core.impl; + +import org.kie.dmn.api.core.event.AfterEvaluateConditionalEvent; +import org.kie.dmn.api.core.EvaluatorResult; + +public class AfterEvaluateConditionalEventImpl implements AfterEvaluateConditionalEvent { + + private final EvaluatorResult evaluatorResult; + private final String executedId; + + public AfterEvaluateConditionalEventImpl(EvaluatorResult evaluatorResult, String executedId) { + this.evaluatorResult = evaluatorResult; + this.executedId = executedId; + } + + @Override + public EvaluatorResult getEvaluatorResultResult() { + return evaluatorResult; + } + + @Override + public String getExecutedId() { + return executedId; + } +} diff --git a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/DMNRuntimeEventManagerUtils.java b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/DMNRuntimeEventManagerUtils.java index 23879b1c7af..d4a65088c76 100644 --- a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/DMNRuntimeEventManagerUtils.java +++ b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/DMNRuntimeEventManagerUtils.java @@ -26,8 +26,10 @@ import org.kie.dmn.api.core.ast.BusinessKnowledgeModelNode; import org.kie.dmn.api.core.ast.DecisionNode; import org.kie.dmn.api.core.ast.DecisionServiceNode; +import org.kie.dmn.api.core.event.AfterConditionalEvaluationEvent; import org.kie.dmn.api.core.event.AfterEvaluateAllEvent; import org.kie.dmn.api.core.event.AfterEvaluateBKMEvent; +import org.kie.dmn.api.core.event.AfterEvaluateConditionalEvent; import org.kie.dmn.api.core.event.AfterEvaluateContextEntryEvent; import org.kie.dmn.api.core.event.AfterEvaluateDecisionEvent; import org.kie.dmn.api.core.event.AfterEvaluateDecisionServiceEvent; @@ -42,6 +44,7 @@ import org.kie.dmn.api.core.event.BeforeInvokeBKMEvent; import org.kie.dmn.api.core.event.DMNRuntimeEventListener; import org.kie.dmn.api.core.event.DMNRuntimeEventManager; +import org.kie.dmn.api.core.EvaluatorResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -149,6 +152,20 @@ public static void fireAfterEvaluateAll(DMNRuntimeEventManagerImpl eventManager, } } + public static void fireAfterEvaluateConditional(DMNRuntimeEventManager eventManager, EvaluatorResult evaluatorResult, String executedId) { + if( eventManager.hasListeners() ) { + AfterEvaluateConditionalEvent event = new AfterEvaluateConditionalEventImpl(evaluatorResult, executedId); + notifyListeners(eventManager, l -> l.afterEvaluateConditional(event)); + } + } + + public static void fireAfterConditionalEvaluation(DMNRuntimeEventManager eventManager, EvaluatorResult evaluatorResult, String idExecuted) { + if( eventManager.hasListeners() ) { + AfterConditionalEvaluationEvent event = new AfterConditionalEvaluationEventImpl(evaluatorResult, idExecuted); + notifyListeners(eventManager, l -> l.afterConditionalEvaluation(event)); + } + } + private static void notifyListeners(DMNRuntimeEventManager eventManager, Consumer consumer) { for( DMNRuntimeEventListener listener : eventManager.getListeners() ) { try { @@ -159,6 +176,7 @@ private static void notifyListeners(DMNRuntimeEventManager eventManager, Consume } } + private DMNRuntimeEventManagerUtils() { // Constructing instances is not allowed for this class } diff --git a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/DMNRuntimeImpl.java b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/DMNRuntimeImpl.java index 12a3eebea54..203c44f32af 100644 --- a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/DMNRuntimeImpl.java +++ b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/DMNRuntimeImpl.java @@ -45,7 +45,7 @@ import org.kie.dmn.api.core.event.BeforeEvaluateDecisionEvent; import org.kie.dmn.api.core.event.DMNRuntimeEventListener; import org.kie.dmn.core.api.DMNFactory; -import org.kie.dmn.core.api.EvaluatorResult; +import org.kie.dmn.api.core.EvaluatorResult; import org.kie.dmn.core.ast.BusinessKnowledgeModelNodeImpl; import org.kie.dmn.core.ast.DMNBaseNode; import org.kie.dmn.core.ast.DMNDecisionServiceEvaluator; diff --git a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/pmml/AbstractDMNKiePMMLInvocationEvaluator.java b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/pmml/AbstractDMNKiePMMLInvocationEvaluator.java index 584005239ce..414d1efbc4b 100644 --- a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/pmml/AbstractDMNKiePMMLInvocationEvaluator.java +++ b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/pmml/AbstractDMNKiePMMLInvocationEvaluator.java @@ -28,8 +28,8 @@ import org.kie.dmn.api.core.DMNResult; import org.kie.dmn.api.core.DMNType; import org.kie.dmn.api.core.event.DMNRuntimeEventManager; -import org.kie.dmn.core.api.EvaluatorResult; -import org.kie.dmn.core.api.EvaluatorResult.ResultType; +import org.kie.dmn.api.core.EvaluatorResult; +import org.kie.dmn.api.core.EvaluatorResult.ResultType; import org.kie.dmn.core.ast.EvaluatorResultImpl; import org.kie.dmn.core.impl.CompositeTypeImpl; import org.kie.dmn.core.impl.DMNResultImpl; diff --git a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/pmml/AbstractPMMLInvocationEvaluator.java b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/pmml/AbstractPMMLInvocationEvaluator.java index 25f6b18a963..fb07f4708ad 100644 --- a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/pmml/AbstractPMMLInvocationEvaluator.java +++ b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/pmml/AbstractPMMLInvocationEvaluator.java @@ -30,8 +30,8 @@ import org.kie.dmn.api.core.DMNType; import org.kie.dmn.api.core.event.DMNRuntimeEventManager; import org.kie.dmn.core.api.DMNExpressionEvaluator; -import org.kie.dmn.core.api.EvaluatorResult; -import org.kie.dmn.core.api.EvaluatorResult.ResultType; +import org.kie.dmn.api.core.EvaluatorResult; +import org.kie.dmn.api.core.EvaluatorResult.ResultType; import org.kie.dmn.core.ast.DMNFunctionDefinitionEvaluator.FormalParameter; import org.kie.dmn.core.ast.EvaluatorResultImpl; import org.kie.dmn.core.impl.DMNModelImpl; diff --git a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/DMNInputRuntimeTest.java b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/DMNInputRuntimeTest.java index 4feaac9d57a..d89ff7ef4ca 100644 --- a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/DMNInputRuntimeTest.java +++ b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/DMNInputRuntimeTest.java @@ -19,6 +19,7 @@ package org.kie.dmn.core; import java.math.BigDecimal; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -39,7 +40,11 @@ import org.kie.dmn.api.core.ast.DecisionServiceNode; import org.kie.dmn.api.core.ast.InputDataNode; import org.kie.dmn.api.core.ast.ItemDefNode; +import org.kie.dmn.api.core.event.AfterConditionalEvaluationEvent; +import org.kie.dmn.api.core.event.AfterEvaluateConditionalEvent; +import org.kie.dmn.api.core.event.DMNRuntimeEventListener; import org.kie.dmn.core.api.DMNFactory; +import org.kie.dmn.core.api.event.DefaultDMNRuntimeEventListener; import org.kie.dmn.core.util.DMNRuntimeUtil; import static org.assertj.core.api.Assertions.assertThat; @@ -377,6 +382,59 @@ void typeConstraintsChecks(boolean useExecModelCompiler) { assertThat(dmnResult3.getMessages().stream().anyMatch(m -> m.getMessageType().equals(DMNMessageType.ERROR_EVAL_NODE))).isTrue(); } + @ParameterizedTest + @MethodSource("params") + void conditionalIfCheck(boolean useExecModelCompiler) { + init(useExecModelCompiler); + final String ifElementId = "_3C702CE4-E5A0-4B6F-905D-C2621FFFA387"; + final String thenElementId = "_6481FF12-61B5-451C-B775-4143D9B6CD6B"; + final String elseElementId = "_2CD02CB2-6B56-45C4-B461-405E89D45633"; + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("valid_models/DMNv1_5/RiskScore_Simple.dmn", this.getClass() ); + + + final List afterEvaluateConditionalEvents = new ArrayList<>(); + final List afterConditionalEvaluationEvents = new ArrayList<>(); + runtime.addListener(new DefaultDMNRuntimeEventListener() { + + @Override + public void afterEvaluateConditional(AfterEvaluateConditionalEvent event) { + afterEvaluateConditionalEvents.add(event); + } + + @Override + public void afterConditionalEvaluation(AfterConditionalEvaluationEvent event) { + afterConditionalEvaluationEvents.add(event); + } + + }); + final DMNModel dmnModel = runtime.getModel( + "https://kie.org/dmn/_A3317FB1-7BF8-4904-A5F4-2CD63AF3AEC9", + "DMN_A77074C1-21FE-4F7E-9753-F84661569AFC" ); + assertThat(dmnModel).isNotNull(); + assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); + + final DMNContext ctx1 = runtime.newContext(); + ctx1.set("Credit Score", "Poor"); + ctx1.set("DTI", 33); + final DMNResult dmnResult1 = runtime.evaluateAll( dmnModel, ctx1 ); + assertThat(dmnResult1.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult1.getMessages())).isFalse(); + assertThat( dmnResult1.getContext().get( "Risk Score" )).isEqualTo(BigDecimal.valueOf(50)); + assertThat(afterEvaluateConditionalEvents).hasSize(1).allMatch(event -> event.getExecutedId().equals(ifElementId)); + assertThat(afterConditionalEvaluationEvents).hasSize(1).allMatch(event -> event.getExecutedId().equals(elseElementId)); + + // + afterEvaluateConditionalEvents.clear(); + afterConditionalEvaluationEvents.clear(); + final DMNContext ctx2 = runtime.newContext(); + ctx2.set("Credit Score", "Excellent"); + ctx2.set("DTI", 10); + final DMNResult dmnResult2 = runtime.evaluateAll( dmnModel, ctx2 ); + assertThat(dmnResult2.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult1.getMessages())).isFalse(); + assertThat( dmnResult2.getContext().get( "Risk Score" )).isEqualTo(BigDecimal.valueOf(20)); + assertThat(afterEvaluateConditionalEvents).hasSize(1).allMatch(event -> event.getExecutedId().equals(ifElementId)); + assertThat(afterConditionalEvaluationEvents).hasSize(1).allMatch(event -> event.getExecutedId().equals(thenElementId)); + } + @ParameterizedTest @MethodSource("params") void dmnInputDataNodeTypeTest(boolean useExecModelCompiler) { diff --git a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/DMNRuntimeTest.java b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/DMNRuntimeTest.java index 89e261436f7..13a044a6576 100644 --- a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/DMNRuntimeTest.java +++ b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/DMNRuntimeTest.java @@ -63,7 +63,7 @@ import org.kie.dmn.api.core.event.BeforeEvaluateDecisionTableEvent; import org.kie.dmn.api.core.event.DMNRuntimeEventListener; import org.kie.dmn.core.api.DMNFactory; -import org.kie.dmn.core.api.EvaluatorResult; +import org.kie.dmn.api.core.EvaluatorResult; import org.kie.dmn.core.ast.DMNContextEvaluator; import org.kie.dmn.core.ast.DecisionNodeImpl; import org.kie.dmn.core.ast.EvaluatorResultImpl; diff --git a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/ast/DMNConditionalEvaluatorTest.java b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/ast/DMNConditionalEvaluatorTest.java new file mode 100644 index 00000000000..4514ce77ce6 --- /dev/null +++ b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/ast/DMNConditionalEvaluatorTest.java @@ -0,0 +1,175 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.dmn.core.ast; + +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.kie.dmn.api.core.EvaluatorResult; +import org.kie.dmn.api.core.event.AfterConditionalEvaluationEvent; +import org.kie.dmn.api.core.event.AfterEvaluateConditionalEvent; +import org.kie.dmn.api.core.event.DMNRuntimeEventListener; +import org.kie.dmn.api.core.event.DMNRuntimeEventManager; +import org.kie.dmn.core.api.DMNExpressionEvaluator; +import org.kie.dmn.core.impl.DMNResultImpl; +import org.kie.dmn.model.api.ChildExpression; +import org.kie.dmn.model.api.Conditional; +import org.kie.dmn.model.api.DMNElement; +import org.kie.dmn.model.api.DMNModelInstrumentedBase; +import org.kie.dmn.model.api.Expression; +import org.mockito.ArgumentCaptor; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +class DMNConditionalEvaluatorTest { + + private static final String ID_ELEMENT_ID = "ID_ELEMENT_ID"; + private static final String THEN_ELEMENT_ID = "THEN_ELEMENT_ID"; + private static final String ELSE_ELEMENT_ID = "ELSE_ELEMENT_ID"; + private static DMNRuntimeEventManager eventManagerMock; + private static DMNRuntimeEventListener spiedListener; + private static EvaluatorResult ifEvaluationMock; + private static EvaluatorResult thenEvaluationMock; + private static EvaluatorResult elseEvaluationMock; + private static DMNResultImpl dmnResultMock; + private static DMNConditionalEvaluator dmnConditionalEvaluator; + + @BeforeAll + static void setUp() { + spiedListener = spy(DMNRuntimeEventListener.class); + Set listeners = Collections.singleton(spiedListener); + eventManagerMock = mock(DMNRuntimeEventManager.class); + when(eventManagerMock.hasListeners()).thenReturn(true); + when(eventManagerMock.getListeners()).thenReturn(listeners); + ifEvaluationMock = mock(EvaluatorResult.class); + thenEvaluationMock = mock(EvaluatorResult.class); + elseEvaluationMock = mock(EvaluatorResult.class); + + dmnResultMock = mock(DMNResultImpl.class); + DMNExpressionEvaluator ifEvaluatorMock = mock(DMNExpressionEvaluator.class); + DMNExpressionEvaluator thenEvaluatorMock = mock(DMNExpressionEvaluator.class); + DMNExpressionEvaluator elseEvaluatorMock = mock(DMNExpressionEvaluator.class); + + when(ifEvaluatorMock.evaluate(eventManagerMock, dmnResultMock)).thenReturn(ifEvaluationMock); + when(thenEvaluatorMock.evaluate(eventManagerMock, dmnResultMock)).thenReturn(thenEvaluationMock); + when(elseEvaluatorMock.evaluate(eventManagerMock, dmnResultMock)).thenReturn(elseEvaluationMock); + + ChildExpression ifMock = mock(ChildExpression.class); + when(ifMock.getId()).thenReturn(ID_ELEMENT_ID); + + ChildExpression thenMock = mock(ChildExpression.class); + when(thenMock.getId()).thenReturn(THEN_ELEMENT_ID); + + ChildExpression elseMock = mock(ChildExpression.class); + when(elseMock.getId()).thenReturn(ELSE_ELEMENT_ID); + + Conditional conditionalMock = mock(Conditional.class); + when(conditionalMock.getIf()).thenReturn(ifMock); + when(conditionalMock.getThen()).thenReturn(thenMock); + when(conditionalMock.getElse()).thenReturn(elseMock); + + List nodeChildren = Collections.singletonList(conditionalMock); + DMNElement nodeMock = mock(DMNElement.class); + when(nodeMock.getChildren()).thenReturn(nodeChildren); + + dmnConditionalEvaluator = new DMNConditionalEvaluator("name", + nodeMock, + ifEvaluatorMock, + thenEvaluatorMock, + elseEvaluatorMock); + } + + @BeforeEach + void setup() { + reset(spiedListener); + } + + @Test + void evaluateListenerInvocation() { + when(ifEvaluationMock.getResultType()).thenReturn(EvaluatorResult.ResultType.FAILURE); // not interested in + // nested execution + + dmnConditionalEvaluator.evaluate(eventManagerMock, dmnResultMock); + ArgumentCaptor evaluateConditionalEventArgumentCaptor = + ArgumentCaptor.forClass(AfterEvaluateConditionalEvent.class); + verify(spiedListener).afterEvaluateConditional(evaluateConditionalEventArgumentCaptor.capture()); + AfterEvaluateConditionalEvent evaluateConditionalEvent = evaluateConditionalEventArgumentCaptor.getValue(); + assertThat(evaluateConditionalEvent).isNotNull(); + assertThat(evaluateConditionalEvent.getEvaluatorResultResult()).isEqualTo(ifEvaluationMock); + assertThat(evaluateConditionalEvent.getExecutedId()).isEqualTo(ID_ELEMENT_ID); + } + + @Test + void evaluateManageBooleanOrNullIfResultInvocation() { + when(ifEvaluationMock.getResultType()).thenReturn(EvaluatorResult.ResultType.SUCCESS); + when(ifEvaluationMock.getResult()).thenReturn(true); + + DMNConditionalEvaluator spiedDmnConditionalEvaluator = spy(dmnConditionalEvaluator); + spiedDmnConditionalEvaluator.evaluate(eventManagerMock, dmnResultMock); + verify(spiedDmnConditionalEvaluator).manageBooleanOrNullIfResult(true, eventManagerMock, dmnResultMock); + } + + @Test + void manageBooleanOrNullIfResultWithTrue() { + dmnConditionalEvaluator.manageBooleanOrNullIfResult(true, eventManagerMock, dmnResultMock); + ArgumentCaptor afterConditionalEvaluationEventArgumentCaptor = + ArgumentCaptor.forClass(AfterConditionalEvaluationEvent.class); + verify(spiedListener).afterConditionalEvaluation(afterConditionalEvaluationEventArgumentCaptor.capture()); + AfterConditionalEvaluationEvent conditionalEvaluationEvent = + afterConditionalEvaluationEventArgumentCaptor.getValue(); + assertThat(conditionalEvaluationEvent).isNotNull(); + assertThat(conditionalEvaluationEvent.getEvaluatorResultResult()).isEqualTo(thenEvaluationMock); + assertThat(conditionalEvaluationEvent.getExecutedId()).isEqualTo(THEN_ELEMENT_ID); + } + + @Test + void manageBooleanOrNullIfResultWithFalse() { + dmnConditionalEvaluator.manageBooleanOrNullIfResult(false, eventManagerMock, dmnResultMock); + ArgumentCaptor afterConditionalEvaluationEventArgumentCaptor = + ArgumentCaptor.forClass(AfterConditionalEvaluationEvent.class); + verify(spiedListener).afterConditionalEvaluation(afterConditionalEvaluationEventArgumentCaptor.capture()); + AfterConditionalEvaluationEvent conditionalEvaluationEvent = + afterConditionalEvaluationEventArgumentCaptor.getValue(); + assertThat(conditionalEvaluationEvent).isNotNull(); + assertThat(conditionalEvaluationEvent.getEvaluatorResultResult()).isEqualTo(elseEvaluationMock); + assertThat(conditionalEvaluationEvent.getExecutedId()).isEqualTo(ELSE_ELEMENT_ID); + } + + @Test + void manageBooleanOrNullIfResultWithNull() { + dmnConditionalEvaluator.manageBooleanOrNullIfResult(null, eventManagerMock, dmnResultMock); + ArgumentCaptor afterConditionalEvaluationEventArgumentCaptor = + ArgumentCaptor.forClass(AfterConditionalEvaluationEvent.class); + verify(spiedListener).afterConditionalEvaluation(afterConditionalEvaluationEventArgumentCaptor.capture()); + AfterConditionalEvaluationEvent conditionalEvaluationEvent = + afterConditionalEvaluationEventArgumentCaptor.getValue(); + assertThat(conditionalEvaluationEvent).isNotNull(); + assertThat(conditionalEvaluationEvent.getEvaluatorResultResult()).isEqualTo(elseEvaluationMock); + assertThat(conditionalEvaluationEvent.getExecutedId()).isEqualTo(ELSE_ELEMENT_ID); + } +} \ No newline at end of file diff --git a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/ast/DMNContextEvaluatorTest.java b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/ast/DMNContextEvaluatorTest.java index 066c5439439..ab1f01394f0 100644 --- a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/ast/DMNContextEvaluatorTest.java +++ b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/ast/DMNContextEvaluatorTest.java @@ -31,7 +31,7 @@ import org.kie.dmn.api.core.ast.DecisionNode; import org.kie.dmn.core.api.DMNExpressionEvaluator; import org.kie.dmn.core.api.DMNFactory; -import org.kie.dmn.core.api.EvaluatorResult; +import org.kie.dmn.api.core.EvaluatorResult; import org.kie.dmn.core.impl.DMNDecisionResultImpl; import org.kie.dmn.core.impl.DMNResultImpl; import org.kie.dmn.core.impl.DMNResultImplFactory; diff --git a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/impl/DMNRuntimeEventManagerUtilsTest.java b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/impl/DMNRuntimeEventManagerUtilsTest.java new file mode 100644 index 00000000000..1a78b34fe8c --- /dev/null +++ b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/impl/DMNRuntimeEventManagerUtilsTest.java @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.dmn.core.impl; + +import java.util.Collections; +import java.util.Set; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.kie.dmn.api.core.EvaluatorResult; +import org.kie.dmn.api.core.event.AfterConditionalEvaluationEvent; +import org.kie.dmn.api.core.event.AfterEvaluateConditionalEvent; +import org.kie.dmn.api.core.event.DMNRuntimeEventListener; +import org.kie.dmn.api.core.event.DMNRuntimeEventManager; +import org.mockito.ArgumentCaptor; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +class DMNRuntimeEventManagerUtilsTest { + + private static DMNRuntimeEventManager eventManagerMock; + private static DMNRuntimeEventListener spiedListener; + + @BeforeAll + static void setUp() { + spiedListener = spy(DMNRuntimeEventListener.class); + Set listeners = Collections.singleton(spiedListener); + eventManagerMock = mock(DMNRuntimeEventManager.class); + when(eventManagerMock.hasListeners()).thenReturn(true); + when(eventManagerMock.getListeners()).thenReturn(listeners); + } + + @Test + void fireAfterEvaluateConditional() { + EvaluatorResult evaluatorResult = mock(EvaluatorResult.class); + String executedId = "EXECUTED_ID"; + DMNRuntimeEventManagerUtils.fireAfterEvaluateConditional(eventManagerMock, evaluatorResult, executedId); + ArgumentCaptor evaluateConditionalEventArgumentCaptor = ArgumentCaptor.forClass(AfterEvaluateConditionalEvent.class); + verify(spiedListener).afterEvaluateConditional (evaluateConditionalEventArgumentCaptor.capture()); + AfterEvaluateConditionalEvent evaluateConditionalEvent = evaluateConditionalEventArgumentCaptor.getValue(); + assertThat(evaluateConditionalEvent).isNotNull(); + assertThat(evaluateConditionalEvent.getEvaluatorResultResult()).isEqualTo(evaluatorResult); + assertThat(evaluateConditionalEvent.getExecutedId()).isEqualTo(executedId); + } + + @Test + void fireAfterConditionalEvaluation() { + EvaluatorResult evaluatorResult = mock(EvaluatorResult.class); + String executedId = "EXECUTED_ID"; + DMNRuntimeEventManagerUtils.fireAfterConditionalEvaluation(eventManagerMock, evaluatorResult, executedId); + ArgumentCaptor conditionalEvaluationEventArgumentCaptor = ArgumentCaptor.forClass(AfterConditionalEvaluationEvent.class); + verify(spiedListener).afterConditionalEvaluation (conditionalEvaluationEventArgumentCaptor.capture()); + AfterConditionalEvaluationEvent evaluateConditionalEvent = conditionalEvaluationEventArgumentCaptor.getValue(); + assertThat(evaluateConditionalEvent).isNotNull(); + assertThat(evaluateConditionalEvent.getEvaluatorResultResult()).isEqualTo(evaluatorResult); + assertThat(evaluateConditionalEvent.getExecutedId()).isEqualTo(executedId); + } +} \ No newline at end of file diff --git a/kie-dmn/kie-dmn-legacy-tests/src/test/java/org/kie/dmn/legacy/tests/core/v1_1/DMNRuntimeTest.java b/kie-dmn/kie-dmn-legacy-tests/src/test/java/org/kie/dmn/legacy/tests/core/v1_1/DMNRuntimeTest.java index b5443e3e861..e562d67e1aa 100644 --- a/kie-dmn/kie-dmn-legacy-tests/src/test/java/org/kie/dmn/legacy/tests/core/v1_1/DMNRuntimeTest.java +++ b/kie-dmn/kie-dmn-legacy-tests/src/test/java/org/kie/dmn/legacy/tests/core/v1_1/DMNRuntimeTest.java @@ -58,7 +58,7 @@ import org.kie.dmn.api.core.event.BeforeEvaluateDecisionTableEvent; import org.kie.dmn.api.core.event.DMNRuntimeEventListener; import org.kie.dmn.core.api.DMNFactory; -import org.kie.dmn.core.api.EvaluatorResult; +import org.kie.dmn.api.core.EvaluatorResult; import org.kie.dmn.core.ast.DMNContextEvaluator; import org.kie.dmn.core.ast.DecisionNodeImpl; import org.kie.dmn.core.ast.EvaluatorResultImpl; diff --git a/kie-dmn/kie-dmn-signavio/src/main/java/org/kie/dmn/signavio/MultiInstanceDecisionLogic.java b/kie-dmn/kie-dmn-signavio/src/main/java/org/kie/dmn/signavio/MultiInstanceDecisionLogic.java index 542b7c3ff91..aab6c9897d5 100644 --- a/kie-dmn/kie-dmn-signavio/src/main/java/org/kie/dmn/signavio/MultiInstanceDecisionLogic.java +++ b/kie-dmn/kie-dmn-signavio/src/main/java/org/kie/dmn/signavio/MultiInstanceDecisionLogic.java @@ -33,8 +33,8 @@ import org.kie.dmn.api.core.ast.DMNNode; import org.kie.dmn.api.core.event.DMNRuntimeEventManager; import org.kie.dmn.core.api.DMNExpressionEvaluator; -import org.kie.dmn.core.api.EvaluatorResult; -import org.kie.dmn.core.api.EvaluatorResult.ResultType; +import org.kie.dmn.api.core.EvaluatorResult; +import org.kie.dmn.api.core.EvaluatorResult.ResultType; import org.kie.dmn.core.ast.DMNBaseNode; import org.kie.dmn.core.ast.DecisionNodeImpl; import org.kie.dmn.core.ast.EvaluatorResultImpl; diff --git a/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_5/RiskScore_Simple.dmn b/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_5/RiskScore_Simple.dmn new file mode 100644 index 00000000000..ea0d40e36a1 --- /dev/null +++ b/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_5/RiskScore_Simple.dmn @@ -0,0 +1,228 @@ + + + + string + + "Poor", "Fair", "Excellent" + + + + string + + "High", "Medium", "Low" + + + + string + + "Qualified", "Not Qualified" + + + + + + + + + + + + + + + + + + + + Credit Score + + + + + DTI + + + + + + + "Poor" + + + - + + + 30 + + + // Your annotations here + + + + + "Fair" + + + - + + + 20 + + + + + + + + "Excellent" + + + - + + + 10 + + + + + + + + - + + + > 40 + + + 30 + + + + + + + + - + + + [20..40] + + + 20 + + + + + + + + - + + + < 20 + + + 10 + + + + + + + + + + + + + + + + Risk Score <= 30 + + + + + "Qualified" + + + + + "Not Qualified" + + + + + + + + + + 60 + 145 + 118 + 118 + 240 + + + 120 + + + 60 + 145 + 118 + 118 + 240 + + + 190 + + + 190 + + + 60 + 145 + 118 + 118 + 240 + + + 232 + + + 232 + + + 190 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kie-dmn/kie-dmn-trisotech/src/main/java/org/kie/dmn/trisotech/core/ast/DMNConditionalEvaluator.java b/kie-dmn/kie-dmn-trisotech/src/main/java/org/kie/dmn/trisotech/core/ast/DMNConditionalEvaluator.java index 4a2a1e15586..7821ce36724 100644 --- a/kie-dmn/kie-dmn-trisotech/src/main/java/org/kie/dmn/trisotech/core/ast/DMNConditionalEvaluator.java +++ b/kie-dmn/kie-dmn-trisotech/src/main/java/org/kie/dmn/trisotech/core/ast/DMNConditionalEvaluator.java @@ -22,8 +22,8 @@ import org.kie.dmn.api.core.DMNResult; import org.kie.dmn.api.core.event.DMNRuntimeEventManager; import org.kie.dmn.core.api.DMNExpressionEvaluator; -import org.kie.dmn.core.api.EvaluatorResult; -import org.kie.dmn.core.api.EvaluatorResult.ResultType; +import org.kie.dmn.api.core.EvaluatorResult; +import org.kie.dmn.api.core.EvaluatorResult.ResultType; import org.kie.dmn.core.ast.EvaluatorResultImpl; import org.kie.dmn.core.impl.DMNResultImpl; import org.kie.dmn.core.util.MsgUtil; diff --git a/kie-dmn/kie-dmn-trisotech/src/main/java/org/kie/dmn/trisotech/core/ast/DMNFilterEvaluator.java b/kie-dmn/kie-dmn-trisotech/src/main/java/org/kie/dmn/trisotech/core/ast/DMNFilterEvaluator.java index 167a6bd01ad..f5482b7b7c0 100644 --- a/kie-dmn/kie-dmn-trisotech/src/main/java/org/kie/dmn/trisotech/core/ast/DMNFilterEvaluator.java +++ b/kie-dmn/kie-dmn-trisotech/src/main/java/org/kie/dmn/trisotech/core/ast/DMNFilterEvaluator.java @@ -18,7 +18,6 @@ */ package org.kie.dmn.trisotech.core.ast; -import java.util.Arrays; import java.util.Collections; import java.util.LinkedList; import java.util.List; @@ -29,8 +28,8 @@ import org.kie.dmn.api.core.DMNResult; import org.kie.dmn.api.core.event.DMNRuntimeEventManager; import org.kie.dmn.core.api.DMNExpressionEvaluator; -import org.kie.dmn.core.api.EvaluatorResult; -import org.kie.dmn.core.api.EvaluatorResult.ResultType; +import org.kie.dmn.api.core.EvaluatorResult; +import org.kie.dmn.api.core.EvaluatorResult.ResultType; import org.kie.dmn.core.ast.EvaluatorResultImpl; import org.kie.dmn.core.impl.DMNResultImpl; import org.kie.dmn.core.util.MsgUtil; diff --git a/kie-dmn/kie-dmn-trisotech/src/main/java/org/kie/dmn/trisotech/core/ast/DMNIteratorEvaluator.java b/kie-dmn/kie-dmn-trisotech/src/main/java/org/kie/dmn/trisotech/core/ast/DMNIteratorEvaluator.java index 0c5a30c0eb7..6536b46adbf 100644 --- a/kie-dmn/kie-dmn-trisotech/src/main/java/org/kie/dmn/trisotech/core/ast/DMNIteratorEvaluator.java +++ b/kie-dmn/kie-dmn-trisotech/src/main/java/org/kie/dmn/trisotech/core/ast/DMNIteratorEvaluator.java @@ -26,8 +26,8 @@ import org.kie.dmn.api.core.DMNResult; import org.kie.dmn.api.core.event.DMNRuntimeEventManager; import org.kie.dmn.core.api.DMNExpressionEvaluator; -import org.kie.dmn.core.api.EvaluatorResult; -import org.kie.dmn.core.api.EvaluatorResult.ResultType; +import org.kie.dmn.api.core.EvaluatorResult; +import org.kie.dmn.api.core.EvaluatorResult.ResultType; import org.kie.dmn.core.ast.EvaluatorResultImpl; import org.kie.dmn.core.impl.DMNResultImpl; import org.kie.dmn.core.util.MsgUtil;