Skip to content

Commit e9937d9

Browse files
authored
Merge pull request #490 from swagger-api/default-interfaces
refs swagger-api/swagger-codegen#8833 - fix spring templates, add defaultInterfaces, springboot v2
2 parents 4a7d0f4 + 303bb3f commit e9937d9

File tree

184 files changed

+155
-7533
lines changed

Some content is hidden

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

184 files changed

+155
-7533
lines changed

src/main/java/io/swagger/codegen/v3/generators/java/AbstractJavaCodegen.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ public void processOpts() {
376376
} else {
377377
importMapping.put("Schema", "io.swagger.v3.oas.annotations.media.Schema");
378378
}
379-
379+
380380
importMapping.put("JsonProperty", "com.fasterxml.jackson.annotation.JsonProperty");
381381
importMapping.put("JsonSubTypes", "com.fasterxml.jackson.annotation.JsonSubTypes");
382382
importMapping.put("JsonTypeInfo", "com.fasterxml.jackson.annotation.JsonTypeInfo");
@@ -398,7 +398,7 @@ public void processOpts() {
398398
if(additionalProperties.containsKey(JAVA8_MODE)) {
399399
setJava8Mode(Boolean.parseBoolean(additionalProperties.get(JAVA8_MODE).toString()));
400400
if ( java8Mode ) {
401-
additionalProperties.put("java8", "true");
401+
additionalProperties.put("java8", true);
402402
}
403403
}
404404

@@ -427,7 +427,7 @@ public void processOpts() {
427427
importMapping.put("LocalDate", "org.joda.time.LocalDate");
428428
importMapping.put("DateTime", "org.joda.time.DateTime");
429429
} else if (dateLibrary.startsWith("java8")) {
430-
additionalProperties.put("java8", "true");
430+
additionalProperties.put("java8", true);
431431
additionalProperties.put("jsr310", "true");
432432
typeMapping.put("date", "LocalDate");
433433
importMapping.put("LocalDate", "java.time.LocalDate");
@@ -1345,7 +1345,7 @@ private String deriveInvokerPackageName(String input) {
13451345
public void setSupportJava6(boolean value) {
13461346
this.supportJava6 = value;
13471347
}
1348-
1348+
13491349
public String toRegularExpression(String pattern) {
13501350
return escapeText(pattern);
13511351
}
@@ -1401,7 +1401,7 @@ public void setLanguageArguments(List<CodegenArgument> languageArguments) {
14011401
.value(Boolean.FALSE.toString()));
14021402
}
14031403
}
1404-
1404+
14051405
super.setLanguageArguments(languageArguments);
14061406
}
14071407
}

src/main/java/io/swagger/codegen/v3/generators/java/Spring2Codegen.java

Lines changed: 0 additions & 763 deletions
This file was deleted.

src/main/java/io/swagger/codegen/v3/generators/java/SpringCodegen.java

Lines changed: 66 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
import io.swagger.codegen.v3.SupportingFile;
1616
import io.swagger.codegen.v3.generators.features.BeanValidationFeatures;
1717
import io.swagger.codegen.v3.generators.features.OptionalFeatures;
18-
import io.swagger.codegen.v3.templates.MustacheTemplateEngine;
19-
import io.swagger.codegen.v3.templates.TemplateEngine;
2018
import io.swagger.codegen.v3.utils.URLPathUtil;
2119
import io.swagger.v3.oas.models.OpenAPI;
2220
import io.swagger.v3.oas.models.Operation;
@@ -41,9 +39,6 @@
4139
import static io.swagger.codegen.v3.CodegenConstants.IS_ENUM_EXT_NAME;
4240
import static io.swagger.codegen.v3.generators.handlebars.ExtensionHelper.getBooleanValue;
4341

