From 2e46bb9b9fa35fe16f5d80839b8fe2e568f77c0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20C=C3=B4t=C3=A9?= Date: Mon, 10 Apr 2017 11:23:28 -0400 Subject: [PATCH 1/3] Add File support + some fixes to Play generator (#5263) * First commit of the Java Play Framework server generator. It is highly based on Spring so there might me a couple of things that don't make sense (like options or parameters) for the Play Framework. * Fix suggestions in the PR discussion + add .bat and .sh file as requested. * Updated Readme.md file * Remove unused mustache file + fix baseName vs paramName in all the mustache files. * Fix the compilation error when we have a body which is a list or map. Doesn't fix the problem with the annotation itself. * Fix the problem with the Http.MultipartFormData.FilePart * Return a FileInputStream when the returnType is "file" + Fix a couple of other bugs with boolean + updated sample * Return an InputStream instead of FileInputStream (except in the instantiation) * A little cleanup for the form param of type file. --- .../io/swagger/codegen/CodegenParameter.java | 3 --- .../languages/JavaPlayFrameworkCodegen.java | 21 ++++++++++--------- .../conversionBegin.mustache | 2 +- .../JavaPlayFramework/conversionEnd.mustache | 2 +- .../JavaPlayFramework/formParams.mustache | 2 +- .../JavaPlayFramework/newApi.mustache | 4 +++- .../newApiController.mustache | 6 +++--- .../app/controllers/PetApiController.java | 2 +- .../app/controllers/PetApiControllerImp.java | 11 +++++++++- .../PetApiControllerImpInterface.java | 2 +- .../controllers/StoreApiControllerImp.java | 5 +++++ .../app/controllers/UserApiControllerImp.java | 9 ++++++++ 12 files changed, 46 insertions(+), 23 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenParameter.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenParameter.java index 43a3abce0a1..e65c6ffe841 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenParameter.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenParameter.java @@ -12,9 +12,6 @@ public class CodegenParameter { public String baseName, paramName, dataType, datatypeWithEnum, dataFormat, collectionFormat, description, unescapedDescription, baseType, defaultValue, enumName; - //This was added for javaPlayFramework specifically to get around a bug in swagger-play. See generator for more info on the bug. - public String dataTypeForImplicitParam; - public String example; // example value (x-example) public String jsonSchema; public boolean isString, isInteger, isLong, isFloat, isDouble, isByteArray, isBinary, isBoolean, isDate, isDateTime; diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavaPlayFrameworkCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavaPlayFrameworkCodegen.java index 67ed428add3..3577bd43fd1 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavaPlayFrameworkCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavaPlayFrameworkCodegen.java @@ -188,6 +188,9 @@ public class JavaPlayFrameworkCodegen extends AbstractJavaCodegen implements Bea typeMapping.put("DateTime", "OffsetDateTime"); importMapping.put("LocalDate", "java.time.LocalDate"); importMapping.put("OffsetDateTime", "java.time.OffsetDateTime"); + + importMapping.put("InputStream", "java.io.InputStream"); + typeMapping.put("file", "InputStream"); } @Override @@ -249,17 +252,15 @@ public class JavaPlayFrameworkCodegen extends AbstractJavaCodegen implements Bea List ops = (List) operations.get("operation"); for (CodegenOperation operation : ops) { - //This is to fix this bug in the swagger-play project: https://github.com/swagger-api/swagger-play/issues/131 - //We need to explicitly add the model package name in front of the dataType because if we don't, the - //implicitParam is not valid and show error when loading the documentation - //This can be removed safely after the bug has been fixed for (CodegenParameter param : operation.allParams) { - if (!param.isPathParam ) { - if (!param.isPrimitiveType && !param.isListContainer && !param.isMapContainer) { - param.dataTypeForImplicitParam = String.format("%s.%s", modelPackage, param.dataType); - } else { - param.dataTypeForImplicitParam = param.dataType; - } + if (param.isFormParam && param.isFile) { + param.dataType = "Http.MultipartFormData.FilePart"; + } + } + + for (CodegenParameter param : operation.formParams) { + if (param.isFile) { + param.dataType = "Http.MultipartFormData.FilePart"; } } diff --git a/modules/swagger-codegen/src/main/resources/JavaPlayFramework/conversionBegin.mustache b/modules/swagger-codegen/src/main/resources/JavaPlayFramework/conversionBegin.mustache index 21631412a2b..a931bc896f8 100644 --- a/modules/swagger-codegen/src/main/resources/JavaPlayFramework/conversionBegin.mustache +++ b/modules/swagger-codegen/src/main/resources/JavaPlayFramework/conversionBegin.mustache @@ -1 +1 @@ -{{#isInteger}}Integer.parseInt({{/isInteger}}{{#isDouble}}Double.parseDouble({{/isDouble}}{{#isLong}}Long.parseLong({{/isLong}}{{#isFloat}}Float.parseFloat({{/isFloat}}{{#isString}}(String){{/isString}} \ No newline at end of file +{{#isBoolean}}Boolean.getBoolean({{/isBoolean}}{{#isInteger}}Integer.parseInt({{/isInteger}}{{#isDouble}}Double.parseDouble({{/isDouble}}{{#isLong}}Long.parseLong({{/isLong}}{{#isFloat}}Float.parseFloat({{/isFloat}}{{#isString}}(String){{/isString}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/JavaPlayFramework/conversionEnd.mustache b/modules/swagger-codegen/src/main/resources/JavaPlayFramework/conversionEnd.mustache index 2a36cdff8ab..3686f93ac6a 100644 --- a/modules/swagger-codegen/src/main/resources/JavaPlayFramework/conversionEnd.mustache +++ b/modules/swagger-codegen/src/main/resources/JavaPlayFramework/conversionEnd.mustache @@ -1 +1 @@ -{{#isInteger}}){{/isInteger}}{{#isDouble}}){{/isDouble}}{{#isLong}}){{/isLong}}{{#isFloat}}){{/isFloat}}{{#isString}}{{/isString}} \ No newline at end of file +{{#isBoolean}}){{/isBoolean}}{{#isInteger}}){{/isInteger}}{{#isDouble}}){{/isDouble}}{{#isLong}}){{/isLong}}{{#isFloat}}){{/isFloat}}{{#isString}}{{/isString}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/JavaPlayFramework/formParams.mustache b/modules/swagger-codegen/src/main/resources/JavaPlayFramework/formParams.mustache index 866a5e96df5..cf484cd9c00 100644 --- a/modules/swagger-codegen/src/main/resources/JavaPlayFramework/formParams.mustache +++ b/modules/swagger-codegen/src/main/resources/JavaPlayFramework/formParams.mustache @@ -1 +1 @@ -{{#isFormParam}}{{#notFile}}{{{dataType}}} {{paramName}}{{/notFile}}{{#isFile}}Http.MultipartFormData.FilePart {{paramName}}{{/isFile}}{{/isFormParam}} \ No newline at end of file +{{#isFormParam}}{{{dataType}}} {{paramName}}{{/isFormParam}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/JavaPlayFramework/newApi.mustache b/modules/swagger-codegen/src/main/resources/JavaPlayFramework/newApi.mustache index 79696c93f56..1c23543a7e7 100644 --- a/modules/swagger-codegen/src/main/resources/JavaPlayFramework/newApi.mustache +++ b/modules/swagger-codegen/src/main/resources/JavaPlayFramework/newApi.mustache @@ -7,6 +7,7 @@ import play.mvc.Http; import java.util.List; import java.util.ArrayList; import java.util.HashMap; +import java.io.FileInputStream; {{#useBeanValidation}} import javax.validation.constraints.*; {{/useBeanValidation}} @@ -14,9 +15,10 @@ import javax.validation.constraints.*; {{#operations}} public class {{classname}}ControllerImp {{#useInterfaces}}implements {{classname}}ControllerImpInterface{{/useInterfaces}} { {{#operation}} + {{#useInterfaces}}@Override{{/useInterfaces}} public {{>returnTypes}} {{operationId}}({{#allParams}}{{>pathParams}}{{>queryParams}}{{>bodyParams}}{{>formParams}}{{>headerParams}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) {{#handleExceptions}}throws Exception{{/handleExceptions}} { //Do your magic!!! - {{#returnType}}return new {{>returnTypesNoVoidNoAbstract}}();{{/returnType}} + {{#returnType}}{{#isResponseFile}}return new FileInputStream("replace this");{{/isResponseFile}}{{^isResponseFile}}return new {{>returnTypesNoVoidNoAbstract}}();{{/isResponseFile}}{{/returnType}} } {{/operation}} diff --git a/modules/swagger-codegen/src/main/resources/JavaPlayFramework/newApiController.mustache b/modules/swagger-codegen/src/main/resources/JavaPlayFramework/newApiController.mustache index b209947327a..34e39b01982 100644 --- a/modules/swagger-codegen/src/main/resources/JavaPlayFramework/newApiController.mustache +++ b/modules/swagger-codegen/src/main/resources/JavaPlayFramework/newApiController.mustache @@ -84,7 +84,7 @@ public class {{classname}}Controller extends Controller { {{/queryParams}} {{#formParams}} {{^notFile}} - Http.MultipartFormData.FilePart {{paramName}} = request().body().asMultipartFormData().getFile("{{baseName}}"); + {{{dataType}}} {{paramName}} = request().body().asMultipartFormData().getFile("{{baseName}}"); {{#required}}if (({{paramName}} == null || ((File) {{paramName}}.getFile()).length() == 0)) { throw new RuntimeException("File cannot be empty"); } @@ -140,8 +140,8 @@ public class {{classname}}Controller extends Controller { {{/collectionFormat}} {{/headerParams}} {{#returnType}}{{>returnTypesNoVoid}} obj = {{/returnType}}imp.{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}); - {{#returnType}}JsonNode result = mapper.valueToTree(obj); - return ok(result);{{/returnType}} + {{#returnType}}{{^isResponseFile}}JsonNode result = mapper.valueToTree(obj); + return ok(result);{{/isResponseFile}}{{#isResponseFile}}return ok(obj);{{/isResponseFile}}{{/returnType}} {{^returnType}}return ok();{{/returnType}} } {{/operation}} diff --git a/samples/server/petstore/java-play-framework/app/controllers/PetApiController.java b/samples/server/petstore/java-play-framework/app/controllers/PetApiController.java index 4676ab98cae..2d40ebc807f 100644 --- a/samples/server/petstore/java-play-framework/app/controllers/PetApiController.java +++ b/samples/server/petstore/java-play-framework/app/controllers/PetApiController.java @@ -1,6 +1,6 @@ package controllers; -import java.io.File; +import java.io.InputStream; import apimodels.Pet; import play.mvc.Controller; diff --git a/samples/server/petstore/java-play-framework/app/controllers/PetApiControllerImp.java b/samples/server/petstore/java-play-framework/app/controllers/PetApiControllerImp.java index 9433941bc3f..d01b6dab626 100644 --- a/samples/server/petstore/java-play-framework/app/controllers/PetApiControllerImp.java +++ b/samples/server/petstore/java-play-framework/app/controllers/PetApiControllerImp.java @@ -1,50 +1,59 @@ package controllers; -import java.io.File; +import java.io.InputStream; import apimodels.Pet; import play.mvc.Http; import java.util.List; import java.util.ArrayList; import java.util.HashMap; +import java.io.FileInputStream; import javax.validation.constraints.*; public class PetApiControllerImp implements PetApiControllerImpInterface { + @Override public void addPet(Pet body) throws Exception { //Do your magic!!! } + @Override public void deletePet(Long petId, String apiKey) throws Exception { //Do your magic!!! } + @Override public List findPetsByStatus( List status) throws Exception { //Do your magic!!! return new ArrayList(); } + @Override public List findPetsByTags( List tags) throws Exception { //Do your magic!!! return new ArrayList(); } + @Override public Pet getPetById(Long petId) throws Exception { //Do your magic!!! return new Pet(); } + @Override public void updatePet(Pet body) throws Exception { //Do your magic!!! } + @Override public void updatePetWithForm(String petId, String name, String status) throws Exception { //Do your magic!!! } + @Override public void uploadFile(Long petId, String additionalMetadata, Http.MultipartFormData.FilePart file) throws Exception { //Do your magic!!! diff --git a/samples/server/petstore/java-play-framework/app/controllers/PetApiControllerImpInterface.java b/samples/server/petstore/java-play-framework/app/controllers/PetApiControllerImpInterface.java index c7c65c48ecd..ae52ce3cc3d 100644 --- a/samples/server/petstore/java-play-framework/app/controllers/PetApiControllerImpInterface.java +++ b/samples/server/petstore/java-play-framework/app/controllers/PetApiControllerImpInterface.java @@ -1,6 +1,6 @@ package controllers; -import java.io.File; +import java.io.InputStream; import apimodels.Pet; import play.mvc.Http; diff --git a/samples/server/petstore/java-play-framework/app/controllers/StoreApiControllerImp.java b/samples/server/petstore/java-play-framework/app/controllers/StoreApiControllerImp.java index e276e9c592c..bf151107bcf 100644 --- a/samples/server/petstore/java-play-framework/app/controllers/StoreApiControllerImp.java +++ b/samples/server/petstore/java-play-framework/app/controllers/StoreApiControllerImp.java @@ -7,24 +7,29 @@ import play.mvc.Http; import java.util.List; import java.util.ArrayList; import java.util.HashMap; +import java.io.FileInputStream; import javax.validation.constraints.*; public class StoreApiControllerImp implements StoreApiControllerImpInterface { + @Override public void deleteOrder(String orderId) throws Exception { //Do your magic!!! } + @Override public Map getInventory() throws Exception { //Do your magic!!! return new HashMap(); } + @Override public Order getOrderById(String orderId) throws Exception { //Do your magic!!! return new Order(); } + @Override public Order placeOrder(Order body) throws Exception { //Do your magic!!! return new Order(); diff --git a/samples/server/petstore/java-play-framework/app/controllers/UserApiControllerImp.java b/samples/server/petstore/java-play-framework/app/controllers/UserApiControllerImp.java index d4cdd55295c..14ec57ee007 100644 --- a/samples/server/petstore/java-play-framework/app/controllers/UserApiControllerImp.java +++ b/samples/server/petstore/java-play-framework/app/controllers/UserApiControllerImp.java @@ -7,44 +7,53 @@ import play.mvc.Http; import java.util.List; import java.util.ArrayList; import java.util.HashMap; +import java.io.FileInputStream; import javax.validation.constraints.*; public class UserApiControllerImp implements UserApiControllerImpInterface { + @Override public void createUser(User body) throws Exception { //Do your magic!!! } + @Override public void createUsersWithArrayInput(List body) throws Exception { //Do your magic!!! } + @Override public void createUsersWithListInput(List body) throws Exception { //Do your magic!!! } + @Override public void deleteUser(String username) throws Exception { //Do your magic!!! } + @Override public User getUserByName(String username) throws Exception { //Do your magic!!! return new User(); } + @Override public String loginUser( String username, String password) throws Exception { //Do your magic!!! return new String(); } + @Override public void logoutUser() throws Exception { //Do your magic!!! } + @Override public void updateUser(String username, User body) throws Exception { //Do your magic!!! From fea8699d8b12ee63c627f007767c646e1469f35c Mon Sep 17 00:00:00 2001 From: Simon Marti Date: Mon, 10 Apr 2017 17:25:09 +0200 Subject: [PATCH 2/3] Fix environment variable support in successive Maven plugin executions (#5351) * Fix environment variable support in successive Maven plugin executions System properties were retained across multiple successive executions, resulting in unpredictable behavior. Property values are now properly reset to their original value after plugin execution. Fixes #5350 * Add explanation to environment variable reset mechanism in Maven plugin --- .../java/io/swagger/codegen/plugin/CodeGenMojo.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/CodeGenMojo.java b/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/CodeGenMojo.java index b3df005872b..32a3b65cd63 100644 --- a/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/CodeGenMojo.java +++ b/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/CodeGenMojo.java @@ -381,9 +381,12 @@ public class CodeGenMojo extends AbstractMojo { } } + Map originalEnvironmentVariables = new HashMap<>(); + if (environmentVariables != null) { for(String key : environmentVariables.keySet()) { + originalEnvironmentVariables.put(key, System.getProperty(key)); String value = environmentVariables.get(key); if(value == null) { // don't put null values @@ -431,5 +434,15 @@ public class CodeGenMojo extends AbstractMojo { String sourceJavaFolder = output.toString() + "/" + sourceFolder; project.addCompileSourceRoot(sourceJavaFolder); } + + // Reset all environment variables to their original value. This prevents unexpected behaviour + // when running the plugin multiple consecutive times with different configurations. + for(Map.Entry entry : originalEnvironmentVariables.entrySet()) { + if(entry.getValue() == null) { + System.clearProperty(entry.getKey()); + } else { + System.setProperty(entry.getKey(), entry.getValue()); + } + } } } From 1734ac4ed0876715361581e3efff71bdbccdced1 Mon Sep 17 00:00:00 2001 From: Simon Marti Date: Mon, 10 Apr 2017 17:31:58 +0200 Subject: [PATCH 3/3] Add option to skip Maven plugin execution (#5337) * Add option to skip Maven plugin execution The execution is skipped if either the codegen.skip property or the configuration parameter is set. This is consistent with how many other Maven plugins, such as maven-exec-plugin and maven-clean-plugin, handle this. * Add documentation for Maven `skip` property --- .../swagger-codegen-maven-plugin/README.md | 1 + .../swagger/codegen/plugin/CodeGenMojo.java | 20 +++++++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/modules/swagger-codegen-maven-plugin/README.md b/modules/swagger-codegen-maven-plugin/README.md index 0b71c64b68f..789a503aca0 100644 --- a/modules/swagger-codegen-maven-plugin/README.md +++ b/modules/swagger-codegen-maven-plugin/README.md @@ -59,6 +59,7 @@ mvn clean compile - `generateModelDocumentation` - generate the model documentation (`true` by default. Only available if `generateModels` is `true`) - `generateSupportingFiles` - generate the supporting files (`true` by default) - `supportingFilesToGenerate` - A comma separated list of supporting files to generate. All files is the default. +- `skip` - skip code generation (`false` by default. Can also be set globally through the `codegen.skip` property) ### Custom Generator diff --git a/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/CodeGenMojo.java b/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/CodeGenMojo.java index 32a3b65cd63..998911ca3b0 100644 --- a/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/CodeGenMojo.java +++ b/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/CodeGenMojo.java @@ -228,7 +228,11 @@ public class CodeGenMojo extends AbstractMojo { @Parameter(name = "generateApiDocumentation", required = false) private Boolean generateApiDocumentation = true; - + /** + * Skip the execution. + */ + @Parameter(name = "skip", property = "codegen.skip", required = false, defaultValue = "false") + private Boolean skip; /** * Add the output directory to the project as a source root, so that the @@ -252,6 +256,14 @@ public class CodeGenMojo extends AbstractMojo { @Override public void execute() throws MojoExecutionException { + if(skip) { + getLog().info("Code generation is skipped."); + // Even when no new sources are generated, the existing ones should + // still be compiled if needed. + addCompileSourceRootIfConfigured(); + return; + } + //attempt to read from config file CodegenConfigurator configurator = CodegenConfigurator.fromFile(configurationFile); @@ -427,7 +439,11 @@ public class CodeGenMojo extends AbstractMojo { throw new MojoExecutionException("Code generation failed. See above for the full exception."); } - if (addCompileSourceRoot) { + addCompileSourceRootIfConfigured(); + } + + private void addCompileSourceRootIfConfigured() { + if(addCompileSourceRoot) { final Object sourceFolderObject = configOptions == null ? null : configOptions.get(CodegenConstants.SOURCE_FOLDER); final String sourceFolder = sourceFolderObject == null ? "src/main/java" : sourceFolderObject.toString();