Skip to content

Commit 4b128f4

Browse files
[java][microprofile] Support useSealedOneOfInterfaces (#24267)
When useSealedOneOfInterfaces=true, render the generated oneOf interface as a sealed interface and its subtypes as final classes in the microprofile library (Jackson serialization), matching the existing WebClient/RestClient behaviour of the option. - microprofile pojo.mustache: add the shared {{>sealed}}/{{>permits}} partials to the class declaration so permitted children become final (a sealed interface requires its permitted subtypes to be final/sealed/non-sealed). - JavaClientCodegen: force Java 17 for the microprofile library when useSealedOneOfInterfaces is set (sealed types require Java 17); CliOption description updated to include microprofile. - pom_3.0.mustache: emit java.version 17 when java17 is set. - Test JavaClientCodegenTest#sealedOneOfInterfaceMicroprofileJackson. - New microprofile-oneof-sealed sample (Java 17), registered in the samples-java-client-jdk17.yaml workflow. Default output is unchanged; the partials are gated on the flag.
1 parent fa7ef56 commit 4b128f4

36 files changed

Lines changed: 1617 additions & 5 deletions

File tree

‎.github/workflows/samples-java-client-jdk17.yaml‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ on:
1919
- samples/client/others/java/restclient-useAbstractionForFiles/**
2020
- samples/client/petstore/java/jersey3-oneOf/**
2121
- samples/client/petstore/java/jersey3-jackson3/**
22+
- samples/client/petstore/java/microprofile-oneof-sealed/**
2223
pull_request:
2324
paths:
2425
- samples/client/petstore/java/resttemplate-jakarta/**
@@ -37,6 +38,7 @@ on:
3738
- samples/client/others/java/restclient-useAbstractionForFiles/**
3839
- samples/client/petstore/java/jersey3-oneOf/**
3940
- samples/client/petstore/java/jersey3-jackson3/**
41+
- samples/client/petstore/java/microprofile-oneof-sealed/**
4042
jobs:
4143
build:
4244
name: Build Java Client JDK17
@@ -70,6 +72,7 @@ jobs:
7072
- samples/client/others/java/restclient-useAbstractionForFiles
7173
- samples/client/petstore/java/jersey3-oneOf
7274
- samples/client/petstore/java/jersey3-jackson3
75+
- samples/client/petstore/java/microprofile-oneof-sealed
7376
steps:
7477
- uses: actions/checkout@v7
7578
- uses: actions/setup-java@v5
@@ -108,4 +111,6 @@ jobs:
108111

109112
- name: Build
110113
working-directory: ${{ matrix.sample }}
114+
# the microprofile library does not generate a Gradle build; skip samples without a wrapper
115+
if: ${{ hashFiles(format('{0}/gradlew', matrix.sample)) != '' }}
111116
run: /bin/sh gradlew build -x test --no-daemon
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
generatorName: java
2+
outputDir: samples/client/petstore/java/microprofile-oneof-sealed
3+
library: microprofile
4+
inputSpec: modules/openapi-generator/src/test/resources/3_0/java/oneof_interface_petstore.yaml
5+
templateDir: modules/openapi-generator/src/main/resources/Java
6+
additionalProperties:
7+
serializationLibrary: jackson
8+
artifactId: microprofile-oneof-sealed
9+
useOneOfInterfaces: "true"
10+
useSealedOneOfInterfaces: "true"
11+
microprofileRestClientVersion: "3.0"
12+
hideGenerationTimestamp: true

‎docs/generators/java-microprofile.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
108108
|useRuntimeException|Use RuntimeException instead of Exception. Only jersey2, jersey3, okhttp-gson, vertx, microprofile support this option.| |false|
109109
|useRxJava2|Whether to use the RxJava2 adapter with the retrofit2 library. IMPORTANT: This option has been deprecated.| |false|
110110
|useRxJava3|Whether to use the RxJava3 adapter with the retrofit2 library. IMPORTANT: This option has been deprecated.| |false|
111-
|useSealedOneOfInterfaces|Generate the oneOf interfaces as sealed interfaces. Only supported for WebClient and RestClient.| |false|
111+
|useSealedOneOfInterfaces|Generate the oneOf interfaces as sealed interfaces. Only supported for WebClient, RestClient and Microprofile (with Jackson).| |false|
112112
|useSingleRequestParameter|Setting this property to "true" will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter. ONLY native, jersey2, jersey3, okhttp-gson, microprofile, Spring RestClient, Spring WebClient support this option. Setting this property to "static" does the same as "true", but also makes the generated arguments class static with single parameter instantiation.| |false|
113113
|useSpringBoot4|Generate code and provide dependencies for use with Spring Boot 4.x.| |false|
114114
|useUnaryInterceptor|If true it will generate ResponseInterceptors using a UnaryOperator. This can be usefull for manipulating the request before it gets passed, for example doing your own decryption| |false|

‎docs/generators/java.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
108108
|useRuntimeException|Use RuntimeException instead of Exception. Only jersey2, jersey3, okhttp-gson, vertx, microprofile support this option.| |false|
109109
|useRxJava2|Whether to use the RxJava2 adapter with the retrofit2 library. IMPORTANT: This option has been deprecated.| |false|
110110
|useRxJava3|Whether to use the RxJava3 adapter with the retrofit2 library. IMPORTANT: This option has been deprecated.| |false|
111-
|useSealedOneOfInterfaces|Generate the oneOf interfaces as sealed interfaces. Only supported for WebClient and RestClient.| |false|
111+
|useSealedOneOfInterfaces|Generate the oneOf interfaces as sealed interfaces. Only supported for WebClient, RestClient and Microprofile (with Jackson).| |false|
112112
|useSingleRequestParameter|Setting this property to "true" will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter. ONLY native, jersey2, jersey3, okhttp-gson, microprofile, Spring RestClient, Spring WebClient support this option. Setting this property to "static" does the same as "true", but also makes the generated arguments class static with single parameter instantiation.| |false|
113113
|useSpringBoot4|Generate code and provide dependencies for use with Spring Boot 4.x.| |false|
114114
|useUnaryInterceptor|If true it will generate ResponseInterceptors using a UnaryOperator. This can be usefull for manipulating the request before it gets passed, for example doing your own decryption| |false|

‎modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaClientCodegen.java‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ public JavaClientCodegen() {
282282
cliOptions.add(CliOption.newBoolean(FAIL_ON_UNKNOWN_PROPERTIES, "Fail Jackson de-serialization on unknown properties", this.failOnUnknownProperties));
283283
cliOptions.add(CliOption.newBoolean(USE_JACKSON_3, "Use Jackson 3 instead of Jackson 2. Supported for 'native', 'apache-httpclient', and 'jersey3' libraries (requires Java 17+) and for Spring 'resttemplate', 'webclient', and 'restclient' libraries (require useSpringBoot4=true).", this.useJackson3));
284284
cliOptions.add(CliOption.newBoolean(SUPPORT_VERTX_FUTURE, "Also generate api methods that return a vertx Future instead of taking a callback. Only `vertx` supports this option. Requires vertx 4 or greater.", this.supportVertxFuture));
285-
cliOptions.add(CliOption.newBoolean(USE_SEALED_ONE_OF_INTERFACES, "Generate the oneOf interfaces as sealed interfaces. Only supported for WebClient and RestClient.", this.useSealedOneOfInterfaces));
285+
cliOptions.add(CliOption.newBoolean(USE_SEALED_ONE_OF_INTERFACES, "Generate the oneOf interfaces as sealed interfaces. Only supported for WebClient, RestClient and Microprofile (with Jackson).", this.useSealedOneOfInterfaces));
286286
cliOptions.add(CliOption.newBoolean(USE_UNARY_INTERCEPTOR, "If true it will generate ResponseInterceptors using a UnaryOperator. This can be usefull for manipulating the request before it gets passed, for example doing your own decryption", this.useUnaryInterceptor));
287287
cliOptions.add(CliOption.newBoolean(USE_JSPECIFY, "Use Jspecify for null checks. Only supported for " + JSPECIFY_SUPPORTED_LIBRARIES, useJspecify));
288288
cliOptions.add(CliOption.newBoolean(USE_DEDUCTION_FOR_ONE_OF_INTERFACES, USE_DEDUCTION_FOR_ONE_OF_INTERFACES_DESC, useDeductionForOneOfInterfaces));
@@ -442,6 +442,10 @@ public void processOpts() {
442442
writePropertyBack(JAVA_17, true);
443443
}
444444

445+
if (libMicroprofile && useSealedOneOfInterfaces) {
446+
writePropertyBack(JAVA_17, true);
447+
}
448+
445449
if (!useRxJava && !useRxJava2 && !useRxJava3) {
446450
additionalProperties.put(DO_NOT_USE_RX, true);
447451
}

‎modules/openapi-generator/src/main/resources/Java/libraries/microprofile/pojo.mustache‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
{{#vendorExtensions.x-class-extra-annotation}}
2828
{{{.}}}
2929
{{/vendorExtensions.x-class-extra-annotation}}
30-
public class {{classname}} {{#parent}}extends {{{.}}}{{/parent}}{{#vendorExtensions.x-implements}}{{#-first}} implements {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{/vendorExtensions.x-implements}} {
30+
public {{>sealed}}class {{classname}} {{#parent}}extends {{{.}}}{{/parent}}{{#vendorExtensions.x-implements}}{{#-first}} implements {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{/vendorExtensions.x-implements}} {{>permits}}{
3131
{{#vars}}{{#isEnum}}{{^isContainer}}
3232
{{>enumClass}}{{/isContainer}}{{#isContainer}}{{#mostInnerItems}}
3333
{{>enumClass}}{{/mostInnerItems}}{{/isContainer}}{{/isEnum}}

‎modules/openapi-generator/src/main/resources/Java/libraries/microprofile/pom_3.0.mustache‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@
209209
</repository>
210210
</repositories>
211211
<properties>
212-
<java.version>11</java.version>
212+
<java.version>{{#java17}}17{{/java17}}{{^java17}}11{{/java17}}</java.version>
213213
<maven.compiler.source>${java.version}</maven.compiler.source>
214214
<maven.compiler.target>${java.version}</maven.compiler.target>
215215
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

‎modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4219,6 +4219,33 @@ public void oneOfInterfaceMicroprofileJackson() {
42194219
assertFileNotContains(model.resolve("CatRequest.java"), "public final class");
42204220
}
42214221

4222+
@Test
4223+
public void sealedOneOfInterfaceMicroprofileJackson() {
4224+
final Path output = newTempFolder();
4225+
final CodegenConfigurator configurator = new CodegenConfigurator()
4226+
.setGeneratorName(JAVA_GENERATOR)
4227+
.setLibrary(MICROPROFILE)
4228+
.setAdditionalProperties(Map.of(
4229+
USE_ONE_OF_INTERFACES, "true",
4230+
USE_SEALED_ONE_OF_INTERFACES, "true",
4231+
CodegenConstants.SERIALIZATION_LIBRARY, SERIALIZATION_LIBRARY_JACKSON,
4232+
JavaClientCodegen.MICROPROFILE_REST_CLIENT_VERSION, "3.0"
4233+
))
4234+
.setInputSpec("src/test/resources/3_0/java/oneof_interface_petstore.yaml")
4235+
.setOutputDir(output.toString().replace("\\", "/"));
4236+
4237+
new DefaultGenerator().opts(configurator.toClientOptInput()).generate();
4238+
4239+
final Path model = output.resolve("src/main/java/org/openapitools/client/model");
4240+
assertFileContains(model.resolve("PetRequest.java"), "public sealed interface PetRequest permits CatRequest, DogRequest {");
4241+
assertFileContains(model.resolve("CatRequest.java"), "public final class CatRequest");
4242+
assertFileContains(model.resolve("CatRequest.java"), "implements PetRequest");
4243+
assertFileContains(model.resolve("DogRequest.java"), "public final class DogRequest");
4244+
// sealed requires Java 17 in the generated pom
4245+
assertFileContains(output.resolve("pom.xml"), "<java.version>17</java.version>");
4246+
assertFileNotContains(output.resolve("pom.xml"), "<java.version>11</java.version>");
4247+
}
4248+
42224249
@DataProvider(name = "sealedInterfaceScenarios")
42234250
public static Object[][] sealedInterfaceScenarios() {
42244251
return new Object[][]{
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# OpenAPI Generator Ignore
2+
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
3+
4+
# Use this file to prevent files from being overwritten by the generator.
5+
# The patterns follow closely to .gitignore or .dockerignore.
6+
7+
# As an example, the C# client generator defines ApiClient.cs.
8+
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
9+
#ApiClient.cs
10+
11+
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
12+
#foo/*/qux
13+
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
14+
15+
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
16+
#foo/**/qux
17+
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
18+
19+
# You can also negate patterns with an exclamation (!).
20+
# For example, you can ignore all files in a docs folder with the file extension .md:
21+
#docs/*.md
22+
# Then explicitly reverse the ignore rule for a single file:
23+
#!docs/README.md
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
README.md
2+
docs/CatRequest.md
3+
docs/DefaultApi.md
4+
docs/DogRequest.md
5+
docs/PetBase.md
6+
docs/PetRequest.md
7+
docs/PetType.md
8+
pom.xml
9+
src/main/java/org/openapitools/client/RFC3339DateFormat.java
10+
src/main/java/org/openapitools/client/RFC3339InstantDeserializer.java
11+
src/main/java/org/openapitools/client/RFC3339JavaTimeModule.java
12+
src/main/java/org/openapitools/client/api/ApiException.java
13+
src/main/java/org/openapitools/client/api/ApiExceptionMapper.java
14+
src/main/java/org/openapitools/client/api/DefaultApi.java
15+
src/main/java/org/openapitools/client/model/CatRequest.java
16+
src/main/java/org/openapitools/client/model/DogRequest.java
17+
src/main/java/org/openapitools/client/model/PetBase.java
18+
src/main/java/org/openapitools/client/model/PetRequest.java
19+
src/main/java/org/openapitools/client/model/PetType.java

0 commit comments

Comments
 (0)