Skip to content

Commit

Permalink
Merge pull request #160 from swagger-api/spring-generator-update
Browse files Browse the repository at this point in the history
Spring generator update
  • Loading branch information
HugoMario authored Aug 31, 2018
2 parents 6e92a85 + 9ecd799 commit 92dadca
Show file tree
Hide file tree
Showing 54 changed files with 2,050 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1980,9 +1980,8 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation
schema = schemas.get(schemaName);
}
final Map<String, Schema> propertyMap = schema.getProperties();
boolean isMultipart = body.getContent().containsKey("multipart/form-data");
if (propertyMap != null && !propertyMap.isEmpty()) {
boolean isMultipart = body.getContent().containsKey("multipart/form-data");

for (String propertyName : propertyMap.keySet()) {
CodegenParameter codegenParameter = fromParameter(new Parameter()
.name(propertyName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
import io.swagger.codegen.v3.SupportingFile;
import io.swagger.codegen.v3.generators.features.BeanValidationFeatures;
import io.swagger.codegen.v3.generators.features.OptionalFeatures;
import io.swagger.codegen.v3.templates.MustacheTemplateEngine;
import io.swagger.codegen.v3.templates.TemplateEngine;
import io.swagger.codegen.v3.utils.URLPathUtil;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
Expand Down Expand Up @@ -130,6 +132,8 @@ public String getHelp() {

@Override
public void processOpts() {
setUseOas2(true);
additionalProperties.put(CodegenConstants.USE_OAS2, true);

// Process java8 option before common java ones to change the default dateLibrary to java8.
if (additionalProperties.containsKey(JAVA_8)) {
Expand All @@ -153,12 +157,7 @@ public void processOpts() {
super.processOpts();

if (StringUtils.isBlank(templateDir)) {
String templateVersion = getTemplateVersion();
if (StringUtils.isNotBlank(templateVersion)) {
embeddedTemplateDir = templateDir = String.format("%s" + File.separator + "JavaSpring", templateVersion);
} else {
embeddedTemplateDir = templateDir = String.format("%s" + File.separator + "JavaSpring", DEFAULT_TEMPLATE_VERSION);
}
embeddedTemplateDir = templateDir = "mustache" + File.separator + "JavaSpring";
}

// clear model and api doc template as this codegen
Expand Down Expand Up @@ -247,9 +246,10 @@ public void processOpts() {
}
}

supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));

if (!this.interfaceOnly) {
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));

if (library.equals(DEFAULT_LIBRARY)) {
supportingFiles.add(new SupportingFile("homeController.mustache",
Expand Down Expand Up @@ -326,10 +326,6 @@ public void processOpts() {
if (this.async) {
additionalProperties.put(RESPONSE_WRAPPER, "CompletableFuture");
}
typeMapping.put("date", "LocalDate");
typeMapping.put("DateTime", "OffsetDateTime");
importMapping.put("LocalDate", "java.time.LocalDate");
importMapping.put("OffsetDateTime", "java.time.OffsetDateTime");
} else if (this.async) {
additionalProperties.put(RESPONSE_WRAPPER, "Callable");
}
Expand Down Expand Up @@ -373,8 +369,6 @@ public void execute(Template.Fragment fragment, Writer writer) throws IOExceptio
writer.write(fragment.execute().replaceAll("\\r|\\n", ""));
}
});

importMapping.put("JsonTypeId", "com.fasterxml.jackson.annotation.JsonTypeId");
}

@Override
Expand Down Expand Up @@ -471,21 +465,13 @@ public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
if (operations != null) {
List<CodegenOperation> ops = (List<CodegenOperation>) operations.get("operation");
for (final CodegenOperation operation : ops) {
boolean multipleReturnTypes = false;
String previousReturnType = null;

List<CodegenResponse> responses = operation.responses;
if (responses != null) {
for (final CodegenResponse resp : responses) {
if ("0".equals(resp.code)) {
resp.code = "200";
}

if (previousReturnType != null && !previousReturnType.equals(resp.dataType)) {
multipleReturnTypes = true;
}

doDataTypeAssignment(resp.dataType, new SpringCodegen.DataTypeAssigner() {
doDataTypeAssignment(resp.dataType, new DataTypeAssigner() {
@Override
public void setReturnType(final String returnType) {
resp.dataType = returnType;
Expand All @@ -496,15 +482,10 @@ public void setReturnContainer(final String returnContainer) {
resp.containerType = returnContainer;
}
});
previousReturnType = resp.dataType;
}
}

if (multipleReturnTypes) {
operation.returnType = "?";
}

doDataTypeAssignment(operation.returnType, new SpringCodegen.DataTypeAssigner() {

doDataTypeAssignment(operation.returnType, new DataTypeAssigner() {

@Override
public void setReturnType(final String returnType) {
Expand Down Expand Up @@ -629,6 +610,15 @@ public void setParameterExampleValue(CodegenParameter p) {
}
}

public String toBooleanGetter(String name) {
return getterAndSetterCapitalize(name);
}

@Override
public TemplateEngine getTemplateEngine() {
return new MustacheTemplateEngine(this);
}

public void setTitle(String title) {
this.title = title;
}
Expand Down Expand Up @@ -692,7 +682,7 @@ public void postProcessModelProperty(CodegenModel model, CodegenProperty propert
if (model.discriminator != null && model.discriminator.getPropertyName().equals(property.baseName)) {
property.vendorExtensions.put("x-is-discriminator-property", true);

model.imports.add("JsonTypeId");
//model.imports.add("JsonTypeId");
}
}

Expand Down
136 changes: 136 additions & 0 deletions src/main/resources/mustache/JavaSpring/api.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/**
* NOTE: This class is auto generated by the swagger code generator program ({{{generatorVersion}}}).
* https://github.com/swagger-api/swagger-codegen
* Do not edit the class manually.
*/
package {{package}};

{{#imports}}import {{import}};
{{/imports}}
{{#jdk8-no-delegate}}
import com.fasterxml.jackson.databind.ObjectMapper;
{{/jdk8-no-delegate}}
import io.swagger.annotations.*;
{{#jdk8-no-delegate}}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
{{/jdk8-no-delegate}}
import org.springframework.http.ResponseEntity;
{{#useBeanValidation}}
import org.springframework.validation.annotation.Validated;
{{/useBeanValidation}}
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;

{{#jdk8-no-delegate}}
import javax.servlet.http.HttpServletRequest;
{{/jdk8-no-delegate}}
{{#useBeanValidation}}
import javax.validation.Valid;
import javax.validation.constraints.*;
{{/useBeanValidation}}
{{#jdk8-no-delegate}}
import java.io.IOException;
{{/jdk8-no-delegate}}
import java.util.List;
import java.util.Map;
{{#jdk8-no-delegate}}
import java.util.Optional;
{{/jdk8-no-delegate}}
{{^jdk8-no-delegate}}
{{#useOptional}}
import java.util.Optional;
{{/useOptional}}
{{/jdk8-no-delegate}}
{{#async}}
import java.util.concurrent.{{^jdk8}}Callable{{/jdk8}}{{#jdk8}}CompletableFuture{{/jdk8}};
{{/async}}
{{>generatedAnnotation}}
@Api(value = "{{{baseName}}}", description = "the {{{baseName}}} API")
{{#operations}}
public interface {{classname}} {
{{#jdk8}}

{{^isDelegate}}
Logger log = LoggerFactory.getLogger({{classname}}.class);

default Optional<ObjectMapper> getObjectMapper() {
return Optional.empty();
}

default Optional<HttpServletRequest> getRequest() {
return Optional.empty();
}

default Optional<String> getAcceptHeader() {
return getRequest().map(r -> r.getHeader("Accept"));
}
{{/isDelegate}}
{{#isDelegate}}
{{classname}}Delegate getDelegate();
{{/isDelegate}}
{{/jdk8}}
{{#operation}}

@ApiOperation(value = "{{{summary}}}", nickname = "{{{operationId}}}", notes = "{{{notes}}}"{{#returnBaseType}}, response = {{{returnBaseType}}}.class{{/returnBaseType}}{{#returnContainer}}, responseContainer = "{{{returnContainer}}}"{{/returnContainer}}{{#hasAuthMethods}}, authorizations = {
{{#authMethods}}@Authorization(value = "{{name}}"{{#isOAuth}}, scopes = {
{{#scopes}}@AuthorizationScope(scope = "{{scope}}", description = "{{description}}"){{#hasMore}},
{{/hasMore}}{{/scopes}}
}{{/isOAuth}}){{#hasMore}},
{{/hasMore}}{{/authMethods}}
}{{/hasAuthMethods}}, tags={ {{#vendorExtensions.x-tags}}"{{tag}}",{{/vendorExtensions.x-tags}} })
@ApiResponses(value = { {{#responses}}
@ApiResponse(code = {{{code}}}, message = "{{{message}}}"{{#baseType}}, response = {{{baseType}}}.class{{/baseType}}{{#containerType}}, responseContainer = "{{{containerType}}}"{{/containerType}}){{#hasMore}},{{/hasMore}}{{/responses}} })
{{#implicitHeaders}}
@ApiImplicitParams({
{{#headerParams}}
{{>implicitHeader}}
{{/headerParams}}
})
{{/implicitHeaders}}
@RequestMapping(value = "{{{path}}}",{{#singleContentTypes}}{{#hasProduces}}
produces = "{{{vendorExtensions.x-accepts}}}", {{/hasProduces}}{{#hasConsumes}}
consumes = "{{{vendorExtensions.x-contentType}}}",{{/hasConsumes}}{{/singleContentTypes}}{{^singleContentTypes}}{{#hasProduces}}
produces = { {{#produces}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }, {{/hasProduces}}{{#hasConsumes}}
consumes = { {{#consumes}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} },{{/hasConsumes}}{{/singleContentTypes}}
method = RequestMethod.{{httpMethod}})
{{#jdk8}}default {{/jdk8}}{{#responseWrapper}}{{.}}<{{/responseWrapper}}ResponseEntity<{{>returnTypes}}>{{#responseWrapper}}>{{/responseWrapper}} {{#delegate-method}}_{{/delegate-method}}{{operationId}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{#hasMore}},{{/hasMore}}{{/allParams}}){{^jdk8}};{{/jdk8}}{{#jdk8}} {
{{#delegate-method}}
return {{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
}

// Override this method
default {{#responseWrapper}}{{.}}<{{/responseWrapper}}ResponseEntity<{{>returnTypes}}>{{#responseWrapper}}>{{/responseWrapper}} {{operationId}}({{#allParams}}{{^isFile}}{{{dataType}}}{{/isFile}}{{#isFile}}MultipartFile{{/isFile}} {{paramName}}{{#hasMore}},{{/hasMore}}{{/allParams}}) {
{{/delegate-method}}
{{^isDelegate}}
if(getObjectMapper().isPresent() && getAcceptHeader().isPresent()) {
{{#examples}}
if (getAcceptHeader().get().contains("{{{contentType}}}")) {
try {
return {{#async}}CompletableFuture.completedFuture({{/async}}new ResponseEntity<>(getObjectMapper().get().readValue("{{#lambdaRemoveLineBreak}}{{#lambdaEscapeDoubleQuote}}{{{example}}}{{/lambdaEscapeDoubleQuote}}{{/lambdaRemoveLineBreak}}", {{>exampleReturnTypes}}.class), HttpStatus.NOT_IMPLEMENTED){{#async}}){{/async}};
} catch (IOException e) {
log.error("Couldn't serialize response for content type {{{contentType}}}", e);
return {{#async}}CompletableFuture.completedFuture({{/async}}new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR){{#async}}){{/async}};
}
}
{{/examples}}
} else {
log.warn("ObjectMapper or HttpServletRequest not configured in default {{classname}} interface so no example is generated");
}
return {{#async}}CompletableFuture.completedFuture({{/async}}new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED){{#async}}){{/async}};
{{/isDelegate}}
{{#isDelegate}}
return getDelegate().{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
{{/isDelegate}}
}{{/jdk8}}

{{/operation}}
}
{{/operations}}
Loading

0 comments on commit 92dadca

Please sign in to comment.