Search in sources :

Example 1 with InvalidParametersEvent

use of org.kie.dmn.feel.runtime.events.InvalidParametersEvent in project drools by kiegroup.

the class BaseFEELFunction method invokeReflectively.

@Override
public Object invokeReflectively(EvaluationContext ctx, Object[] params) {
    // use reflection to call the appropriate invoke method
    try {
        boolean isNamedParams = params.length > 0 && params[0] instanceof NamedParameter;
        if (!isCustomFunction()) {
            List<String> available = null;
            if (isNamedParams) {
                available = Stream.of(params).map(p -> ((NamedParameter) p).getName()).collect(Collectors.toList());
            }
            CandidateMethod cm = getCandidateMethod(ctx, params, isNamedParams, available);
            if (cm != null) {
                Object result = cm.apply.invoke(this, cm.actualParams);
                if (result instanceof Either) {
                    @SuppressWarnings("unchecked") Either<FEELEvent, Object> either = (Either<FEELEvent, Object>) result;
                    Object eitherResult = either.cata((left) -> {
                        ctx.notifyEvt(() -> {
                            if (left instanceof InvalidParametersEvent) {
                                InvalidParametersEvent invalidParametersEvent = (InvalidParametersEvent) left;
                                invalidParametersEvent.setNodeName(getName());
                                invalidParametersEvent.setActualParameters(Stream.of(cm.apply.getParameters()).map(p -> p.getAnnotation(ParameterName.class).value()).collect(Collectors.toList()), Arrays.asList(cm.actualParams));
                            }
                            return left;
                        });
                        return null;
                    }, Function.identity());
                    return eitherResult;
                }
                return result;
            } else {
                String ps = getClass().toString();
                logger.error("Unable to find function '" + getName() + "( " + ps.substring(1, ps.length() - 1) + " )'");
                ctx.notifyEvt(() -> {
                    return new FEELEventBase(Severity.ERROR, "Unable to find function '" + getName() + "( " + ps.substring(1, ps.length() - 1) + " )'", null);
                });
            }
        } else {
            if (isNamedParams) {
                params = rearrangeParameters(params, this.getParameterNames().get(0));
            }
            Object result = invoke(ctx, params);
            if (result instanceof Either) {
                @SuppressWarnings("unchecked") Either<FEELEvent, Object> either = (Either<FEELEvent, Object>) result;
                final Object[] usedParams = params;
                Object eitherResult = either.cata((left) -> {
                    ctx.notifyEvt(() -> {
                        if (left instanceof InvalidParametersEvent) {
                            InvalidParametersEvent invalidParametersEvent = (InvalidParametersEvent) left;
                            invalidParametersEvent.setNodeName(getName());
                            invalidParametersEvent.setActualParameters(IntStream.of(0, usedParams.length).mapToObj(i -> "arg" + i).collect(Collectors.toList()), Arrays.asList(usedParams));
                        }
                        return left;
                    });
                    return null;
                }, Function.identity());
                return normalizeResult(eitherResult);
            }
            return normalizeResult(result);
        }
    } catch (Exception e) {
        logger.error("Error trying to call function " + getName() + ".", e);
        ctx.notifyEvt(() -> {
            return new FEELEventBase(Severity.ERROR, "Error trying to call function " + getName() + ".", e);
        });
    }
    return null;
}
Also used : NamedParameter(org.kie.dmn.feel.lang.impl.NamedParameter) InvalidParametersEvent(org.kie.dmn.feel.runtime.events.InvalidParametersEvent) FEELEventBase(org.kie.dmn.feel.runtime.events.FEELEventBase) Either(org.kie.dmn.feel.util.Either) FEELEvent(org.kie.dmn.api.feel.runtime.events.FEELEvent)

Example 2 with InvalidParametersEvent

use of org.kie.dmn.feel.runtime.events.InvalidParametersEvent in project drools by kiegroup.

the class FlattenFunction method invoke.

