diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunction.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunction.java index 7dcb0a5b26a..c9ea46a7148 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunction.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunction.java @@ -62,6 +62,22 @@ public BaseFEELFunction(String name) { this.symbol = new FunctionSymbol( name, this ); } + private enum CandidateParametersStatus { + PERFECT_MATCH(true), + COERCED(true), + MISSING(false); + + private final boolean found; + + CandidateParametersStatus(boolean found) { + this.found = found; + } + + public boolean isFound() { + return found; + } + } + @Override public String getName() { return name; @@ -178,7 +194,7 @@ private Object[] rearrangeParameters(Object[] params, List pnames) { } private CandidateMethod getCandidateMethod(EvaluationContext ctx, Object[] params, boolean isNamedParams, List available) { - CandidateMethod candidate = null; + CandidateMethod candidateMethod = null; // first, look for exact matches for ( Method m : getClass().getDeclaredMethods() ) { if ( !Modifier.isPublic(m.getModifiers()) || !m.getName().equals( "invoke" ) ) { @@ -225,7 +241,7 @@ private CandidateMethod getCandidateMethod(EvaluationContext ctx, Object[] param continue; } - boolean found = true; + CandidateParametersStatus candidateParameterStatus = CandidateParametersStatus.PERFECT_MATCH; for ( int i = 0; i < parameterTypes.length; i++ ) { Class currentIdxActualParameterType = cm.getActualClasses()[i]; Class expectedParameterType = parameterTypes[i]; @@ -233,35 +249,38 @@ private CandidateMethod getCandidateMethod(EvaluationContext ctx, Object[] param Optional coercedParams = coerceParams(currentIdxActualParameterType, expectedParameterType, actualParams, i); if (coercedParams.isPresent()) { cm.setActualParams(coercedParams.get()); + candidateParameterStatus = CandidateParametersStatus.COERCED; continue; } - found = false; + candidateParameterStatus = CandidateParametersStatus.MISSING; break; } } - if ( found ) { + if ( candidateParameterStatus.isFound() ) { cm.setApply( m ); - if (candidate == null) { - candidate = cm; + if (candidateMethod == null) { + candidateMethod = cm; + } else if (candidateParameterStatus == CandidateParametersStatus.PERFECT_MATCH) { + candidateMethod = cm; + break; } else { - if (cm.getScore() > candidate.getScore()) { - candidate = cm; - } else if (cm.getScore() == candidate.getScore()) { - if (isNamedParams && nullCount(cm.actualParams) candidateMethod.getScore()) { + candidateMethod = cm; + } else if (cm.getScore() == candidateMethod.getScore()) { + if (isNamedParams && nullCount(cm.actualParams) coerceParam(Class currentIdxActualParameterType, Clas singleton list. */ if (!Collection.class.isAssignableFrom(currentIdxActualParameterType) && Collection.class.isAssignableFrom(expectedParameterType)) { - return Optional.of(new ArrayList<>(List.of(actualObject))); + Object singletonValue = coerceParam(currentIdxActualParameterType, currentIdxActualParameterType, actualObject) + .orElse(actualObject); + return Optional.of(List.of(singletonValue)); } if (actualObject instanceof LocalDate localDate && ZonedDateTime.class.isAssignableFrom(expectedParameterType)) { diff --git a/kie-dmn/kie-dmn-signavio/src/main/java/org/kie/dmn/signavio/feel/runtime/functions/ConcatFunction.java b/kie-dmn/kie-dmn-signavio/src/main/java/org/kie/dmn/signavio/feel/runtime/functions/ConcatFunction.java index 602c2b12ccd..26ccfc62252 100644 --- a/kie-dmn/kie-dmn-signavio/src/main/java/org/kie/dmn/signavio/feel/runtime/functions/ConcatFunction.java +++ b/kie-dmn/kie-dmn-signavio/src/main/java/org/kie/dmn/signavio/feel/runtime/functions/ConcatFunction.java @@ -20,6 +20,7 @@ import java.util.Arrays; import java.util.List; +import java.util.Objects; import org.kie.dmn.api.feel.runtime.events.FEELEvent; import org.kie.dmn.feel.runtime.events.InvalidParametersEvent; @@ -39,10 +40,10 @@ public FEELFnResult invoke(@ParameterName("values") List list) { if (list == null) { return FEELFnResult.ofError(new InvalidParametersEvent(FEELEvent.Severity.ERROR, "list", "cannot be null")); } - if (list.contains(null)) { + if (list.stream().anyMatch(Objects::isNull)) { return FEELFnResult.ofError(new InvalidParametersEvent(FEELEvent.Severity.ERROR, "list", "cannot contain null values")); } - + StringBuilder sb = new StringBuilder(); for (Object element : list) { if (!(element instanceof String)) {