diff --git a/api/src/main/java/io/serverlessworkflow/api/WorkflowReader.java b/api/src/main/java/io/serverlessworkflow/api/WorkflowReader.java index 01c6c8b0..4decc696 100644 --- a/api/src/main/java/io/serverlessworkflow/api/WorkflowReader.java +++ b/api/src/main/java/io/serverlessworkflow/api/WorkflowReader.java @@ -16,10 +16,12 @@ package io.serverlessworkflow.api; import io.serverlessworkflow.api.types.Workflow; +import java.io.ByteArrayInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.Reader; +import java.io.StringReader; import java.nio.file.Files; import java.nio.file.Path; @@ -37,6 +39,19 @@ public static Workflow readWorkflow(Path path, WorkflowFormat format) throws IOE return format.mapper().readValue(Files.readAllBytes(path), Workflow.class); } + public static Workflow readWorkflow(byte[] content, WorkflowFormat format) throws IOException { + try (InputStream input = new ByteArrayInputStream(content)) { + return readWorkflow(input, format); + } + } + + public static Workflow readWorkflowFromString(String content, WorkflowFormat format) + throws IOException { + try (Reader reader = new StringReader(content)) { + return readWorkflow(reader, format); + } + } + public static Workflow readWorkflowFromClasspath(String classpath) throws IOException { return readWorkflowFromClasspath( classpath, diff --git a/api/src/main/java/io/serverlessworkflow/api/WorkflowWriter.java b/api/src/main/java/io/serverlessworkflow/api/WorkflowWriter.java index f98e6402..29115396 100644 --- a/api/src/main/java/io/serverlessworkflow/api/WorkflowWriter.java +++ b/api/src/main/java/io/serverlessworkflow/api/WorkflowWriter.java @@ -16,8 +16,10 @@ package io.serverlessworkflow.api; import io.serverlessworkflow.api.types.Workflow; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.io.StringWriter; import java.io.Writer; import java.nio.file.Files; import java.nio.file.Path; @@ -45,5 +47,21 @@ public static void writeWorkflow(Path output, Workflow workflow, WorkflowFormat } } + public static String workflowAsString(Workflow workflow, WorkflowFormat format) + throws IOException { + try (Writer writer = new StringWriter()) { + writeWorkflow(writer, workflow, format); + return writer.toString(); + } + } + + public static byte[] workflowAsBytes(Workflow workflow, WorkflowFormat format) + throws IOException { + try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { + writeWorkflow(out, workflow, format); + return out.toByteArray(); + } + } + private WorkflowWriter() {} } diff --git a/api/src/main/java/io/serverlessworkflow/serialization/DeserializeHelper.java b/api/src/main/java/io/serverlessworkflow/serialization/DeserializeHelper.java index 72b4cce0..cfbd54ca 100644 --- a/api/src/main/java/io/serverlessworkflow/serialization/DeserializeHelper.java +++ b/api/src/main/java/io/serverlessworkflow/serialization/DeserializeHelper.java @@ -21,24 +21,57 @@ import com.fasterxml.jackson.databind.JsonMappingException; import jakarta.validation.ConstraintViolationException; import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.Collection; public class DeserializeHelper { public static T deserializeOneOf( - JsonParser p, Class targetClass, Collection> unionTypes) throws IOException { + JsonParser p, Class targetClass, Collection> oneOfTypes) throws IOException { TreeNode node = p.readValueAsTree(); - JsonProcessingException ex = - new JsonMappingException(p, "Problem deserializing " + targetClass); - for (Class unionType : unionTypes) { - try { - Object object = p.getCodec().treeToValue(node, unionType); - return targetClass.getConstructor(unionType).newInstance(object); - } catch (IOException | ReflectiveOperationException | ConstraintViolationException io) { - ex.addSuppressed(io); + try { + T result = targetClass.getDeclaredConstructor().newInstance(); + Collection exceptions = new ArrayList<>(); + for (Class oneOfType : oneOfTypes) { + try { + assingIt(p, result, node, targetClass, oneOfType); + break; + } catch (IOException | ConstraintViolationException | InvocationTargetException ex) { + exceptions.add(ex); + } + } + if (exceptions.size() == oneOfTypes.size()) { + JsonMappingException ex = + new JsonMappingException( + p, + String.format( + "Error deserializing class %s, all oneOf alternatives %s has failed ", + targetClass, oneOfTypes)); + exceptions.forEach(ex::addSuppressed); + throw ex; + } + return result; + } catch (ReflectiveOperationException ex) { + throw new IllegalStateException(ex); + } + } + + private static void assingIt( + JsonParser p, T result, TreeNode node, Class targetClass, Class type) + throws JsonProcessingException, ReflectiveOperationException { + findSetMethod(targetClass, type).invoke(result, p.getCodec().treeToValue(node, type)); + } + + private static Method findSetMethod(Class targetClass, Class type) { + for (Method method : targetClass.getMethods()) { + OneOfSetter oneOfSetter = method.getAnnotation(OneOfSetter.class); + if (oneOfSetter != null && type.equals(oneOfSetter.value())) { + return method; } } - throw ex; + throw new IllegalStateException("Cannot find a setter for type " + type); } public static T deserializeItem(JsonParser p, Class targetClass, Class valueClass) diff --git a/api/src/main/java/io/serverlessworkflow/serialization/OneOfSetter.java b/api/src/main/java/io/serverlessworkflow/serialization/OneOfSetter.java new file mode 100644 index 00000000..098df425 --- /dev/null +++ b/api/src/main/java/io/serverlessworkflow/serialization/OneOfSetter.java @@ -0,0 +1,28 @@ +/* + * 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.serialization; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Retention(RUNTIME) +@Target(METHOD) +public @interface OneOfSetter { + Class value(); +} diff --git a/api/src/test/java/io/serverlessworkflow/api/FeaturesTest.java b/api/src/test/java/io/serverlessworkflow/api/FeaturesTest.java index 5672bbc9..81d10ecf 100644 --- a/api/src/test/java/io/serverlessworkflow/api/FeaturesTest.java +++ b/api/src/test/java/io/serverlessworkflow/api/FeaturesTest.java @@ -17,7 +17,10 @@ import static io.serverlessworkflow.api.WorkflowReader.readWorkflow; import static io.serverlessworkflow.api.WorkflowReader.readWorkflowFromClasspath; +import static io.serverlessworkflow.api.WorkflowWriter.workflowAsBytes; +import static io.serverlessworkflow.api.WorkflowWriter.workflowAsString; import static io.serverlessworkflow.api.WorkflowWriter.writeWorkflow; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertNotNull; import io.serverlessworkflow.api.types.Workflow; @@ -32,6 +35,13 @@ public class FeaturesTest { @ParameterizedTest @ValueSource( strings = { + "features/authentication-bearer.yaml", + "features/authentication-bearer-uri-format.yaml", + "features/authentication-oauth2.yaml", + "features/authentication-oauth2-secret.yaml", + "features/authentication-oidc.yaml", + "features/authentication-oidc-secret.yaml", + "features/authentication-reusable.yaml", "features/callHttp.yaml", "features/callOpenAPI.yaml", "features/composite.yaml", @@ -51,7 +61,7 @@ public class FeaturesTest { public void testSpecFeaturesParsing(String workflowLocation) throws IOException { Workflow workflow = readWorkflowFromClasspath(workflowLocation); assertWorkflow(workflow); - assertWorkflow(writeAndReadInMemory(workflow)); + assertWorkflowEquals(workflow, writeAndReadInMemory(workflow)); } private static Workflow writeAndReadInMemory(Workflow workflow) throws IOException { @@ -70,4 +80,11 @@ private static void assertWorkflow(Workflow workflow) { assertNotNull(workflow.getDocument()); assertNotNull(workflow.getDo()); } + + private static void assertWorkflowEquals(Workflow workflow, Workflow other) throws IOException { + assertThat(workflowAsString(workflow, WorkflowFormat.YAML)) + .isEqualTo(workflowAsString(other, WorkflowFormat.YAML)); + assertThat(workflowAsBytes(workflow, WorkflowFormat.JSON)) + .isEqualTo(workflowAsBytes(other, WorkflowFormat.JSON)); + } } diff --git a/api/src/test/resources/features/authentication-bearer-uri-format.yaml b/api/src/test/resources/features/authentication-bearer-uri-format.yaml new file mode 100644 index 00000000..b0019fbb --- /dev/null +++ b/api/src/test/resources/features/authentication-bearer-uri-format.yaml @@ -0,0 +1,15 @@ +document: + dsl: '1.0.0-alpha5' + namespace: examples + name: bearer-auth + version: '0.1.0' +do: + - getPet: + call: http + with: + method: get + endpoint: + uri: https://petstore.swagger.io/v2/pet/{petId} + authentication: + bearer: + token: ${ .token } diff --git a/api/src/test/resources/features/authentication-bearer.yaml b/api/src/test/resources/features/authentication-bearer.yaml new file mode 100644 index 00000000..f0c42741 --- /dev/null +++ b/api/src/test/resources/features/authentication-bearer.yaml @@ -0,0 +1,15 @@ +document: + dsl: '1.0.0-alpha5' + namespace: examples + name: bearer-auth-uri-format + version: '0.1.0' +do: + - getPet: + call: http + with: + method: get + endpoint: + uri: https://petstore.swagger.io/v2/pet/1 + authentication: + bearer: + token: ${ .token } \ No newline at end of file diff --git a/api/src/test/resources/features/authentication-oauth2-secret.yaml b/api/src/test/resources/features/authentication-oauth2-secret.yaml new file mode 100644 index 00000000..635076ab --- /dev/null +++ b/api/src/test/resources/features/authentication-oauth2-secret.yaml @@ -0,0 +1,18 @@ +document: + dsl: 1.0.0-alpha1 + namespace: examples + name: oauth2-authentication + version: 1.0.0-alpha1 +use: + secrets: + - mySecret +do: + - getPet: + call: http + with: + method: get + endpoint: + uri: https://petstore.swagger.io/v2/pet/{petId} + authentication: + oauth2: + use: mySecret \ No newline at end of file diff --git a/api/src/test/resources/features/authentication-oauth2.yaml b/api/src/test/resources/features/authentication-oauth2.yaml new file mode 100644 index 00000000..625a1e2c --- /dev/null +++ b/api/src/test/resources/features/authentication-oauth2.yaml @@ -0,0 +1,22 @@ +document: + dsl: '1.0.0-alpha5' + namespace: examples + name: oauth2-authentication + version: '0.1.0' +do: + - getPet: + call: http + with: + method: get + endpoint: + uri: https://petstore.swagger.io/v2/pet/{petId} + authentication: + oauth2: + authority: http://keycloak/realms/fake-authority + endpoints: #optional + token: /auth/token #defaults to /oauth2/token + introspection: /auth/introspect #defaults to /oauth2/introspect + grant: client_credentials + client: + id: workflow-runtime-id + secret: workflow-runtime-secret \ No newline at end of file diff --git a/api/src/test/resources/features/authentication-oidc-secret.yaml b/api/src/test/resources/features/authentication-oidc-secret.yaml new file mode 100644 index 00000000..19c387c1 --- /dev/null +++ b/api/src/test/resources/features/authentication-oidc-secret.yaml @@ -0,0 +1,18 @@ +document: + dsl: 1.0.0-alpha1 + namespace: examples + name: oidc-authentication + version: 1.0.0-alpha1 +use: + secrets: + - mySecret +do: + - getPet: + call: http + with: + method: get + endpoint: + uri: https://petstore.swagger.io/v2/pet/{petId} + authentication: + oidc: + use: mySecret \ No newline at end of file diff --git a/api/src/test/resources/features/authentication-oidc.yaml b/api/src/test/resources/features/authentication-oidc.yaml new file mode 100644 index 00000000..18aec74d --- /dev/null +++ b/api/src/test/resources/features/authentication-oidc.yaml @@ -0,0 +1,19 @@ +document: + dsl: '1.0.0-alpha5' + namespace: examples + name: oidc-authentication + version: '0.1.0' +do: + - getPet: + call: http + with: + method: get + endpoint: + uri: https://petstore.swagger.io/v2/pet/{petId} + authentication: + oidc: + authority: http://keycloak/realms/fake-authority #endpoints are resolved using the OIDC configuration located at '/.well-known/openid-configuration' + grant: client_credentials + client: + id: workflow-runtime-id + secret: workflow-runtime-secret \ No newline at end of file diff --git a/api/src/test/resources/features/authentication-reusable.yaml b/api/src/test/resources/features/authentication-reusable.yaml new file mode 100644 index 00000000..a5da803d --- /dev/null +++ b/api/src/test/resources/features/authentication-reusable.yaml @@ -0,0 +1,19 @@ +document: + dsl: '1.0.0-alpha5' + namespace: examples + name: bearer-auth + version: '0.1.0' +use: + authentications: + petStoreAuth: + bearer: + token: ${ .token } +do: + - getPet: + call: http + with: + method: get + endpoint: + uri: https://petstore.swagger.io/v2/pet/{petId} + authentication: + use: petStoreAuth 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 8d5b921d..df3ead34 100644 --- a/custom-generator/src/main/java/io/serverlessworkflow/generator/AllAnyOneOfSchemaRule.java +++ b/custom-generator/src/main/java/io/serverlessworkflow/generator/AllAnyOneOfSchemaRule.java @@ -136,68 +136,74 @@ public JType apply( Schema schema) { Optional refType = refType(nodeName, schemaNode, parent, generatableType, schema); - List unionTypes = new ArrayList<>(); + List oneOfTypes = new ArrayList<>(); + List allOfTypes = new ArrayList<>(); - unionType("oneOf", nodeName, schemaNode, parent, generatableType, schema, unionTypes); - unionType("anyOf", nodeName, schemaNode, parent, generatableType, schema, unionTypes); - unionType("allOf", nodeName, schemaNode, parent, generatableType, schema, unionTypes); + unionType("oneOf", nodeName, schemaNode, parent, generatableType, schema, oneOfTypes); + unionType("anyOf", nodeName, schemaNode, parent, generatableType, schema, oneOfTypes); + unionType("allOf", nodeName, schemaNode, parent, generatableType, schema, allOfTypes); - Collections.sort(unionTypes); + Collections.sort(oneOfTypes); JType javaType; if (schemaNode.has("enum")) { javaType = ruleFactory.getEnumRule().apply(nodeName, schemaNode, parent, generatableType, schema); - } else if (!schemaNode.has("properties") && unionTypes.isEmpty() && refType.isPresent()) { + } else if (!schemaNode.has("properties") + && oneOfTypes.isEmpty() + && allOfTypes.isEmpty() + && refType.isPresent()) { javaType = refType.get(); - } else if (!unionTypes.isEmpty()) { + } else { JPackage container = generatableType.getPackage(); - JType generatedType = - ruleFactory.getTypeRule().apply(nodeName, schemaNode, parent, container, schema); - try { - JDefinedClass unionClass; - Optional commonType; - if (generatedType instanceof JDefinedClass) { - JDefinedClass clazz = (JDefinedClass) generatedType; - if (clazz.methods().isEmpty()) { - unionClass = clazz; - commonType = Optional.empty(); + javaType = ruleFactory.getTypeRule().apply(nodeName, schemaNode, parent, container, schema); + if (javaType instanceof JDefinedClass) { + javaType = + populateAllOf( + schema, populateRef((JDefinedClass) javaType, refType, schema), allOfTypes); + } + if (!oneOfTypes.isEmpty()) { + try { + JDefinedClass unionClass; + Optional commonType; + if (javaType instanceof JDefinedClass) { + JDefinedClass clazz = (JDefinedClass) javaType; + if (clazz.methods().isEmpty()) { + unionClass = clazz; + commonType = Optional.empty(); + } else { + unionClass = container._class(clazz.name() + "Union"); + commonType = Optional.of(clazz); + } } else { - unionClass = container._class(clazz.name() + "Union"); - commonType = Optional.of(clazz); + unionClass = + container._class( + ruleFactory + .getNameHelper() + .getUniqueClassName(nodeName, schemaNode, container)); + commonType = Optional.empty(); } - - } else { - unionClass = - container._class( - ruleFactory.getNameHelper().getUniqueClassName(nodeName, schemaNode, container)); - commonType = Optional.empty(); + javaType = populateOneOf(schema, unionClass, commonType, oneOfTypes); + } catch (JClassAlreadyExistsException ex) { + throw new IllegalStateException(ex); } - javaType = - populateRef(populateClass(schema, unionClass, commonType, unionTypes), refType, schema); - schema.setJavaTypeIfEmpty(javaType); - } catch (JClassAlreadyExistsException ex) { - throw new IllegalStateException(ex); - } - } else { - javaType = - ruleFactory - .getTypeRule() - .apply(nodeName, schemaNode, parent, generatableType.getPackage(), schema); - if (javaType instanceof JDefinedClass) { - populateRef((JDefinedClass) javaType, refType, schema); } schema.setJavaTypeIfEmpty(javaType); } - return javaType; } - private JDefinedClass populateClass( + private JDefinedClass populateAllOf( + Schema parentSchema, JDefinedClass definedClass, Collection allOfTypes) { + return wrapAll(parentSchema, definedClass, Optional.empty(), allOfTypes, Optional.empty()); + } + + private JDefinedClass populateOneOf( Schema parentSchema, JDefinedClass definedClass, Optional commonType, - Collection unionTypes) { + Collection oneOfTypes) { + JFieldVar valueField = definedClass.field( JMod.PRIVATE, @@ -210,9 +216,7 @@ private JDefinedClass populateClass( .owner() .ref(GeneratorUtils.ONE_OF_VALUE_PROVIDER_INTERFACE_NAME) .narrow(valueField.type())); - GeneratorUtils.implementInterface(definedClass, valueField); - try { JDefinedClass serializer = generateSerializer(definedClass); definedClass.annotate(JsonSerialize.class).param("using", serializer); @@ -221,28 +225,33 @@ private JDefinedClass populateClass( } try { - JDefinedClass deserializer = generateDeserializer(definedClass, unionTypes); + JDefinedClass deserializer = + generateDeserializer(definedClass, oneOfTypes, "deserializeOneOf"); definedClass.annotate(JsonDeserialize.class).param("using", deserializer); } catch (JClassAlreadyExistsException ex) { // already deserialized aware } + return wrapAll(parentSchema, definedClass, commonType, oneOfTypes, Optional.of(valueField)); + } + + private JDefinedClass wrapAll( + Schema parentSchema, + JDefinedClass definedClass, + Optional commonType, + Collection types, + Optional valueField) { Collection stringTypes = new ArrayList<>(); - for (JTypeWrapper unionType : unionTypes) { + for (JTypeWrapper unionType : types) { if (isStringType(unionType.getType())) { stringTypes.add(unionType); } else { - if (unionType.getType() instanceof JDefinedClass) { commonType.ifPresent( c -> ((JDefinedClass) unionType.getType())._extends((JDefinedClass) c)); } - wrapIt( - parentSchema, - definedClass, - Optional.of(valueField), - unionType.getType(), - unionType.getNode()); + + wrapIt(parentSchema, definedClass, valueField, unionType.getType(), unionType.getNode()); } } if (!stringTypes.isEmpty()) { @@ -291,7 +300,7 @@ private JDefinedClass generateSerializer(JDefinedClass relatedClass) } private JDefinedClass generateDeserializer( - JDefinedClass relatedClass, Collection unionTypes) + JDefinedClass relatedClass, Collection oneOfTypes, String methodName) throws JClassAlreadyExistsException { JDefinedClass definedClass = GeneratorUtils.deserializerClass(relatedClass); GeneratorUtils.fillDeserializer( @@ -299,20 +308,25 @@ private JDefinedClass generateDeserializer( relatedClass, (method, parserParam) -> { JBlock body = method.body(); - JInvocation list = definedClass.owner().ref(List.class).staticInvoke("of"); - unionTypes.forEach(c -> list.arg(((JClass) c.getType()).dotclass())); + body._return( definedClass .owner() .ref(GeneratorUtils.DESERIALIZE_HELPER_NAME) - .staticInvoke("deserializeOneOf") + .staticInvoke(methodName) .arg(parserParam) .arg(relatedClass.dotclass()) - .arg(list)); + .arg(list(definedClass, oneOfTypes))); }); return definedClass; } + private JInvocation list(JDefinedClass definedClass, Collection list) { + JInvocation result = definedClass.owner().ref(List.class).staticInvoke("of"); + list.forEach(c -> result.arg(((JClass) c.getType()).dotclass())); + return result; + } + private void wrapIt( Schema parentSchema, JDefinedClass definedClass, @@ -320,35 +334,61 @@ private void wrapIt( JType unionType, JsonNode node) { JFieldVar instanceField = getInstanceField(parentSchema, definedClass, unionType, node); - JMethod constructor = definedClass.constructor(JMod.PUBLIC); - JVar instanceParam = constructor.param(unionType, instanceField.name()); - JBlock body = constructor.body(); - valueField.ifPresent(v -> body.assign(JExpr._this().ref(v), instanceParam)); - body.assign(JExpr._this().ref(instanceField), instanceParam); + JMethod method = getSetterMethod(definedClass, instanceField, node); + method + .body() + .assign( + JExpr._this().ref(instanceField), + setupMethod(definedClass, method, valueField, instanceField)); + } + + private JVar setupMethod( + JDefinedClass definedClass, + JMethod method, + Optional valueField, + JFieldVar instanceField) { + JVar methodParam = method.param(instanceField.type(), instanceField.name()); + valueField.ifPresent( + v -> { + method.body().assign(JExpr._this().ref(v), methodParam); + method + .annotate(definedClass.owner().ref(GeneratorUtils.SETTER_ANNOTATION_NAME)) + .param("value", instanceField.type()); + }); + return methodParam; + } + + private JMethod getSetterMethod( + JDefinedClass definedClass, JFieldVar instanceField, JsonNode node) { + String setterName = ruleFactory.getNameHelper().getSetterName(instanceField.name(), node); + JMethod fluentMethod = + definedClass.method(JMod.PUBLIC, definedClass, setterName.replaceFirst("set", "with")); + JBlock body = fluentMethod.body(); + body.assign(instanceField, fluentMethod.param(instanceField.type(), "value")); + body._return(JExpr._this()); + return definedClass.method(JMod.PUBLIC, definedClass.owner().VOID, setterName); } private void wrapStrings( Schema parentSchema, JDefinedClass definedClass, - JFieldVar valueField, + Optional valueField, Collection stringTypes) { Iterator iter = stringTypes.iterator(); JTypeWrapper first = iter.next(); - JMethod constructor = definedClass.constructor(JMod.PUBLIC); - - JBlock body = constructor.body(); String pattern = pattern(first.getNode(), parentSchema); if (pattern == null && iter.hasNext()) { pattern = ".*"; } JFieldVar instanceField = getInstanceField(parentSchema, definedClass, first.getType(), first.getNode()); - JVar instanceParam = constructor.param(first.type, instanceField.name()); - body.assign(JExpr._this().ref(valueField), instanceParam); + JMethod setterMethod = getSetterMethod(definedClass, instanceField, first.getNode()); + JVar methodParam = setupMethod(definedClass, setterMethod, valueField, instanceField); + JBlock body = setterMethod.body(); if (pattern != null) { JConditional condition = - body._if(getPatternCondition(pattern, body, instanceField, instanceParam, definedClass)); - condition._then().assign(JExpr._this().ref(instanceField), instanceParam); + body._if(getPatternCondition(pattern, body, instanceField, methodParam, definedClass)); + condition._then().assign(JExpr._this().ref(instanceField), methodParam); while (iter.hasNext()) { JTypeWrapper item = iter.next(); instanceField = @@ -359,8 +399,8 @@ private void wrapStrings( } condition = condition._elseif( - getPatternCondition(pattern, body, instanceField, instanceParam, definedClass)); - condition._then().assign(JExpr._this().ref(instanceField), instanceParam); + getPatternCondition(pattern, body, instanceField, methodParam, definedClass)); + condition._then().assign(JExpr._this().ref(instanceField), methodParam); } condition ._else() @@ -372,10 +412,10 @@ private void wrapStrings( .ref(String.class) .staticInvoke("format") .arg("%s does not match any pattern") - .arg(instanceParam)) + .arg(methodParam)) .arg(JExpr._null())); } else { - body.assign(JExpr._this().ref(instanceField), instanceParam); + body.assign(JExpr._this().ref(instanceField), methodParam); } } @@ -388,7 +428,7 @@ private JFieldVar getInstanceField( ruleFactory .getNameHelper() .getPropertyName(getTypeName(node, type, parentSchema), node)); - GeneratorUtils.buildMethod( + GeneratorUtils.getterMethod( definedClass, instanceField, ruleFactory.getNameHelper(), instanceField.name()); return instanceField; } 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 7248d594..e7af60d5 100644 --- a/custom-generator/src/main/java/io/serverlessworkflow/generator/GeneratorUtils.java +++ b/custom-generator/src/main/java/io/serverlessworkflow/generator/GeneratorUtils.java @@ -38,6 +38,8 @@ public class GeneratorUtils { "io.serverlessworkflow.serialization.DeserializeHelper"; public static final String ONE_OF_VALUE_PROVIDER_INTERFACE_NAME = "io.serverlessworkflow.api.OneOfValueProvider"; + public static final String SETTER_ANNOTATION_NAME = + "io.serverlessworkflow.serialization.OneOfSetter"; @FunctionalInterface public interface SerializerFiller { @@ -66,7 +68,7 @@ public static JMethod implementInterface(JDefinedClass definedClass, JFieldVar v return method; } - public static JMethod buildMethod( + public static JMethod getterMethod( JDefinedClass definedClass, JFieldVar instanceField, NameHelper nameHelper, String name) { JMethod method = definedClass.method( diff --git a/custom-generator/src/main/java/io/serverlessworkflow/generator/UnevaluatedPropertiesRule.java b/custom-generator/src/main/java/io/serverlessworkflow/generator/UnevaluatedPropertiesRule.java index 0e937658..18bdbba6 100644 --- a/custom-generator/src/main/java/io/serverlessworkflow/generator/UnevaluatedPropertiesRule.java +++ b/custom-generator/src/main/java/io/serverlessworkflow/generator/UnevaluatedPropertiesRule.java @@ -70,7 +70,7 @@ private JDefinedClass addKeyValueFields( JType stringClass = jclass.owner()._ref(String.class); JFieldVar nameField = jclass.field(JMod.PRIVATE, stringClass, nameHelper.getPropertyName("name", null)); - JMethod nameMethod = GeneratorUtils.buildMethod(jclass, nameField, nameHelper, "name"); + JMethod nameMethod = GeneratorUtils.getterMethod(jclass, nameField, nameHelper, "name"); JType propertyType; if (node != null && node.size() != 0) { String pathToAdditionalProperties; @@ -98,7 +98,7 @@ private JDefinedClass addKeyValueFields( jclass.field( JMod.PRIVATE, propertyType, nameHelper.getPropertyName(propertyType.name(), null)); JMethod valueMethod = - GeneratorUtils.buildMethod(jclass, valueField, nameHelper, propertyType.name()); + GeneratorUtils.getterMethod(jclass, valueField, nameHelper, propertyType.name()); jclass .annotate(JsonSerialize.class) .param("using", generateSerializer(jclass, nameMethod, valueMethod));