diff --git a/experimental/lambda/src/main/java/io/serverlessworkflow/impl/expressions/func/JavaExpressionFactory.java b/experimental/lambda/src/main/java/io/serverlessworkflow/impl/expressions/func/JavaExpressionFactory.java index bdc1aedf9..4727fc375 100644 --- a/experimental/lambda/src/main/java/io/serverlessworkflow/impl/expressions/func/JavaExpressionFactory.java +++ b/experimental/lambda/src/main/java/io/serverlessworkflow/impl/expressions/func/JavaExpressionFactory.java @@ -25,6 +25,7 @@ import io.serverlessworkflow.api.types.func.TypedJavaContextFunction; import io.serverlessworkflow.api.types.func.TypedJavaFilterFunction; import io.serverlessworkflow.api.types.func.TypedPredicate; +import io.serverlessworkflow.impl.WorkflowModel; import io.serverlessworkflow.impl.WorkflowPredicate; import io.serverlessworkflow.impl.expressions.AbstractExpressionFactory; import io.serverlessworkflow.impl.expressions.ExpressionDescriptor; @@ -44,20 +45,31 @@ public ObjectExpression buildExpression(ExpressionDescriptor descriptor) { if (value instanceof Function func) { return (w, t, n) -> func.apply(n.asJavaObject()); } else if (value instanceof TypedFunction func) { - return (w, t, n) -> func.function().apply(n.as(func.argClass()).orElseThrow()); + return (w, t, n) -> func.function().apply(convert(n, func.argClass())); } else if (value instanceof JavaFilterFunction func) { return (w, t, n) -> func.apply(n.asJavaObject(), w, t); } else if (value instanceof TypedJavaFilterFunction func) { - return (w, t, n) -> func.function().apply(n.as(func.argClass()).orElseThrow(), w, t); + return (w, t, n) -> func.function().apply(convert(n, func.argClass()), w, t); } else if (value instanceof JavaContextFunction func) { return (w, t, n) -> func.apply(n.asJavaObject(), w); } else if (value instanceof TypedJavaContextFunction func) { - return (w, t, n) -> func.function().apply(n.as(func.argClass()).orElseThrow(), w); + return (w, t, n) -> func.function().apply(convert(n, func.argClass()), w); } else { return (w, t, n) -> value; } } + private T convert(WorkflowModel model, Class argClass) { + return model.isNull() + ? null + : model + .as(argClass) + .orElseThrow( + () -> + new IllegalArgumentException( + "Cannot convert model " + model.asJavaObject() + " to class" + argClass)); + } + @Override public int priority(ExpressionDescriptor descriptor) { Object value = descriptor.asObject(); diff --git a/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/FuncDSLDataFlowTransformationHelpersTest.java b/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/FuncDSLDataFlowTransformationHelpersTest.java index b1a8236bc..4d307ce22 100644 --- a/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/FuncDSLDataFlowTransformationHelpersTest.java +++ b/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/FuncDSLDataFlowTransformationHelpersTest.java @@ -122,7 +122,8 @@ void test_output_with_exportAs() { Long taskOutput = output(taskContextData, Long.class); softly.assertThat(taskOutput).isEqualTo(15L); return taskOutput * 2; - })) + }, + Object.class)) .build(); try (WorkflowApplication app = WorkflowApplication.builder().build()) { diff --git a/impl/core/src/main/java/io/serverlessworkflow/impl/WorkflowModel.java b/impl/core/src/main/java/io/serverlessworkflow/impl/WorkflowModel.java index faee2114e..91b2faf3b 100644 --- a/impl/core/src/main/java/io/serverlessworkflow/impl/WorkflowModel.java +++ b/impl/core/src/main/java/io/serverlessworkflow/impl/WorkflowModel.java @@ -39,4 +39,8 @@ public interface WorkflowModel { Class objectClass(); Optional as(Class clazz); + + default boolean isNull() { + return asJavaObject() == null; + } } diff --git a/impl/model/src/main/java/io/serverlessworkflow/impl/model/jackson/JacksonModel.java b/impl/model/src/main/java/io/serverlessworkflow/impl/model/jackson/JacksonModel.java index 34c9775dc..e30581711 100644 --- a/impl/model/src/main/java/io/serverlessworkflow/impl/model/jackson/JacksonModel.java +++ b/impl/model/src/main/java/io/serverlessworkflow/impl/model/jackson/JacksonModel.java @@ -46,6 +46,11 @@ protected JacksonModel(JsonNode node) { this.node = node; } + @Override + public boolean isNull() { + return node.isNull(); + } + @Override public Optional asBoolean() { return node.isBoolean() ? Optional.of(node.asBoolean()) : Optional.empty();