Skip to content

Commit

Permalink
Fix
Browse files Browse the repository at this point in the history
  • Loading branch information
yesamer committed Jun 21, 2024
1 parent 35380b6 commit 56b29f5
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -178,7 +194,7 @@ private Object[] rearrangeParameters(Object[] params, List<String> pnames) {
}

private CandidateMethod getCandidateMethod(EvaluationContext ctx, Object[] params, boolean isNamedParams, List<String> 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" ) ) {
Expand Down Expand Up @@ -225,43 +241,46 @@ 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];
if ( currentIdxActualParameterType != null && !expectedParameterType.isAssignableFrom( currentIdxActualParameterType ) ) {
Optional<Object[]> 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)<nullCount(candidate.actualParams)) {
candidate = cm; // `cm` narrower for named parameters without need of passing nulls.
} else if (candidate.getApply().getParameterTypes().length == 1
if (cm.getScore() > candidateMethod.getScore()) {
candidateMethod = cm;
} else if (cm.getScore() == candidateMethod.getScore()) {
if (isNamedParams && nullCount(cm.actualParams)<nullCount(candidateMethod.actualParams)) {
candidateMethod = cm; // `cm` narrower for named parameters without need of passing nulls.
} else if (candidateMethod.getApply().getParameterTypes().length == 1
&& cm.getApply().getParameterTypes().length == 1
&& candidate.getApply().getParameterTypes()[0].equals(Object.class)
&& candidateMethod.getApply().getParameterTypes()[0].equals(Object.class)
&& !cm.getApply().getParameterTypes()[0].equals(Object.class)) {
candidate = cm; // `cm` is more narrowed, hence reflect `candidate` to be now `cm`.
candidateMethod = cm; // `cm` is more narrowed, hence reflect `candidateMethod` to be now `cm`.
}
} else {
// do nothing.
}
}
}
}
return candidate;

return candidateMethod;
}

private static long nullCount(Object[] params) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

import java.time.LocalDate;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
Expand Down Expand Up @@ -73,7 +72,9 @@ static Optional<Object> 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)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -39,10 +40,10 @@ public FEELFnResult<String> 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)) {
Expand Down

0 comments on commit 56b29f5

Please sign in to comment.