diff --git a/api/src/main/java/io/serverlessworkflow/api/OneOfValueProvider.java b/api/src/main/java/io/serverlessworkflow/api/OneOfValueProvider.java new file mode 100644 index 00000000..f3d2ab26 --- /dev/null +++ b/api/src/main/java/io/serverlessworkflow/api/OneOfValueProvider.java @@ -0,0 +1,20 @@ +/* + * Copyright 2020-Present The Serverless Workflow Specification Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.serverlessworkflow.api; + +public interface OneOfValueProvider { + Object get(); +} diff --git a/api/src/test/java/io/serverlessworkflow/api/ApiTest.java b/api/src/test/java/io/serverlessworkflow/api/ApiTest.java index 8e4c27b7..ac5f7532 100644 --- a/api/src/test/java/io/serverlessworkflow/api/ApiTest.java +++ b/api/src/test/java/io/serverlessworkflow/api/ApiTest.java @@ -34,12 +34,14 @@ void testCallHTTPAPI() throws IOException { assertThat(workflow.getDo().get(0).getName()).isNotNull(); assertThat(workflow.getDo().get(0).getTask()).isNotNull(); Task task = workflow.getDo().get(0).getTask(); - CallTask callTask = task.getCallTask(); - assertThat(callTask).isNotNull(); - assertThat(task.getDoTask()).isNull(); - CallHTTP httpCall = callTask.getCallHTTP(); - assertThat(httpCall).isNotNull(); - assertThat(callTask.getCallAsyncAPI()).isNull(); - assertThat(httpCall.getWith().getMethod()).isEqualTo("get"); + if (task.get() instanceof CallTask) { + CallTask callTask = task.getCallTask(); + assertThat(callTask).isNotNull(); + assertThat(task.getDoTask()).isNull(); + CallHTTP httpCall = callTask.getCallHTTP(); + assertThat(httpCall).isNotNull(); + assertThat(callTask.getCallAsyncAPI()).isNull(); + assertThat(httpCall.getWith().getMethod()).isEqualTo("get"); + } } } diff --git a/custom-generator/src/main/java/io/serverlessworkflow/generator/AllAnyOneOfSchemaRule.java b/custom-generator/src/main/java/io/serverlessworkflow/generator/AllAnyOneOfSchemaRule.java index e2b781c8..1e99f0fd 100644 --- a/custom-generator/src/main/java/io/serverlessworkflow/generator/AllAnyOneOfSchemaRule.java +++ b/custom-generator/src/main/java/io/serverlessworkflow/generator/AllAnyOneOfSchemaRule.java @@ -31,6 +31,7 @@ import com.sun.codemodel.JMod; import com.sun.codemodel.JPackage; import com.sun.codemodel.JType; +import com.sun.codemodel.JVar; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URLDecoder; @@ -102,13 +103,27 @@ private boolean isCandidateForCreation(Collection unionTypes) { private JDefinedClass populateClass( JDefinedClass definedClass, Optional refType, Collection unionTypes) { - unionTypes.forEach(unionType -> wrapIt(definedClass, unionType)); + JType clazzClass = definedClass.owner()._ref(Object.class); + + JFieldVar valueField = + definedClass.field( + JMod.PRIVATE, + clazzClass, + ruleFactory.getNameHelper().getPropertyName("value", null), + null); + + definedClass._implements( + definedClass.owner().ref(GeneratorUtils.ONE_OF_VALUE_PROVIDER_INTERFACE_NAME)); + + GeneratorUtils.implementInterface(definedClass, valueField); + + unionTypes.forEach(unionType -> wrapIt(definedClass, valueField, unionType)); refType.ifPresent( type -> { if (type instanceof JClass) { definedClass._extends((JClass) type); } else { - wrapIt(definedClass, type); + wrapIt(definedClass, valueField, type); } }); if (definedClass.constructors().hasNext() @@ -166,23 +181,25 @@ private JDefinedClass createUnionClass( definedClass .annotate(JsonDeserialize.class) .param("using", generateDeserializer(definedClass, unionTypes)); + return populateClass(definedClass, refType, unionTypes); } catch (JClassAlreadyExistsException e) { throw new IllegalArgumentException(e); } } - private void wrapIt(JDefinedClass definedClass, JType unionType) { + private void wrapIt(JDefinedClass definedClass, JFieldVar valueField, JType unionType) { final String name = unionType.name(); JFieldVar instanceField = definedClass.field( JMod.PRIVATE, unionType, ruleFactory.getNameHelper().getPropertyName(name, null)); GeneratorUtils.buildMethod(definedClass, instanceField, ruleFactory.getNameHelper(), name); JMethod constructor = definedClass.constructor(JMod.PUBLIC); + JVar instanceParam = constructor.param(unionType, instanceField.name()); constructor .body() - .assign( - JExpr._this().ref(instanceField), constructor.param(unionType, instanceField.name())); + .assign(JExpr._this().ref(valueField), instanceParam) + .assign(JExpr._this().ref(instanceField), instanceParam); } private void unionType( diff --git a/custom-generator/src/main/java/io/serverlessworkflow/generator/GeneratorUtils.java b/custom-generator/src/main/java/io/serverlessworkflow/generator/GeneratorUtils.java index ffc23466..ebf1c507 100644 --- a/custom-generator/src/main/java/io/serverlessworkflow/generator/GeneratorUtils.java +++ b/custom-generator/src/main/java/io/serverlessworkflow/generator/GeneratorUtils.java @@ -36,6 +36,8 @@ public class GeneratorUtils { "io.serverlessworkflow.serialization.SerializeHelper"; public static final String DESERIALIZE_HELPER_NAME = "io.serverlessworkflow.serialization.DeserializeHelper"; + public static final String ONE_OF_VALUE_PROVIDER_INTERFACE_NAME = + "io.serverlessworkflow.api.OneOfValueProvider"; @FunctionalInterface public interface SerializerFiller { @@ -55,6 +57,13 @@ public static JDefinedClass deserializerClass(JDefinedClass relatedClass) { return createClass(relatedClass, JsonDeserializer.class, "Deserializer"); } + public static JMethod implementInterface(JDefinedClass definedClass, JFieldVar valueField) { + JMethod method = definedClass.method(JMod.PUBLIC, Object.class, "get"); + method.annotate(Override.class); + method.body()._return(valueField); + return method; + } + public static JMethod buildMethod( JDefinedClass definedClass, JFieldVar instanceField, NameHelper nameHelper, String name) { JMethod method =