Skip to content

Commit 762322b

Browse files
committed
[Fix #1351] Generating native file
Signed-off-by: fjtirado <ftirados@redhat.com>
1 parent b6c7557 commit 762322b

6 files changed

Lines changed: 171 additions & 25 deletions

File tree

api/pom.xml

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
<name>Serverless Workflow :: API</name>
1212
<packaging>jar</packaging>
1313
<description>Java SDK for Serverless Workflow Specification</description>
14+
<properties>
15+
<version.build-helper-maven-plugin>3.6.1</version.build-helper-maven-plugin>
16+
</properties>
1417

1518
<dependencies>
1619
<dependency>
@@ -75,9 +78,8 @@
7578
<scope>test</scope>
7679
</dependency>
7780
</dependencies>
78-
<build>
81+
<build>
7982
<plugins>
80-
8183
<plugin>
8284
<groupId>io.serverlessworkflow</groupId>
8385
<artifactId>serverless-workflow-jackson-generator</artifactId>
@@ -100,7 +102,7 @@
100102
<!-- a hint for IDE's to add the java sources to the classpath -->
101103
<groupId>org.codehaus.mojo</groupId>
102104
<artifactId>build-helper-maven-plugin</artifactId>
103-
<version>3.6.1</version>
105+
<version>${version.build-helper-maven-plugin}</version>
104106
<executions>
105107
<execution>
106108
<id>add-mixin</id>
@@ -116,6 +118,27 @@
116118
</execution>
117119
</executions>
118120
</plugin>
121+
<plugin>
122+
<groupId>org.codehaus.mojo</groupId>
123+
<artifactId>build-helper-maven-plugin</artifactId>
124+
<version>${version.build-helper-maven-plugin}</version>
125+
<executions>
126+
<execution>
127+
<id>add-resource</id>
128+
<phase>generate-sources</phase>
129+
<goals>
130+
<goal>add-resource</goal>
131+
</goals>
132+
<configuration>
133+
<resources>
134+
<resource>
135+
<directory>${project.build.directory}/generated-resources</directory>
136+
</resource>
137+
</resources>
138+
</configuration>
139+
</execution>
140+
</executions>
141+
</plugin>
119142
</plugins>
120143
</build>
121-
</project>
144+
</project>
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
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.graalvm;
17+
18+
import com.fasterxml.jackson.databind.JsonNode;
19+
import com.fasterxml.jackson.databind.ObjectMapper;
20+
import com.fasterxml.jackson.databind.node.ArrayNode;
21+
import com.sun.codemodel.JDefinedClass;
22+
import java.io.IOException;
23+
import java.io.Writer;
24+
import java.nio.file.Files;
25+
import java.nio.file.Path;
26+
import java.util.stream.Stream;
27+
28+
public class ReflectNativeFileHandler {
29+
30+
private final String groupId;
31+
private final String artifactId;
32+
private final ArrayNode rootObject;
33+
private static final ObjectMapper objectMapper = new ObjectMapper();
34+
35+
public ReflectNativeFileHandler(String groupId, String artifactId) {
36+
this.groupId = groupId;
37+
this.artifactId = artifactId;
38+
this.rootObject = objectMapper.createArrayNode();
39+
}
40+
41+
public ReflectNativeFileHandler addClasses(Stream<String> classNames) {
42+
classNames.forEach(this::addClass);
43+
return this;
44+
}
45+
46+
public ReflectNativeFileHandler addClasses(Iterable<String> classNames) {
47+
classNames.forEach(this::addClass);
48+
return this;
49+
}
50+
51+
public ReflectNativeFileHandler addClass(String refClassName) {
52+
rootObject.add(buildObjectFromClass(refClassName));
53+
return this;
54+
}
55+
56+
public ReflectNativeFileHandler addClass(JDefinedClass definedClass) {
57+
addClass(definedClass.fullName());
58+
return this;
59+
}
60+
61+
private static JsonNode buildObjectFromClass(String refClassName) {
62+
return objectMapper
63+
.createObjectNode()
64+
.put("name", refClassName)
65+
.put("queryAllPublicConstructors", true)
66+
.put("queryAllDeclaredConstructors", true)
67+
.put("queryAllPublicMethods", true)
68+
.put("queryAllDeclaredMethods", true)
69+
.put("allPublicConstructors", true)
70+
.put("allDeclaredConstructors", true)
71+
.put("allPublicMethods", true)
72+
.put("allDeclaredMethods", true)
73+
.put("allPublicFields", true)
74+
.put("allDeclaredFields", true)
75+
.put("allPublicClasses", true)
76+
.put("allDeclaredClasses", true);
77+
}
78+
79+
public void generate(Path rootPath) throws IOException {
80+
try (Writer out =
81+
Files.newBufferedWriter(
82+
Files.createDirectories(
83+
rootPath
84+
.resolve("META-INF")
85+
.resolve("native-image")
86+
.resolve(groupId)
87+
.resolve(artifactId))
88+
.resolve("reflect-config.json"))) {
89+
objectMapper.writeValue(out, rootObject);
90+
}
91+
}
92+
}

generators/jackson/src/main/java/io/serverlessworkflow/generator/jackson/GeneratorUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ public static void fillDeserializer(
8383
private static JDefinedClass createClass(
8484
JPackage jPackage, JClass relatedClass, Class<?> serializerClass, String suffix)
8585
throws JClassAlreadyExistsException {
86-
JDefinedClass definedClass = jPackage._class(JMod.NONE, relatedClass.name() + suffix);
86+
JDefinedClass definedClass = jPackage._class(JMod.PUBLIC, relatedClass.name() + suffix);
8787
definedClass._extends(definedClass.owner().ref(serializerClass).narrow(relatedClass));
8888
return definedClass;
8989
}

generators/jackson/src/main/java/io/serverlessworkflow/generator/jackson/JacksonMixInPojo.java

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import io.serverlessworkflow.annotations.Item;
5151
import io.serverlessworkflow.annotations.ItemKey;
5252
import io.serverlessworkflow.annotations.ItemValue;
53+
import io.serverlessworkflow.generator.graalvm.ReflectNativeFileHandler;
5354
import java.io.File;
5455
import java.io.IOException;
5556
import java.io.PrintStream;
@@ -78,6 +79,17 @@ public class JacksonMixInPojo extends AbstractMojo {
7879
defaultValue = "${project.build.directory}/generated-sources/jacksonmixinpojo")
7980
private File outputDirectory;
8081

82+
@Parameter(defaultValue = "${project.groupId}", readonly = true, required = true)
83+
private String groupId;
84+
85+
@Parameter(defaultValue = "${project.artifactId}", readonly = true, required = true)
86+
private String artifactId;
87+
88+
@Parameter(
89+
property = "jacksonmixinpojo.outputResources",
90+
defaultValue = "${project.build.directory}/generated-resources")
91+
private File outputResources;
92+
8193
@Parameter(property = "jacksonmixinpojo.srcPackage")
8294
private String srcPackage;
8395

@@ -90,6 +102,7 @@ public class JacksonMixInPojo extends AbstractMojo {
90102
private JCodeModel codeModel;
91103
private JPackage rootPackage;
92104
private JMethod setupMethod;
105+
private ReflectNativeFileHandler nativeHandler;
93106

94107
@FunctionalInterface
95108
interface AnnotationProcessor {
@@ -107,12 +120,14 @@ public void execute() throws MojoExecutionException, MojoFailureException {
107120
.acceptPackages(srcPackage)
108121
.scan()) {
109122
codeModel = new JCodeModel();
123+
nativeHandler = new ReflectNativeFileHandler(groupId, artifactId);
110124
rootPackage = codeModel._package(targetPackage);
111125
setupMethod =
112126
rootPackage
113127
._class("JacksonMixInModule")
114128
._extends(SimpleModule.class)
115129
.method(JMod.PUBLIC, codeModel.VOID, SETUP_METHOD);
130+
nativeHandler.addClasses(result.getAllClasses().stream().map(c -> c.getName()));
116131
processAnnotatedClasses(result, ExclusiveUnion.class, this::buildExclusiveUnionMixIn);
117132
processAnnotatedClasses(result, InclusiveUnion.class, this::buildInclusiveUnionMixIn);
118133
processAnnotatedClasses(result, AdditionalProperties.class, this::buildAdditionalPropsMixIn);
@@ -124,6 +139,8 @@ public void execute() throws MojoExecutionException, MojoFailureException {
124139
.arg(setupMethod.param(SetupContext.class, "context"));
125140
Files.createDirectories(outputDirectory.toPath());
126141
codeModel.build(outputDirectory, (PrintStream) null);
142+
143+
nativeHandler.generate(outputResources.toPath());
127144
} catch (JClassAlreadyExistsException | IOException e) {
128145
getLog().error(e);
129146
}
@@ -179,31 +196,28 @@ private void buildItemMixIn(ClassInfo classInfo, JDefinedClass mixClass)
179196
classInfo.getMethodInfo().filter(m -> m.hasAnnotation(ItemKey.class)).get(0);
180197
MethodInfo valueMethod =
181198
classInfo.getMethodInfo().filter(m -> m.hasAnnotation(ItemValue.class)).get(0);
182-
mixClass
183-
.annotate(JsonSerialize.class)
184-
.param(
185-
"using",
186-
GeneratorUtils.generateSerializer(
187-
rootPackage, relClass, keyMethod.getName(), valueMethod.getName()));
188-
mixClass
189-
.annotate(JsonDeserialize.class)
190-
.param(
191-
"using",
192-
GeneratorUtils.generateDeserializer(rootPackage, relClass, getReturnType(valueMethod)));
199+
JDefinedClass serializerClass =
200+
GeneratorUtils.generateSerializer(
201+
rootPackage, relClass, keyMethod.getName(), valueMethod.getName());
202+
nativeHandler.addClass(serializerClass);
203+
mixClass.annotate(JsonSerialize.class).param("using", serializerClass);
204+
JDefinedClass deserializerClass =
205+
GeneratorUtils.generateDeserializer(rootPackage, relClass, getReturnType(valueMethod));
206+
nativeHandler.addClass(deserializerClass);
207+
mixClass.annotate(JsonDeserialize.class).param("using", deserializerClass);
193208
}
194209

195210
private void buildExclusiveUnionMixIn(ClassInfo unionClassInfo, JDefinedClass unionMixClass)
196211
throws JClassAlreadyExistsException {
197212
JClass unionClass = codeModel.ref(unionClassInfo.getName());
198-
unionMixClass
199-
.annotate(JsonSerialize.class)
200-
.param("using", GeneratorUtils.generateSerializer(rootPackage, unionClass));
201-
unionMixClass
202-
.annotate(JsonDeserialize.class)
203-
.param(
204-
"using",
205-
GeneratorUtils.generateDeserializer(
206-
rootPackage, unionClass, getUnionClasses(ExclusiveUnion.class, unionClassInfo)));
213+
JDefinedClass serializerClass = GeneratorUtils.generateSerializer(rootPackage, unionClass);
214+
unionMixClass.annotate(JsonSerialize.class).param("using", serializerClass);
215+
nativeHandler.addClass(serializerClass);
216+
JDefinedClass deserializerClass =
217+
GeneratorUtils.generateDeserializer(
218+
rootPackage, unionClass, getUnionClasses(ExclusiveUnion.class, unionClassInfo));
219+
unionMixClass.annotate(JsonDeserialize.class).param("using", deserializerClass);
220+
nativeHandler.addClass(deserializerClass);
207221
}
208222

209223
private void buildInclusiveUnionMixIn(ClassInfo unionClassInfo, JDefinedClass unionMixClass)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[
2+
{"name":"io.serverlessworkflow.impl.WorkflowError","queryAllPublicConstructors":true,"queryAllDeclaredConstructors":true,"queryAllPublicMethods":true,"queryAllDeclaredMethods":true,"allPublicConstructors":true,"allDeclaredConstructors":true,"allPublicMethods":true,"allDeclaredMethods":true,"allPublicFields":true,"allDeclaredFields":true,"allPublicClasses":true,"allDeclaredClasses":true}
3+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[
2+
{"name":"io.serverlessworkflow.impl.executors.openapi.UnifiedOpenAPI","queryAllPublicConstructors":true,"queryAllDeclaredConstructors":true,"queryAllPublicMethods":true,"queryAllDeclaredMethods":true,"allPublicConstructors":true,"allDeclaredConstructors":true,"allPublicMethods":true,"allDeclaredMethods":true,"allPublicFields":true,"allDeclaredFields":true,"allPublicClasses":true,"allDeclaredClasses":true},
3+
{"name":"io.serverlessworkflow.impl.executors.openapi.UnifiedOpenAPI$Components","queryAllPublicConstructors":true,"queryAllDeclaredConstructors":true,"queryAllPublicMethods":true,"queryAllDeclaredMethods":true,"allPublicConstructors":true,"allDeclaredConstructors":true,"allPublicMethods":true,"allDeclaredMethods":true,"allPublicFields":true,"allDeclaredFields":true,"allPublicClasses":true,"allDeclaredClasses":true},
4+
{"name":"io.serverlessworkflow.impl.executors.openapi.UnifiedOpenAPI$Content","queryAllPublicConstructors":true,"queryAllDeclaredConstructors":true,"queryAllPublicMethods":true,"queryAllDeclaredMethods":true,"allPublicConstructors":true,"allDeclaredConstructors":true,"allPublicMethods":true,"allDeclaredMethods":true,"allPublicFields":true,"allDeclaredFields":true,"allPublicClasses":true,"allDeclaredClasses":true},
5+
{"name":"io.serverlessworkflow.impl.executors.openapi.UnifiedOpenAPI$HttpOperation","queryAllPublicConstructors":true,"queryAllDeclaredConstructors":true,"queryAllPublicMethods":true,"queryAllDeclaredMethods":true,"allPublicConstructors":true,"allDeclaredConstructors":true,"allPublicMethods":true,"allDeclaredMethods":true,"allPublicFields":true,"allDeclaredFields":true,"allPublicClasses":true,"allDeclaredClasses":true},
6+
{"name":"io.serverlessworkflow.impl.executors.openapi.UnifiedOpenAPI$MediaType","queryAllPublicConstructors":true,"queryAllDeclaredConstructors":true,"queryAllPublicMethods":true,"queryAllDeclaredMethods":true,"allPublicConstructors":true,"allDeclaredConstructors":true,"allPublicMethods":true,"allDeclaredMethods":true,"allPublicFields":true,"allDeclaredFields":true,"allPublicClasses":true,"allDeclaredClasses":true},
7+
{"name":"io.serverlessworkflow.impl.executors.openapi.UnifiedOpenAPI$Operation","queryAllPublicConstructors":true,"queryAllDeclaredConstructors":true,"queryAllPublicMethods":true,"queryAllDeclaredMethods":true,"allPublicConstructors":true,"allDeclaredConstructors":true,"allPublicMethods":true,"allDeclaredMethods":true,"allPublicFields":true,"allDeclaredFields":true,"allPublicClasses":true,"allDeclaredClasses":true},
8+
{"name":"io.serverlessworkflow.impl.executors.openapi.UnifiedOpenAPI$Parameter","queryAllPublicConstructors":true,"queryAllDeclaredConstructors":true,"queryAllPublicMethods":true,"queryAllDeclaredMethods":true,"allPublicConstructors":true,"allDeclaredConstructors":true,"allPublicMethods":true,"allDeclaredMethods":true,"allPublicFields":true,"allDeclaredFields":true,"allPublicClasses":true,"allDeclaredClasses":true},
9+
{"name":"io.serverlessworkflow.impl.executors.openapi.UnifiedOpenAPI$PathItem","queryAllPublicConstructors":true,"queryAllDeclaredConstructors":true,"queryAllPublicMethods":true,"queryAllDeclaredMethods":true,"allPublicConstructors":true,"allDeclaredConstructors":true,"allPublicMethods":true,"allDeclaredMethods":true,"allPublicFields":true,"allDeclaredFields":true,"allPublicClasses":true,"allDeclaredClasses":true},
10+
{"name":"io.serverlessworkflow.impl.executors.openapi.UnifiedOpenAPI$RequestBody","queryAllPublicConstructors":true,"queryAllDeclaredConstructors":true,"queryAllPublicMethods":true,"queryAllDeclaredMethods":true,"allPublicConstructors":true,"allDeclaredConstructors":true,"allPublicMethods":true,"allDeclaredMethods":true,"allPublicFields":true,"allDeclaredFields":true,"allPublicClasses":true,"allDeclaredClasses":true},
11+
{"name":"io.serverlessworkflow.impl.executors.openapi.UnifiedOpenAPI$Schema","queryAllPublicConstructors":true,"queryAllDeclaredConstructors":true,"queryAllPublicMethods":true,"queryAllDeclaredMethods":true,"allPublicConstructors":true,"allDeclaredConstructors":true,"allPublicMethods":true,"allDeclaredMethods":true,"allPublicFields":true,"allDeclaredFields":true,"allPublicClasses":true,"allDeclaredClasses":true},
12+
{"name":"io.serverlessworkflow.impl.executors.openapi.UnifiedOpenAPI$Server","queryAllPublicConstructors":true,"queryAllDeclaredConstructors":true,"queryAllPublicMethods":true,"queryAllDeclaredMethods":true,"allPublicConstructors":true,"allDeclaredConstructors":true,"allPublicMethods":true,"allDeclaredMethods":true,"allPublicFields":true,"allDeclaredFields":true,"allPublicClasses":true,"allDeclaredClasses":true},
13+
{"name":"io.serverlessworkflow.impl.executors.openapi.UnifiedOpenAPI$SwaggerVersion","queryAllPublicConstructors":true,"queryAllDeclaredConstructors":true,"queryAllPublicMethods":true,"queryAllDeclaredMethods":true,"allPublicConstructors":true,"allDeclaredConstructors":true,"allPublicMethods":true,"allDeclaredMethods":true,"allPublicFields":true,"allDeclaredFields":true,"allPublicClasses":true,"allDeclaredClasses":true}
14+
]

0 commit comments

Comments
 (0)