Skip to content

Commit 0f6b620

Browse files
[Java Spring OAS3] Minor fixes and general improvements (#11229)
* * Use Relative Imports for org.springframework.core.io.Resource * api.mustache: Add operationId to atOperation annotation * Overhaul atSchema annotation in model * Add spring-stubs-oas3.yaml test config * Optimize mustache templates * Use Relative Imports for DateTimeFormat, Pageable and ApiIgnore * Add spring-stubs-oas3.yaml test config * Generate all samples * Explain fromOperation override to support more logic-less templates. * Support RootUriTemplateHandler from spring-boot * Revert "Support RootUriTemplateHandler from spring-boot" This reverts commit 1915f8b. * Evaluate additional property useSpringfox as Boolean * Generate all samples after merge (java-camel) * Fix typo * Move java-camel test deom samples.circleci.spring to samples.circleci profile. * re-generate all samples after merge * Generate samples and docs after merge * Generate samples after merge conflicts resolved
1 parent e477538 commit 0f6b620

File tree

1,609 files changed

+14268
-14523
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,609 files changed

+14268
-14523
lines changed

bin/configs/spring-stubs-oas3.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
generatorName: spring
2+
outputDir: samples/openapi3/client/petstore/spring-stubs
3+
inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml
4+
templateDir: modules/openapi-generator/src/main/resources/JavaSpring
5+
additionalProperties:
6+
groupId: org.openapitools.openapi3
7+
artifactId: spring-stubs
8+
oas3: "true"
9+
interfaceOnly: "true"
10+
singleContentTypes: "true"
11+
hideGenerationTimestamp: "true"

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

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import static org.apache.commons.lang3.StringUtils.isNotEmpty;
2121
import static org.openapitools.codegen.utils.StringUtils.camelize;
2222

23-
import io.swagger.v3.oas.models.media.Schema;
2423
import java.io.File;
2524
import java.net.URL;
2625
import java.util.ArrayList;
@@ -33,6 +32,12 @@
3332
import java.util.regex.Matcher;
3433
import java.util.stream.Collectors;
3534

35+
import com.samskivert.mustache.Mustache;
36+
import io.swagger.v3.oas.models.OpenAPI;
37+
import io.swagger.v3.oas.models.Operation;
38+
import io.swagger.v3.oas.models.PathItem;
39+
import io.swagger.v3.oas.models.media.Schema;
40+
import io.swagger.v3.oas.models.servers.Server;
3641
import org.apache.commons.lang3.tuple.Pair;
3742
import org.openapitools.codegen.CliOption;
3843
import org.openapitools.codegen.CodegenConstants;
@@ -59,12 +64,6 @@
5964
import org.slf4j.Logger;
6065
import org.slf4j.LoggerFactory;
6166

62-
import com.samskivert.mustache.Mustache;
63-
64-
import io.swagger.v3.oas.models.OpenAPI;
65-
import io.swagger.v3.oas.models.Operation;
66-
import io.swagger.v3.oas.models.PathItem;
67-
6867
public class SpringCodegen extends AbstractJavaCodegen
6968
implements BeanValidationFeatures, PerformBeanValidationFeatures, OptionalFeatures {
7069
private final Logger LOGGER = LoggerFactory.getLogger(SpringCodegen.class);
@@ -390,8 +389,11 @@ public void processOpts() {
390389
}
391390
additionalProperties.put(UNHANDLED_EXCEPTION_HANDLING, this.isUnhandledException());
392391

393-
typeMapping.put("file", "org.springframework.core.io.Resource");
394-
importMapping.put("org.springframework.core.io.Resource", "org.springframework.core.io.Resource");
392+
typeMapping.put("file", "Resource");
393+
importMapping.put("Resource", "org.springframework.core.io.Resource");
394+
importMapping.put("Pageable", "org.springframework.data.domain.Pageable");
395+
importMapping.put("DateTimeFormat", "org.springframework.format.annotation.DateTimeFormat");
396+
importMapping.put("ApiIgnore", "springfox.documentation.annotations.ApiIgnore");
395397

396398
if (useOptional) {
397399
writePropertyBack(USE_OPTIONAL, useOptional);
@@ -899,6 +901,11 @@ public void setUnhandledException(boolean unhandledException) {
899901
public void postProcessModelProperty(CodegenModel model, CodegenProperty property) {
900902
super.postProcessModelProperty(model, property);
901903

904+
// add org.springframework.format.annotation.DateTimeFormat when needed
905+
if (property.isDate || property.isDateTime) {
906+
model.imports.add("DateTimeFormat");
907+
}
908+
902909
if ("null".equals(property.example)) {
903910
property.example = null;
904911
}
@@ -938,6 +945,29 @@ public CodegenModel fromModel(String name, Schema model) {
938945
return codegenModel;
939946
}
940947

948+
/*
949+
* Add dynamic imports based on the parameters and vendor extensions of an operation.
950+
* The imports are expanded by the mustache {{import}} tag available to model and api
951+
* templates.
952+
*/
953+
@Override
954+
public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, List<Server> servers) {
955+
CodegenOperation codegenOperation = super.fromOperation(path, httpMethod, operation, servers);
956+
957+
// add org.springframework.format.annotation.DateTimeFormat when needed
958+
codegenOperation.allParams.stream().filter(p -> p.isDate || p.isDateTime).findFirst()
959+
.ifPresent(p -> codegenOperation.imports.add("DateTimeFormat"));
960+
961+
// add org.springframework.data.domain.Pageable import when needed
962+
if (codegenOperation.vendorExtensions.containsKey("x-spring-paginated")) {
963+
codegenOperation.imports.add("Pageable");
964+
if (Boolean.TRUE.equals(additionalProperties.get("useSpringfox"))) {
965+
codegenOperation.imports.add("ApiIgnore");
966+
}
967+
}
968+
return codegenOperation;
969+
}
970+
941971
@Override
942972
public Map<String, Object> postProcessModelsEnum(Map<String, Object> objs) {
943973
objs = super.postProcessModelsEnum(objs);
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
{{#additionalEnumTypeAnnotations}}{{{.}}}
1+
{{#additionalEnumTypeAnnotations}}
2+
{{{.}}}
23
{{/additionalEnumTypeAnnotations}}
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
{{#additionalModelTypeAnnotations}}{{{.}}}
1+
{{#additionalModelTypeAnnotations}}
2+
{{{.}}}
23
{{/additionalModelTypeAnnotations}}

modules/openapi-generator/src/main/resources/JavaSpring/api.mustache

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ import org.springframework.stereotype.Controller;
3737
{{/useSpringController}}
3838
import org.springframework.web.bind.annotation.*;
3939
{{#jdk8-no-delegate}}
40-
{{^reactive}}
40+
{{^reactive}}
4141
import org.springframework.web.context.request.NativeWebRequest;
42-
{{/reactive}}
42+
{{/reactive}}
4343
{{/jdk8-no-delegate}}
4444
import org.springframework.web.multipart.MultipartFile;
4545
{{#reactive}}
@@ -59,21 +59,28 @@ import java.util.Map;
5959
import java.util.Optional;
6060
{{/jdk8-no-delegate}}
6161
{{^jdk8-no-delegate}}
62-
{{#useOptional}}
62+
{{#useOptional}}
6363
import java.util.Optional;
64-
{{/useOptional}}
64+
{{/useOptional}}
6565
{{/jdk8-no-delegate}}
6666
{{#async}}
6767
import java.util.concurrent.{{^jdk8}}Callable{{/jdk8}}{{#jdk8}}CompletableFuture{{/jdk8}};
6868
{{/async}}
69+
import javax.annotation.Generated;
70+
6971
{{>generatedAnnotation}}
7072
{{#useBeanValidation}}
7173
@Validated
7274
{{/useBeanValidation}}
7375
{{#useSpringController}}
7476
@Controller
7577
{{/useSpringController}}
76-
{{#oas3}}@Tag(name = "{{{baseName}}}", description = "the {{{baseName}}} API"){{/oas3}}{{^oas3}}@Api(value = "{{{baseName}}}", description = "the {{{baseName}}} API"){{/oas3}}
78+
{{#oas3}}
79+
@Tag(name = "{{{baseName}}}", description = "the {{{baseName}}} API")
80+
{{/oas3}}
81+
{{^oas3}}
82+
@Api(value = "{{{baseName}}}", description = "the {{{baseName}}} API")
83+
{{/oas3}}
7784
{{#operations}}
7885
{{#virtualService}}
7986
@VirtualService
@@ -121,8 +128,13 @@ public interface {{classname}} {
121128
{{/virtualService}}
122129
{{#oas3}}
123130
@Operation(
124-
summary = "{{{summary}}}",
131+
operationId = "{{{operationId}}}",
132+
{{#summary}}
133+
summary = "{{{.}}}",
134+
{{/summary}}
135+
{{#vendorExtensions.x-tags}}
125136
tags = { {{#vendorExtensions.x-tags}}"{{tag}}"{{^-last}}, {{/-last}}{{/vendorExtensions.x-tags}} },
137+
{{/vendorExtensions.x-tags}}
126138
responses = {
127139
{{#responses}}
128140
@ApiResponse(responseCode = "{{{code}}}", description = "{{{message}}}"{{#baseType}}, content = @Content(mediaType = "application/json", schema = @Schema(implementation = {{{baseType}}}.class)){{/baseType}}){{^-last}},{{/-last}}
@@ -189,15 +201,15 @@ public interface {{classname}} {
189201
{{#jdk8-default-interface}}default {{/jdk8-default-interface}}{{#responseWrapper}}{{.}}<{{/responseWrapper}}ResponseEntity<{{>returnTypes}}>{{#responseWrapper}}>{{/responseWrapper}} {{#delegate-method}}_{{/delegate-method}}{{operationId}}(
190202
{{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{>cookieParams}}{{^-last}},
191203
{{/-last}}{{/allParams}}{{#reactive}}{{#hasParams}},
192-
{{/hasParams}}{{#oas3}}@Parameter(hidden = true){{/oas3}}{{#useSpringfox}}@springfox.documentation.annotations.ApiIgnore{{/useSpringfox}} final ServerWebExchange exchange{{/reactive}}{{#vendorExtensions.x-spring-paginated}}{{#hasParams}},
193-
{{/hasParams}}{{#useSpringfox}}@springfox.documentation.annotations.ApiIgnore {{/useSpringfox}}final org.springframework.data.domain.Pageable pageable{{/vendorExtensions.x-spring-paginated}}
204+
{{/hasParams}}{{#oas3}}@Parameter(hidden = true){{/oas3}}{{#useSpringfox}}@ApiIgnore{{/useSpringfox}} final ServerWebExchange exchange{{/reactive}}{{#vendorExtensions.x-spring-paginated}}{{#hasParams}},
205+
{{/hasParams}}{{#useSpringfox}}@ApiIgnore {{/useSpringfox}}final Pageable pageable{{/vendorExtensions.x-spring-paginated}}
194206
){{^jdk8-default-interface}};{{/jdk8-default-interface}}{{#jdk8-default-interface}}{{#unhandledException}} throws Exception{{/unhandledException}} {
195207
{{#delegate-method}}
196208
return {{operationId}}({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#reactive}}{{#hasParams}}, {{/hasParams}}exchange{{/reactive}}{{#vendorExtensions.x-spring-paginated}}, pageable{{/vendorExtensions.x-spring-paginated}});
197209
}
198210

199211
// Override this method
200-
{{#jdk8-default-interface}}default {{/jdk8-default-interface}} {{#responseWrapper}}{{.}}<{{/responseWrapper}}ResponseEntity<{{>returnTypes}}>{{#responseWrapper}}>{{/responseWrapper}} {{operationId}}({{#allParams}}{{^isFile}}{{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{{dataType}}}{{/reactive}}{{#reactive}}{{^isArray}}Mono<{{{dataType}}}>{{/isArray}}{{#isArray}}Flux<{{{baseType}}}>{{/isArray}}{{/reactive}}{{/isBodyParam}}{{/isFile}}{{#isFile}}{{#reactive}}Flux<Part>{{/reactive}}{{^reactive}}MultipartFile{{/reactive}}{{/isFile}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#reactive}}{{#hasParams}}, {{/hasParams}}{{#useSpringfox}}@springfox.documentation.annotations.ApiIgnore{{/useSpringfox}} final ServerWebExchange exchange{{/reactive}}{{#vendorExtensions.x-spring-paginated}}, {{#useSpringfox}}@springfox.documentation.annotations.ApiIgnore{{/useSpringfox}} final org.springframework.data.domain.Pageable pageable{{/vendorExtensions.x-spring-paginated}}){{#unhandledException}} throws Exception{{/unhandledException}} {
212+
{{#jdk8-default-interface}}default {{/jdk8-default-interface}} {{#responseWrapper}}{{.}}<{{/responseWrapper}}ResponseEntity<{{>returnTypes}}>{{#responseWrapper}}>{{/responseWrapper}} {{operationId}}({{#allParams}}{{^isFile}}{{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{{dataType}}}{{/reactive}}{{#reactive}}{{^isArray}}Mono<{{{dataType}}}>{{/isArray}}{{#isArray}}Flux<{{{baseType}}}>{{/isArray}}{{/reactive}}{{/isBodyParam}}{{/isFile}}{{#isFile}}{{#reactive}}Flux<Part>{{/reactive}}{{^reactive}}MultipartFile{{/reactive}}{{/isFile}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#reactive}}{{#hasParams}}, {{/hasParams}}{{#useSpringfox}}@ApiIgnore{{/useSpringfox}} final ServerWebExchange exchange{{/reactive}}{{#vendorExtensions.x-spring-paginated}}, {{#useSpringfox}}@ApiIgnore{{/useSpringfox}} final Pageable pageable{{/vendorExtensions.x-spring-paginated}}){{#unhandledException}} throws Exception{{/unhandledException}} {
201213
{{/delegate-method}}
202214
{{^isDelegate}}
203215
{{>methodBody}}

modules/openapi-generator/src/main/resources/JavaSpring/apiController.mustache

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,35 +31,35 @@ import org.springframework.web.bind.annotation.CookieValue;
3131
import org.springframework.web.bind.annotation.RequestParam;
3232
import org.springframework.web.bind.annotation.RequestPart;
3333
{{/jdk8}}
34+
import org.springframework.beans.factory.annotation.Autowired;
3435
{{^isDelegate}}
3536
import org.springframework.web.context.request.NativeWebRequest;
3637
{{/isDelegate}}
3738
{{^jdk8}}
3839
import org.springframework.web.multipart.MultipartFile;
39-
{{#vendorExtensions.x-spring-paginated}}
40-
import org.springframework.data.domain.Pageable;
41-
{{/vendorExtensions.x-spring-paginated}}
4240

43-
{{#useBeanValidation}}
41+
{{#useBeanValidation}}
4442
import javax.validation.constraints.*;
4543
import javax.validation.Valid;
46-
{{/useBeanValidation}}
44+
{{/useBeanValidation}}
4745
{{/jdk8}}
4846
{{#jdk8}}
4947
import java.util.Optional;
5048
{{/jdk8}}
5149
{{^jdk8}}
52-
{{#useOptional}}
50+
{{#useOptional}}
5351
import java.util.Optional;
54-
{{/useOptional}}
52+
{{/useOptional}}
5553
{{/jdk8}}
5654
{{^jdk8}}
5755
import java.util.List;
5856
import java.util.Map;
59-
{{#async}}
57+
{{#async}}
6058
import java.util.concurrent.Callable;
61-
{{/async}}
59+
{{/async}}
6260
{{/jdk8}}
61+
import javax.annotation.Generated;
62+
6363
{{>generatedAnnotation}}
6464
@Controller
6565
{{=<% %>=}}
@@ -71,7 +71,7 @@ public class {{classname}}Controller implements {{classname}} {
7171

7272
private final {{classname}}Delegate delegate;
7373

74-
public {{classname}}Controller(@org.springframework.beans.factory.annotation.Autowired(required = false) {{classname}}Delegate delegate) {
74+
public {{classname}}Controller(@Autowired(required = false) {{classname}}Delegate delegate) {
7575
{{#jdk8}}
7676
this.delegate = Optional.ofNullable(delegate).orElse(new {{classname}}Delegate() {});
7777
}
@@ -93,7 +93,7 @@ public class {{classname}}Controller implements {{classname}} {
9393
{{/jdk8}}
9494
private final NativeWebRequest request;
9595

96-
@org.springframework.beans.factory.annotation.Autowired
96+
@Autowired
9797
public {{classname}}Controller(NativeWebRequest request) {
9898
this.request = request;
9999
}
@@ -132,7 +132,7 @@ public class {{classname}}Controller implements {{classname}} {
132132
public {{#responseWrapper}}{{.}}<{{/responseWrapper}}ResponseEntity<{{>returnTypes}}>{{#responseWrapper}}>{{/responseWrapper}} {{operationId}}(
133133
{{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{>cookieParams}}{{^-last}},
134134
{{/-last}}{{/allParams}}{{#vendorExtensions.x-spring-paginated}}{{#hasParams}},
135-
{{/hasParams}}{{#useSpringfox}}@springfox.documentation.annotations.ApiIgnore {{/useSpringfox}}final Pageable pageable{{/vendorExtensions.x-spring-paginated}}
135+
{{/hasParams}}{{#useSpringfox}}@ApiIgnore {{/useSpringfox}}final Pageable pageable{{/vendorExtensions.x-spring-paginated}}
136136
) {
137137
{{^isDelegate}}
138138
{{^async}}

modules/openapi-generator/src/main/resources/JavaSpring/apiDelegate.mustache

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@ package {{package}};
22

33
{{#imports}}import {{import}};
44
{{/imports}}
5-
{{#vendorExtensions.x-spring-paginated}}
6-
import org.springframework.data.domain.Pageable;
7-
{{/vendorExtensions.x-spring-paginated}}
85
{{#jdk8}}
96
import org.springframework.http.HttpStatus;
107
import org.springframework.http.MediaType;
@@ -34,6 +31,7 @@ import java.util.Optional;
3431
{{#async}}
3532
import java.util.concurrent.{{^jdk8}}Callable{{/jdk8}}{{#jdk8}}CompletableFuture{{/jdk8}};
3633
{{/async}}
34+
import javax.annotation.Generated;
3735

3836
{{#operations}}
3937
/**
@@ -72,7 +70,7 @@ public interface {{classname}}Delegate {
7270
*/
7371
{{#jdk8-default-interface}}default {{/jdk8-default-interface}}{{#responseWrapper}}{{.}}<{{/responseWrapper}}ResponseEntity<{{>returnTypes}}>{{#responseWrapper}}>{{/responseWrapper}} {{operationId}}({{#allParams}}{{^isFile}}{{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{{dataType}}}{{/reactive}}{{#reactive}}{{^isArray}}Mono<{{{dataType}}}>{{/isArray}}{{#isArray}}Flux<{{{baseType}}}>{{/isArray}}{{/reactive}}{{/isBodyParam}}{{/isFile}}{{#isFile}}{{#isArray}}List<{{/isArray}}{{#reactive}}Flux<Part>{{/reactive}}{{^reactive}}MultipartFile{{/reactive}}{{#isArray}}>{{/isArray}}{{/isFile}} {{paramName}}{{^-last}},
7472
{{/-last}}{{/allParams}}{{#reactive}}{{#hasParams}},
75-
{{/hasParams}}ServerWebExchange exchange{{/reactive}}{{#vendorExtensions.x-spring-paginated}}, final org.springframework.data.domain.Pageable pageable{{/vendorExtensions.x-spring-paginated}}){{#unhandledException}} throws Exception{{/unhandledException}}{{^jdk8-default-interface}};{{/jdk8-default-interface}}{{#jdk8-default-interface}} {
73+
{{/hasParams}}ServerWebExchange exchange{{/reactive}}{{#vendorExtensions.x-spring-paginated}}, final Pageable pageable{{/vendorExtensions.x-spring-paginated}}){{#unhandledException}} throws Exception{{/unhandledException}}{{^jdk8-default-interface}};{{/jdk8-default-interface}}{{#jdk8-default-interface}} {
7674
{{>methodBody}}
7775
}{{/jdk8-default-interface}}
7876

modules/openapi-generator/src/main/resources/JavaSpring/apiException.mustache

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package {{apiPackage}};
22

3+
import javax.annotation.Generated;
4+
35
/**
46
* The exception that can be used to store the HTTP status code returned by an API response.
57
*/

modules/openapi-generator/src/main/resources/JavaSpring/apiOriginFilter.mustache

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package {{apiPackage}};
22

33
import java.io.IOException;
44

5+
import javax.annotation.Generated;
56
import javax.servlet.*;
67
import javax.servlet.http.HttpServletResponse;
78

modules/openapi-generator/src/main/resources/JavaSpring/apiResponseMessage.mustache

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package {{apiPackage}};
22

3+
import javax.annotation.Generated;
34
import javax.xml.bind.annotation.XmlTransient;
45

56
{{>generatedAnnotation}}

0 commit comments

Comments
 (0)