44-
/*
45-
DEPRECATED, Spring Boot 1 is in maintenance mode only. Please use JavaSpring2.
46-
*/
4742
public class SpringCodegen extends AbstractJavaCodegen implements BeanValidationFeatures, OptionalFeatures {
4843
static Logger LOGGER = LoggerFactory.getLogger(SpringCodegen.class);
4944
public static final String DEFAULT_LIBRARY = "spring-boot";
@@ -53,7 +48,6 @@ public class SpringCodegen extends AbstractJavaCodegen implements BeanValidation
5348
public static final String INTERFACE_ONLY = "interfaceOnly";
5449
public static final String DELEGATE_PATTERN = "delegatePattern";
5550
public static final String SINGLE_CONTENT_TYPES = "singleContentTypes";
56-
public static final String JAVA_8 = "java8";
5751
public static final String ASYNC = "async";
5852
public static final String RESPONSE_WRAPPER = "responseWrapper";
5953
public static final String USE_TAGS = "useTags";
@@ -62,6 +56,9 @@ public class SpringCodegen extends AbstractJavaCodegen implements BeanValidation
6256
public static final String IMPLICIT_HEADERS = "implicitHeaders";
6357
public static final String SWAGGER_DOCKET_CONFIG = "swaggerDocketConfig";
6458
public static final String TARGET_OPENFEIGN = "generateForOpenFeign";
59+
public static final String DEFAULT_INTERFACES = "defaultInterfaces";
60+
public static final String SPRING_BOOT_VERSION = "springBootVersion";
61+
public static final String SPRING_BOOT_VERSION_2 = "springBootV2";
6562

6663
protected String title = "swagger-petstore";
6764
protected String configPackage = "io.swagger.configuration";
@@ -79,6 +76,8 @@ public class SpringCodegen extends AbstractJavaCodegen implements BeanValidation
7976
protected boolean swaggerDocketConfig = false;
8077
protected boolean useOptional = false;
8178
protected boolean openFeign = false;
79+
protected boolean defaultInterfaces = true;
80+
protected String springBootVersion = "1.5.22.RELEASE";
8281

8382
public SpringCodegen() {
8483
super();
@@ -100,7 +99,6 @@ public SpringCodegen() {
10099
cliOptions.add(CliOption.newBoolean(INTERFACE_ONLY, "Whether to generate only API interface stubs without the server files."));
101100
cliOptions.add(CliOption.newBoolean(DELEGATE_PATTERN, "Whether to generate the server files using the delegate pattern"));
102101
cliOptions.add(CliOption.newBoolean(SINGLE_CONTENT_TYPES, "Whether to select only one produces/consumes content-type by operation."));
103-
cliOptions.add(CliOption.newBoolean(JAVA_8, "use java8 default interface"));
104102
cliOptions.add(CliOption.newBoolean(ASYNC, "use async Callable controllers"));
105103
cliOptions.add(new CliOption(RESPONSE_WRAPPER, "wrap the responses in given type (Future,Callable,CompletableFuture,ListenableFuture,DeferredResult,HystrixCommand,RxObservable,RxSingle or fully qualified type)"));
106104
cliOptions.add(CliOption.newBoolean(USE_TAGS, "use tags for creating interface and controller classnames"));
@@ -110,6 +108,7 @@ public SpringCodegen() {
110108
cliOptions.add(CliOption.newBoolean(USE_OPTIONAL,
111109
"Use Optional container for optional parameters"));
112110
cliOptions.add(CliOption.newBoolean(TARGET_OPENFEIGN,"Generate for usage with OpenFeign (instead of feign)"));
111+
cliOptions.add(CliOption.newBoolean(DEFAULT_INTERFACES, "Generate default implementations for interfaces").defaultValue("true"));
113112

114113
supportedLibraries.put(DEFAULT_LIBRARY, "Spring-boot Server application using the SpringFox integration.");
115114
supportedLibraries.put(SPRING_MVC_LIBRARY, "Spring-MVC Server application using the SpringFox integration.");
@@ -121,6 +120,14 @@ public SpringCodegen() {
121120
library.setEnum(supportedLibraries);
122121
library.setDefault(DEFAULT_LIBRARY);
123122
cliOptions.add(library);
123+
124+
CliOption springBootVersionOption = new CliOption(SPRING_BOOT_VERSION, "Spring boot version");
125+
Map<String, String> springBootEnum = new HashMap<>();
126+
springBootEnum.put("1.5.22.RELEASE", "1.5.22.RELEASE");
127+
springBootEnum.put("2.1.7.RELEASE", "2.1.7.RELEASE");
128+
springBootVersionOption.setEnum(springBootEnum);
129+
cliOptions.add(springBootVersionOption);
130+
124131
}
125132

126133
@Override
@@ -144,15 +151,23 @@ public void processOpts() {
144151
additionalProperties.put(CodegenConstants.USE_OAS2, true);
145152

146153
// Process java8 option before common java ones to change the default dateLibrary to java8.
147-
if (additionalProperties.containsKey(JAVA_8)) {
148-
this.setJava8(Boolean.valueOf(additionalProperties.get(JAVA_8).toString()));
154+
if (additionalProperties.containsKey(JAVA8_MODE)) {
155+
this.setJava8(Boolean.valueOf(additionalProperties.get(JAVA8_MODE).toString()));
156+
}
157+
158+
if (additionalProperties.containsKey(DATE_LIBRARY)) {
159+
if (additionalProperties.get(DATE_LIBRARY).toString().startsWith("java8")) {
160+
this.setJava8(Boolean.valueOf(additionalProperties.get(JAVA8_MODE).toString()));
161+
}
149162
}
150163
if (this.java8) {
151164
additionalProperties.put("javaVersion", "1.8");
152-
additionalProperties.put("jdk8", "true");
165+
additionalProperties.put("jdk8", true);
153166
if (!additionalProperties.containsKey(DATE_LIBRARY)) {
154167
setDateLibrary("java8");
155168
}
169+
} else {
170+
this.defaultInterfaces = false;
156171
}
157172

158173
// set invokerPackage as basePackage
@@ -198,10 +213,6 @@ public void processOpts() {
198213
this.setSingleContentTypes(Boolean.valueOf(additionalProperties.get(SINGLE_CONTENT_TYPES).toString()));
199214
}
200215

201-
if (additionalProperties.containsKey(JAVA_8)) {
202-
this.setJava8(Boolean.valueOf(additionalProperties.get(JAVA_8).toString()));
203-
}
204-
205216
if (additionalProperties.containsKey(ASYNC)) {
206217
this.setAsync(Boolean.valueOf(additionalProperties.get(ASYNC).toString()));
207218
}
@@ -226,6 +237,20 @@ public void processOpts() {
226237
this.setOpenFeign(convertPropertyToBoolean(TARGET_OPENFEIGN));
227238
}
228239

240+
if (additionalProperties.containsKey(DEFAULT_INTERFACES)) {
241+
this.setDefaultInterfaces(Boolean.valueOf(additionalProperties.get(DEFAULT_INTERFACES).toString()));
242+
}
243+
additionalProperties.put(DEFAULT_INTERFACES, this.defaultInterfaces);
244+
245+
if (additionalProperties.containsKey(SPRING_BOOT_VERSION)) {
246+
this.springBootVersion = additionalProperties.get(SPRING_BOOT_VERSION).toString();
247+
}
248+
additionalProperties.put(SPRING_BOOT_VERSION, this.springBootVersion);
249+
if (springBootVersion.startsWith("2")) {
250+
additionalProperties.put(SPRING_BOOT_VERSION_2, true);
251+
this.setOpenFeign(true);
252+
}
253+
229254
if (useBeanValidation) {
230255
writePropertyBack(USE_BEANVALIDATION, useBeanValidation);
231256
}
@@ -252,7 +277,7 @@ public void processOpts() {
252277
} else {
253278
throw new IllegalArgumentException(
254279
String.format("Can not generate code with `%s` and `%s` true while `%s` is false.",
255-
DELEGATE_PATTERN, INTERFACE_ONLY, JAVA_8));
280+
DELEGATE_PATTERN, INTERFACE_ONLY, JAVA8_MODE));
256281
}
257282
}
258283

@@ -262,6 +287,7 @@ public void processOpts() {
262287
if (!this.interfaceOnly) {
263288

264289
if (library.equals(DEFAULT_LIBRARY)) {
290+
apiTestTemplateFiles.clear();
265291
supportingFiles.add(new SupportingFile("homeController.mustache",
266292
(sourceFolder + File.separator + configPackage).replace(".", java.io.File.separator), "HomeController.java"));
267293
supportingFiles.add(new SupportingFile("swagger2SpringBoot.mustache",
@@ -288,13 +314,24 @@ public void processOpts() {
288314
(sourceFolder + File.separator + configPackage).replace(".", java.io.File.separator), "ApiKeyRequestInterceptor.java"));
289315
supportingFiles.add(new SupportingFile("clientConfiguration.mustache",
290316
(sourceFolder + File.separator + configPackage).replace(".", java.io.File.separator), "ClientConfiguration.java"));
291-
supportingFiles.add(new SupportingFile("Application.mustache",
292-
(testFolder + File.separator + basePackage).replace(".", java.io.File.separator), "Application.java"));
293317
apiTemplateFiles.put("apiClient.mustache", "Client.java");
294318
if (!additionalProperties.containsKey(SINGLE_CONTENT_TYPES)) {
295319
additionalProperties.put(SINGLE_CONTENT_TYPES, "true");
296320
this.setSingleContentTypes(true);
297321
}
322+
if (additionalProperties.containsKey(CodegenConstants.GENERATE_API_TESTS)) {
323+
if (Boolean.valueOf(additionalProperties.get(CodegenConstants.GENERATE_API_TESTS).toString())) {
324+
// TODO Api Tests are not currently supported in spring-cloud template
325+
apiTestTemplateFiles.clear();
326+
supportingFiles.add(new SupportingFile("application-test.mustache",
327+
("src.test.resources").replace(".", java.io.File.separator), "application.yml"));
328+
supportingFiles.add(new SupportingFile("TestUtils.mustache",
329+
(testFolder + File.separator + basePackage).replace(".", java.io.File.separator), "TestUtils.java"));
330+
supportingFiles.add(new SupportingFile("Application.mustache",
331+
(testFolder + File.separator + basePackage).replace(".", java.io.File.separator), "Application.java"));
332+
333+
}
334+
}
298335
} else {
299336
apiTemplateFiles.put("apiController.mustache", "Controller.java");
300337
supportingFiles.add(new SupportingFile("apiException.mustache",
@@ -313,6 +350,9 @@ public void processOpts() {
313350
(sourceFolder + File.separator + configPackage).replace(".", java.io.File.separator), "SwaggerDocumentationConfig.java"));
314351
}
315352

353+
if (this.interfaceOnly) {
354+
apiTestTemplateFiles.clear();
355+
}
316356
if ("threetenbp".equals(dateLibrary)) {
317357
supportingFiles.add(new SupportingFile("customInstantDeserializer.mustache",
318358
(sourceFolder + File.separator + configPackage).replace(".", java.io.File.separator), "CustomInstantDeserializer.java"));
@@ -333,8 +373,6 @@ public void processOpts() {
333373
}
334374

335375
if (this.java8) {
336-
additionalProperties.put("javaVersion", "1.8");
337-
additionalProperties.put("jdk8", "true");
338376
if (this.async) {
339377
additionalProperties.put(RESPONSE_WRAPPER, "CompletableFuture");
340378
}
@@ -343,7 +381,7 @@ public void processOpts() {
343381
}
344382

345383
if(this.openFeign){
346-
additionalProperties.put("isOpenFeign", "true");
384+
additionalProperties.put("isOpenFeign", true);
347385
}
348386

349387
// Some well-known Spring or Spring-Cloud response wrappers
@@ -385,6 +423,10 @@ public void execute(Template.Fragment fragment, Writer writer) throws IOExceptio
385423
writer.write(fragment.execute().replaceAll("\\r|\\n", ""));
386424
}
387425
});
426+
427+
if ((this.java8 && !this.defaultInterfaces) || !this.java8) {
428+
additionalProperties.put("fullController", true);
429+
}
388430
}
389431

390432
@Override
@@ -779,4 +821,8 @@ public void setUseOptional(boolean useOptional) {
779821
public void setOpenFeign(boolean openFeign) {
780822
this.openFeign = openFeign;
781823
}
824+
825+
public void setDefaultInterfaces(boolean defaultInterfaces) {
826+
this.defaultInterfaces = defaultInterfaces;
827+
}
782828
}

src/main/resources/META-INF/services/io.swagger.codegen.v3.CodegenConfig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ io.swagger.codegen.v3.generators.java.JavaResteasyEapServerCodegen
1616
io.swagger.codegen.v3.generators.java.JavaResteasyServerCodegen
1717
io.swagger.codegen.v3.generators.java.MicronautCodegen
1818
io.swagger.codegen.v3.generators.java.SpringCodegen
19-
io.swagger.codegen.v3.generators.java.Spring2Codegen
2019
io.swagger.codegen.v3.generators.nodejs.NodeJSServerCodegen
2120
io.swagger.codegen.v3.generators.openapi.OpenAPIGenerator
2221
io.swagger.codegen.v3.generators.openapi.OpenAPIYamlGenerator
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package {{basePackage}};
2+
3+
import java.util.Random;
4+
import java.util.concurrent.atomic.AtomicLong;
5+
6+
public class TestUtils {
7+
private static final AtomicLong atomicId = createAtomicId();
8+
9+
public static long nextId() {
10+
return atomicId.getAndIncrement();
11+
}
12+
13+
private static AtomicLong createAtomicId() {
14+
int baseId = new Random(System.currentTimeMillis()).nextInt(1000000) + 20000;
15+
return new AtomicLong((long) baseId);
16+
}
17+
}

src/main/resources/handlebars/JavaSpring/api.mustache

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -61,17 +61,17 @@ public interface {{classname}} {
6161
{{^isDelegate}}
6262
Logger log = LoggerFactory.getLogger({{classname}}.class);
6363

64-
default Optional<ObjectMapper> getObjectMapper() {
64+
{{#defaultInterfaces}}default {{/defaultInterfaces}}Optional<ObjectMapper> getObjectMapper(){{^defaultInterfaces}};{{/defaultInterfaces}}{{#defaultInterfaces}}{
6565
return Optional.empty();
66-
}
66+
}{{/defaultInterfaces}}
6767

68-
default Optional<HttpServletRequest> getRequest() {
68+
{{#defaultInterfaces}}default {{/defaultInterfaces}}Optional<HttpServletRequest> getRequest(){{^defaultInterfaces}};{{/defaultInterfaces}}{{#defaultInterfaces}}{
6969
return Optional.empty();
70-
}
70+
}{{/defaultInterfaces}}
7171

72-
default Optional<String> getAcceptHeader() {
72+
{{#defaultInterfaces}}default Optional<String> getAcceptHeader() {
7373
return getRequest().map(r -> r.getHeader("Accept"));
74-
}
74+
}{{/defaultInterfaces}}
7575
{{/isDelegate}}
7676
{{#isDelegate}}
7777
{{classname}}Delegate getDelegate();
@@ -81,9 +81,8 @@ public interface {{classname}} {
8181
{{#contents}}
8282

8383
@ApiOperation(value = "{{{summary}}}", nickname = "{{{operationId}}}", notes = "{{{notes}}}"{{#returnBaseType}}, response = {{{returnBaseType}}}.class{{/returnBaseType}}{{#returnContainer}}, responseContainer = "{{{returnContainer}}}"{{/returnContainer}}{{#hasAuthMethods}}, authorizations = {
84-
{{#authMethods}}@Authorization(value = "{{name}}"{{#isOAuth}}, scopes = {
85-
{{#scopes}}@AuthorizationScope(scope = "{{scope}}", description = "{{description}}"){{#hasMore}},
86-
{{/hasMore}}{{/scopes}}
84+
{{#authMethods}}@Authorization(value = "{{name}}"{{#isOAuth}}, scopes = { {{#each scopes}}
85+
@AuthorizationScope(scope = "{{@key}}", description = "{{this}}"){{^@last}},{{/@last}}{{/each}}
8786
}{{/isOAuth}}){{#hasMore}},
8887
{{/hasMore}}{{/authMethods}}
8988
}{{/hasAuthMethods}}, tags={ {{#vendorExtensions.x-tags}}"{{tag}}",{{/vendorExtensions.x-tags}} })
@@ -102,7 +101,7 @@ public interface {{classname}} {
102101
produces = { {{#produces}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }, {{/hasProduces}}{{#hasConsumes}}
103102
consumes = { {{#consumes}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} },{{/hasConsumes}}{{/singleContentTypes}}
104103
method = RequestMethod.{{httpMethod}})
105-
{{#jdk8}}default {{/jdk8}}{{#responseWrapper}}{{.}}<{{/responseWrapper}}ResponseEntity<{{>returnTypes}}>{{#responseWrapper}}>{{/responseWrapper}} {{#delegate-method}}_{{/delegate-method}}{{operationId}}({{#parameters}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{#hasMore}},{{/hasMore}}{{/parameters}}){{^jdk8}};{{/jdk8}}{{#jdk8}} {
104+
{{#defaultInterfaces}}default {{/defaultInterfaces}}{{#responseWrapper}}{{.}}<{{/responseWrapper}}ResponseEntity<{{>returnTypes}}>{{#responseWrapper}}>{{/responseWrapper}} {{#delegate-method}}_{{/delegate-method}}{{operationId}}({{#parameters}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{#hasMore}},{{/hasMore}}{{/parameters}}){{^defaultInterfaces}};{{/defaultInterfaces}}{{#defaultInterfaces}} {
106105
{{#delegate-method}}
107106
return {{operationId}}({{#parameters}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/parameters}});
108107
}
@@ -130,7 +129,7 @@ public interface {{classname}} {
130129
{{#isDelegate}}
131130
return getDelegate().{{operationId}}({{#parameters}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/parameters}});
132131
{{/isDelegate}}
133-
}{{/jdk8}}
132+
}{{/defaultInterfaces}}
134133

135134
{{/contents}}
136135
{{/operation}}

0 commit comments

Comments
 (0)