diff --git a/api/src/test/java/io/serverlessworkflow/api/FeaturesTest.java b/api/src/test/java/io/serverlessworkflow/api/FeaturesTest.java index de2591a3..8e77673b 100644 --- a/api/src/test/java/io/serverlessworkflow/api/FeaturesTest.java +++ b/api/src/test/java/io/serverlessworkflow/api/FeaturesTest.java @@ -42,7 +42,8 @@ public class FeaturesTest { "features/raise.yaml", "features/set.yaml", "features/switch.yaml", - "features/try.yaml" + "features/try.yaml", + "features/listen.yaml" }) public void testSpecFeaturesParsing(String workflowLocation) throws IOException { Workflow workflow = readWorkflowFromClasspath(workflowLocation); diff --git a/api/src/test/resources/features/listen.yaml b/api/src/test/resources/features/listen.yaml new file mode 100644 index 00000000..393355d0 --- /dev/null +++ b/api/src/test/resources/features/listen.yaml @@ -0,0 +1,12 @@ +document: + dsl: 1.0.0-alpha1 + namespace: default + name: listen-task +do: + - listenToSomething: + listen: + to: + any: + - with: + source: pepe + type: pepe \ No newline at end of file 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 1e99f0fd..c5496edc 100644 --- a/custom-generator/src/main/java/io/serverlessworkflow/generator/AllAnyOneOfSchemaRule.java +++ b/custom-generator/src/main/java/io/serverlessworkflow/generator/AllAnyOneOfSchemaRule.java @@ -105,19 +105,41 @@ private JDefinedClass populateClass( JDefinedClass definedClass, Optional refType, Collection unionTypes) { JType clazzClass = definedClass.owner()._ref(Object.class); - JFieldVar valueField = - definedClass.field( - JMod.PRIVATE, - clazzClass, - ruleFactory.getNameHelper().getPropertyName("value", null), - null); + Optional valueField; + if (!unionTypes.isEmpty()) { + valueField = + Optional.of( + definedClass.field( + JMod.PRIVATE, + clazzClass, + ruleFactory.getNameHelper().getPropertyName("value", null), + null)); + + definedClass._implements( + definedClass.owner().ref(GeneratorUtils.ONE_OF_VALUE_PROVIDER_INTERFACE_NAME)); - definedClass._implements( - definedClass.owner().ref(GeneratorUtils.ONE_OF_VALUE_PROVIDER_INTERFACE_NAME)); + GeneratorUtils.implementInterface(definedClass, valueField.orElseThrow()); - GeneratorUtils.implementInterface(definedClass, valueField); + try { + JDefinedClass serializer = generateSerializer(definedClass); + definedClass.annotate(JsonSerialize.class).param("using", serializer); + } catch (JClassAlreadyExistsException ex) { + // already serialized aware + } + + try { + JDefinedClass deserializer = generateDeserializer(definedClass, unionTypes); + definedClass.annotate(JsonDeserialize.class).param("using", deserializer); + } catch (JClassAlreadyExistsException ex) { + // already deserialized aware + } + for (JType unionType : unionTypes) { + wrapIt(definedClass, valueField, unionType); + } + } else { + valueField = Optional.empty(); + } - unionTypes.forEach(unionType -> wrapIt(definedClass, valueField, unionType)); refType.ifPresent( type -> { if (type instanceof JClass) { @@ -126,6 +148,7 @@ private JDefinedClass populateClass( wrapIt(definedClass, valueField, type); } }); + if (definedClass.constructors().hasNext() && definedClass.getConstructor(new JType[0]) == null) { definedClass.constructor(JMod.PUBLIC); @@ -133,7 +156,8 @@ private JDefinedClass populateClass( return definedClass; } - private JDefinedClass generateSerializer(JDefinedClass relatedClass) { + private JDefinedClass generateSerializer(JDefinedClass relatedClass) + throws JClassAlreadyExistsException { JDefinedClass definedClass = GeneratorUtils.serializerClass(relatedClass); GeneratorUtils.fillSerializer( definedClass, @@ -150,7 +174,8 @@ private JDefinedClass generateSerializer(JDefinedClass relatedClass) { } private JDefinedClass generateDeserializer( - JDefinedClass relatedClass, Collection unionTypes) { + JDefinedClass relatedClass, Collection unionTypes) + throws JClassAlreadyExistsException { JDefinedClass definedClass = GeneratorUtils.deserializerClass(relatedClass); GeneratorUtils.fillDeserializer( definedClass, @@ -173,22 +198,18 @@ private JDefinedClass generateDeserializer( private JDefinedClass createUnionClass( String nodeName, JPackage container, Optional refType, Collection unionTypes) { - final String className = - ruleFactory.getNameHelper().getUniqueClassName(nodeName, null, container); try { - JDefinedClass definedClass = container._class(className); - definedClass.annotate(JsonSerialize.class).param("using", generateSerializer(definedClass)); - definedClass - .annotate(JsonDeserialize.class) - .param("using", generateDeserializer(definedClass, unionTypes)); - - return populateClass(definedClass, refType, unionTypes); + return populateClass( + container._class( + ruleFactory.getNameHelper().getUniqueClassName(nodeName, null, container)), + refType, + unionTypes); } catch (JClassAlreadyExistsException e) { throw new IllegalArgumentException(e); } } - private void wrapIt(JDefinedClass definedClass, JFieldVar valueField, JType unionType) { + private void wrapIt(JDefinedClass definedClass, Optional valueField, JType unionType) { final String name = unionType.name(); JFieldVar instanceField = definedClass.field( @@ -196,10 +217,9 @@ private void wrapIt(JDefinedClass definedClass, JFieldVar valueField, JType unio 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(valueField), instanceParam) - .assign(JExpr._this().ref(instanceField), instanceParam); + JBlock body = constructor.body(); + valueField.ifPresent(v -> body.assign(JExpr._this().ref(v), instanceParam)); + body.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 ebf1c507..ce3badc2 100644 --- a/custom-generator/src/main/java/io/serverlessworkflow/generator/GeneratorUtils.java +++ b/custom-generator/src/main/java/io/serverlessworkflow/generator/GeneratorUtils.java @@ -49,11 +49,13 @@ public interface DeserializerFiller { void accept(JMethod method, JVar parserParam); } - public static JDefinedClass serializerClass(JDefinedClass relatedClass) { + public static JDefinedClass serializerClass(JDefinedClass relatedClass) + throws JClassAlreadyExistsException { return createClass(relatedClass, JsonSerializer.class, "Serializer"); } - public static JDefinedClass deserializerClass(JDefinedClass relatedClass) { + public static JDefinedClass deserializerClass(JDefinedClass relatedClass) + throws JClassAlreadyExistsException { return createClass(relatedClass, JsonDeserializer.class, "Deserializer"); } @@ -97,15 +99,12 @@ public static void fillDeserializer( } private static JDefinedClass createClass( - JDefinedClass relatedClass, Class serializerClass, String suffix) { - try { - JDefinedClass definedClass = - relatedClass._package()._class(JMod.NONE, relatedClass.name() + suffix); - definedClass._extends(definedClass.owner().ref(serializerClass).narrow(relatedClass)); - return definedClass; - } catch (JClassAlreadyExistsException ex) { - throw new IllegalArgumentException(ex); - } + JDefinedClass relatedClass, Class serializerClass, String suffix) + throws JClassAlreadyExistsException { + JDefinedClass definedClass = + relatedClass._package()._class(JMod.NONE, relatedClass.name() + suffix); + definedClass._extends(definedClass.owner().ref(serializerClass).narrow(relatedClass)); + return definedClass; } private GeneratorUtils() {} 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 25eacd11..0e937658 100644 --- a/custom-generator/src/main/java/io/serverlessworkflow/generator/UnevaluatedPropertiesRule.java +++ b/custom-generator/src/main/java/io/serverlessworkflow/generator/UnevaluatedPropertiesRule.java @@ -20,6 +20,7 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.sun.codemodel.JBlock; import com.sun.codemodel.JClass; +import com.sun.codemodel.JClassAlreadyExistsException; import com.sun.codemodel.JDefinedClass; import com.sun.codemodel.JExpr; import com.sun.codemodel.JFieldVar; @@ -52,14 +53,19 @@ public JDefinedClass apply( } else if (node != null && checkIntValue(parent, "maxProperties", 1) && checkIntValue(parent, "minProperties", 1)) { - return addKeyValueFields(jclass, node, parent, nodeName, schema); + try { + return addKeyValueFields(jclass, node, parent, nodeName, schema); + } catch (JClassAlreadyExistsException e) { + throw new IllegalArgumentException(e); + } } else { return super.apply(nodeName, node, parent, jclass, schema); } } private JDefinedClass addKeyValueFields( - JDefinedClass jclass, JsonNode node, JsonNode parent, String nodeName, Schema schema) { + JDefinedClass jclass, JsonNode node, JsonNode parent, String nodeName, Schema schema) + throws JClassAlreadyExistsException { NameHelper nameHelper = ruleFactory.getNameHelper(); JType stringClass = jclass.owner()._ref(String.class); JFieldVar nameField = @@ -107,7 +113,8 @@ private JDefinedClass addKeyValueFields( return jclass; } - private JDefinedClass generateDeserializer(JDefinedClass relatedClass, JType propertyType) { + private JDefinedClass generateDeserializer(JDefinedClass relatedClass, JType propertyType) + throws JClassAlreadyExistsException { JDefinedClass definedClass = GeneratorUtils.deserializerClass(relatedClass); GeneratorUtils.fillDeserializer( definedClass, @@ -127,7 +134,8 @@ private JDefinedClass generateDeserializer(JDefinedClass relatedClass, JType pro } private JDefinedClass generateSerializer( - JDefinedClass relatedClass, JMethod nameMethod, JMethod valueMethod) { + JDefinedClass relatedClass, JMethod nameMethod, JMethod valueMethod) + throws JClassAlreadyExistsException { JDefinedClass definedClass = GeneratorUtils.serializerClass(relatedClass); GeneratorUtils.fillSerializer( definedClass,