Skip to content

Commit 0e6a2f9

Browse files
committed
feat: add support for Swagger v3 annotations to jaxrs-spec
1 parent 7ce0096 commit 0e6a2f9

10 files changed

Lines changed: 85 additions & 8 deletions

File tree

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ public class JavaJAXRSSpecServerCodegen extends AbstractJavaJAXRSServerCodegen {
4242
public static final String GENERATE_POM = "generatePom";
4343
public static final String USE_SWAGGER_ANNOTATIONS = "useSwaggerAnnotations";
4444
public static final String USE_MICROPROFILE_OPENAPI_ANNOTATIONS = "useMicroProfileOpenAPIAnnotations";
45+
public static final String USE_SWAGGER_V3_ANNOTATIONS = "useSwaggerV3Annotations";
4546
public static final String USE_MUTINY = "useMutiny";
4647
public static final String OPEN_API_SPEC_FILE_LOCATION = "openApiSpecFileLocation";
4748
public static final String GENERATE_JSON_CREATOR = "generateJsonCreator";
@@ -57,6 +58,7 @@ public class JavaJAXRSSpecServerCodegen extends AbstractJavaJAXRSServerCodegen {
5758
private boolean returnJbossResponse = false;
5859
private boolean generatePom = true;
5960
private boolean useSwaggerAnnotations = true;
61+
private boolean useSwaggerV3Annotations = false;
6062
private boolean useMicroProfileOpenAPIAnnotations = false;
6163
private boolean useMutiny = false;
6264

@@ -133,6 +135,7 @@ public JavaJAXRSSpecServerCodegen() {
133135
cliOptions.add(CliOption.newBoolean(RETURN_RESPONSE, "Whether generate API interface should return javax.ws.rs.core.Response instead of a deserialized entity. Only useful if interfaceOnly is true.").defaultValue(String.valueOf(returnResponse)));
134136
cliOptions.add(CliOption.newBoolean(RETURN_JBOSS_RESPONSE, "Whether generate API interface should return `org.jboss.resteasy.reactive.RestResponse` instead of a deserialized entity. This flag cannot be combined with `returnResponse` flag. It requires the flag `interfaceOnly` and `useJakartaEE` set to true, because `org.jboss.resteasy.reactive.RestResponse` was introduced in Quarkus 2.x").defaultValue(String.valueOf(returnJbossResponse)));
135137
cliOptions.add(CliOption.newBoolean(USE_SWAGGER_ANNOTATIONS, "Whether to generate Swagger annotations.", useSwaggerAnnotations));
138+
cliOptions.add(CliOption.newBoolean(USE_SWAGGER_V3_ANNOTATIONS, "Whether to generate Swagger v3 (OpenAPI v3) annotations.", useSwaggerV3Annotations));
136139
cliOptions.add(CliOption.newBoolean(USE_MICROPROFILE_OPENAPI_ANNOTATIONS, "Whether to generate Microprofile OpenAPI annotations. Only valid when library is set to quarkus.", useMicroProfileOpenAPIAnnotations));
137140
cliOptions.add(CliOption.newString(OPEN_API_SPEC_FILE_LOCATION, "Location where the file containing the spec will be generated in the output folder. No file generated when set to null or empty string."));
138141
cliOptions.add(CliOption.newBoolean(SUPPORT_ASYNC, "Wrap responses in CompletionStage type, allowing asynchronous computation (requires JAX-RS 2.1).", supportAsync));
@@ -149,14 +152,28 @@ public void processOpts() {
149152
convertPropertyToBooleanAndWriteBack(RETURN_JBOSS_RESPONSE, value -> returnJbossResponse = value);
150153
convertPropertyToBooleanAndWriteBack(SUPPORT_ASYNC, this::setSupportAsync);
151154
if (QUARKUS_LIBRARY.equals(library) || THORNTAIL_LIBRARY.equals(library) || HELIDON_LIBRARY.equals(library) || OPEN_LIBERTY_LIBRARY.equals(library) || KUMULUZEE_LIBRARY.equals(library)) {
155+
// disable Swagger v2 annotations in library modes; MicroProfile or Swagger v3 may be used instead
152156
useSwaggerAnnotations = false;
153157
} else {
154158
convertPropertyToBooleanAndWriteBack(USE_SWAGGER_ANNOTATIONS, value -> useSwaggerAnnotations = value);
155159
}
160+
// Swagger v3 can be used regardless of library
161+
convertPropertyToBooleanAndWriteBack(USE_SWAGGER_V3_ANNOTATIONS, value -> useSwaggerV3Annotations = value);
162+
// prefer v3 when requested
163+
if (useSwaggerV3Annotations) {
164+
useSwaggerAnnotations = false;
165+
}
156166
if (KUMULUZEE_LIBRARY.equals(library)) {
157167
super.setSourceFolder("src/main/java");
158168
}
159169

170+
if (useSwaggerAnnotations && useSwaggerV3Annotations) {
171+
throw new IllegalArgumentException("Flags 'useSwaggerAnnotations' (v2) and 'useSwaggerV3Annotations' (v3) are mutually exclusive. Please enable only one.");
172+
}
173+
if (useSwaggerV3Annotations && useMicroProfileOpenAPIAnnotations) {
174+
throw new IllegalArgumentException("Flags 'useSwaggerV3Annotations' and 'useMicroProfileOpenAPIAnnotations' are mutually exclusive. Please enable only one.");
175+
}
176+
160177
if (QUARKUS_LIBRARY.equals(library)) {
161178
convertPropertyToBooleanAndWriteBack(USE_MICROPROFILE_OPENAPI_ANNOTATIONS, value -> useMicroProfileOpenAPIAnnotations = value);
162179
}
@@ -184,6 +201,11 @@ public void processOpts() {
184201

185202
super.processOpts();
186203

204+
// expose flags to templates
205+
additionalProperties.put(USE_SWAGGER_ANNOTATIONS, useSwaggerAnnotations);
206+
additionalProperties.put(USE_SWAGGER_V3_ANNOTATIONS, useSwaggerV3Annotations);
207+
additionalProperties.put(USE_MICROPROFILE_OPENAPI_ANNOTATIONS, useMicroProfileOpenAPIAnnotations);
208+
187209
supportingFiles.clear(); // Don't need extra files provided by AbstractJAX-RS & Java Codegen
188210
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")
189211
.doNotOverwrite());

modules/openapi-generator/src/main/resources/JavaJaxRS/spec/api.mustache

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ import {{javaxPackage}}.ws.rs.core.Response;
99
{{#useSwaggerAnnotations}}
1010
import io.swagger.annotations.*;
1111
{{/useSwaggerAnnotations}}
12+
{{#useSwaggerV3Annotations}}
13+
import io.swagger.v3.oas.annotations.*;
14+
import io.swagger.v3.oas.annotations.media.*;
15+
import io.swagger.v3.oas.annotations.responses.*;
16+
import io.swagger.v3.oas.annotations.tags.Tag;
17+
{{/useSwaggerV3Annotations}}
1218
{{#supportAsync}}
1319
import java.util.concurrent.CompletionStage;
1420
import java.util.concurrent.CompletableFuture;
@@ -27,7 +33,8 @@ import {{javaxPackage}}.validation.Valid;{{/useBeanValidation}}
2733
@Path("{{commonPath}}")
2834
{{/interfaceOnly}}
2935
{{#useSwaggerAnnotations}}
30-
@Api(description = "the {{{baseName}}} API"){{/useSwaggerAnnotations}}{{#hasConsumes}}
36+
@Api(description = "the {{{baseName}}} API"){{/useSwaggerAnnotations}}{{#useSwaggerV3Annotations}}
37+
@Tag(name = "{{{baseName}}}"){{/useSwaggerV3Annotations}}{{#hasConsumes}}
3138
@Consumes({ {{#consumes}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/consumes}} }){{/hasConsumes}}{{#hasProduces}}
3239
@Produces({ {{#produces}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/produces}} }){{/hasProduces}}
3340
{{>generatedAnnotation}}

modules/openapi-generator/src/main/resources/JavaJaxRS/spec/apiInterface.mustache

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,8 @@
2626
})
2727
{{/implicitHeadersParams.0}}
2828
@ApiResponses(value = { {{#responses}}
29-
@ApiResponse(code = {{{code}}}, message = "{{{message}}}", response = {{{baseType}}}.class{{#returnContainer}}, responseContainer = "{{{.}}}"{{/returnContainer}}){{^-last}},{{/-last}}{{/responses}} }){{/useSwaggerAnnotations}}
29+
@ApiResponse(code = {{{code}}}, message = "{{{message}}}", response = {{{baseType}}}.class{{#returnContainer}}, responseContainer = "{{{.}}}"{{/returnContainer}}){{^-last}},{{/-last}}{{/responses}} }){{/useSwaggerAnnotations}}{{#useSwaggerV3Annotations}}
30+
@Operation(summary = "{{{summary}}}", description = "{{{notes}}}")
31+
@ApiResponses(value = { {{#responses}}
32+
@ApiResponse(responseCode = "{{{code}}}", description = "{{{message}}}"){{^-last}},{{/-last}}{{/responses}} }){{/useSwaggerV3Annotations}}
3033
{{#supportAsync}}{{>returnAsyncTypeInterface}}{{/supportAsync}}{{^supportAsync}}{{#returnResponse}}Response{{/returnResponse}}{{^returnResponse}}{{>returnTypeInterface}}{{/returnResponse}}{{/supportAsync}} {{nickname}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>cookieParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{^-last}},{{/-last}}{{/allParams}});

modules/openapi-generator/src/main/resources/JavaJaxRS/spec/apiMethod.mustache

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@
1717
{{/implicitHeadersParams.0}}
1818
@ApiResponses(value = { {{#responses}}
1919
@ApiResponse(code = {{{code}}}, message = "{{{message}}}", response = {{{baseType}}}.class{{#containerType}}, responseContainer = "{{{.}}}"{{/containerType}}){{^-last}},{{/-last}}{{/responses}}
20-
}){{/useSwaggerAnnotations}}
20+
}){{/useSwaggerAnnotations}}{{#useSwaggerV3Annotations}}
21+
@Operation(summary = "{{{summary}}}", description = "{{{notes}}}")
22+
@ApiResponses(value = { {{#responses}}
23+
@ApiResponse(responseCode = "{{{code}}}", description = "{{{message}}}"){{^-last}},{{/-last}}{{/responses}}
24+
}){{/useSwaggerV3Annotations}}
2125
public {{#supportAsync}}CompletionStage<{{/supportAsync}}Response{{#supportAsync}}>{{/supportAsync}} {{nickname}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>cookieParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{^-last}},{{/-last}}{{/allParams}}) {
2226
return {{#supportAsync}}CompletableFuture.supplyAsync(() -> {{/supportAsync}}Response.ok().entity("magic!").build(){{#supportAsync}}){{/supportAsync}};
2327
}

modules/openapi-generator/src/main/resources/JavaJaxRS/spec/libraries/quarkus/api.mustache

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ import org.jboss.resteasy.annotations.GZIP;
1414
{{#useSwaggerAnnotations}}
1515
import io.swagger.annotations.*;
1616
{{/useSwaggerAnnotations}}
17+
{{#useSwaggerV3Annotations}}
18+
import io.swagger.v3.oas.annotations.*;
19+
import io.swagger.v3.oas.annotations.media.*;
20+
import io.swagger.v3.oas.annotations.responses.*;
21+
import io.swagger.v3.oas.annotations.tags.Tag;
22+
{{/useSwaggerV3Annotations}}
1723

1824
{{#supportAsync}}
1925
{{#useMutiny}}
@@ -96,7 +102,8 @@ import {{javaxPackage}}.validation.Valid;{{/useBeanValidation}}
96102
openIdConnectUrl = "{{openIdConnectUrl}}"
97103
){{^-last}}, {{/-last}}{{/isOpenId}}{{/authMethods}}
98104
}){{/hasAuthMethods}}{{/useMicroProfileOpenAPIAnnotations}}{{#useSwaggerAnnotations}}
99-
@Api(description = "the {{{baseName}}} API"){{/useSwaggerAnnotations}}
105+
@Api(description = "the {{{baseName}}} API"){{/useSwaggerAnnotations}}{{#useSwaggerV3Annotations}}
106+
@Tag(name = "{{{baseName}}}"){{/useSwaggerV3Annotations}}
100107
@Path("{{commonPath}}"){{#hasConsumes}}
101108
@Consumes({ {{#consumes}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/consumes}} }){{/hasConsumes}}{{#hasProduces}}
102109
@Produces({ {{#produces}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/produces}} }){{/hasProduces}}

modules/openapi-generator/src/main/resources/JavaJaxRS/spec/libraries/quarkus/apiInterface.mustache

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@
1919
})
2020
{{/implicitHeadersParams.0}}
2121
@ApiResponses(value = { {{#responses}}
22-
@ApiResponse(code = {{{code}}}, message = "{{{message}}}", response = {{{baseType}}}.class{{#returnContainer}}, responseContainer = "{{{.}}}"{{/returnContainer}}){{^-last}},{{/-last}}{{/responses}} }){{/useSwaggerAnnotations}}{{#useMicroProfileOpenAPIAnnotations}}
22+
@ApiResponse(code = {{{code}}}, message = "{{{message}}}", response = {{{baseType}}}.class{{#returnContainer}}, responseContainer = "{{{.}}}"{{/returnContainer}}){{^-last}},{{/-last}}{{/responses}} }){{/useSwaggerAnnotations}}{{#useSwaggerV3Annotations}}
23+
@Operation(summary = "{{{summary}}}", description = "{{{notes}}}")
24+
@ApiResponses(value = { {{#responses}}
25+
@ApiResponse(responseCode = "{{{code}}}", description = "{{{message}}}"){{^-last}},{{/-last}}{{/responses}} }){{/useSwaggerV3Annotations}}{{#useMicroProfileOpenAPIAnnotations}}
2326
{{#hasAuthMethods}}@org.eclipse.microprofile.openapi.annotations.security.SecurityRequirements(value = {
2427
{{#authMethods}}{{#isOAuth}}@org.eclipse.microprofile.openapi.annotations.security.SecurityRequirement(
2528
name = "{{name}}",

modules/openapi-generator/src/main/resources/JavaJaxRS/spec/libraries/quarkus/apiMethod.mustache

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@
2020
{{/implicitHeadersParams.0}}
2121
@ApiResponses(value = { {{#responses}}
2222
@ApiResponse(code = {{{code}}}, message = "{{{message}}}", response = {{{baseType}}}.class{{#containerType}}, responseContainer = "{{{.}}}"{{/containerType}}){{^-last}},{{/-last}}{{/responses}}
23-
}){{/useSwaggerAnnotations}}{{#useMicroProfileOpenAPIAnnotations}}
23+
}){{/useSwaggerAnnotations}}{{#useSwaggerV3Annotations}}
24+
@Operation(summary = "{{{summary}}}", description = "{{{notes}}}")
25+
@ApiResponses(value = { {{#responses}}
26+
@ApiResponse(responseCode = "{{{code}}}", description = "{{{message}}}"){{^-last}},{{/-last}}{{/responses}}
27+
}){{/useSwaggerV3Annotations}}{{#useMicroProfileOpenAPIAnnotations}}
2428
{{#hasAuthMethods}}@org.eclipse.microprofile.openapi.annotations.security.SecurityRequirements(value={
2529
{{#authMethods}}{{#isOAuth}}@org.eclipse.microprofile.openapi.annotations.security.SecurityRequirement(name = "{{name}}", scopes = { {{#scopes}} "{{scope}}"{{^-last}},{{/-last}} {{/scopes}} }){{^-last}},{{/-last}}{{/isOAuth}}{{^isOAuth}} @org.eclipse.microprofile.openapi.annotations.security.SecurityRequirement(name = "{{name}}"){{^-last}},{{/-last}}{{/isOAuth}}
2630
{{/authMethods}} }){{/hasAuthMethods}}

modules/openapi-generator/src/main/resources/JavaJaxRS/spec/libraries/quarkus/pom.mustache

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@
4444
{{#useSwaggerAnnotations}}
4545
<io.swagger.annotations.version>1.6.10</io.swagger.annotations.version>
4646
{{/useSwaggerAnnotations}}
47+
{{#useSwaggerV3Annotations}}
48+
<io.swagger.v3.annotations.version>2.2.21</io.swagger.v3.annotations.version>
49+
{{/useSwaggerV3Annotations}}
4750
{{#useMutiny}}
4851
<smallrye.rest.client.version>1.2.1</smallrye.rest.client.version>
4952
{{/useMutiny}}
@@ -118,6 +121,14 @@
118121
<scope>provided</scope>
119122
</dependency>
120123
{{/useSwaggerAnnotations}}
124+
{{#useSwaggerV3Annotations}}
125+
<dependency>
126+
<groupId>io.swagger.core.v3</groupId>
127+
<artifactId>swagger-annotations</artifactId>
128+
<version>${io.swagger.v3.annotations.version}</version>
129+
<scope>provided</scope>
130+
</dependency>
131+
{{/useSwaggerV3Annotations}}
121132
{{#useMutiny}}
122133
<dependency>
123134
<groupId>io.smallrye</groupId>

modules/openapi-generator/src/main/resources/JavaJaxRS/spec/pojo.mustache

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
{{#useSwaggerAnnotations}}
22
import io.swagger.annotations.*;
33
{{/useSwaggerAnnotations}}
4+
{{#useSwaggerV3Annotations}}
5+
import io.swagger.v3.oas.annotations.media.Schema;
6+
{{/useSwaggerV3Annotations}}
47
import java.util.Objects;
58
{{#jackson}}
69
import com.fasterxml.jackson.annotation.JsonProperty;
@@ -21,7 +24,8 @@ import {{javaxPackage}}.xml.bind.annotation.XmlEnumValue;
2124
{{#discriminator}}{{>typeInfoAnnotation}}{{/discriminator}}{{#description}}/**
2225
* {{.}}
2326
**/{{/description}}
24-
{{#useSwaggerAnnotations}}{{#description}}@ApiModel(description = "{{{.}}}"){{/description}}{{/useSwaggerAnnotations}}{{#useMicroProfileOpenAPIAnnotations}}
27+
{{#useSwaggerAnnotations}}{{#description}}@ApiModel(description = "{{{.}}}"){{/description}}{{/useSwaggerAnnotations}}{{#useSwaggerV3Annotations}}
28+
@Schema({{#title}}title="{{{.}}}", {{/title}}{{#description}}description="{{{.}}}"{{/description}}{{^description}}description=""{{/description}}){{/useSwaggerV3Annotations}}{{#useMicroProfileOpenAPIAnnotations}}
2529
@org.eclipse.microprofile.openapi.annotations.media.Schema({{#title}}title="{{{.}}}", {{/title}}{{#description}}description="{{{.}}}"{{/description}}{{^description}}description=""{{/description}}){{/useMicroProfileOpenAPIAnnotations}}
2630
{{#jackson}}@JsonTypeName("{{name}}"){{/jackson}}
2731
{{>generatedAnnotation}}{{>additionalModelTypeAnnotations}}{{>xmlPojoAnnotation}}
@@ -109,7 +113,8 @@ public class {{classname}} {{#parent}}extends {{{.}}}{{/parent}} {{#vendorExtens
109113
@XmlElement(name="{{baseName}}"{{#required}}, required = {{required}}{{/required}})
110114
{{/withXml}}
111115
{{#vendorExtensions.x-extra-annotation}}{{{vendorExtensions.x-extra-annotation}}}{{/vendorExtensions.x-extra-annotation}}{{#useSwaggerAnnotations}}
112-
@ApiModelProperty({{#example}}example = "{{{.}}}", {{/example}}{{#required}}required = {{required}}, {{/required}}value = "{{{description}}}"){{/useSwaggerAnnotations}}{{#useMicroProfileOpenAPIAnnotations}}
116+
@ApiModelProperty({{#example}}example = "{{{.}}}", {{/example}}{{#required}}required = {{required}}, {{/required}}value = "{{{description}}}"){{/useSwaggerAnnotations}}{{#useSwaggerV3Annotations}}
117+
@Schema({{#example}}example = "{{{.}}}", {{/example}}{{#required}}required = {{required}}, {{/required}}description = "{{{description}}}"){{/useSwaggerV3Annotations}}{{#useMicroProfileOpenAPIAnnotations}}
113118
@org.eclipse.microprofile.openapi.annotations.media.Schema({{#example}}example = "{{{.}}}", {{/example}}{{#required}}required = {{required}}, {{/required}}description = "{{{description}}}"){{/useMicroProfileOpenAPIAnnotations}}
114119
{{#jackson}}@JsonProperty({{#required}}required = {{required}}, value = {{/required}}"{{baseName}}"){{/jackson}}
115120
{{#useBeanValidation}}{{>beanValidation}}{{/useBeanValidation}}public {{>beanValidatedType}} {{getter}}() {

modules/openapi-generator/src/main/resources/JavaJaxRS/spec/pom.mustache

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,14 @@
120120
<version>1.5.3</version>
121121
</dependency>
122122
{{/useSwaggerAnnotations}}
123+
{{#useSwaggerV3Annotations}}
124+
<dependency>
125+
<groupId>io.swagger.core.v3</groupId>
126+
<artifactId>swagger-annotations</artifactId>
127+
<scope>provided</scope>
128+
<version>${io.swagger.v3.annotations.version}</version>
129+
</dependency>
130+
{{/useSwaggerV3Annotations}}
123131
<!-- @Nullable annotation -->
124132
<dependency>
125133
<groupId>com.google.code.findbugs</groupId>
@@ -202,5 +210,8 @@
202210
{{#openApiNullable}}
203211
<jackson-databind-nullable-version>0.2.8</jackson-databind-nullable-version>
204212
{{/openApiNullable}}
213+
{{#useSwaggerV3Annotations}}
214+
<io.swagger.v3.annotations.version>2.2.21</io.swagger.v3.annotations.version>
215+
{{/useSwaggerV3Annotations}}
205216
</properties>
206217
</project>

0 commit comments

Comments
 (0)