feat: update runtime classes for CESQL
Signed-off-by: Calum Murray <cmurray@redhat.com>
This commit is contained in:
parent
588648110f
commit
48fd18e31c
|
@ -2,19 +2,20 @@ package io.cloudevents.sql.impl.runtime;
|
|||
|
||||
import io.cloudevents.sql.EvaluationContext;
|
||||
import io.cloudevents.sql.EvaluationException;
|
||||
import io.cloudevents.sql.impl.ExceptionThrower;
|
||||
import io.cloudevents.sql.ExceptionFactory;
|
||||
import io.cloudevents.sql.impl.ExceptionFactoryImpl;
|
||||
import org.antlr.v4.runtime.misc.Interval;
|
||||
|
||||
public class EvaluationContextImpl implements EvaluationContext {
|
||||
|
||||
private final Interval expressionInterval;
|
||||
private final String expressionText;
|
||||
private final ExceptionThrower exceptionThrower;
|
||||
private final ExceptionFactory exceptionFactory;
|
||||
|
||||
public EvaluationContextImpl(Interval expressionInterval, String expressionText, ExceptionThrower exceptionThrower) {
|
||||
public EvaluationContextImpl(Interval expressionInterval, String expressionText, ExceptionFactory exceptionFactory) {
|
||||
this.expressionInterval = expressionInterval;
|
||||
this.expressionText = expressionText;
|
||||
this.exceptionThrower = exceptionThrower;
|
||||
this.exceptionFactory = exceptionFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -28,12 +29,7 @@ public class EvaluationContextImpl implements EvaluationContext {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void appendException(EvaluationException exception) {
|
||||
this.exceptionThrower.throwException(exception);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendException(EvaluationException.EvaluationExceptionFactory exceptionFactory) {
|
||||
this.exceptionThrower.throwException(exceptionFactory.create(expressionInterval(), expressionText()));
|
||||
public ExceptionFactory exceptionFactory() {
|
||||
return this.exceptionFactory;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ public class EvaluationRuntimeBuilder {
|
|||
|
||||
public EvaluationRuntime build() {
|
||||
return new EvaluationRuntimeImpl(
|
||||
new TypeCastingProvider(),
|
||||
functionTable
|
||||
);
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import io.cloudevents.sql.*;
|
|||
public class EvaluationRuntimeImpl implements EvaluationRuntime {
|
||||
|
||||
private static class SingletonContainer {
|
||||
private final static EvaluationRuntimeImpl INSTANCE = new EvaluationRuntimeImpl(new TypeCastingProvider(), FunctionTable.getDefaultInstance());
|
||||
private final static EvaluationRuntimeImpl INSTANCE = new EvaluationRuntimeImpl(FunctionTable.getDefaultInstance());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -15,29 +15,12 @@ public class EvaluationRuntimeImpl implements EvaluationRuntime {
|
|||
return EvaluationRuntimeImpl.SingletonContainer.INSTANCE;
|
||||
}
|
||||
|
||||
private final TypeCastingProvider typeCastingProvider;
|
||||
private final FunctionTable functionTable;
|
||||
|
||||
public EvaluationRuntimeImpl(TypeCastingProvider typeCastingProvider, FunctionTable functionTable) {
|
||||
this.typeCastingProvider = typeCastingProvider;
|
||||
public EvaluationRuntimeImpl(FunctionTable functionTable) {
|
||||
this.functionTable = functionTable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canCast(Object value, Type target) {
|
||||
return this.typeCastingProvider.canCast(value, target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object cast(EvaluationContext ctx, Object value, Type target) {
|
||||
return this.typeCastingProvider.cast(ctx, value, target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object cast(Object value, Type target) throws EvaluationException {
|
||||
return this.typeCastingProvider.cast(FailFastExceptionThrower.getInstance(), value, target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Function resolveFunction(String name, int args) throws IllegalStateException {
|
||||
return functionTable.resolve(name, args);
|
||||
|
|
|
@ -5,6 +5,7 @@ import io.cloudevents.sql.EvaluationException;
|
|||
import io.cloudevents.sql.EvaluationRuntime;
|
||||
import io.cloudevents.sql.Expression;
|
||||
import io.cloudevents.sql.Result;
|
||||
import io.cloudevents.sql.impl.ExceptionFactoryImpl;
|
||||
import io.cloudevents.sql.impl.ExpressionInternal;
|
||||
|
||||
public class ExpressionImpl implements Expression {
|
||||
|
@ -17,14 +18,15 @@ public class ExpressionImpl implements Expression {
|
|||
|
||||
@Override
|
||||
public Result evaluate(EvaluationRuntime evaluationRuntime, CloudEvent event) {
|
||||
ExceptionStore exceptions = new ExceptionStore();
|
||||
Object value = this.expressionInternal.evaluate(evaluationRuntime, event, exceptions);
|
||||
return new EvaluationResult(value, exceptions.getExceptions());
|
||||
ExceptionFactoryImpl exceptionFactory = new ExceptionFactoryImpl(false);
|
||||
return this.expressionInternal.evaluate(evaluationRuntime, event, exceptionFactory);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object tryEvaluate(EvaluationRuntime evaluationRuntime, CloudEvent event) throws EvaluationException {
|
||||
return this.expressionInternal.evaluate(evaluationRuntime, event, FailFastExceptionThrower.getInstance());
|
||||
ExceptionFactoryImpl exceptionFactory = new ExceptionFactoryImpl(true);
|
||||
return this.expressionInternal.evaluate(evaluationRuntime, event, exceptionFactory).value();
|
||||
}
|
||||
|
||||
public ExpressionInternal getExpressionInternal() {
|
||||
|
|
|
@ -12,18 +12,18 @@ public class FunctionTable {
|
|||
private static class SingletonContainer {
|
||||
private final static FunctionTable INSTANCE = new FunctionTable(
|
||||
Stream.of(
|
||||
new InfallibleOneArgumentFunction<>("ABS", Integer.class, Math::abs),
|
||||
new AbsFunction(),
|
||||
new IntFunction(),
|
||||
new BoolFunction(),
|
||||
new StringFunction(),
|
||||
new IsBoolFunction(),
|
||||
new IsIntFunction(),
|
||||
new InfallibleOneArgumentFunction<>("LENGTH", String.class, String::length),
|
||||
new InfallibleOneArgumentFunction<>("LENGTH", String.class, Integer.class, String::length),
|
||||
new ConcatFunction(),
|
||||
new ConcatWSFunction(),
|
||||
new InfallibleOneArgumentFunction<>("LOWER", String.class, String::toLowerCase),
|
||||
new InfallibleOneArgumentFunction<>("UPPER", String.class, String::toUpperCase),
|
||||
new InfallibleOneArgumentFunction<>("TRIM", String.class, String::trim),
|
||||
new InfallibleOneArgumentFunction<>("LOWER", String.class, String.class, String::toLowerCase),
|
||||
new InfallibleOneArgumentFunction<>("UPPER", String.class, String.class, String::toUpperCase),
|
||||
new InfallibleOneArgumentFunction<>("TRIM", String.class, String.class, String::trim),
|
||||
new LeftFunction(),
|
||||
new RightFunction(),
|
||||
new SubstringFunction(),
|
||||
|
|
|
@ -2,13 +2,12 @@ package io.cloudevents.sql.impl.runtime;
|
|||
|
||||
import io.cloudevents.sql.EvaluationContext;
|
||||
import io.cloudevents.sql.Type;
|
||||
import io.cloudevents.sql.impl.ExceptionFactory;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class TypeCastingProvider {
|
||||
|
||||
boolean canCast(Object value, Type target) {
|
||||
public static boolean canCast(Object value, Type target) {
|
||||
if (target.valueClass().equals(value.getClass())) {
|
||||
return true;
|
||||
}
|
||||
|
@ -22,7 +21,7 @@ public class TypeCastingProvider {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return value instanceof Boolean;
|
||||
case BOOLEAN:
|
||||
if (value instanceof String) {
|
||||
try {
|
||||
|
@ -31,58 +30,55 @@ public class TypeCastingProvider {
|
|||
} catch (IllegalArgumentException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} else return value instanceof Integer;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Object cast(EvaluationContext ctx, Object value, Type target) {
|
||||
Objects.requireNonNull(value);
|
||||
if (target.valueClass().equals(value.getClass())) {
|
||||
return value;
|
||||
public static EvaluationResult cast(EvaluationContext ctx, EvaluationResult result, Type target) {
|
||||
Objects.requireNonNull(result);
|
||||
Objects.requireNonNull(result.value());
|
||||
if (target.valueClass().equals(result.value().getClass())) {
|
||||
return result;
|
||||
}
|
||||
switch (target) {
|
||||
case ANY:
|
||||
return value;
|
||||
return result;
|
||||
case STRING:
|
||||
return Objects.toString(value);
|
||||
return result.copyWithValue(Objects.toString(result.value()));
|
||||
case INTEGER:
|
||||
if (value instanceof String) {
|
||||
if (result.value() instanceof String) {
|
||||
try {
|
||||
return Integer.parseInt((String) value);
|
||||
return result.copyWithValue(Integer.parseInt((String) result.value()));
|
||||
} catch (NumberFormatException e) {
|
||||
ctx.appendException(
|
||||
ExceptionFactory.castError(String.class, Integer.class, e)
|
||||
);
|
||||
return new EvaluationResult(0, ctx.exceptionFactory().castError(String.class, Integer.class, e).create(ctx.expressionInterval(), ctx.expressionText()));
|
||||
}
|
||||
} else if (result.value() instanceof Boolean) {
|
||||
if ((Boolean) result.value()) {
|
||||
return result.copyWithValue(1);
|
||||
}
|
||||
return result.copyWithValue(0);
|
||||
} else {
|
||||
ctx.appendException(
|
||||
ExceptionFactory.invalidCastTarget(value.getClass(), target.valueClass())
|
||||
);
|
||||
return new EvaluationResult(0, ctx.exceptionFactory().invalidCastTarget(result.getClass(), target.valueClass()).create(ctx.expressionInterval(), ctx.expressionText()));
|
||||
}
|
||||
return 0;
|
||||
case BOOLEAN:
|
||||
if (value instanceof String) {
|
||||
if (result.value() instanceof String) {
|
||||
try {
|
||||
return parseBool((String) value);
|
||||
return result.copyWithValue(parseBool((String) result.value()));
|
||||
} catch (IllegalArgumentException e) {
|
||||
ctx.appendException(
|
||||
ExceptionFactory.castError(String.class, Boolean.class, e)
|
||||
);
|
||||
return new EvaluationResult(false, ctx.exceptionFactory().castError(String.class, Boolean.class, e).create(ctx.expressionInterval(), ctx.expressionText()));
|
||||
}
|
||||
} else if (result.value() instanceof Integer) {
|
||||
return result.copyWithValue(((Integer) result.value()) != 0);
|
||||
} else {
|
||||
ctx.appendException(
|
||||
ExceptionFactory.invalidCastTarget(value.getClass(), target.valueClass())
|
||||
);
|
||||
return new EvaluationResult(false, ctx.exceptionFactory().invalidCastTarget(result.getClass(), target.getClass()).create(ctx.expressionInterval(), ctx.expressionText()));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// This should never happen
|
||||
throw new IllegalArgumentException("target type doesn't correspond to a known type");
|
||||
}
|
||||
|
||||
private boolean parseBool(String val) {
|
||||
private static boolean parseBool(String val) {
|
||||
switch (val.toLowerCase()) {
|
||||
case "true":
|
||||
return true;
|
||||
|
|
Loading…
Reference in New Issue