From 77746af6cba6b7df6df7210036bf4b0d9d0378af Mon Sep 17 00:00:00 2001 From: Francisco Javier Tirado Sarti Date: Wed, 26 Jun 2024 18:47:39 +0200 Subject: [PATCH 1/4] [Fix #380] Change item API Signed-off-by: Francisco Javier Tirado Sarti --- .../api/CallTaskDeserializer.java | 2 +- .../api/CallTaskSerializer.java | 2 +- .../api/DeserializeHelper.java | 15 ++++- .../api/ObjectMapperFactory.java | 7 +++ .../api/SerializeHelper.java | 2 +- .../api/SwitchDeserializer.java | 31 ++++++++++ .../api/SwitchSerializer.java | 33 ++++++++++ .../api/TaskDeserializer.java | 2 +- .../api/TaskItemDeserializer.java | 31 ++++++++++ .../api/TaskItemSerializer.java | 33 ++++++++++ .../api/TaskSerializer.java | 2 +- .../io/serverlessworkflow/api/ApiTest.java | 6 +- .../generator/AllAnyOneOfSchemaRule.java | 14 +---- .../generator/GeneratorUtils.java | 38 ++++++++++++ .../generator/UnevaluatedPropertiesRule.java | 60 ++++++++++++++++++- 15 files changed, 255 insertions(+), 23 deletions(-) create mode 100644 api/src/main/java/io/serverlessworkflow/api/SwitchDeserializer.java create mode 100644 api/src/main/java/io/serverlessworkflow/api/SwitchSerializer.java create mode 100644 api/src/main/java/io/serverlessworkflow/api/TaskItemDeserializer.java create mode 100644 api/src/main/java/io/serverlessworkflow/api/TaskItemSerializer.java create mode 100644 custom-generator/src/main/java/io/serverlessworkflow/generator/GeneratorUtils.java diff --git a/api/src/main/java/io/serverlessworkflow/api/CallTaskDeserializer.java b/api/src/main/java/io/serverlessworkflow/api/CallTaskDeserializer.java index fcfec397..097c77b5 100644 --- a/api/src/main/java/io/serverlessworkflow/api/CallTaskDeserializer.java +++ b/api/src/main/java/io/serverlessworkflow/api/CallTaskDeserializer.java @@ -30,7 +30,7 @@ class CallTaskDeserializer extends JsonDeserializer { @Override public CallTask deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { - return DeserializeHelper.deserialize( + return DeserializeHelper.deserializeOneOf( p, CallTask.class, List.of(CallHTTP.class, CallAsyncAPI.class, CallOpenAPI.class, CallGRPC.class)); diff --git a/api/src/main/java/io/serverlessworkflow/api/CallTaskSerializer.java b/api/src/main/java/io/serverlessworkflow/api/CallTaskSerializer.java index 18abac33..866875ba 100644 --- a/api/src/main/java/io/serverlessworkflow/api/CallTaskSerializer.java +++ b/api/src/main/java/io/serverlessworkflow/api/CallTaskSerializer.java @@ -25,6 +25,6 @@ class CallTaskSerializer extends JsonSerializer { @Override public void serialize(CallTask value, JsonGenerator gen, SerializerProvider serializers) throws IOException { - SerializeHelper.serialize(gen, value); + SerializeHelper.serializeOneOf(gen, value); } } diff --git a/api/src/main/java/io/serverlessworkflow/api/DeserializeHelper.java b/api/src/main/java/io/serverlessworkflow/api/DeserializeHelper.java index ba35b90d..b6dd947b 100644 --- a/api/src/main/java/io/serverlessworkflow/api/DeserializeHelper.java +++ b/api/src/main/java/io/serverlessworkflow/api/DeserializeHelper.java @@ -24,7 +24,7 @@ public class DeserializeHelper { - public static T deserialize( + public static T deserializeOneOf( JsonParser p, Class targetClass, Collection> unionTypes) throws IOException { TreeNode node = p.readValueAsTree(); JsonProcessingException ex = new JsonMappingException("Problem deserializing " + targetClass); @@ -38,4 +38,17 @@ public static T deserialize( } throw ex; } + + public static T deserializeItem(JsonParser p, Class targetClass, Class valueClass) + throws IOException { + TreeNode node = p.readValueAsTree(); + String fieldName = node.fieldNames().next(); + try { + return targetClass + .getConstructor(String.class, valueClass) + .newInstance(fieldName, p.getCodec().treeToValue(node.get(fieldName), valueClass)); + } catch (ReflectiveOperationException e) { + throw new IOException(e); + } + } } diff --git a/api/src/main/java/io/serverlessworkflow/api/ObjectMapperFactory.java b/api/src/main/java/io/serverlessworkflow/api/ObjectMapperFactory.java index d3a9645c..a245a07f 100644 --- a/api/src/main/java/io/serverlessworkflow/api/ObjectMapperFactory.java +++ b/api/src/main/java/io/serverlessworkflow/api/ObjectMapperFactory.java @@ -21,7 +21,9 @@ import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator.Feature; import io.serverlessworkflow.api.types.CallTask; +import io.serverlessworkflow.api.types.Switch; import io.serverlessworkflow.api.types.Task; +import io.serverlessworkflow.api.types.TaskItem; class ObjectMapperFactory { @@ -44,6 +46,11 @@ private static ObjectMapper configure(ObjectMapper mapper) { simpleModule.addSerializer(Task.class, new TaskSerializer()); simpleModule.addDeserializer(CallTask.class, new CallTaskDeserializer()); simpleModule.addSerializer(CallTask.class, new CallTaskSerializer()); + simpleModule.addDeserializer(TaskItem.class, new TaskItemDeserializer()); + simpleModule.addSerializer(TaskItem.class, new TaskItemSerializer()); + simpleModule.addSerializer(Switch.class, new SwitchSerializer()); + simpleModule.addDeserializer(Switch.class, new SwitchDeserializer()); + return mapper .configure(SerializationFeature.INDENT_OUTPUT, true) .configure(SerializationFeature.WRITE_EMPTY_JSON_ARRAYS, false) diff --git a/api/src/main/java/io/serverlessworkflow/api/SerializeHelper.java b/api/src/main/java/io/serverlessworkflow/api/SerializeHelper.java index e08de159..85857637 100644 --- a/api/src/main/java/io/serverlessworkflow/api/SerializeHelper.java +++ b/api/src/main/java/io/serverlessworkflow/api/SerializeHelper.java @@ -20,7 +20,7 @@ import java.lang.reflect.Method; public class SerializeHelper { - public static void serialize(JsonGenerator jgen, Object item) throws IOException { + public static void serializeOneOf(JsonGenerator jgen, Object item) throws IOException { try { for (Method m : item.getClass().getDeclaredMethods()) { Object value = m.invoke(item); diff --git a/api/src/main/java/io/serverlessworkflow/api/SwitchDeserializer.java b/api/src/main/java/io/serverlessworkflow/api/SwitchDeserializer.java new file mode 100644 index 00000000..21ede4a3 --- /dev/null +++ b/api/src/main/java/io/serverlessworkflow/api/SwitchDeserializer.java @@ -0,0 +1,31 @@ +/* + * 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; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import io.serverlessworkflow.api.types.Switch; +import io.serverlessworkflow.api.types.SwitchProperty; +import java.io.IOException; + +class SwitchDeserializer extends JsonDeserializer { + + @Override + public Switch deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + return DeserializeHelper.deserializeItem(p, Switch.class, SwitchProperty.class); + } +} diff --git a/api/src/main/java/io/serverlessworkflow/api/SwitchSerializer.java b/api/src/main/java/io/serverlessworkflow/api/SwitchSerializer.java new file mode 100644 index 00000000..ed64fcb9 --- /dev/null +++ b/api/src/main/java/io/serverlessworkflow/api/SwitchSerializer.java @@ -0,0 +1,33 @@ +/* + * 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; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import io.serverlessworkflow.api.types.Switch; +import java.io.IOException; + +class SwitchSerializer extends JsonSerializer { + + @Override + public void serialize(Switch value, JsonGenerator gen, SerializerProvider serializers) + throws IOException { + gen.writeStartObject(); + gen.writeObjectField(value.getName(), value.getSwitchProperty()); + gen.writeEndObject(); + } +} diff --git a/api/src/main/java/io/serverlessworkflow/api/TaskDeserializer.java b/api/src/main/java/io/serverlessworkflow/api/TaskDeserializer.java index d81091ca..45892cb7 100644 --- a/api/src/main/java/io/serverlessworkflow/api/TaskDeserializer.java +++ b/api/src/main/java/io/serverlessworkflow/api/TaskDeserializer.java @@ -38,7 +38,7 @@ class TaskDeserializer extends JsonDeserializer { @Override public Task deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { - return DeserializeHelper.deserialize( + return DeserializeHelper.deserializeOneOf( p, Task.class, List.of( diff --git a/api/src/main/java/io/serverlessworkflow/api/TaskItemDeserializer.java b/api/src/main/java/io/serverlessworkflow/api/TaskItemDeserializer.java new file mode 100644 index 00000000..00c6d352 --- /dev/null +++ b/api/src/main/java/io/serverlessworkflow/api/TaskItemDeserializer.java @@ -0,0 +1,31 @@ +/* + * 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; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import io.serverlessworkflow.api.types.Task; +import io.serverlessworkflow.api.types.TaskItem; +import java.io.IOException; + +class TaskItemDeserializer extends JsonDeserializer { + + @Override + public TaskItem deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + return DeserializeHelper.deserializeItem(p, TaskItem.class, Task.class); + } +} diff --git a/api/src/main/java/io/serverlessworkflow/api/TaskItemSerializer.java b/api/src/main/java/io/serverlessworkflow/api/TaskItemSerializer.java new file mode 100644 index 00000000..53e8a265 --- /dev/null +++ b/api/src/main/java/io/serverlessworkflow/api/TaskItemSerializer.java @@ -0,0 +1,33 @@ +/* + * 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; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import io.serverlessworkflow.api.types.TaskItem; +import java.io.IOException; + +class TaskItemSerializer extends JsonSerializer { + + @Override + public void serialize(TaskItem value, JsonGenerator gen, SerializerProvider serializers) + throws IOException { + gen.writeStartObject(); + gen.writeObjectField(value.getName(), value.getTask()); + gen.writeEndObject(); + } +} diff --git a/api/src/main/java/io/serverlessworkflow/api/TaskSerializer.java b/api/src/main/java/io/serverlessworkflow/api/TaskSerializer.java index 3900f16e..1f9d65f9 100644 --- a/api/src/main/java/io/serverlessworkflow/api/TaskSerializer.java +++ b/api/src/main/java/io/serverlessworkflow/api/TaskSerializer.java @@ -26,6 +26,6 @@ class TaskSerializer extends JsonSerializer { @Override public void serialize(Task value, JsonGenerator gen, SerializerProvider serializers) throws IOException { - SerializeHelper.serialize(gen, value); + SerializeHelper.serializeOneOf(gen, value); } } diff --git a/api/src/test/java/io/serverlessworkflow/api/ApiTest.java b/api/src/test/java/io/serverlessworkflow/api/ApiTest.java index 87924497..8e4c27b7 100644 --- a/api/src/test/java/io/serverlessworkflow/api/ApiTest.java +++ b/api/src/test/java/io/serverlessworkflow/api/ApiTest.java @@ -31,9 +31,9 @@ public class ApiTest { void testCallHTTPAPI() throws IOException { Workflow workflow = readWorkflowFromClasspath("features/callHttp.yaml"); assertThat(workflow.getDo()).isNotEmpty(); - assertThat(workflow.getDo().get(0).getAdditionalProperties()).isNotEmpty(); - assertThat(workflow.getDo().get(0).getAdditionalProperties().values()).isNotEmpty(); - Task task = workflow.getDo().get(0).getAdditionalProperties().values().iterator().next(); + 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(); 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 e16e07bc..d4bcac84 100644 --- a/custom-generator/src/main/java/io/serverlessworkflow/generator/AllAnyOneOfSchemaRule.java +++ b/custom-generator/src/main/java/io/serverlessworkflow/generator/AllAnyOneOfSchemaRule.java @@ -15,8 +15,6 @@ */ package io.serverlessworkflow.generator; -import static org.apache.commons.lang3.StringUtils.*; - import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; import com.sun.codemodel.JClass; @@ -127,16 +125,8 @@ private JDefinedClass createUnionClass( private void wrapIt(JDefinedClass definedClass, JType unionType) { JFieldVar instanceField = - definedClass.field( - JMod.PRIVATE, - unionType, - ruleFactory.getNameHelper().getPropertyName(unionType.name(), null)); - JMethod method = - definedClass.method( - JMod.PUBLIC, - unionType, - ruleFactory.getNameHelper().getGetterName(unionType.name(), unionType, null)); - method.body()._return(instanceField); + GeneratorUtils.addGetter( + definedClass, unionType, ruleFactory.getNameHelper(), unionType.name()); JMethod constructor = definedClass.constructor(JMod.PUBLIC); constructor .body() diff --git a/custom-generator/src/main/java/io/serverlessworkflow/generator/GeneratorUtils.java b/custom-generator/src/main/java/io/serverlessworkflow/generator/GeneratorUtils.java new file mode 100644 index 00000000..d6736159 --- /dev/null +++ b/custom-generator/src/main/java/io/serverlessworkflow/generator/GeneratorUtils.java @@ -0,0 +1,38 @@ +/* + * 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.generator; + +import com.sun.codemodel.JDefinedClass; +import com.sun.codemodel.JFieldVar; +import com.sun.codemodel.JMethod; +import com.sun.codemodel.JMod; +import com.sun.codemodel.JType; +import org.jsonschema2pojo.util.NameHelper; + +public class GeneratorUtils { + + public static JFieldVar addGetter( + JDefinedClass definedClass, JType type, NameHelper nameHelper, String name) { + JFieldVar instanceField = + definedClass.field(JMod.PRIVATE, type, nameHelper.getPropertyName(name, null)); + JMethod method = + definedClass.method(JMod.PUBLIC, type, nameHelper.getGetterName(name, type, null)); + method.body()._return(instanceField); + return instanceField; + } + + 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 b523967b..e94d6a25 100644 --- a/custom-generator/src/main/java/io/serverlessworkflow/generator/UnevaluatedPropertiesRule.java +++ b/custom-generator/src/main/java/io/serverlessworkflow/generator/UnevaluatedPropertiesRule.java @@ -17,15 +17,25 @@ import com.fasterxml.jackson.databind.JsonNode; import com.sun.codemodel.JDefinedClass; +import com.sun.codemodel.JExpr; +import com.sun.codemodel.JFieldVar; +import com.sun.codemodel.JMethod; +import com.sun.codemodel.JMod; +import com.sun.codemodel.JType; import org.jsonschema2pojo.Schema; import org.jsonschema2pojo.rules.AdditionalPropertiesRule; import org.jsonschema2pojo.rules.Rule; +import org.jsonschema2pojo.rules.RuleFactory; +import org.jsonschema2pojo.util.NameHelper; public class UnevaluatedPropertiesRule extends AdditionalPropertiesRule implements Rule { - public UnevaluatedPropertiesRule(UnreferencedFactory unreferencedFactory) { - super(unreferencedFactory); + private RuleFactory ruleFactory; + + public UnevaluatedPropertiesRule(RuleFactory ruleFactory) { + super(ruleFactory); + this.ruleFactory = ruleFactory; } public JDefinedClass apply( @@ -35,8 +45,54 @@ public JDefinedClass apply( || (node == null && parent.has("properties"))) { // no additional properties allowed return jclass; + } else if (node != null + && checkIntValue(parent, "maxProperties", 1) + && checkIntValue(parent, "minProperties", 1)) { + return addKeyValueFields(jclass, node, parent, nodeName, schema); } else { return super.apply(nodeName, node, parent, jclass, schema); } } + + private JDefinedClass addKeyValueFields( + JDefinedClass jclass, JsonNode node, JsonNode parent, String nodeName, Schema schema) { + NameHelper nameHelper = ruleFactory.getNameHelper(); + JType stringClass = jclass.owner()._ref(String.class); + JFieldVar nameField = GeneratorUtils.addGetter(jclass, stringClass, nameHelper, "name"); + JType propertyType; + if (node != null && node.size() != 0) { + String pathToAdditionalProperties; + if (schema.getId().getFragment() == null) { + pathToAdditionalProperties = "#/additionalProperties"; + } else { + pathToAdditionalProperties = "#" + schema.getId().getFragment() + "/additionalProperties"; + } + Schema additionalPropertiesSchema = + ruleFactory + .getSchemaStore() + .create( + schema, + pathToAdditionalProperties, + ruleFactory.getGenerationConfig().getRefFragmentPathDelimiters()); + propertyType = + ruleFactory + .getSchemaRule() + .apply(nodeName + "Property", node, parent, jclass, additionalPropertiesSchema); + additionalPropertiesSchema.setJavaTypeIfEmpty(propertyType); + } else { + propertyType = jclass.owner().ref(Object.class); + } + JFieldVar valueField = + GeneratorUtils.addGetter(jclass, propertyType, nameHelper, propertyType.name()); + JMethod constructor = jclass.constructor(JMod.PUBLIC); + constructor + .body() + .assign(JExpr._this().ref(nameField), constructor.param(stringClass, nameField.name())) + .assign(JExpr._this().ref(valueField), constructor.param(propertyType, valueField.name())); + return jclass; + } + + private boolean checkIntValue(JsonNode node, String propName, int value) { + return node.has(propName) && node.get(propName).asInt() == value; + } } From a050a536437c5cedf5fa70bb417e79f1d17c2038 Mon Sep 17 00:00:00 2001 From: Francisco Javier Tirado Sarti Date: Thu, 27 Jun 2024 11:03:58 +0200 Subject: [PATCH 2/4] [Fix #380] SwitchPRoperty to SwitchItem Signed-off-by: Francisco Javier Tirado Sarti --- .../io/serverlessworkflow/api/ObjectMapperFactory.java | 6 +++--- ...chDeserializer.java => SwitchItemDeserializer.java} | 10 +++++----- ...SwitchSerializer.java => SwitchItemSerializer.java} | 8 ++++---- api/src/main/resources/schema/workflow.yaml | 2 ++ 4 files changed, 14 insertions(+), 12 deletions(-) rename api/src/main/java/io/serverlessworkflow/api/{SwitchDeserializer.java => SwitchItemDeserializer.java} (71%) rename api/src/main/java/io/serverlessworkflow/api/{SwitchSerializer.java => SwitchItemSerializer.java} (77%) diff --git a/api/src/main/java/io/serverlessworkflow/api/ObjectMapperFactory.java b/api/src/main/java/io/serverlessworkflow/api/ObjectMapperFactory.java index a245a07f..f45c7632 100644 --- a/api/src/main/java/io/serverlessworkflow/api/ObjectMapperFactory.java +++ b/api/src/main/java/io/serverlessworkflow/api/ObjectMapperFactory.java @@ -21,7 +21,7 @@ import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator.Feature; import io.serverlessworkflow.api.types.CallTask; -import io.serverlessworkflow.api.types.Switch; +import io.serverlessworkflow.api.types.SwitchItem; import io.serverlessworkflow.api.types.Task; import io.serverlessworkflow.api.types.TaskItem; @@ -48,8 +48,8 @@ private static ObjectMapper configure(ObjectMapper mapper) { simpleModule.addSerializer(CallTask.class, new CallTaskSerializer()); simpleModule.addDeserializer(TaskItem.class, new TaskItemDeserializer()); simpleModule.addSerializer(TaskItem.class, new TaskItemSerializer()); - simpleModule.addSerializer(Switch.class, new SwitchSerializer()); - simpleModule.addDeserializer(Switch.class, new SwitchDeserializer()); + simpleModule.addSerializer(SwitchItem.class, new SwitchItemSerializer()); + simpleModule.addDeserializer(SwitchItem.class, new SwitchItemDeserializer()); return mapper .configure(SerializationFeature.INDENT_OUTPUT, true) diff --git a/api/src/main/java/io/serverlessworkflow/api/SwitchDeserializer.java b/api/src/main/java/io/serverlessworkflow/api/SwitchItemDeserializer.java similarity index 71% rename from api/src/main/java/io/serverlessworkflow/api/SwitchDeserializer.java rename to api/src/main/java/io/serverlessworkflow/api/SwitchItemDeserializer.java index 21ede4a3..02d93585 100644 --- a/api/src/main/java/io/serverlessworkflow/api/SwitchDeserializer.java +++ b/api/src/main/java/io/serverlessworkflow/api/SwitchItemDeserializer.java @@ -18,14 +18,14 @@ import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; -import io.serverlessworkflow.api.types.Switch; -import io.serverlessworkflow.api.types.SwitchProperty; +import io.serverlessworkflow.api.types.SwitchCase; +import io.serverlessworkflow.api.types.SwitchItem; import java.io.IOException; -class SwitchDeserializer extends JsonDeserializer { +class SwitchItemDeserializer extends JsonDeserializer { @Override - public Switch deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { - return DeserializeHelper.deserializeItem(p, Switch.class, SwitchProperty.class); + public SwitchItem deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + return DeserializeHelper.deserializeItem(p, SwitchItem.class, SwitchCase.class); } } diff --git a/api/src/main/java/io/serverlessworkflow/api/SwitchSerializer.java b/api/src/main/java/io/serverlessworkflow/api/SwitchItemSerializer.java similarity index 77% rename from api/src/main/java/io/serverlessworkflow/api/SwitchSerializer.java rename to api/src/main/java/io/serverlessworkflow/api/SwitchItemSerializer.java index ed64fcb9..f76582cb 100644 --- a/api/src/main/java/io/serverlessworkflow/api/SwitchSerializer.java +++ b/api/src/main/java/io/serverlessworkflow/api/SwitchItemSerializer.java @@ -18,16 +18,16 @@ import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; -import io.serverlessworkflow.api.types.Switch; +import io.serverlessworkflow.api.types.SwitchItem; import java.io.IOException; -class SwitchSerializer extends JsonSerializer { +class SwitchItemSerializer extends JsonSerializer { @Override - public void serialize(Switch value, JsonGenerator gen, SerializerProvider serializers) + public void serialize(SwitchItem value, JsonGenerator gen, SerializerProvider serializers) throws IOException { gen.writeStartObject(); - gen.writeObjectField(value.getName(), value.getSwitchProperty()); + gen.writeObjectField(value.getName(), value.getSwitchCase()); gen.writeEndObject(); } } diff --git a/api/src/main/resources/schema/workflow.yaml b/api/src/main/resources/schema/workflow.yaml index d3a20f2f..1c6d1bcc 100644 --- a/api/src/main/resources/schema/workflow.yaml +++ b/api/src/main/resources/schema/workflow.yaml @@ -571,8 +571,10 @@ $defs: type: object minProperties: 1 maxProperties: 1 + title: SwitchItem additionalProperties: type: object + title: SwitchCase properties: name: type: string From eb0b906b00bb32e508f7a0fed5834112bae7c704 Mon Sep 17 00:00:00 2001 From: Francisco Javier Tirado Sarti Date: Fri, 28 Jun 2024 10:36:21 +0200 Subject: [PATCH 3/4] [Fix #380] oneOf as Optional Signed-off-by: Francisco Javier Tirado Sarti --- api/pom.xml | 4 ++++ .../api/ObjectMapperFactory.java | 4 +++- .../serverlessworkflow/api/SerializeHelper.java | 5 +++-- .../java/io/serverlessworkflow/api/ApiTest.java | 15 ++++++++------- .../generator/AllAnyOneOfSchemaRule.java | 2 +- .../generator/GeneratorUtils.java | 16 ++++++++++++++++ pom.xml | 5 +++++ 7 files changed, 40 insertions(+), 11 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 37524b37..1e643d36 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -29,6 +29,10 @@ com.fasterxml.jackson.dataformat jackson-dataformat-yaml + + com.fasterxml.jackson.datatype + jackson-datatype-jdk8 + jakarta.validation jakarta.validation-api diff --git a/api/src/main/java/io/serverlessworkflow/api/ObjectMapperFactory.java b/api/src/main/java/io/serverlessworkflow/api/ObjectMapperFactory.java index f45c7632..74611b2b 100644 --- a/api/src/main/java/io/serverlessworkflow/api/ObjectMapperFactory.java +++ b/api/src/main/java/io/serverlessworkflow/api/ObjectMapperFactory.java @@ -20,6 +20,7 @@ import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator.Feature; +import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; import io.serverlessworkflow.api.types.CallTask; import io.serverlessworkflow.api.types.SwitchItem; import io.serverlessworkflow.api.types.Task; @@ -55,7 +56,8 @@ private static ObjectMapper configure(ObjectMapper mapper) { .configure(SerializationFeature.INDENT_OUTPUT, true) .configure(SerializationFeature.WRITE_EMPTY_JSON_ARRAYS, false) .configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false) - .registerModule(simpleModule); + .registerModule(simpleModule) + .registerModule(new Jdk8Module()); } private ObjectMapperFactory() {} diff --git a/api/src/main/java/io/serverlessworkflow/api/SerializeHelper.java b/api/src/main/java/io/serverlessworkflow/api/SerializeHelper.java index 85857637..7a37e40a 100644 --- a/api/src/main/java/io/serverlessworkflow/api/SerializeHelper.java +++ b/api/src/main/java/io/serverlessworkflow/api/SerializeHelper.java @@ -18,13 +18,14 @@ import com.fasterxml.jackson.core.JsonGenerator; import java.io.IOException; import java.lang.reflect.Method; +import java.util.Optional; public class SerializeHelper { public static void serializeOneOf(JsonGenerator jgen, Object item) throws IOException { try { for (Method m : item.getClass().getDeclaredMethods()) { - Object value = m.invoke(item); - if (value != null) { + Optional value = (Optional) m.invoke(item); + if (value.isPresent()) { jgen.writeObject(value); break; } diff --git a/api/src/test/java/io/serverlessworkflow/api/ApiTest.java b/api/src/test/java/io/serverlessworkflow/api/ApiTest.java index 8e4c27b7..6344a0a2 100644 --- a/api/src/test/java/io/serverlessworkflow/api/ApiTest.java +++ b/api/src/test/java/io/serverlessworkflow/api/ApiTest.java @@ -23,6 +23,7 @@ import io.serverlessworkflow.api.types.Task; import io.serverlessworkflow.api.types.Workflow; import java.io.IOException; +import java.util.Optional; import org.junit.jupiter.api.Test; public class ApiTest { @@ -34,12 +35,12 @@ 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"); + Optional callTask = task.getCallTask(); + assertThat(callTask).isPresent(); + assertThat(task.getDoTask()).isEmpty(); + Optional httpCall = callTask.flatMap(CallTask::getCallHTTP); + assertThat(httpCall).isPresent(); + assertThat(callTask.flatMap(CallTask::getCallAsyncAPI)).isEmpty(); + assertThat(httpCall.get().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 d4bcac84..467a2b5f 100644 --- a/custom-generator/src/main/java/io/serverlessworkflow/generator/AllAnyOneOfSchemaRule.java +++ b/custom-generator/src/main/java/io/serverlessworkflow/generator/AllAnyOneOfSchemaRule.java @@ -125,7 +125,7 @@ private JDefinedClass createUnionClass( private void wrapIt(JDefinedClass definedClass, JType unionType) { JFieldVar instanceField = - GeneratorUtils.addGetter( + GeneratorUtils.addOptionalGetter( definedClass, unionType, ruleFactory.getNameHelper(), unionType.name()); JMethod constructor = definedClass.constructor(JMod.PUBLIC); constructor 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 d6736159..92db2612 100644 --- a/custom-generator/src/main/java/io/serverlessworkflow/generator/GeneratorUtils.java +++ b/custom-generator/src/main/java/io/serverlessworkflow/generator/GeneratorUtils.java @@ -15,11 +15,13 @@ */ package io.serverlessworkflow.generator; +import com.sun.codemodel.JClass; import com.sun.codemodel.JDefinedClass; import com.sun.codemodel.JFieldVar; import com.sun.codemodel.JMethod; import com.sun.codemodel.JMod; import com.sun.codemodel.JType; +import java.util.Optional; import org.jsonschema2pojo.util.NameHelper; public class GeneratorUtils { @@ -34,5 +36,19 @@ public static JFieldVar addGetter( return instanceField; } + public static JFieldVar addOptionalGetter( + JDefinedClass definedClass, JType type, NameHelper nameHelper, String name) { + JFieldVar instanceField = + definedClass.field(JMod.PRIVATE, type, nameHelper.getPropertyName(name, null)); + JClass optionalRef = definedClass.owner().ref(Optional.class).narrow(type); + JMethod method = + definedClass.method(JMod.PUBLIC, optionalRef, nameHelper.getGetterName(name, type, null)); + method + .body() + ._return( + definedClass.owner().ref(Optional.class).staticInvoke("ofNullable").arg(instanceField)); + return instanceField; + } + private GeneratorUtils() {} } diff --git a/pom.xml b/pom.xml index 6635b583..fabfff08 100644 --- a/pom.xml +++ b/pom.xml @@ -114,6 +114,11 @@ jackson-core ${version.com.fasterxml.jackson} + + com.fasterxml.jackson.datatype + jackson-datatype-jdk8 + ${version.com.fasterxml.jackson} + com.fasterxml.jackson.core jackson-databind From 9a91a058a3ec300b30cd75a11eeeffca1c2e47e8 Mon Sep 17 00:00:00 2001 From: Francisco Javier Tirado Sarti Date: Fri, 28 Jun 2024 15:15:42 +0200 Subject: [PATCH 4/4] Revert "[Fix #380] oneOf as Optional" This reverts commit eb0b906b00bb32e508f7a0fed5834112bae7c704. --- api/pom.xml | 4 ---- .../api/ObjectMapperFactory.java | 4 +--- .../serverlessworkflow/api/SerializeHelper.java | 5 ++--- .../java/io/serverlessworkflow/api/ApiTest.java | 15 +++++++-------- .../generator/AllAnyOneOfSchemaRule.java | 2 +- .../generator/GeneratorUtils.java | 16 ---------------- pom.xml | 5 ----- 7 files changed, 11 insertions(+), 40 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 1e643d36..37524b37 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -29,10 +29,6 @@ com.fasterxml.jackson.dataformat jackson-dataformat-yaml - - com.fasterxml.jackson.datatype - jackson-datatype-jdk8 - jakarta.validation jakarta.validation-api diff --git a/api/src/main/java/io/serverlessworkflow/api/ObjectMapperFactory.java b/api/src/main/java/io/serverlessworkflow/api/ObjectMapperFactory.java index 74611b2b..f45c7632 100644 --- a/api/src/main/java/io/serverlessworkflow/api/ObjectMapperFactory.java +++ b/api/src/main/java/io/serverlessworkflow/api/ObjectMapperFactory.java @@ -20,7 +20,6 @@ import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator.Feature; -import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; import io.serverlessworkflow.api.types.CallTask; import io.serverlessworkflow.api.types.SwitchItem; import io.serverlessworkflow.api.types.Task; @@ -56,8 +55,7 @@ private static ObjectMapper configure(ObjectMapper mapper) { .configure(SerializationFeature.INDENT_OUTPUT, true) .configure(SerializationFeature.WRITE_EMPTY_JSON_ARRAYS, false) .configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false) - .registerModule(simpleModule) - .registerModule(new Jdk8Module()); + .registerModule(simpleModule); } private ObjectMapperFactory() {} diff --git a/api/src/main/java/io/serverlessworkflow/api/SerializeHelper.java b/api/src/main/java/io/serverlessworkflow/api/SerializeHelper.java index 7a37e40a..85857637 100644 --- a/api/src/main/java/io/serverlessworkflow/api/SerializeHelper.java +++ b/api/src/main/java/io/serverlessworkflow/api/SerializeHelper.java @@ -18,14 +18,13 @@ import com.fasterxml.jackson.core.JsonGenerator; import java.io.IOException; import java.lang.reflect.Method; -import java.util.Optional; public class SerializeHelper { public static void serializeOneOf(JsonGenerator jgen, Object item) throws IOException { try { for (Method m : item.getClass().getDeclaredMethods()) { - Optional value = (Optional) m.invoke(item); - if (value.isPresent()) { + Object value = m.invoke(item); + if (value != null) { jgen.writeObject(value); break; } diff --git a/api/src/test/java/io/serverlessworkflow/api/ApiTest.java b/api/src/test/java/io/serverlessworkflow/api/ApiTest.java index 6344a0a2..8e4c27b7 100644 --- a/api/src/test/java/io/serverlessworkflow/api/ApiTest.java +++ b/api/src/test/java/io/serverlessworkflow/api/ApiTest.java @@ -23,7 +23,6 @@ import io.serverlessworkflow.api.types.Task; import io.serverlessworkflow.api.types.Workflow; import java.io.IOException; -import java.util.Optional; import org.junit.jupiter.api.Test; public class ApiTest { @@ -35,12 +34,12 @@ 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(); - Optional callTask = task.getCallTask(); - assertThat(callTask).isPresent(); - assertThat(task.getDoTask()).isEmpty(); - Optional httpCall = callTask.flatMap(CallTask::getCallHTTP); - assertThat(httpCall).isPresent(); - assertThat(callTask.flatMap(CallTask::getCallAsyncAPI)).isEmpty(); - assertThat(httpCall.get().getWith().getMethod()).isEqualTo("get"); + 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 467a2b5f..d4bcac84 100644 --- a/custom-generator/src/main/java/io/serverlessworkflow/generator/AllAnyOneOfSchemaRule.java +++ b/custom-generator/src/main/java/io/serverlessworkflow/generator/AllAnyOneOfSchemaRule.java @@ -125,7 +125,7 @@ private JDefinedClass createUnionClass( private void wrapIt(JDefinedClass definedClass, JType unionType) { JFieldVar instanceField = - GeneratorUtils.addOptionalGetter( + GeneratorUtils.addGetter( definedClass, unionType, ruleFactory.getNameHelper(), unionType.name()); JMethod constructor = definedClass.constructor(JMod.PUBLIC); constructor 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 92db2612..d6736159 100644 --- a/custom-generator/src/main/java/io/serverlessworkflow/generator/GeneratorUtils.java +++ b/custom-generator/src/main/java/io/serverlessworkflow/generator/GeneratorUtils.java @@ -15,13 +15,11 @@ */ package io.serverlessworkflow.generator; -import com.sun.codemodel.JClass; import com.sun.codemodel.JDefinedClass; import com.sun.codemodel.JFieldVar; import com.sun.codemodel.JMethod; import com.sun.codemodel.JMod; import com.sun.codemodel.JType; -import java.util.Optional; import org.jsonschema2pojo.util.NameHelper; public class GeneratorUtils { @@ -36,19 +34,5 @@ public static JFieldVar addGetter( return instanceField; } - public static JFieldVar addOptionalGetter( - JDefinedClass definedClass, JType type, NameHelper nameHelper, String name) { - JFieldVar instanceField = - definedClass.field(JMod.PRIVATE, type, nameHelper.getPropertyName(name, null)); - JClass optionalRef = definedClass.owner().ref(Optional.class).narrow(type); - JMethod method = - definedClass.method(JMod.PUBLIC, optionalRef, nameHelper.getGetterName(name, type, null)); - method - .body() - ._return( - definedClass.owner().ref(Optional.class).staticInvoke("ofNullable").arg(instanceField)); - return instanceField; - } - private GeneratorUtils() {} } diff --git a/pom.xml b/pom.xml index fabfff08..6635b583 100644 --- a/pom.xml +++ b/pom.xml @@ -114,11 +114,6 @@ jackson-core ${version.com.fasterxml.jackson} - - com.fasterxml.jackson.datatype - jackson-datatype-jdk8 - ${version.com.fasterxml.jackson} - com.fasterxml.jackson.core jackson-databind