public FEELFnResult<List> invoke(@ParameterName("list") Object list) {
    if (list == null) {
        return FEELFnResult.ofError(new InvalidParametersEvent(Severity.ERROR, "list", "cannot be null"));
    }
    // spec requires us to return a new list
    final List<Object> result = new ArrayList<>();
    flattenList(list, result);
    return FEELFnResult.ofResult(result);
}
Also used : ArrayList(java.util.ArrayList) InvalidParametersEvent(org.kie.dmn.feel.runtime.events.InvalidParametersEvent)

Example 3 with InvalidParametersEvent

use of org.kie.dmn.feel.runtime.events.InvalidParametersEvent in project drools by kiegroup.

the class TimeFunction method invoke.

public FEELFnResult<TemporalAccessor> invoke(@ParameterName("hour") Number hour, @ParameterName("minute") Number minute, @ParameterName("second") Number seconds, @ParameterName("offset") Duration offset) {
    if (hour == null) {
        return FEELFnResult.ofError(new InvalidParametersEvent(Severity.ERROR, "hour", "cannot be null"));
    }
    if (minute == null) {
        return FEELFnResult.ofError(new InvalidParametersEvent(Severity.ERROR, "minute", "cannot be null"));
    }
    if (seconds == null) {
        return FEELFnResult.ofError(new InvalidParametersEvent(Severity.ERROR, "seconds", "cannot be null"));
    }
    try {
        int nanosecs = 0;
        if (seconds instanceof BigDecimal) {
            BigDecimal secs = (BigDecimal) seconds;
            nanosecs = secs.subtract(secs.setScale(0, BigDecimal.ROUND_DOWN)).multiply(NANO_MULT).intValue();
        }
        if (offset == null) {
            return FEELFnResult.ofResult(LocalTime.of(hour.intValue(), minute.intValue(), seconds.intValue(), nanosecs));
        } else {
            return FEELFnResult.ofResult(OffsetTime.of(hour.intValue(), minute.intValue(), seconds.intValue(), nanosecs, ZoneOffset.ofTotalSeconds((int) offset.getSeconds())));
        }
    } catch (DateTimeException e) {
        return FEELFnResult.ofError(new InvalidParametersEvent(Severity.ERROR, "time-parsing exception", e));
    }
}
Also used : DateTimeException(java.time.DateTimeException) InvalidParametersEvent(org.kie.dmn.feel.runtime.events.InvalidParametersEvent) BigDecimal(java.math.BigDecimal)

Example 4 with InvalidParametersEvent

use of org.kie.dmn.feel.runtime.events.InvalidParametersEvent in project drools by kiegroup.

the class InvokeFunction method invoke.

public FEELFnResult<Object> invoke(@ParameterName("ctx") EvaluationContext ctx, @ParameterName("namespace") String namespace, @ParameterName("model name") String modelName, @ParameterName("decision name") String decisionName, @ParameterName("parameters") Map<String, Object> parameters) {
    DMNRuntime dmnRuntime = ctx.getDMNRuntime();
    if (namespace == null) {
        return FEELFnResult.ofError(new InvalidParametersEvent(FEELEvent.Severity.ERROR, "namespace", "cannot be null"));
    }
    if (modelName == null) {
        return FEELFnResult.ofError(new InvalidParametersEvent(FEELEvent.Severity.ERROR, "model name", "cannot be null"));
    }
    if (decisionName == null) {
        return FEELFnResult.ofError(new InvalidParametersEvent(FEELEvent.Severity.ERROR, "decision name", "cannot be null"));
    }
    if (parameters == null) {
        return FEELFnResult.ofError(new InvalidParametersEvent(FEELEvent.Severity.ERROR, "parameters", "cannot be null"));
    }
    FEELEvent capturedException = null;
    try {
        ctx.enterFrame();
        DMNModel dmnModel = dmnRuntime.getModel(namespace, modelName);
        if (dmnModel == null) {
            return FEELFnResult.ofError(new FEELEventBase(FEELEvent.Severity.ERROR, "Cannot find model '" + modelName + "' in namespace " + namespace, null));
        }
        if (dmnModel.getDecisionByName(decisionName) == null) {
            return FEELFnResult.ofError(new FEELEventBase(FEELEvent.Severity.ERROR, "Cannot find decision '" + decisionName + "' in the model", null));
        }
        DMNContext dmnContext = dmnRuntime.newContext();
        dmnContext.getAll().putAll(parameters);
        DMNResult requiredDecisionResult = dmnRuntime.evaluateByName(dmnModel, dmnContext, decisionName);
        if (requiredDecisionResult.hasErrors()) {
            return FEELFnResult.ofError(new FEELEventBase(FEELEvent.Severity.ERROR, "Errors occurred while invoking the external decision: " + requiredDecisionResult.getMessages(), null));
        }
        return FEELFnResult.ofResult(requiredDecisionResult.getContext().get(decisionName));
    } catch (Exception e) {
        capturedException = new FEELEventBase(FEELEvent.Severity.ERROR, "Error invoking function", new RuntimeException("Error invoking function " + getName() + ".", e));
    } finally {
        ctx.exitFrame();
    }
    return FEELFnResult.ofError(capturedException);
}
Also used : DMNResult(org.kie.dmn.api.core.DMNResult) FEELEventBase(org.kie.dmn.feel.runtime.events.FEELEventBase) DMNContext(org.kie.dmn.api.core.DMNContext) InvalidParametersEvent(org.kie.dmn.feel.runtime.events.InvalidParametersEvent) FEELEvent(org.kie.dmn.api.feel.runtime.events.FEELEvent) DMNRuntime(org.kie.dmn.api.core.DMNRuntime) DMNModel(org.kie.dmn.api.core.DMNModel)

