Skip to content

Commit

Permalink
Merge pull request #1166 from swagger-api/micronaut-3
Browse files Browse the repository at this point in the history
Micronaut 3 update.
  • Loading branch information
HugoMario authored Jun 9, 2023
2 parents 07d2077 + 1c5d5f0 commit 66dcca9
Show file tree
Hide file tree
Showing 26 changed files with 256 additions and 201 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.swagger.codegen.v3.generators.java;

import com.github.jknack.handlebars.Handlebars;
import com.github.jknack.handlebars.Lambda;
import com.google.common.collect.ImmutableMap;
import io.swagger.codegen.v3.*;
Expand Down Expand Up @@ -30,10 +31,18 @@
public class MicronautCodegen extends AbstractJavaCodegen implements BeanValidationFeatures, OptionalFeatures {

private static Logger LOGGER = LoggerFactory.getLogger(MicronautCodegen.class);
private static final String DEFAULT_LIBRARY = "rxjava3";
private static final String RXJAVA3_LIBRARY = "rxjava3";
private static final String RXJAVA2_LIBRARY = "rxjava2";
private static final String REACTOR_LIBRARY = "reactor";
private static final String TITLE = "title";
private static final String CONFIG_PACKAGE = "configPackage";
private static final String BASE_PACKAGE = "basePackage";
private static final String USE_TAGS = "useTags";
private static final String USE_RXJAVA = "useRxJava";
private static final String USE_RXJAVA2 = "useRxJava2";
private static final String USE_RXJAVA3 = "useRxJava3";
private static final String USE_REACTOR = "useReactor";
private static final String IMPLICIT_HEADERS = "implicitHeaders";
private static final String SKIP_SUPPORT_FILES = "skipSupportFiles";

Expand Down Expand Up @@ -69,16 +78,21 @@ private void init() {
cliOptions.add(new CliOption(BASE_PACKAGE, "base package (invokerPackage) for generated code"));
cliOptions.add(new CliOption(SKIP_SUPPORT_FILES, "skip support files such as pom.xml, mvnw, etc from code generation."));
cliOptions.add(CliOption.newBoolean(USE_TAGS, "use tags for creating interface and controller classnames"));
cliOptions.add(CliOption.newBoolean(USE_BEANVALIDATION, "Use BeanValidation API annotations"));

CliOption useBeanValidation = CliOption.newBoolean(USE_BEANVALIDATION, "Use BeanValidation API annotations");
useBeanValidation.setDefault("true");
cliOptions.add(useBeanValidation);

cliOptions.add(CliOption.newBoolean(IMPLICIT_HEADERS, "Use of @ApiImplicitParams for headers."));
cliOptions.add(CliOption.newBoolean(USE_OPTIONAL,
"Use Optional container for optional parameters"));

supportedLibraries.put(DEFAULT_LIBRARY, "Java Micronaut Server application.");
supportedLibraries.put(DEFAULT_LIBRARY, "Java Micronaut Server application with RxJava3 reactive streams implementation");
supportedLibraries.put(USE_RXJAVA2, "Java Micronaut Server application with RxJava2 reactive streams implementation");
supportedLibraries.put(REACTOR_LIBRARY, "Java Micronaut Server application with Project Reactor reactive streams implementation");
setLibrary(DEFAULT_LIBRARY);

CliOption library = new CliOption(CodegenConstants.LIBRARY, "library template (sub-template) to use");
library.setDefault(DEFAULT_LIBRARY);
library.setEnum(supportedLibraries);
library.setDefault(DEFAULT_LIBRARY);
cliOptions.add(library);
Expand Down Expand Up @@ -138,8 +152,8 @@ public void processOpts() {
this.setBasePackage((String) additionalProperties.get(BASE_PACKAGE));
}

if (additionalProperties.containsKey(USE_TAGS)) {
this.setUseTags(Boolean.valueOf(additionalProperties.get(USE_TAGS).toString()));
if (additionalProperties.get(USE_TAGS) != null) {
this.setUseTags(Boolean.parseBoolean(additionalProperties.get(USE_TAGS).toString()));
}

if (additionalProperties.containsKey(USE_BEANVALIDATION)) {
Expand All @@ -151,21 +165,23 @@ public void processOpts() {
}

boolean skipSupportFiles = false;
if (additionalProperties.containsKey(SKIP_SUPPORT_FILES)) {
skipSupportFiles = Boolean.valueOf(additionalProperties.get(SKIP_SUPPORT_FILES).toString());
if (additionalProperties.get(SKIP_SUPPORT_FILES) != null) {
skipSupportFiles = Boolean.parseBoolean(additionalProperties.get(SKIP_SUPPORT_FILES).toString());
}

if (useBeanValidation) {
writePropertyBack(USE_BEANVALIDATION, useBeanValidation);
}
writePropertyBack(USE_BEANVALIDATION, useBeanValidation);

if (additionalProperties.containsKey(IMPLICIT_HEADERS)) {
this.setImplicitHeaders(Boolean.valueOf(additionalProperties.get(IMPLICIT_HEADERS).toString()));
if (additionalProperties.get(IMPLICIT_HEADERS) != null) {
this.setImplicitHeaders(Boolean.parseBoolean(additionalProperties.get(IMPLICIT_HEADERS).toString()));
}

if (useOptional) {
writePropertyBack(USE_OPTIONAL, useOptional);
writePropertyBack(USE_OPTIONAL, useOptional);
if (isRxJava2Library()) {
additionalProperties.put(USE_RXJAVA2, true);
} else {
additionalProperties.put(USE_RXJAVA3, isRxJava3Library());
}
additionalProperties.put(USE_REACTOR, isReactorLibrary());

if (!skipSupportFiles) {
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
Expand All @@ -174,7 +190,8 @@ public void processOpts() {
supportingFiles.add(new SupportingFile("mvnw.cmd", "", "mvnw.cmd"));
supportingFiles.add(new SupportingFile("unsupportedOperationExceptionHandler.mustache",
(sourceFolder + File.separator + configPackage).replace(".", File.separator), "UnsupportedOperationExceptionHandler.java"));
supportingFiles.add(new SupportingFile("mainApplication.mustache", (sourceFolder + File.separator).replace(".", File.separator), "MainApplication.java"));
supportingFiles.add(new SupportingFile("mainApplication.mustache", (sourceFolder + File.separator + basePackage).replace(".", File.separator), "MainApplication.java"));
apiTemplateFiles.put("apiController.mustache", "Controller.java");
}
addHandlebarsLambdas(additionalProperties);
}
Expand Down Expand Up @@ -529,4 +546,22 @@ public void setUseBeanValidation(boolean useBeanValidation) {
public void setUseOptional(boolean useOptional) {
this.useOptional = useOptional;
}

@Override
public void addHandlebarHelpers(Handlebars handlebars) {
handlebars.setInfiniteLoops(true);
super.addHandlebarHelpers(handlebars);
}

private boolean isRxJava2Library() {
return library.equals(RXJAVA2_LIBRARY);
}

private boolean isRxJava3Library() {
return library.equals(RXJAVA3_LIBRARY);
}

private boolean isReactorLibrary() {
return library.equals(REACTOR_LIBRARY);
}
}
20 changes: 15 additions & 5 deletions src/main/resources/handlebars/JavaMicronaut/api.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,20 @@ package {{package}};
import com.fasterxml.jackson.databind.ObjectMapper;
import io.micronaut.http.*;
import io.micronaut.http.annotation.*;
{{#useRxJava3}}
import io.reactivex.rxjava3.core.Single;
{{/useRxJava3}}
{{^useRxJava3}}
{{#useRxJava2}}
import io.reactivex.Single;
{{/useRxJava2}}
{{/useRxJava3}}
import io.swagger.v3.oas.annotations.*;
import io.swagger.v3.oas.annotations.responses.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
{{#useReactor}}
import org.reactivestreams.Publisher;
import reactor.core.publisher.Mono;
{{/useReactor}}

{{#useBeanValidation}}
{{#jakarta}}
Expand All @@ -31,11 +40,12 @@ import javax.validation.constraints.*;
import java.io.IOException;
import java.util.List;
import java.util.Map;
{{#useOptional}}
import java.util.Optional;
{{/useOptional}}

{{>generatedAnnotation}}
{{#operations}}
@Controller
public interface {{classname}} {
{{#operation}}
Expand All @@ -53,8 +63,8 @@ public interface {{classname}} {
})
{{/implicitHeaders}}
@{{#lambda.capitalise}}{{httpMethod}}{{/lambda.capitalise}}(value = "{{{path}}}"{{#hasProduces}}, produces = { {{#produces}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }{{/hasProduces}}{{#hasConsumes}}, consumes = {{braces "left"}}{{#consumes}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/consumes}}{{braces "right"}}{{/hasConsumes}})
default Single<HttpResponse<{{>returnTypes}}>> {{operationId}}({{#parameters}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{#hasMore}},{{/hasMore}}{{/parameters}}) {
return Single.fromCallable(() -> {
default Single<HttpResponse<{{>returnTypes}}>> {{operationId}}({{#parameters}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>cookieParams}}{{>bodyParams}}{{>formParams}}{{#hasMore}},{{/hasMore}}{{/parameters}}) {
return {{^useReactor}}Single{{/useReactor}}{{#useReactor}}Mono{{/useReactor}}.fromCallable(() -> {
throw new UnsupportedOperationException();
});
}
Expand Down
55 changes: 55 additions & 0 deletions src/main/resources/handlebars/JavaMicronaut/apiController.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package {{package}};

{{#imports}}
import {{import}};

{{/imports}}
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.HttpResponse;
{{#useRxJava3}}
import io.reactivex.rxjava3.core.Single;
{{/useRxJava3}}
{{^useRxJava3}}
{{#useRxJava2}}
import io.reactivex.Single;
{{/useRxJava2}}
{{/useRxJava3}}
{{#useReactor}}
import org.reactivestreams.Publisher;
import reactor.core.publisher.Mono;
{{/useReactor}}

{{#useBeanValidation}}
import javax.annotation.Nullable;
import javax.validation.Valid;
import javax.validation.constraints.*;
{{/useBeanValidation}}
import java.util.List;
import java.util.Map;
{{#useOptional}}
import java.util.Optional;
{{/useOptional}}

{{#operations}}
@Controller
public class {{classname}}Controller implements {{classname}} {
{{#operation}}
{{#contents}}

@Override
public Single<HttpResponse<{{>returnTypes}}>> {{operationId}}({{#parameters}}{{#useBeanValidation}}{{!
Bean validation spec for path parameters (PathParam is always required)
}}{{#isPathParam}}{{>beanValidationParams}}{{/isPathParam}}{{!
Bean validation spec for any other parameters
}}{{^isPathParam}}{{>nullableBeanValidationParams}}{{/isPathParam}}{{/useBeanValidation}}{{!
Method argument type and name
}}{{>optionalDataType}} {{paramName}}{{!
Arguments separator, if required
}}{{#hasMore}}, {{/hasMore}}{{/parameters}}) {
// TODO: Implement me
return {{classname}}.super.{{operationId}}({{#parameters}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/parameters}});
}
{{/contents}}
{{/operation}}
}
{{/operations}}
19 changes: 9 additions & 10 deletions src/main/resources/handlebars/JavaMicronaut/api_test.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,12 @@ package {{package}};

import io.micronaut.http.HttpResponse;
import io.micronaut.http.HttpStatus;
import io.micronaut.test.annotation.MicronautTest;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import org.junit.jupiter.api.Test;

{{#jakarta}}
{{#useReactor}}
import reactor.core.publisher.Mono;
{{/useReactor}}
import jakarta.inject.Inject;
{{/jakarta}}
{{^jakarta}}
import javax.inject.Inject;
{{/jakarta}}

import java.util.*;

Expand All @@ -28,18 +25,20 @@ class {{classname}}ControllerTest {
{{#operations}}
{{#operation}}
{{#contents}}
{{#@first}}
@Test
void {{operationId}}{{#isForm}}WithForm{{/isForm}}Test() {
void {{operationId}}{{#isForm}}Form{{/isForm}}Test() {
{{#parameters}}
{{{dataType}}} {{paramName}} = {{{example}}};
{{{dataType}}} {{paramName}} = null;
{{/parameters}}
try {
api.{{operationId}}({{#parameters}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/parameters}}).blockingGet();
//TODO: {{#useReactor}}Mono.from({{/useReactor}}api.{{operationId}}({{#parameters}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/parameters}}){{#useReactor}}){{/useReactor}}{{^useReactor}}.blockingGet();{{/useReactor}}{{#useReactor}}.block();{{/useReactor}}
} catch (UnsupportedOperationException e) {
assumeTrue(false, "API is not yet implemented");
}
}

{{/@first}}
{{/contents}}
{{/operation}}
{{/operations}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
{{/required}}{{#isContainer}}{{^isPrimitiveType}}{{^isEnum}}
@Valid{{/isEnum}}{{/isPrimitiveType}}{{/isContainer}}{{#isNotContainer}}{{^isPrimitiveType}}
@Valid{{/isPrimitiveType}}{{/isNotContainer}}
{{>beanValidationCore}}
{{>beanValidationCore}}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{#useBeanValidation}}{{>beanValidationParamsInner}}{{>beanValidationCore}}{{/useBeanValidation}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{{^isPrimitiveType}}{{^isEnum}}{{!
Non-container
}}{{^isContainer}}@Valid {{/isContainer}}{{!
Container
}}{{#isContainer}}{{#items}}{{>beanValidationParamsInner}}{{/items}}{{/isContainer}}{{/isEnum}}{{/isPrimitiveType}}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1 +1 @@
{{#isBodyParam}}@Parameter(description = "{{{description}}}") {{#useBeanValidation}}@Valid {{/useBeanValidation}}@Body {{{dataType}}} {{paramName}}{{/isBodyParam}}
{{#isBodyParam}}{{>nullableBeanValidationParams}}@Parameter(description = "{{{description}}}") @Body {{{dataType}}} {{paramName}}{{/isBodyParam}}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{#isCookieParam}}{{>nullableBeanValidationParams}}@Parameter(description = "{{{description}}}") @CookieValue(value="{{baseName}}") {{>optionalDataType}} {{paramName}}{{/isCookieParam}}
23 changes: 8 additions & 15 deletions src/main/resources/handlebars/JavaMicronaut/enumClass.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,16 @@
* {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{{description}}}{{/description}}
*/
public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} {
{{#allowableValues}}
{{#enumVars}}
{{#gson}}
{{#allowableValues}}
{{#enumVars}}
@SerializedName({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}})
{{{name}}}({{{value}}}){{^@last}},
{{/@last}}{{#@last}};{{/@last}}
{{/enumVars}}
{{/allowableValues}}
{{/gson}}
{{^gson}}
{{#allowableValues}}
{{#enumVars}}
{{{name}}}({{{value}}}){{^@last}},
{{/@last}}{{#@last}};{{/@last}}
{{/enumVars}}
{{/allowableValues}}
{{#value}}
@SerializedName({{{toQuotedWord value}}})
{{/value}}
{{/gson}}
{{{name}}}({{#value}}{{{value}}}{{/value}}{{^value}}null{{/value}}){{^@last}},{{/@last}}{{#@last}};{{/@last}}
{{/enumVars}}
{{/allowableValues}}

private {{{datatype}}} value;

Expand Down
21 changes: 10 additions & 11 deletions src/main/resources/handlebars/JavaMicronaut/enumOuterClass.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,16 @@ import com.fasterxml.jackson.annotation.JsonCreator;
* {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{{description}}}{{/description}}
*/
public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} {
{{#gson}}
{{#allowableValues}}{{#enumVars}}
@SerializedName({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}})
{{{name}}}({{{value}}}){{^@last}},
{{/@last}}{{#@last}};{{/@last}}{{/enumVars}}{{/allowableValues}}
{{/gson}}
{{^gson}}
{{#allowableValues}}{{#enumVars}}
{{{name}}}({{{value}}}){{^@last}},
{{/@last}}{{#@last}};{{/@last}}{{/enumVars}}{{/allowableValues}}
{{/gson}}
{{#allowableValues}}
{{#enumVars}}
{{#gson}}
{{#value}}
@SerializedName({{{toQuotedWord value}}})
{{/value}}
{{/gson}}
{{{name}}}({{#value}}{{{value}}}{{/value}}{{^value}}null{{/value}}){{^@last}},{{/@last}}{{#@last}};{{/@last}}
{{/enumVars}}
{{/allowableValues}}

private {{{dataType}}} value;

Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{{#isFormParam}}{{#notFile}}@Parameter(description = "{{{description}}}") @QueryValue(value = "{{baseName}}") {{{dataType}}} {{paramName}}{{/notFile}}{{#isFile}}@Parameter(description = "file detail") {{#useBeanValidation}}@Valid {{/useBeanValidation}}MultipartFile {{baseName}}{{/isFile}}{{/isFormParam}}
{{#isFormParam}}{{#notFile}}{{>nullableBeanValidationParams}}@Parameter(description = "{{{description}}}") @Body(value = "{{baseName}}") {{{dataType}}} {{paramName}}{{/notFile}}{{#isFile}}@Parameter(description = "file detail") {{#useBeanValidation}}@Valid {{/useBeanValidation}}File {{baseName}}{{/isFile}}{{/isFormParam}}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{{#isHeaderParam}}{{#useBeanValidation}}{{>beanValidationHeaderParams}}{{/useBeanValidation}}@Parameter(description = "{{{description}}}") {{#useBeanValidation}}@Valid {{/useBeanValidation}}@Header(value = "{{baseName}}") {{>optionalDataType}} {{paramName}}{{/isHeaderParam}}
{{#isHeaderParam}}{{>nullableBeanValidationParams}}@Parameter(description = "{{{description}}}") @Header(value = "{{baseName}}") {{>optionalDataType}} {{paramName}}{{/isHeaderParam}}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import io.swagger.v3.oas.annotations.info.*;
info = @Info(
title = "{{appName}}",
version = "{{appVersion}}",
description = "{{appDescription}}",
description = "{{{appDescription}}}",
contact = @Contact(
name = "{{infoName}}",
email = "{{infoEmail}}"
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/handlebars/JavaMicronaut/model.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import java.util.Objects;
import java.io.Serializable;
{{/serializableModel}}
{{#useBeanValidation}}
import io.micronaut.core.annotation.Introspected;
import io.micronaut.validation.Validated;
{{#jakarta}}
import jakarta.validation.Valid;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{#useBeanValidation}}{{#required}}@NotNull {{/required}}{{^required}}@Nullable {{/required}}{{>beanValidationParams}}{{/useBeanValidation}}
Loading

0 comments on commit 66dcca9

Please sign in to comment.