![JAR search and dependency download from the Maven repository](/logo.png)
org.openapitools.codegen.languages.JavaClientCodegen Maven / Gradle / Ivy
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
* Copyright 2018 SmartBear Software
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.codegen.languages;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.media.Schema;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.*;
import org.openapitools.codegen.languages.features.BeanValidationFeatures;
import org.openapitools.codegen.languages.features.GzipFeatures;
import org.openapitools.codegen.languages.features.PerformBeanValidationFeatures;
import org.openapitools.codegen.meta.features.DocumentationFeature;
import org.openapitools.codegen.meta.features.GlobalFeature;
import org.openapitools.codegen.templating.mustache.CaseFormatLambda;
import org.openapitools.codegen.utils.ProcessUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static com.google.common.base.CaseFormat.LOWER_CAMEL;
import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE;
import static java.util.Collections.sort;
import static org.openapitools.codegen.utils.StringUtils.camelize;
public class JavaClientCodegen extends AbstractJavaCodegen
implements BeanValidationFeatures, PerformBeanValidationFeatures, GzipFeatures {
static final String MEDIA_TYPE = "mediaType";
private final Logger LOGGER = LoggerFactory.getLogger(JavaClientCodegen.class);
public static final String USE_RX_JAVA = "useRxJava";
public static final String USE_RX_JAVA2 = "useRxJava2";
public static final String USE_RX_JAVA3 = "useRxJava3";
public static final String DO_NOT_USE_RX = "doNotUseRx";
public static final String USE_PLAY_WS = "usePlayWS";
public static final String PLAY_VERSION = "playVersion";
public static final String ASYNC_NATIVE = "asyncNative";
public static final String CONFIG_KEY = "configKey";
public static final String PARCELABLE_MODEL = "parcelableModel";
public static final String USE_RUNTIME_EXCEPTION = "useRuntimeException";
public static final String USE_REFLECTION_EQUALS_HASHCODE = "useReflectionEqualsHashCode";
public static final String CASE_INSENSITIVE_RESPONSE_HEADERS = "caseInsensitiveResponseHeaders";
public static final String MICROPROFILE_FRAMEWORK = "microprofileFramework";
public static final String USE_ABSTRACTION_FOR_FILES = "useAbstractionForFiles";
public static final String DYNAMIC_OPERATIONS = "dynamicOperations";
public static final String SUPPORT_STREAMING = "supportStreaming";
public static final String GRADLE_PROPERTIES= "gradleProperties";
public static final String ERROR_OBJECT_TYPE= "errorObjectType";
public static final String ERROR_OBJECT_SUBTYPE= "errorObjectSubtype";
public static final String PLAY_24 = "play24";
public static final String PLAY_25 = "play25";
public static final String PLAY_26 = "play26";
public static final String MICROPROFILE_DEFAULT = "default";
public static final String MICROPROFILE_KUMULUZEE = "kumuluzee";
public static final String FEIGN = "feign";
public static final String GOOGLE_API_CLIENT = "google-api-client";
public static final String JERSEY1 = "jersey1";
public static final String JERSEY2 = "jersey2";
public static final String NATIVE = "native";
public static final String OKHTTP_GSON = "okhttp-gson";
public static final String OKHTTP_GSON_NEXTGEN = "okhttp-gson-nextgen";
public static final String RESTEASY = "resteasy";
public static final String RESTTEMPLATE = "resttemplate";
public static final String WEBCLIENT = "webclient";
public static final String REST_ASSURED = "rest-assured";
public static final String RETROFIT_2 = "retrofit2";
public static final String VERTX = "vertx";
public static final String MICROPROFILE = "microprofile";
public static final String APACHE = "apache-httpclient";
public static final String SERIALIZATION_LIBRARY_GSON = "gson";
public static final String SERIALIZATION_LIBRARY_JACKSON = "jackson";
public static final String SERIALIZATION_LIBRARY_JSONB = "jsonb";
protected String gradleWrapperPackage = "gradle.wrapper";
protected boolean useRxJava = false;
protected boolean useRxJava2 = false;
protected boolean useRxJava3 = false;
// backwards compatibility for openapi configs that specify neither rx1 nor rx2
// (mustache does not allow for boolean operators so we need this extra field)
protected boolean doNotUseRx = true;
protected boolean usePlayWS = false;
protected String playVersion = PLAY_26;
protected String microprofileFramework = MICROPROFILE_DEFAULT;
protected String configKey = null;
protected boolean asyncNative = false;
protected boolean parcelableModel = false;
protected boolean useBeanValidation = false;
protected boolean performBeanValidation = false;
protected boolean useGzipFeature = false;
protected boolean useRuntimeException = false;
protected boolean useReflectionEqualsHashCode = false;
protected boolean caseInsensitiveResponseHeaders = false;
protected boolean useAbstractionForFiles = false;
protected boolean dynamicOperations = false;
protected boolean supportStreaming = false;
protected String gradleProperties;
protected String errorObjectType;
protected List errorObjectSubtype;
protected String authFolder;
protected String serializationLibrary = null;
public JavaClientCodegen() {
super();
// TODO: Move GlobalFeature.ParameterizedServer to library: jersey after moving featureSet to generatorMetadata
modifyFeatureSet(features -> features
.includeDocumentationFeatures(DocumentationFeature.Readme)
.includeGlobalFeatures(GlobalFeature.ParameterizedServer)
);
outputFolder = "generated-code" + File.separator + "java";
embeddedTemplateDir = templateDir = "Java";
invokerPackage = "org.openapitools.client";
artifactId = "openapi-java-client";
apiPackage = "org.openapitools.client.api";
modelPackage = "org.openapitools.client.model";
// cliOptions default redefinition need to be updated
updateOption(CodegenConstants.INVOKER_PACKAGE, this.getInvokerPackage());
updateOption(CodegenConstants.ARTIFACT_ID, this.getArtifactId());
updateOption(CodegenConstants.API_PACKAGE, apiPackage);
updateOption(CodegenConstants.MODEL_PACKAGE, modelPackage);
modelTestTemplateFiles.put("model_test.mustache", ".java");
cliOptions.add(CliOption.newBoolean(USE_RX_JAVA, "Whether to use the RxJava adapter with the retrofit2 library. IMPORTANT: this option has been deprecated and will be removed in the 5.x release."));
cliOptions.add(CliOption.newBoolean(USE_RX_JAVA2, "Whether to use the RxJava2 adapter with the retrofit2 library."));
cliOptions.add(CliOption.newBoolean(USE_RX_JAVA3, "Whether to use the RxJava3 adapter with the retrofit2 library."));
cliOptions.add(CliOption.newBoolean(PARCELABLE_MODEL, "Whether to generate models for Android that implement Parcelable with the okhttp-gson library."));
cliOptions.add(CliOption.newBoolean(USE_PLAY_WS, "Use Play! Async HTTP client (Play WS API)"));
cliOptions.add(CliOption.newString(PLAY_VERSION, "Version of Play! Framework (possible values \"play24\" (Deprecated), \"play25\" (Deprecated), \"play26\" (Default))"));
cliOptions.add(CliOption.newBoolean(USE_BEANVALIDATION, "Use BeanValidation API annotations"));
cliOptions.add(CliOption.newBoolean(PERFORM_BEANVALIDATION, "Perform BeanValidation"));
cliOptions.add(CliOption.newBoolean(USE_GZIP_FEATURE, "Send gzip-encoded requests"));
cliOptions.add(CliOption.newBoolean(USE_RUNTIME_EXCEPTION, "Use RuntimeException instead of Exception"));
cliOptions.add(CliOption.newBoolean(ASYNC_NATIVE, "If true, async handlers will be used, instead of the sync version"));
cliOptions.add(CliOption.newBoolean(USE_REFLECTION_EQUALS_HASHCODE, "Use org.apache.commons.lang3.builder for equals and hashCode in the models. WARNING: This will fail under a security manager, unless the appropriate permissions are set up correctly and also there's potential performance impact."));
cliOptions.add(CliOption.newBoolean(CASE_INSENSITIVE_RESPONSE_HEADERS, "Make API response's headers case-insensitive. Available on " + OKHTTP_GSON + ", " + JERSEY2 + " libraries"));
cliOptions.add(CliOption.newString(MICROPROFILE_FRAMEWORK, "Framework for microprofile. Possible values \"kumuluzee\""));
cliOptions.add(CliOption.newBoolean(USE_ABSTRACTION_FOR_FILES, "Use alternative types instead of java.io.File to allow passing bytes without a file on disk. Available on resttemplate, webclient, libraries"));
cliOptions.add(CliOption.newBoolean(DYNAMIC_OPERATIONS, "Generate operations dynamically at runtime from an OAS", this.dynamicOperations));
cliOptions.add(CliOption.newBoolean(SUPPORT_STREAMING, "Support streaming endpoint (beta)", this.supportStreaming));
cliOptions.add(CliOption.newString(GRADLE_PROPERTIES, "Append additional Gradle proeprties to the gradle.properties file"));
cliOptions.add(CliOption.newString(ERROR_OBJECT_TYPE, "Error Object type. (This option is for okhttp-gson-next-gen only)"));
cliOptions.add(CliOption.newString(CONFIG_KEY, "Config key in @RegisterRestClient. Default to none. Only `microprofile` supports this option."));
supportedLibraries.put(JERSEY1, "HTTP client: Jersey client 1.19.x. JSON processing: Jackson 2.9.x. Enable gzip request encoding using '-DuseGzipFeature=true'. IMPORTANT NOTE: jersey 1.x is no longer actively maintained so please upgrade to 'jersey2' or other HTTP libraries instead.");
supportedLibraries.put(JERSEY2, "HTTP client: Jersey client 2.25.1. JSON processing: Jackson 2.9.x");
supportedLibraries.put(FEIGN, "HTTP client: OpenFeign 10.x. JSON processing: Jackson 2.9.x.");
supportedLibraries.put(OKHTTP_GSON, "[DEFAULT] HTTP client: OkHttp 3.x. JSON processing: Gson 2.8.x. Enable Parcelable models on Android using '-DparcelableModel=true'. Enable gzip request encoding using '-DuseGzipFeature=true'.");
supportedLibraries.put(OKHTTP_GSON_NEXTGEN, "HTTP client: OkHttp 3.x. JSON processing: Gson 2.8.x.'. Better support for oneOf/anyOf with breaking changes. Will replace `okhttp-gson` in the 6.0.0 release. IMPORTANT: this may subject to breaking changes without further notice.");
supportedLibraries.put(RETROFIT_2, "HTTP client: OkHttp 3.x. JSON processing: Gson 2.x (Retrofit 2.3.0). Enable the RxJava adapter using '-DuseRxJava[2/3]=true'. (RxJava 1.x or 2.x or 3.x)");
supportedLibraries.put(RESTTEMPLATE, "HTTP client: Spring RestTemplate 4.x. JSON processing: Jackson 2.9.x");
supportedLibraries.put(WEBCLIENT, "HTTP client: Spring WebClient 5.x. JSON processing: Jackson 2.9.x");
supportedLibraries.put(RESTEASY, "HTTP client: Resteasy client 3.x. JSON processing: Jackson 2.9.x");
supportedLibraries.put(VERTX, "HTTP client: VertX client 3.x. JSON processing: Jackson 2.9.x");
supportedLibraries.put(GOOGLE_API_CLIENT, "HTTP client: Google API client 1.x. JSON processing: Jackson 2.9.x");
supportedLibraries.put(REST_ASSURED, "HTTP client: rest-assured : 4.x. JSON processing: Gson 2.x or Jackson 2.10.x. Only for Java 8");
supportedLibraries.put(NATIVE, "HTTP client: Java native HttpClient. JSON processing: Jackson 2.9.x. Only for Java11+");
supportedLibraries.put(MICROPROFILE, "HTTP client: Microprofile client 1.x. JSON processing: JSON-B");
supportedLibraries.put(APACHE, "HTTP client: Apache httpclient 4.x");
CliOption libraryOption = new CliOption(CodegenConstants.LIBRARY, "library template (sub-template) to use");
libraryOption.setEnum(supportedLibraries);
// set okhttp-gson as the default
libraryOption.setDefault(OKHTTP_GSON);
cliOptions.add(libraryOption);
setLibrary(OKHTTP_GSON);
CliOption serializationLibrary = new CliOption(CodegenConstants.SERIALIZATION_LIBRARY, "Serialization library, default depends on value of the option library");
Map serializationOptions = new HashMap<>();
serializationOptions.put(SERIALIZATION_LIBRARY_GSON, "Use Gson as serialization library");
serializationOptions.put(SERIALIZATION_LIBRARY_JACKSON, "Use Jackson as serialization library");
serializationOptions.put(SERIALIZATION_LIBRARY_JSONB, "Use JSON-B as serialization library");
serializationLibrary.setEnum(serializationOptions);
cliOptions.add(serializationLibrary);
// Ensure the OAS 3.x discriminator mappings include any descendent schemas that allOf
// inherit from self, any oneOf schemas, any anyOf schemas, any x-discriminator-values,
// and the discriminator mapping schemas in the OAS document.
this.setLegacyDiscriminatorBehavior(false);
}
@Override
public CodegenType getTag() {
return CodegenType.CLIENT;
}
@Override
public String getName() {
return "java";
}
@Override
public String getHelp() {
return "Generates a Java client library (HTTP lib: Jersey (1.x, 2.x), Retrofit (2.x), OpenFeign (10.x) and more.";
}
@Override
public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation co, Map> operations) {
super.addOperationToGroup(tag, resourcePath, operation, co, operations);
if (MICROPROFILE.equals(getLibrary())) {
co.subresourceOperation = !co.path.isEmpty();
}
}
@Override
public void processOpts() {
if ((WEBCLIENT.equals(getLibrary()) && "threetenbp".equals(dateLibrary)) || NATIVE.equals(getLibrary())) {
dateLibrary = "java8";
} else if (MICROPROFILE.equals(getLibrary()) && "threetenbp".equals(dateLibrary)) {
dateLibrary = "legacy";
}
super.processOpts();
// RxJava
if (additionalProperties.containsKey(USE_RX_JAVA) && additionalProperties.containsKey(USE_RX_JAVA2) && additionalProperties.containsKey(USE_RX_JAVA3)) {
LOGGER.warn("You specified all RxJava versions 1, 2 and 3 but they are mutually exclusive. Defaulting to v3.");
this.setUseRxJava3(Boolean.parseBoolean(additionalProperties.get(USE_RX_JAVA3).toString()));
} else {
if (additionalProperties.containsKey(USE_RX_JAVA) && additionalProperties.containsKey(USE_RX_JAVA2)) {
LOGGER.warn("You specified both RxJava versions 1 and 2 but they are mutually exclusive. Defaulting to v2.");
this.setUseRxJava2(Boolean.parseBoolean(additionalProperties.get(USE_RX_JAVA2).toString()));
} else if (additionalProperties.containsKey(USE_RX_JAVA) && additionalProperties.containsKey(USE_RX_JAVA3)) {
LOGGER.warn("You specified both RxJava versions 1 and 3 but they are mutually exclusive. Defaulting to v3.");
this.setUseRxJava3(Boolean.parseBoolean(additionalProperties.get(USE_RX_JAVA3).toString()));
} else if (additionalProperties.containsKey(USE_RX_JAVA2) && additionalProperties.containsKey(USE_RX_JAVA3)) {
LOGGER.warn("You specified both RxJava versions 2 and 3 but they are mutually exclusive. Defaulting to v3.");
this.setUseRxJava3(Boolean.parseBoolean(additionalProperties.get(USE_RX_JAVA3).toString()));
} else {
if (additionalProperties.containsKey(USE_RX_JAVA)) {
this.setUseRxJava(Boolean.parseBoolean(additionalProperties.get(USE_RX_JAVA).toString()));
}
if (additionalProperties.containsKey(USE_RX_JAVA2)) {
this.setUseRxJava2(Boolean.parseBoolean(additionalProperties.get(USE_RX_JAVA2).toString()));
}
if (additionalProperties.containsKey(USE_RX_JAVA3)) {
this.setUseRxJava3(Boolean.parseBoolean(additionalProperties.get(USE_RX_JAVA3).toString()));
}
}
}
if (!useRxJava && !useRxJava2 && !useRxJava3) {
additionalProperties.put(DO_NOT_USE_RX, true);
}
// Java Play
if (additionalProperties.containsKey(USE_PLAY_WS)) {
this.setUsePlayWS(Boolean.parseBoolean(additionalProperties.get(USE_PLAY_WS).toString()));
}
additionalProperties.put(USE_PLAY_WS, usePlayWS);
if (additionalProperties.containsKey(PLAY_VERSION)) {
this.setPlayVersion(additionalProperties.get(PLAY_VERSION).toString());
}
additionalProperties.put(PLAY_VERSION, playVersion);
// Microprofile framework
if (additionalProperties.containsKey(MICROPROFILE_FRAMEWORK)) {
if (!MICROPROFILE_KUMULUZEE.equals(microprofileFramework)) {
throw new RuntimeException("Invalid microprofileFramework '" + microprofileFramework + "'. Must be 'kumuluzee' or none.");
}
this.setMicroprofileFramework(additionalProperties.get(MICROPROFILE_FRAMEWORK).toString());
}
additionalProperties.put(MICROPROFILE_FRAMEWORK, microprofileFramework);
if (additionalProperties.containsKey(CONFIG_KEY)) {
this.setConfigKey(additionalProperties.get(CONFIG_KEY).toString());
}
if (additionalProperties.containsKey(ASYNC_NATIVE)) {
this.setAsyncNative(convertPropertyToBooleanAndWriteBack(ASYNC_NATIVE));
}
if (additionalProperties.containsKey(PARCELABLE_MODEL)) {
this.setParcelableModel(Boolean.parseBoolean(additionalProperties.get(PARCELABLE_MODEL).toString()));
}
// put the boolean value back to PARCELABLE_MODEL in additionalProperties
additionalProperties.put(PARCELABLE_MODEL, parcelableModel);
if (additionalProperties.containsKey(USE_BEANVALIDATION)) {
this.setUseBeanValidation(convertPropertyToBooleanAndWriteBack(USE_BEANVALIDATION));
}
if (additionalProperties.containsKey(PERFORM_BEANVALIDATION)) {
this.setPerformBeanValidation(convertPropertyToBooleanAndWriteBack(PERFORM_BEANVALIDATION));
}
if (additionalProperties.containsKey(USE_GZIP_FEATURE)) {
this.setUseGzipFeature(convertPropertyToBooleanAndWriteBack(USE_GZIP_FEATURE));
}
if (additionalProperties.containsKey(USE_RUNTIME_EXCEPTION)) {
this.setUseRuntimeException(convertPropertyToBooleanAndWriteBack(USE_RUNTIME_EXCEPTION));
}
if (additionalProperties.containsKey(USE_REFLECTION_EQUALS_HASHCODE)) {
this.setUseReflectionEqualsHashCode(convertPropertyToBooleanAndWriteBack(USE_REFLECTION_EQUALS_HASHCODE));
}
if (additionalProperties.containsKey(CASE_INSENSITIVE_RESPONSE_HEADERS)) {
this.setUseReflectionEqualsHashCode(convertPropertyToBooleanAndWriteBack(CASE_INSENSITIVE_RESPONSE_HEADERS));
}
if (additionalProperties.containsKey(USE_ABSTRACTION_FOR_FILES)) {
this.setUseAbstractionForFiles(convertPropertyToBooleanAndWriteBack(USE_ABSTRACTION_FOR_FILES));
}
if (additionalProperties.containsKey(DYNAMIC_OPERATIONS)) {
this.setDynamicOperations(Boolean.parseBoolean(additionalProperties.get(DYNAMIC_OPERATIONS).toString()));
}
additionalProperties.put(DYNAMIC_OPERATIONS, dynamicOperations);
if (additionalProperties.containsKey(SUPPORT_STREAMING)) {
this.setSupportStreaming(Boolean.parseBoolean(additionalProperties.get(SUPPORT_STREAMING).toString()));
}
additionalProperties.put(SUPPORT_STREAMING, supportStreaming);
if (additionalProperties.containsKey(GRADLE_PROPERTIES)) {
this.setGradleProperties(additionalProperties.get(GRADLE_PROPERTIES).toString());
}
additionalProperties.put(GRADLE_PROPERTIES, gradleProperties);
if (additionalProperties.containsKey(ERROR_OBJECT_TYPE)) {
this.setErrorObjectType(additionalProperties.get(ERROR_OBJECT_TYPE).toString());
}
additionalProperties.put(ERROR_OBJECT_TYPE, errorObjectType);
if (additionalProperties.containsKey(ERROR_OBJECT_SUBTYPE)) {
this.setErrorObjectSubtype((List)additionalProperties.get(ERROR_OBJECT_SUBTYPE));
}
additionalProperties.put(ERROR_OBJECT_SUBTYPE, errorObjectSubtype);
final String invokerFolder = (sourceFolder + '/' + invokerPackage).replace(".", "/");
final String apiFolder = (sourceFolder + '/' + apiPackage).replace(".", "/");
final String modelsFolder = (sourceFolder + File.separator + modelPackage().replace('.', File.separatorChar)).replace('/', File.separatorChar);
authFolder = (sourceFolder + '/' + invokerPackage + ".auth").replace(".", "/");
//Common files
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml").doNotOverwrite());
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md").doNotOverwrite());
supportingFiles.add(new SupportingFile("build.gradle.mustache", "", "build.gradle").doNotOverwrite());
supportingFiles.add(new SupportingFile("build.sbt.mustache", "", "build.sbt").doNotOverwrite());
supportingFiles.add(new SupportingFile("settings.gradle.mustache", "", "settings.gradle").doNotOverwrite());
supportingFiles.add(new SupportingFile("gradle.properties.mustache", "", "gradle.properties").doNotOverwrite());
supportingFiles.add(new SupportingFile("manifest.mustache", projectFolder, "AndroidManifest.xml").doNotOverwrite());
supportingFiles.add(new SupportingFile("travis.mustache", "", ".travis.yml"));
supportingFiles.add(new SupportingFile("ApiClient.mustache", invokerFolder, "ApiClient.java"));
supportingFiles.add(new SupportingFile("ServerConfiguration.mustache", invokerFolder, "ServerConfiguration.java"));
supportingFiles.add(new SupportingFile("ServerVariable.mustache", invokerFolder, "ServerVariable.java"));
if (dynamicOperations) {
supportingFiles.add(new SupportingFile("openapi.mustache", projectFolder + "/resources/openapi", "openapi.yaml"));
supportingFiles.add(new SupportingFile("apiOperation.mustache", invokerFolder, "ApiOperation.java"));
} else {
supportingFiles.add(new SupportingFile("openapi.mustache", "api", "openapi.yaml"));
}
// helper for client library that allow to parse/format java.time.OffsetDateTime or org.threeten.bp.OffsetDateTime
if (additionalProperties.containsKey("jsr310") && (isLibrary(WEBCLIENT) || isLibrary(VERTX) || isLibrary(RESTTEMPLATE) || isLibrary(RESTEASY) || isLibrary(MICROPROFILE) || isLibrary(JERSEY1) || isLibrary(JERSEY2) || isLibrary(APACHE))) {
supportingFiles.add(new SupportingFile("JavaTimeFormatter.mustache", invokerFolder, "JavaTimeFormatter.java"));
}
if (!(RESTTEMPLATE.equals(getLibrary()) || isLibrary(REST_ASSURED) || isLibrary(NATIVE) || isLibrary(MICROPROFILE))) {
supportingFiles.add(new SupportingFile("StringUtil.mustache", invokerFolder, "StringUtil.java"));
}
// google-api-client doesn't use the OpenAPI auth, because it uses Google Credential directly (HttpRequestInitializer)
if (!(isLibrary(GOOGLE_API_CLIENT) || isLibrary(REST_ASSURED) || isLibrary(NATIVE) || isLibrary(MICROPROFILE))) {
supportingFiles.add(new SupportingFile("auth/HttpBasicAuth.mustache", authFolder, "HttpBasicAuth.java"));
supportingFiles.add(new SupportingFile("auth/HttpBearerAuth.mustache", authFolder, "HttpBearerAuth.java"));
supportingFiles.add(new SupportingFile("auth/ApiKeyAuth.mustache", authFolder, "ApiKeyAuth.java"));
}
supportingFiles.add(new SupportingFile("gradlew.mustache", "", "gradlew"));
supportingFiles.add(new SupportingFile("gradlew.bat.mustache", "", "gradlew.bat"));
supportingFiles.add(new SupportingFile("gradle-wrapper.properties.mustache",
gradleWrapperPackage.replace(".", File.separator), "gradle-wrapper.properties"));
supportingFiles.add(new SupportingFile("gradle-wrapper.jar",
gradleWrapperPackage.replace(".", File.separator), "gradle-wrapper.jar"));
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
supportingFiles.add(new SupportingFile("gitignore.mustache", "", ".gitignore"));
if (performBeanValidation) {
supportingFiles.add(new SupportingFile("BeanValidationException.mustache", invokerFolder,
"BeanValidationException.java"));
}
if (additionalProperties.containsKey(CodegenConstants.SERIALIZATION_LIBRARY)) {
setSerializationLibrary(additionalProperties.get(CodegenConstants.SERIALIZATION_LIBRARY).toString());
}
//TODO: add auto-generated doc to feign
if (FEIGN.equals(getLibrary())) {
modelDocTemplateFiles.remove("model_doc.mustache");
apiDocTemplateFiles.remove("api_doc.mustache");
//Templates to decode response headers
supportingFiles.add(new SupportingFile("model/ApiResponse.mustache", modelsFolder, "ApiResponse.java"));
supportingFiles.add(new SupportingFile("ApiResponseDecoder.mustache", invokerFolder, "ApiResponseDecoder.java"));
}
if (!(FEIGN.equals(getLibrary()) || RESTTEMPLATE.equals(getLibrary()) || RETROFIT_2.equals(getLibrary()) || GOOGLE_API_CLIENT.equals(getLibrary()) || REST_ASSURED.equals(getLibrary()) || WEBCLIENT.equals(getLibrary()) || MICROPROFILE.equals(getLibrary()))) {
supportingFiles.add(new SupportingFile("apiException.mustache", invokerFolder, "ApiException.java"));
supportingFiles.add(new SupportingFile("Configuration.mustache", invokerFolder, "Configuration.java"));
supportingFiles.add(new SupportingFile("Pair.mustache", invokerFolder, "Pair.java"));
}
if (!(FEIGN.equals(getLibrary()) || RESTTEMPLATE.equals(getLibrary()) || RETROFIT_2.equals(getLibrary()) || GOOGLE_API_CLIENT.equals(getLibrary()) || REST_ASSURED.equals(getLibrary()) || NATIVE.equals(getLibrary()) || MICROPROFILE.equals(getLibrary()))) {
supportingFiles.add(new SupportingFile("auth/Authentication.mustache", authFolder, "Authentication.java"));
}
if (FEIGN.equals(getLibrary())) {
forceSerializationLibrary(SERIALIZATION_LIBRARY_JACKSON);
supportingFiles.add(new SupportingFile("ParamExpander.mustache", invokerFolder, "ParamExpander.java"));
supportingFiles.add(new SupportingFile("EncodingUtils.mustache", invokerFolder, "EncodingUtils.java"));
supportingFiles.add(new SupportingFile("auth/DefaultApi20Impl.mustache", authFolder, "DefaultApi20Impl.java"));
} else if (OKHTTP_GSON.equals(getLibrary()) || StringUtils.isEmpty(getLibrary()) || OKHTTP_GSON_NEXTGEN.equals(getLibrary())) {
// the "okhttp-gson" library template requires "ApiCallback.mustache" for async call
supportingFiles.add(new SupportingFile("ApiCallback.mustache", invokerFolder, "ApiCallback.java"));
supportingFiles.add(new SupportingFile("ApiResponse.mustache", invokerFolder, "ApiResponse.java"));
supportingFiles.add(new SupportingFile("JSON.mustache", invokerFolder, "JSON.java"));
supportingFiles.add(new SupportingFile("ProgressRequestBody.mustache", invokerFolder, "ProgressRequestBody.java"));
supportingFiles.add(new SupportingFile("ProgressResponseBody.mustache", invokerFolder, "ProgressResponseBody.java"));
supportingFiles.add(new SupportingFile("GzipRequestInterceptor.mustache", invokerFolder, "GzipRequestInterceptor.java"));
if (OKHTTP_GSON_NEXTGEN.equals(getLibrary())) {
supportingFiles.add(new SupportingFile("AbstractOpenApiSchema.mustache", modelsFolder, "AbstractOpenApiSchema.java"));
}
// NOTE: below moved to postProcessOperationsWithModels
//supportingFiles.add(new SupportingFile("auth/OAuthOkHttpClient.mustache", authFolder, "OAuthOkHttpClient.java"));
//supportingFiles.add(new SupportingFile("auth/RetryingOAuth.mustache", authFolder, "RetryingOAuth.java"));
forceSerializationLibrary(SERIALIZATION_LIBRARY_GSON);
} else if (RETROFIT_2.equals(getLibrary())) {
supportingFiles.add(new SupportingFile("auth/OAuthOkHttpClient.mustache", authFolder, "OAuthOkHttpClient.java"));
supportingFiles.add(new SupportingFile("CollectionFormats.mustache", invokerFolder, "CollectionFormats.java"));
forceSerializationLibrary(SERIALIZATION_LIBRARY_GSON);
if (RETROFIT_2.equals(getLibrary()) && !usePlayWS) {
supportingFiles.add(new SupportingFile("JSON.mustache", invokerFolder, "JSON.java"));
}
} else if (JERSEY2.equals(getLibrary())) {
additionalProperties.put("jersey2", true);
supportingFiles.add(new SupportingFile("JSON.mustache", invokerFolder, "JSON.java"));
supportingFiles.add(new SupportingFile("ApiResponse.mustache", invokerFolder, "ApiResponse.java"));
if (ProcessUtils.hasHttpSignatureMethods(openAPI)) {
supportingFiles.add(new SupportingFile("auth/HttpSignatureAuth.mustache", authFolder, "HttpSignatureAuth.java"));
}
supportingFiles.add(new SupportingFile("AbstractOpenApiSchema.mustache", modelsFolder, "AbstractOpenApiSchema.java"));
forceSerializationLibrary(SERIALIZATION_LIBRARY_JACKSON);
// Composed schemas can have the 'additionalProperties' keyword, as specified in JSON schema.
// In principle, this should be enabled by default for all code generators. However due to limitations
// in other code generators, support needs to be enabled on a case-by-case basis.
// The flag below should be set for all Java libraries, but the templates need to be ported
// one by one for each library.
supportsAdditionalPropertiesWithComposedSchema = true;
} else if (NATIVE.equals(getLibrary())) {
setJava8ModeAndAdditionalProperties(true);
supportingFiles.add(new SupportingFile("ApiResponse.mustache", invokerFolder, "ApiResponse.java"));
supportingFiles.add(new SupportingFile("JSON.mustache", invokerFolder, "JSON.java"));
supportingFiles.add(new SupportingFile("AbstractOpenApiSchema.mustache", modelsFolder, "AbstractOpenApiSchema.java"));
forceSerializationLibrary(SERIALIZATION_LIBRARY_JACKSON);
} else if (RESTEASY.equals(getLibrary())) {
setJava8ModeAndAdditionalProperties(true);
supportingFiles.add(new SupportingFile("JSON.mustache", invokerFolder, "JSON.java"));
forceSerializationLibrary(SERIALIZATION_LIBRARY_JACKSON);
} else if (JERSEY1.equals(getLibrary())) {
forceSerializationLibrary(SERIALIZATION_LIBRARY_JACKSON);
} else if (RESTTEMPLATE.equals(getLibrary())) {
forceSerializationLibrary(SERIALIZATION_LIBRARY_JACKSON);
supportingFiles.add(new SupportingFile("auth/Authentication.mustache", authFolder, "Authentication.java"));
} else if (WEBCLIENT.equals(getLibrary())) {
setJava8ModeAndAdditionalProperties(true);
forceSerializationLibrary(SERIALIZATION_LIBRARY_JACKSON);
} else if (VERTX.equals(getLibrary())) {
typeMapping.put("file", "AsyncFile");
importMapping.put("AsyncFile", "io.vertx.core.file.AsyncFile");
setJava8ModeAndAdditionalProperties(true);
forceSerializationLibrary(SERIALIZATION_LIBRARY_JACKSON);
apiTemplateFiles.put("apiImpl.mustache", "Impl.java");
apiTemplateFiles.put("rxApiImpl.mustache", ".java");
supportingFiles.remove(new SupportingFile("manifest.mustache", projectFolder, "AndroidManifest.xml"));
} else if (GOOGLE_API_CLIENT.equals(getLibrary())) {
forceSerializationLibrary(SERIALIZATION_LIBRARY_JACKSON);
} else if (REST_ASSURED.equals(getLibrary())) {
if (getSerializationLibrary() == null) {
LOGGER.info("No serializationLibrary configured, using '{}' as fallback", SERIALIZATION_LIBRARY_GSON);
setSerializationLibrary(SERIALIZATION_LIBRARY_GSON);
}
if (SERIALIZATION_LIBRARY_JACKSON.equals(getSerializationLibrary())) {
supportingFiles.add(new SupportingFile("JacksonObjectMapper.mustache", invokerFolder, "JacksonObjectMapper.java"));
} else if (SERIALIZATION_LIBRARY_GSON.equals(getSerializationLibrary())) {
supportingFiles.add(new SupportingFile("JSON.mustache", invokerFolder, "JSON.java"));
supportingFiles.add(new SupportingFile("GsonObjectMapper.mustache", invokerFolder, "GsonObjectMapper.java"));
}
supportingFiles.add(new SupportingFile("Oper.mustache", apiFolder, "Oper.java"));
additionalProperties.put("convert", new CaseFormatLambda(LOWER_CAMEL, UPPER_UNDERSCORE));
apiTemplateFiles.put("api.mustache", ".java");
supportingFiles.add(new SupportingFile("ResponseSpecBuilders.mustache", invokerFolder, "ResponseSpecBuilders.java"));
} else if (MICROPROFILE.equals(getLibrary())) {
supportingFiles.clear(); // Don't need extra files provided by Java Codegen
String apiExceptionFolder = (sourceFolder + File.separator + apiPackage().replace('.', File.separatorChar)).replace('/', File.separatorChar);
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("api_exception.mustache", apiExceptionFolder, "ApiException.java"));
supportingFiles.add(new SupportingFile("api_exception_mapper.mustache", apiExceptionFolder, "ApiExceptionMapper.java"));
serializationLibrary = "none";
if (microprofileFramework.equals(MICROPROFILE_KUMULUZEE)) {
supportingFiles.add(new SupportingFile("kumuluzee.pom.mustache", "", "pom.xml"));
supportingFiles.add(new SupportingFile("kumuluzee.config.yaml.mustache", "src/main/resources", "config.yaml"));
supportingFiles.add(new SupportingFile("kumuluzee.beans.xml.mustache", "src/main/resources/META-INF", "beans.xml"));
}
} else if (APACHE.equals(getLibrary())) {
setJava8ModeAndAdditionalProperties(true);
forceSerializationLibrary(SERIALIZATION_LIBRARY_JACKSON);
} else {
LOGGER.error("Unknown library option (-l/--library): {}", getLibrary());
}
if (usePlayWS) {
// remove unsupported auth
Iterator iter = supportingFiles.iterator();
while (iter.hasNext()) {
SupportingFile sf = iter.next();
if (sf.getTemplateFile().startsWith("auth/")) {
iter.remove();
}
}
apiTemplateFiles.remove("api.mustache");
if (PLAY_24.equals(playVersion)) {
LOGGER.warn("`play24` option has been deprecated and will be removed in the 5.x release. Please use `play26` instead.");
additionalProperties.put(PLAY_24, true);
apiTemplateFiles.put("play24/api.mustache", ".java");
supportingFiles.add(new SupportingFile("play24/ApiClient.mustache", invokerFolder, "ApiClient.java"));
supportingFiles.add(new SupportingFile("play24/Play24CallFactory.mustache", invokerFolder, "Play24CallFactory.java"));
supportingFiles.add(new SupportingFile("play24/Play24CallAdapterFactory.mustache", invokerFolder,
"Play24CallAdapterFactory.java"));
}
if (PLAY_25.equals(playVersion)) {
LOGGER.warn("`play25` option has been deprecated and will be removed in the 5.x release. Please use `play26` instead.");
additionalProperties.put(PLAY_25, true);
apiTemplateFiles.put("play25/api.mustache", ".java");
supportingFiles.add(new SupportingFile("play25/ApiClient.mustache", invokerFolder, "ApiClient.java"));
supportingFiles.add(new SupportingFile("play25/Play25CallFactory.mustache", invokerFolder, "Play25CallFactory.java"));
supportingFiles.add(new SupportingFile("play25/Play25CallAdapterFactory.mustache", invokerFolder,
"Play25CallAdapterFactory.java"));
setJava8ModeAndAdditionalProperties(true);
}
if (PLAY_26.equals(playVersion)) {
additionalProperties.put(PLAY_26, true);
apiTemplateFiles.put("play26/api.mustache", ".java");
supportingFiles.add(new SupportingFile("play26/ApiClient.mustache", invokerFolder, "ApiClient.java"));
supportingFiles.add(new SupportingFile("play26/Play26CallFactory.mustache", invokerFolder, "Play26CallFactory.java"));
supportingFiles.add(new SupportingFile("play26/Play26CallAdapterFactory.mustache", invokerFolder,
"Play26CallAdapterFactory.java"));
setJava8ModeAndAdditionalProperties(true);
}
supportingFiles.add(new SupportingFile("play-common/auth/ApiKeyAuth.mustache", authFolder, "ApiKeyAuth.java"));
supportingFiles.add(new SupportingFile("auth/Authentication.mustache", authFolder, "Authentication.java"));
supportingFiles.add(new SupportingFile("Pair.mustache", invokerFolder, "Pair.java"));
forceSerializationLibrary(SERIALIZATION_LIBRARY_JACKSON);
}
if (getSerializationLibrary() == null) {
LOGGER.info("No serializationLibrary configured, using '{}' as fallback", SERIALIZATION_LIBRARY_GSON);
setSerializationLibrary(SERIALIZATION_LIBRARY_GSON);
}
switch (getSerializationLibrary()) {
case SERIALIZATION_LIBRARY_JACKSON:
additionalProperties.put(SERIALIZATION_LIBRARY_JACKSON, "true");
additionalProperties.remove(SERIALIZATION_LIBRARY_GSON);
additionalProperties.remove(SERIALIZATION_LIBRARY_JSONB);
supportingFiles.add(new SupportingFile("RFC3339DateFormat.mustache", invokerFolder, "RFC3339DateFormat.java"));
if (!NATIVE.equals(getLibrary())) {
if ("threetenbp".equals(dateLibrary) && !usePlayWS) {
supportingFiles.add(new SupportingFile("CustomInstantDeserializer.mustache", invokerFolder, "CustomInstantDeserializer.java"));
}
}
break;
case SERIALIZATION_LIBRARY_GSON:
additionalProperties.put(SERIALIZATION_LIBRARY_GSON, "true");
additionalProperties.remove(SERIALIZATION_LIBRARY_JACKSON);
additionalProperties.remove(SERIALIZATION_LIBRARY_JSONB);
break;
case SERIALIZATION_LIBRARY_JSONB:
additionalProperties.put(SERIALIZATION_LIBRARY_JSONB, "true");
additionalProperties.remove(SERIALIZATION_LIBRARY_JACKSON);
additionalProperties.remove(SERIALIZATION_LIBRARY_GSON);
break;
default:
additionalProperties.remove(SERIALIZATION_LIBRARY_JACKSON);
additionalProperties.remove(SERIALIZATION_LIBRARY_GSON);
additionalProperties.remove(SERIALIZATION_LIBRARY_JSONB);
break;
}
// authentication related files
// has OAuth defined
if (ProcessUtils.hasOAuthMethods(openAPI)) {
// for okhttp-gson (default), check to see if OAuth is defined and included OAuth-related files accordingly
if ((OKHTTP_GSON.equals(getLibrary()) || StringUtils.isEmpty(getLibrary())) || OKHTTP_GSON_NEXTGEN.equals(getLibrary())) {
supportingFiles.add(new SupportingFile("auth/OAuthOkHttpClient.mustache", authFolder, "OAuthOkHttpClient.java"));
supportingFiles.add(new SupportingFile("auth/RetryingOAuth.mustache", authFolder, "RetryingOAuth.java"));
}
// google-api-client doesn't use the OpenAPI auth, because it uses Google Credential directly (HttpRequestInitializer)
if (!(GOOGLE_API_CLIENT.equals(getLibrary()) || REST_ASSURED.equals(getLibrary()) || usePlayWS
|| NATIVE.equals(getLibrary()) || MICROPROFILE.equals(getLibrary()))) {
supportingFiles.add(new SupportingFile("auth/OAuth.mustache", authFolder, "OAuth.java"));
supportingFiles.add(new SupportingFile("auth/OAuthFlow.mustache", authFolder, "OAuthFlow.java"));
}
// Add OauthPasswordGrant.java and OauthClientCredentialsGrant.java for feign library
if (FEIGN.equals(getLibrary())) {
supportingFiles.add(new SupportingFile("auth/OauthPasswordGrant.mustache", authFolder, "OauthPasswordGrant.java"));
supportingFiles.add(new SupportingFile("auth/OauthClientCredentialsGrant.mustache", authFolder, "OauthClientCredentialsGrant.java"));
supportingFiles.add(new SupportingFile("auth/ApiErrorDecoder.mustache", authFolder, "ApiErrorDecoder.java"));
}
}
}
@SuppressWarnings("unchecked")
@Override
public Map postProcessOperationsWithModels(Map objs, List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy