This is an automated email from the ASF dual-hosted git repository.
gitgabrio pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-kie-drools.git
The following commit(s) were added to refs/heads/main by this push:
new f84a1bef13 [incubator-kie-issues#1326] `Filter`, `Some` and `Every`
expression should fail when the matching function doesn't return a Boolean
(#6000)
f84a1bef13 is described below
commit f84a1bef13220ece78d8f6ccf668ddc3baa4ab65
Author: Yeser Amer <[email protected]>
AuthorDate: Mon Jun 24 13:53:09 2024 +0200
[incubator-kie-issues#1326] `Filter`, `Some` and `Every` expression should
fail when the matching function doesn't return a Boolean (#6000)
* Fix + Tests
* Fix tests
* Minor changes
---
.../org/kie/dmn/core/ast/DMNFilterEvaluator.java | 49 ++++++++--------------
.../org/kie/dmn/core/ast/DMNIteratorEvaluator.java | 36 +++++++++++++---
.../src/main/java/org/kie/dmn/core/util/Msg.java | 2 +
.../kie/dmn/core/v1_4/DMN14ExpressionsTest.java | 8 ++--
.../org/kie/dmn/core/v1_4/dmn14expressions.dmn | 2 +-
5 files changed, 55 insertions(+), 42 deletions(-)
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 750c671e0c..ccaddaac57 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
@@ -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;
@@ -70,8 +69,8 @@ public class DMNFilterEvaluator implements
DMNExpressionEvaluator {
}
Object inObj = inResult.getResult();
- if (inObj instanceof Range) {
- inObj = new IterableRange((Range) inObj);
+ if (inObj instanceof Range range) {
+ inObj = new IterableRange(range);
} else if (!(inObj instanceof Iterable)) {
if (inObj == null) {
MsgUtil.reportMessage(logger,
@@ -85,7 +84,7 @@ public class DMNFilterEvaluator implements
DMNExpressionEvaluator {
return new EvaluatorResultImpl(null, ResultType.FAILURE);
}
- // 10.3.2.9.4 Type conversions "to singleton list"
+ // 10.3.2.9.4 Type conversions "to singleton list"
inObj = Collections.singletonList(inObj);
}
@@ -96,45 +95,33 @@ public class DMNFilterEvaluator implements
DMNExpressionEvaluator {
try {
result.setContext(dmnContext);
- boolean first = true;
- for (Object item : (Iterable) inObj) {
+ for (Object item : (Iterable<?>) inObj) {
dmnContext.set("item", item);
if (item instanceof Map) {
Map<String, Object> complexItem = (Map<String, Object>)
item;
- complexItem.forEach((k, v) -> dmnContext.set(k, v));
+ complexItem.forEach(dmnContext::set);
}
EvaluatorResult evaluate =
filterEvaluator.evaluate(eventManager, dmnr);
Object evalReturn = evaluate.getResult();
//If the evaluation is a boolean result, we add the item based
on a return of true
- if (evalReturn instanceof Boolean && ((Boolean)
evalReturn).booleanValue() == true) {
- returnList.add(item);
- }
-
- //If on the first evaluation, a number is returned, we are
using an index instead of a boolean filter
- if (first && evalReturn instanceof Number) {
- List list = inObj instanceof List ? (List) inObj :
List.of(inObj);
- int i = ((Number) evalReturn).intValue();
- if (i > 0 && i <= list.size()) {
- return new EvaluatorResultImpl(list.get(i - 1),
ResultType.SUCCESS);
- } else if (i < 0 && Math.abs(i) <= list.size()) {
- return new EvaluatorResultImpl(list.get(list.size() +
i), ResultType.SUCCESS);
- } else {
- MsgUtil.reportMessage(logger,
- DMNMessage.Severity.ERROR,
- node,
- result,
- null,
- null,
- Msg.INDEX_OUT_OF_BOUND,
- list.size(),
- i);
- return new EvaluatorResultImpl(null,
ResultType.FAILURE);
+ if (evalReturn instanceof Boolean booleanResult) {
+ if (Boolean.TRUE.equals(booleanResult)) {
+ returnList.add(item);
}
+ } else {
+ MsgUtil.reportMessage(logger,
+ DMNMessage.Severity.ERROR,
+ node,
+ result,
+ null,
+ null,
+ Msg.FILTER_EXPRESSION_RESULT_NOT_BOOLEAN,
+ name);
+ return new EvaluatorResultImpl(null, ResultType.FAILURE);
}
- first = false;
}
} finally {
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 63a8f05b3f..1abbe18e51 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
@@ -72,8 +72,8 @@ public class DMNIteratorEvaluator implements
DMNExpressionEvaluator {
}
Object inObj = inResult.getResult();
- if (inObj instanceof Range) {
- inObj = new IterableRange((Range) inObj);
+ if (inObj instanceof Range range) {
+ inObj = new IterableRange(range);
} else if (!(inObj instanceof Iterable)) {
if (inObj == null) {
MsgUtil.reportMessage(logger,
@@ -112,16 +112,40 @@ public class DMNIteratorEvaluator implements
DMNExpressionEvaluator {
if (type instanceof Every) {
for (Object satisfies : returnList) {
- if (!(satisfies instanceof Boolean) || ((Boolean)
satisfies).booleanValue() == false) {
- return new EvaluatorResultImpl(Boolean.FALSE,
ResultType.SUCCESS);
+ if (satisfies instanceof Boolean satifiesBoolean) {
+ if (Boolean.FALSE.equals(satifiesBoolean)) {
+ return new EvaluatorResultImpl(Boolean.FALSE,
ResultType.SUCCESS);
+ }
+ } else {
+ MsgUtil.reportMessage(logger,
+ DMNMessage.Severity.ERROR,
+ node,
+ result,
+ null,
+ null,
+ Msg.ITERATOR_EXPRESSION_RESULT_NOT_BOOLEAN,
+ name);
+ return new EvaluatorResultImpl(null, ResultType.FAILURE);
}
}
return new EvaluatorResultImpl(Boolean.TRUE, ResultType.SUCCESS);
}
if (type instanceof Some) {
for (Object satisfies : returnList) {
- if (satisfies instanceof Boolean && ((Boolean)
satisfies).booleanValue() == true) {
- return new EvaluatorResultImpl(Boolean.TRUE,
ResultType.SUCCESS);
+ if (satisfies instanceof Boolean satifiesBoolean) {
+ if (Boolean.TRUE.equals(satifiesBoolean)) {
+ return new EvaluatorResultImpl(Boolean.TRUE,
ResultType.SUCCESS);
+ }
+ } else {
+ MsgUtil.reportMessage(logger,
+ DMNMessage.Severity.ERROR,
+ node,
+ result,
+ null,
+ null,
+ Msg.ITERATOR_EXPRESSION_RESULT_NOT_BOOLEAN,
+ name);
+ return new EvaluatorResultImpl(null, ResultType.FAILURE);
}
}
return new EvaluatorResultImpl(Boolean.FALSE, ResultType.SUCCESS);
diff --git a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/util/Msg.java
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/util/Msg.java
index 310b936f57..2f65e3e263 100644
--- a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/util/Msg.java
+++ b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/util/Msg.java
@@ -172,6 +172,8 @@ public final class Msg {
public static final Message2 MISSING_EXPRESSION_FOR_FILTER
= new Message2( DMNMessageType.MISSING_EXPRESSION, "Missing %s expression
for Filter node '%s'" );
public static final Message2 CONDITION_RESULT_NOT_BOOLEAN
= new Message2( DMNMessageType.ERROR_EVAL_NODE, "The if condition on node
%s returned a non boolean result: '%s'" );
public static final Message1 IN_RESULT_NULL
= new Message1( DMNMessageType.ERROR_EVAL_NODE, "The in condition on node
%s returned null.");
+ public static final Message1 FILTER_EXPRESSION_RESULT_NOT_BOOLEAN
= new Message1( DMNMessageType.ERROR_EVAL_NODE, "The filter expression on
node %s returned a non boolean result");
+ public static final Message1 ITERATOR_EXPRESSION_RESULT_NOT_BOOLEAN
= new Message1( DMNMessageType.ERROR_EVAL_NODE, "The satisfy expression
on node %s returned a non boolean result");
public static final Message2 INDEX_OUT_OF_BOUND
= new Message2( DMNMessageType.ERROR_EVAL_NODE, "Index out of bound: list
of %s elements, index %s; will evaluate as FEEL null");
diff --git
a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/v1_4/DMN14ExpressionsTest.java
b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/v1_4/DMN14ExpressionsTest.java
index b684c947a0..1fd9851f69 100644
---
a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/v1_4/DMN14ExpressionsTest.java
+++
b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/v1_4/DMN14ExpressionsTest.java
@@ -170,14 +170,14 @@ public class DMN14ExpressionsTest extends BaseVariantTest
{
testConfig = conf;
setup();
DMNResult results = runtime.evaluateByName(model, new
DMNContextImpl(Collections.singletonMap("Number Input", 5)), "Match by index");
- assertThat(results.getDecisionResultByName("Match by
index").getResult()).isEqualTo(new BigDecimal(5));
+ assertThat(results.getDecisionResultByName("Match by
index").getResult()).asList().hasSize(1);
+ assertThat(results.getDecisionResultByName("Match by
index").getResult()).asList().contains(new BigDecimal(5));
results = runtime.evaluateByName(model, new
DMNContextImpl(Collections.singletonMap("Number Input", -2)), "Match by index");
- assertThat(results.getDecisionResultByName("Match by
index").getResult()).isEqualTo(new BigDecimal(9));
+ assertThat(results.getDecisionResultByName("Match by
index").getResult()).asList().isEmpty();
results = runtime.evaluateByName(model, new
DMNContextImpl(Collections.singletonMap("Number Input", 0)), "Match by index");
- assertThat(results.getMessages()).hasSizeGreaterThan(0);
-
+ assertThat(results.getDecisionResultByName("Match by
index").getResult()).asList().isEmpty();
}
@MethodSource("params")
diff --git
a/kie-dmn/kie-dmn-core/src/test/resources/org/kie/dmn/core/v1_4/dmn14expressions.dmn
b/kie-dmn/kie-dmn-core/src/test/resources/org/kie/dmn/core/v1_4/dmn14expressions.dmn
index 9168bd2473..ef6068630b 100644
---
a/kie-dmn/kie-dmn-core/src/test/resources/org/kie/dmn/core/v1_4/dmn14expressions.dmn
+++
b/kie-dmn/kie-dmn-core/src/test/resources/org/kie/dmn/core/v1_4/dmn14expressions.dmn
@@ -245,7 +245,7 @@
</semantic:in>
<semantic:match id="_362153c8-76bd-4139-aee8-8ef75ebfe42a">
<semantic:literalExpression
id="_2c32d1c1-d954-4422-80a4-36bc2ec63443" triso:descriptionVisible="false">
- <semantic:text>Number Input</semantic:text>
+ <semantic:text>item = Number Input</semantic:text>
</semantic:literalExpression>
</semantic:match>
</semantic:filter>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]