Skip to content

Commit 54446d4

Browse files
committed
[Fix #359] Enhacing deserialization
Signed-off-by: Francisco Javier Tirado Sarti <[email protected]>
1 parent 78a598e commit 54446d4

File tree

9 files changed

+267
-5
lines changed

9 files changed

+267
-5
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Serverless Workflow Java SDK is **not** a workflow runtime implementation but ca
1616

1717
| Latest Releases | Conformance to spec version |
1818
| :---: | :---: |
19-
| [7.0.0.Final](https://github.com/serverlessworkflow/sdk-java/releases/tag/7.0.0.Final) | [v0.10](https://github.com/serverlessworkflow/specification/tree/0.10.x) |
19+
| [7.0.0.Final](https://github.com/serverlessworkflow/sdk-java/releases/tag/7.0.0.Final) | [v1.0.0](https://github.com/serverlessworkflow/specification/tree/1.0.x) |
2020
| [5.0.0.Final](https://github.com/serverlessworkflow/sdk-java/releases/tag/5.0.0.Final) | [v0.8](https://github.com/serverlessworkflow/specification/tree/0.8.x) |
2121
| [4.0.5.Final](https://github.com/serverlessworkflow/sdk-java/releases/tag/4.0.5.Final) | [v0.8](https://github.com/serverlessworkflow/specification/tree/0.8.x) |
2222
| [3.0.0.Final](https://github.com/serverlessworkflow/sdk-java/releases/tag/3.0.0.Final) | [v0.7](https://github.com/serverlessworkflow/specification/tree/0.7.x) |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright 2020-Present The Serverless Workflow Specification Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.serverlessworkflow.api;
17+
18+
import com.fasterxml.jackson.core.JsonParser;
19+
import com.fasterxml.jackson.core.TreeNode;
20+
import java.io.IOException;
21+
import java.io.UncheckedIOException;
22+
import java.util.Collection;
23+
24+
public class DeserializeHelper {
25+
26+
public static <T> T deserialize(
27+
JsonParser p, Class<T> targetClass, Collection<Class<?>> unionTypes) {
28+
try {
29+
TreeNode node = p.readValueAsTree();
30+
RuntimeException ex = new IllegalArgumentException();
31+
for (Class<?> unionType : unionTypes) {
32+
try {
33+
return targetClass
34+
.getConstructor(unionType)
35+
.newInstance(p.getCodec().treeToValue(node, unionType));
36+
} catch (IOException | ReflectiveOperationException io) {
37+
ex.addSuppressed(io);
38+
}
39+
}
40+
throw ex;
41+
} catch (IOException io) {
42+
throw new UncheckedIOException(io);
43+
}
44+
}
45+
}

api/src/main/java/io/serverlessworkflow/api/ObjectMapperFactory.java

+6-2
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@
1515
*/
1616
package io.serverlessworkflow.api;
1717

18-
import com.fasterxml.jackson.databind.DeserializationFeature;
1918
import com.fasterxml.jackson.databind.ObjectMapper;
2019
import com.fasterxml.jackson.databind.SerializationFeature;
20+
import com.fasterxml.jackson.databind.module.SimpleModule;
2121
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
2222
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator.Feature;
23+
import io.serverlessworkflow.api.types.Task;
2324

2425
class ObjectMapperFactory {
2526

@@ -37,11 +38,14 @@ public static final ObjectMapper yamlMapper() {
3738
}
3839

3940
private static ObjectMapper configure(ObjectMapper mapper) {
41+
SimpleModule simpleModule = new SimpleModule();
42+
simpleModule.addDeserializer(Task.class, new TaskDeserializer());
43+
simpleModule.addSerializer(Task.class, new TaskSerializer());
4044
return mapper
4145
.configure(SerializationFeature.INDENT_OUTPUT, true)
4246
.configure(SerializationFeature.WRITE_EMPTY_JSON_ARRAYS, false)
4347
.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false)
44-
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
48+
.registerModule(simpleModule);
4549
}
4650

4751
private ObjectMapperFactory() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright 2020-Present The Serverless Workflow Specification Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.serverlessworkflow.api;
17+
18+
import com.fasterxml.jackson.core.JsonGenerator;
19+
import java.io.IOException;
20+
import java.lang.reflect.Method;
21+
22+
public class SerializeHelper {
23+
public static void serialize(JsonGenerator jgen, Object item) {
24+
try {
25+
for (Method m : item.getClass().getDeclaredMethods()) {
26+
Object value = m.invoke(item);
27+
if (value != null) {
28+
jgen.writeObject(value);
29+
break;
30+
}
31+
}
32+
} catch (ReflectiveOperationException | IOException ex) {
33+
throw new IllegalArgumentException(ex);
34+
}
35+
}
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright 2020-Present The Serverless Workflow Specification Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.serverlessworkflow.api;
17+
18+
import com.fasterxml.jackson.core.JacksonException;
19+
import com.fasterxml.jackson.core.JsonParser;
20+
import com.fasterxml.jackson.databind.DeserializationContext;
21+
import com.fasterxml.jackson.databind.JsonDeserializer;
22+
import io.serverlessworkflow.api.types.CallTask;
23+
import io.serverlessworkflow.api.types.DoTask;
24+
import io.serverlessworkflow.api.types.EmitTask;
25+
import io.serverlessworkflow.api.types.ForTask;
26+
import io.serverlessworkflow.api.types.ForkTask;
27+
import io.serverlessworkflow.api.types.ListenTask;
28+
import io.serverlessworkflow.api.types.RaiseTask;
29+
import io.serverlessworkflow.api.types.RunTask;
30+
import io.serverlessworkflow.api.types.SetTask;
31+
import io.serverlessworkflow.api.types.SwitchTask;
32+
import io.serverlessworkflow.api.types.Task;
33+
import io.serverlessworkflow.api.types.TryTask;
34+
import io.serverlessworkflow.api.types.WaitTask;
35+
import java.io.IOException;
36+
import java.util.List;
37+
38+
public class TaskDeserializer extends JsonDeserializer<Task> {
39+
40+
@Override
41+
public Task deserialize(JsonParser p, DeserializationContext ctxt)
42+
throws IOException, JacksonException {
43+
return DeserializeHelper.deserialize(
44+
p,
45+
Task.class,
46+
List.of(
47+
CallTask.class,
48+
DoTask.class,
49+
SwitchTask.class,
50+
TryTask.class,
51+
RaiseTask.class,
52+
EmitTask.class,
53+
ForkTask.class,
54+
ForTask.class,
55+
ListenTask.class,
56+
SetTask.class,
57+
RunTask.class,
58+
WaitTask.class));
59+
}
60+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright 2020-Present The Serverless Workflow Specification Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.serverlessworkflow.api;
17+
18+
import com.fasterxml.jackson.core.JsonGenerator;
19+
import com.fasterxml.jackson.databind.JsonSerializer;
20+
import com.fasterxml.jackson.databind.SerializerProvider;
21+
import io.serverlessworkflow.api.types.Task;
22+
import java.io.IOException;
23+
24+
public class TaskSerializer extends JsonSerializer<Task> {
25+
26+
@Override
27+
public void serialize(Task value, JsonGenerator gen, SerializerProvider serializers)
28+
throws IOException {
29+
SerializeHelper.serialize(gen, value);
30+
}
31+
}

custom-generator/src/main/java/io/serverlessworkflow/generator/AllAnyOneOfSchemaRule.java

+25-2
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,29 @@
1+
/*
2+
* Copyright 2020-Present The Serverless Workflow Specification Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
116
package io.serverlessworkflow.generator;
217

318
import static org.apache.commons.lang3.StringUtils.*;
419

5-
import com.fasterxml.jackson.annotation.JsonUnwrapped;
620
import com.fasterxml.jackson.databind.JsonNode;
721
import com.fasterxml.jackson.databind.node.ArrayNode;
822
import com.sun.codemodel.JClass;
923
import com.sun.codemodel.JClassAlreadyExistsException;
1024
import com.sun.codemodel.JClassContainer;
1125
import com.sun.codemodel.JDefinedClass;
26+
import com.sun.codemodel.JExpr;
1227
import com.sun.codemodel.JFieldVar;
1328
import com.sun.codemodel.JMethod;
1429
import com.sun.codemodel.JMod;
@@ -93,6 +108,10 @@ private JDefinedClass populateClass(
93108
wrapIt(definedClass, type);
94109
}
95110
});
111+
if (definedClass.constructors().hasNext()
112+
&& definedClass.getConstructor(new JType[0]) == null) {
113+
definedClass.constructor(JMod.PUBLIC);
114+
}
96115
return definedClass;
97116
}
98117

@@ -112,13 +131,17 @@ private void wrapIt(JDefinedClass definedClass, JType unionType) {
112131
JMod.PRIVATE,
113132
unionType,
114133
ruleFactory.getNameHelper().getPropertyName(unionType.name(), null));
115-
instanceField.annotate(JsonUnwrapped.class);
116134
JMethod method =
117135
definedClass.method(
118136
JMod.PUBLIC,
119137
unionType,
120138
ruleFactory.getNameHelper().getGetterName(unionType.name(), unionType, null));
121139
method.body()._return(instanceField);
140+
JMethod constructor = definedClass.constructor(JMod.PUBLIC);
141+
constructor
142+
.body()
143+
.assign(
144+
JExpr._this().ref(instanceField), constructor.param(unionType, instanceField.name()));
122145
}
123146

124147
private void unionType(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright 2020-Present The Serverless Workflow Specification Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.serverlessworkflow.generator;
17+
18+
import com.fasterxml.jackson.databind.JsonNode;
19+
import com.sun.codemodel.JDefinedClass;
20+
import org.jsonschema2pojo.Schema;
21+
import org.jsonschema2pojo.rules.AdditionalPropertiesRule;
22+
import org.jsonschema2pojo.rules.Rule;
23+
24+
public class UnevaluatedPropertiesRule extends AdditionalPropertiesRule
25+
implements Rule<JDefinedClass, JDefinedClass> {
26+
27+
public UnevaluatedPropertiesRule(UnreferencedFactory unreferencedFactory) {
28+
super(unreferencedFactory);
29+
}
30+
31+
public JDefinedClass apply(
32+
String nodeName, JsonNode node, JsonNode parent, JDefinedClass jclass, Schema schema) {
33+
JsonNode unevalutedNode = parent.get("unevaluatedProperties");
34+
if (unevalutedNode != null && unevalutedNode.isBoolean() && unevalutedNode.asBoolean() == false
35+
|| node == null) {
36+
// no additional properties allowed
37+
return jclass;
38+
} else {
39+
return super.apply(nodeName, node, parent, jclass, schema);
40+
}
41+
}
42+
}

custom-generator/src/main/java/io/serverlessworkflow/generator/UnreferencedFactory.java

+21
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,22 @@
1+
/*
2+
* Copyright 2020-Present The Serverless Workflow Specification Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
116
package io.serverlessworkflow.generator;
217

318
import com.sun.codemodel.JClassContainer;
19+
import com.sun.codemodel.JDefinedClass;
420
import com.sun.codemodel.JType;
521
import org.jsonschema2pojo.rules.Rule;
622
import org.jsonschema2pojo.rules.RuleFactory;
@@ -10,4 +26,9 @@ public class UnreferencedFactory extends RuleFactory {
1026
public Rule<JClassContainer, JType> getSchemaRule() {
1127
return new AllAnyOneOfSchemaRule(this);
1228
}
29+
30+
@Override
31+
public Rule<JDefinedClass, JDefinedClass> getAdditionalPropertiesRule() {
32+
return new UnevaluatedPropertiesRule(this);
33+
}
1334
}

0 commit comments

Comments
 (0)