Example 5 with InvalidParametersEvent

use of org.kie.dmn.feel.runtime.events.InvalidParametersEvent in project drools by kiegroup.

the class SplitFunction method invoke.

public FEELFnResult<List<String>> invoke(@ParameterName("input") String input, @ParameterName("delimiter") String delimiter, @ParameterName("flags") String flags) {
    if (input == null) {
        return FEELFnResult.ofError(new InvalidParametersEvent(Severity.ERROR, "input", "cannot be null"));
    }
    if (delimiter == null) {
        return FEELFnResult.ofError(new InvalidParametersEvent(Severity.ERROR, "delimiter", "cannot be null"));
    }
    try {
        int f = processFlags(flags);
        Pattern p = Pattern.compile(delimiter, f);
        String[] split = p.split(input);
        return FEELFnResult.ofResult(Arrays.asList(split));
    } catch (PatternSyntaxException e) {
        return FEELFnResult.ofError(new InvalidParametersEvent(Severity.ERROR, "delimiter", "is invalid and can not be compiled", e));
    } catch (IllegalArgumentException t) {
        return FEELFnResult.ofError(new InvalidParametersEvent(Severity.ERROR, "flags", "contains unknown flags", t));
    } catch (Throwable t) {
        return FEELFnResult.ofError(new InvalidParametersEvent(Severity.ERROR, "delimiter", "is invalid and can not be compiled", t));
    }
}
Also used : Pattern(java.util.regex.Pattern) InvalidParametersEvent(org.kie.dmn.feel.runtime.events.InvalidParametersEvent) PatternSyntaxException(java.util.regex.PatternSyntaxException)

Aggregations

InvalidParametersEvent (org.kie.dmn.feel.runtime.events.InvalidParametersEvent)27 DateTimeException (java.time.DateTimeException)7 TemporalAccessor (java.time.temporal.TemporalAccessor)6 ArrayList (java.util.ArrayList)6 BigDecimal (java.math.BigDecimal)4 FEELEvent (org.kie.dmn.api.feel.runtime.events.FEELEvent)3 List (java.util.List)2 Map (java.util.Map)2 Pattern (java.util.regex.Pattern)2 PatternSyntaxException (java.util.regex.PatternSyntaxException)2 FEELEventBase (org.kie.dmn.feel.runtime.events.FEELEventBase)2 MathContext (java.math.MathContext)1 DecimalFormat (java.text.DecimalFormat)1 LocalDate (java.time.LocalDate)1 Arrays (java.util.Arrays)1 Collection (java.util.Collection)1 HashMap (java.util.HashMap)1 Function (java.util.function.Function)1 Matcher (java.util.regex.Matcher)1 DMNContext (org.kie.dmn.api.core.DMNContext)1