io.swagger.codegen.v3.generators.java.MicronautCodegen Maven / Gradle / Ivy
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.*;
import io.swagger.codegen.v3.generators.features.BeanValidationFeatures;
import io.swagger.codegen.v3.generators.features.OptionalFeatures;
import io.swagger.codegen.v3.generators.handlebars.lambda.*;
import io.swagger.codegen.v3.utils.URLPathUtil;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.PathItem;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.net.URL;
import java.util.*;
import java.util.stream.Collectors;
import static io.swagger.codegen.v3.CodegenConstants.HAS_ENUMS_EXT_NAME;
import static io.swagger.codegen.v3.CodegenConstants.IS_ENUM_EXT_NAME;
import static io.swagger.codegen.v3.generators.handlebars.ExtensionHelper.getBooleanValue;
import static java.util.Collections.singletonList;
/**
* @author Franz See
*/
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";
private String title = "swagger-petstore";
private String configPackage = "io.swagger.configuration";
private String basePackage = "io.swagger";
private boolean useTags = false;
private boolean useBeanValidation = true;
private boolean implicitHeaders = false;
private boolean useOptional = false;
@SuppressWarnings("unused")
public MicronautCodegen() {
super();
init();
}
private void init() {
outputFolder = "generated-code/javaMicronaut";
apiPackage = "io.swagger.api";
modelPackage = "io.swagger.model";
invokerPackage = "io.swagger.api";
artifactId = "swagger-micronaut";
additionalProperties.put(CONFIG_PACKAGE, configPackage);
additionalProperties.put(BASE_PACKAGE, basePackage);
// micronaut uses the jackson lib
additionalProperties.put("jackson", "true");
cliOptions.add(new CliOption(TITLE, "server title name or client service name"));
cliOptions.add(new CliOption(CONFIG_PACKAGE, "configuration package for generated code"));
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"));
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 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.setEnum(supportedLibraries);
library.setDefault(DEFAULT_LIBRARY);
cliOptions.add(library);
}
@Override
public CodegenType getTag() {
return CodegenType.SERVER;
}
@Override
public String getName() {
return "micronaut";
}
@Override
public String getHelp() {
return "Generates a Java Micronaut Server application.";
}
@Override
public void processOpts() {
setUseOas2(false);
additionalProperties.put(CodegenConstants.USE_OAS2, false);
if (additionalProperties.containsKey("httpMethod")) {
String httpMethod = (String) additionalProperties.get("httpMethod");
String httpMethodNormalCase = Character.toUpperCase(httpMethod.charAt(0)) + httpMethod.substring(1);
additionalProperties.put("httpMethodNormalCase", httpMethodNormalCase);
}
// set invokerPackage as basePackage
if (additionalProperties.containsKey(CodegenConstants.INVOKER_PACKAGE)) {
this.setBasePackage((String) additionalProperties.get(CodegenConstants.INVOKER_PACKAGE));
additionalProperties.put(BASE_PACKAGE, basePackage);
LOGGER.info("Set base package to invoker package (" + basePackage + ")");
}
super.processOpts();
// clear model and api doc template as this codegen
// does not support auto-generated markdown doc at the moment
//TODO: add doc templates
modelDocTemplateFiles.remove("model_doc.mustache");
apiDocTemplateFiles.remove("api_doc.mustache");
if (additionalProperties.containsKey(TITLE)) {
this.setTitle((String) additionalProperties.get(TITLE));
}
if (additionalProperties.containsKey(CONFIG_PACKAGE)) {
this.setConfigPackage((String) additionalProperties.get(CONFIG_PACKAGE));
}
if (additionalProperties.containsKey(BASE_PACKAGE)) {
this.setBasePackage((String) additionalProperties.get(BASE_PACKAGE));
}
if (additionalProperties.get(USE_TAGS) != null) {
this.setUseTags(Boolean.parseBoolean(additionalProperties.get(USE_TAGS).toString()));
}
if (additionalProperties.containsKey(USE_BEANVALIDATION)) {
this.setUseBeanValidation(convertPropertyToBoolean(USE_BEANVALIDATION));
}
if (additionalProperties.containsKey(USE_OPTIONAL)) {
this.setUseOptional(convertPropertyToBoolean(USE_OPTIONAL));
}
boolean skipSupportFiles = false;
if (additionalProperties.get(SKIP_SUPPORT_FILES) != null) {
skipSupportFiles = Boolean.parseBoolean(additionalProperties.get(SKIP_SUPPORT_FILES).toString());
}
writePropertyBack(USE_BEANVALIDATION, useBeanValidation);
if (additionalProperties.get(IMPLICIT_HEADERS) != null) {
this.setImplicitHeaders(Boolean.parseBoolean(additionalProperties.get(IMPLICIT_HEADERS).toString()));
}
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"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("mvnw", "", "mvnw"));
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 + basePackage).replace(".", File.separator), "MainApplication.java"));
apiTemplateFiles.put("apiController.mustache", "Controller.java");
}
addHandlebarsLambdas(additionalProperties);
}
private void addHandlebarsLambdas(Map objs) {
Map lambdas = new ImmutableMap.Builder()
.put("lowercase", new LowercaseLambda().generator(this))
.put("uppercase", new UppercaseLambda())
.put("titlecase", new TitlecaseLambda())
.put("camelcase", new CamelCaseLambda().generator(this))
.put("camelcase_param", new CamelCaseLambda().generator(this).escapeAsParamName(true))
.put("indented", new IndentedLambda())
.put("indented_8", new IndentedLambda(8, " "))
.put("indented_12", new IndentedLambda(12, " "))
.put("indented_16", new IndentedLambda(16, " "))
.put("capitalise", new CapitaliseLambda())
.put("escapeDoubleQuote", new EscapeDoubleQuotesLambda())
.put("removeLineBreak", new RemoveLineBreakLambda())
.build();
if (objs.containsKey("lambda")) {
LOGGER.warn("An property named 'lambda' already exists. Mustache lambdas renamed from 'lambda' to '_lambda'. " +
"You'll likely need to use a custom template, " +
"see https://github.com/swagger-api/swagger-codegen#modifying-the-client-library-format. ");
objs.put("_lambda", lambdas);
} else {
objs.put("lambda", lambdas);
}
}
@Override
public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation co, Map> operations) {
if(!useTags) {
String basePath = resourcePath;
if (basePath.startsWith("/")) {
basePath = basePath.substring(1);
}
int pos = basePath.indexOf("/");
if (pos > 0) {
basePath = basePath.substring(0, pos);
}
if (basePath.equals("")) {
basePath = "default";
} else {
co.subresourceOperation = !co.path.isEmpty();
}
List opList = operations.computeIfAbsent(basePath, k -> new ArrayList<>());
opList.add(co);
co.baseName = basePath;
} else {
super.addOperationToGroup(tag, resourcePath, operation, co, operations);
}
}
@Override
public String getArgumentsLocation() {
return null;
}
@Override
public String getDefaultTemplateDir() {
return "JavaMicronaut";
}
@Override
public void preprocessOpenAPI(OpenAPI openAPI) {
super.preprocessOpenAPI(openAPI);
if(!additionalProperties.containsKey(TITLE)) {
// From the title, compute a reasonable name for the package and the API
String title = openAPI.getInfo().getTitle();
// Drop any API suffix
if (title != null) {
title = title.trim().replace(" ", "-");
if (title.toUpperCase().endsWith("API")) {
title = title.substring(0, title.length() - 3);
}
this.title = camelize(sanitizeName(title), true);
}
additionalProperties.put(TITLE, this.title);
}
final URL urlInfo = URLPathUtil.getServerURL(openAPI);
String port = "8080"; // Default value for a JEE Server
if ( urlInfo != null && urlInfo.getPort() != 0) {
port = String.valueOf(urlInfo.getPort());
}
this.additionalProperties.put("serverPort", port);
if (openAPI.getPaths() != null) {
for (String pathname : openAPI.getPaths().keySet()) {
PathItem pathItem = openAPI.getPaths().get(pathname);
final List operations = pathItem.readOperations();
for (Operation operation : operations) {
if (operation.getTags() != null) {
List
© 2015 - 2024 Weber Informatics LLC | Privacy Policy