Skip to content

Commit

Permalink
[Fix #380] Change item API
Browse files Browse the repository at this point in the history
Signed-off-by: Francisco Javier Tirado Sarti <[email protected]>
  • Loading branch information
fjtirado committed Jun 26, 2024
1 parent fd4b7c4 commit 77746af
Show file tree
Hide file tree
Showing 15 changed files with 255 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class CallTaskDeserializer extends JsonDeserializer<CallTask> {

@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));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ class CallTaskSerializer extends JsonSerializer<CallTask> {
@Override
public void serialize(CallTask value, JsonGenerator gen, SerializerProvider serializers)
throws IOException {
SerializeHelper.serialize(gen, value);
SerializeHelper.serializeOneOf(gen, value);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

public class DeserializeHelper {

public static <T> T deserialize(
public static <T> T deserializeOneOf(
JsonParser p, Class<T> targetClass, Collection<Class<?>> unionTypes) throws IOException {
TreeNode node = p.readValueAsTree();
JsonProcessingException ex = new JsonMappingException("Problem deserializing " + targetClass);
Expand All @@ -38,4 +38,17 @@ public static <T> T deserialize(
}
throw ex;
}

public static <T> T deserializeItem(JsonParser p, Class<T> 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);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand All @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
@@ -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<Switch> {

@Override
public Switch deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
return DeserializeHelper.deserializeItem(p, Switch.class, SwitchProperty.class);
}
}
33 changes: 33 additions & 0 deletions api/src/main/java/io/serverlessworkflow/api/SwitchSerializer.java
Original file line number Diff line number Diff line change
@@ -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<Switch> {

@Override
public void serialize(Switch value, JsonGenerator gen, SerializerProvider serializers)
throws IOException {
gen.writeStartObject();
gen.writeObjectField(value.getName(), value.getSwitchProperty());
gen.writeEndObject();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class TaskDeserializer extends JsonDeserializer<Task> {

@Override
public Task deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
return DeserializeHelper.deserialize(
return DeserializeHelper.deserializeOneOf(
p,
Task.class,
List.of(
Expand Down
Original file line number Diff line number Diff line change
@@ -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<TaskItem> {

@Override
public TaskItem deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
return DeserializeHelper.deserializeItem(p, TaskItem.class, Task.class);
}
}
Original file line number Diff line number Diff line change
@@ -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<TaskItem> {

@Override
public void serialize(TaskItem value, JsonGenerator gen, SerializerProvider serializers)
throws IOException {
gen.writeStartObject();
gen.writeObjectField(value.getName(), value.getTask());
gen.writeEndObject();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ class TaskSerializer extends JsonSerializer<Task> {
@Override
public void serialize(Task value, JsonGenerator gen, SerializerProvider serializers)
throws IOException {
SerializeHelper.serialize(gen, value);
SerializeHelper.serializeOneOf(gen, value);
}
}
6 changes: 3 additions & 3 deletions api/src/test/java/io/serverlessworkflow/api/ApiTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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()
Expand Down
Original file line number Diff line number Diff line change
@@ -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() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<JDefinedClass, JDefinedClass> {

public UnevaluatedPropertiesRule(UnreferencedFactory unreferencedFactory) {
super(unreferencedFactory);
private RuleFactory ruleFactory;

public UnevaluatedPropertiesRule(RuleFactory ruleFactory) {
super(ruleFactory);
this.ruleFactory = ruleFactory;
}

public JDefinedClass apply(
Expand All @@ -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;
}
}

0 comments on commit 77746af

Please sign in to comment.