Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Fix #380] Change item API #383

Merged
merged 4 commits into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.SwitchItem;
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(SwitchItem.class, new SwitchItemSerializer());
simpleModule.addDeserializer(SwitchItem.class, new SwitchItemDeserializer());

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.SwitchCase;
import io.serverlessworkflow.api.types.SwitchItem;
import java.io.IOException;

class SwitchItemDeserializer extends JsonDeserializer<SwitchItem> {

@Override
public SwitchItem deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
return DeserializeHelper.deserializeItem(p, SwitchItem.class, SwitchCase.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.SwitchItem;
import java.io.IOException;

class SwitchItemSerializer extends JsonSerializer<SwitchItem> {

@Override
public void serialize(SwitchItem value, JsonGenerator gen, SerializerProvider serializers)
throws IOException {
gen.writeStartObject();
gen.writeObjectField(value.getName(), value.getSwitchCase());
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);
}
}
2 changes: 2 additions & 0 deletions api/src/main/resources/schema/workflow.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -571,8 +571,10 @@ $defs:
type: object
minProperties: 1
maxProperties: 1
title: SwitchItem
additionalProperties:
type: object
title: SwitchCase
properties:
name:
type: string
Expand Down
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;
}
}
Loading