|
1 | 1 | package io.cloudevents.sql.impl.expressions;
|
2 | 2 |
|
3 | 3 | import io.cloudevents.CloudEvent;
|
| 4 | +import io.cloudevents.SpecVersion; |
| 5 | +import io.cloudevents.sql.EvaluationException; |
4 | 6 | import io.cloudevents.sql.EvaluationRuntime;
|
5 |
| -import io.cloudevents.sql.impl.CloudEventUtils; |
6 | 7 | import io.cloudevents.sql.impl.ExceptionThrower;
|
7 | 8 | import org.antlr.v4.runtime.misc.Interval;
|
8 | 9 |
|
| 10 | +import java.util.Base64; |
| 11 | +import java.util.Objects; |
| 12 | +import java.util.function.Function; |
| 13 | + |
9 | 14 | public class AccessAttributeExpression extends BaseExpression {
|
10 | 15 |
|
11 | 16 | private final String key;
|
| 17 | + private final Function<CloudEvent, Object> getter; |
12 | 18 |
|
13 | 19 | public AccessAttributeExpression(Interval expressionInterval, String expressionText, String key) {
|
14 | 20 | super(expressionInterval, expressionText);
|
15 |
| - this.key = key.toLowerCase(); |
| 21 | + this.key = key; |
| 22 | + this.getter = generateGetter(key); |
16 | 23 | }
|
17 | 24 |
|
18 | 25 | @Override
|
19 | 26 | public Object evaluate(EvaluationRuntime runtime, CloudEvent event, ExceptionThrower thrower) {
|
20 |
| - return CloudEventUtils.accessContextAttribute(thrower, expressionInterval(), expressionText(), event, key); |
| 27 | + Object value = this.getter.apply(event); |
| 28 | + if (value == null) { |
| 29 | + thrower.throwException( |
| 30 | + EvaluationException.missingAttribute(this.expressionInterval(), this.expressionText(), key) |
| 31 | + ); |
| 32 | + return ""; |
| 33 | + } |
| 34 | + |
| 35 | + // Because the CESQL type system is smaller than the CE type system, |
| 36 | + // we need to coherce some values to string |
| 37 | + return coherceTypes(value); |
21 | 38 | }
|
22 | 39 |
|
23 | 40 | @Override
|
24 | 41 | public <T> T visit(ExpressionInternalVisitor<T> visitor) {
|
25 | 42 | return visitor.visitAccessAttributeExpression(this);
|
26 | 43 | }
|
27 | 44 |
|
| 45 | + private static Function<CloudEvent, Object> generateGetter(String key) { |
| 46 | + return SpecVersion.V1.getAllAttributes().contains(key) ? ce -> ce.getAttribute(key) : ce -> ce.getExtension(key); |
| 47 | + } |
| 48 | + |
| 49 | + private static Object coherceTypes(Object value) { |
| 50 | + if (value instanceof Boolean || value instanceof String || value instanceof Integer) { |
| 51 | + // No casting required |
| 52 | + return value; |
| 53 | + } |
| 54 | + if (value instanceof byte[]) { |
| 55 | + return Base64.getEncoder().encodeToString((byte[]) value); |
| 56 | + } |
| 57 | + return Objects.toString(value); |
| 58 | + } |
| 59 | + |
28 | 60 | }
|
0 commit comments