From d4cd0bdc3e021845099ca1897033439e548f8ba8 Mon Sep 17 00:00:00 2001 From: wing328 Date: Tue, 3 Apr 2018 15:45:24 +0800 Subject: [PATCH] add java generator --- .../languages/AbstractJavaCodegen.java | 97 +-- .../codegen/languages/JavaClientCodegen.java | 611 ++++++++++++++++++ .../BeanValidationExtendedFeatures.java | 11 + .../features/BeanValidationFeatures.java | 10 + .../languages/features/CXFFeatures.java | 9 + .../languages/features/CXFServerFeatures.java | 29 + .../languages/features/GzipFeatures.java | 9 + .../languages/features/GzipTestFeatures.java | 9 + .../languages/features/JbossFeature.java | 9 + .../languages/features/LoggingFeatures.java | 9 + .../features/LoggingTestFeatures.java | 8 + .../languages/features/OptionalFeatures.java | 10 + .../PerformBeanValidationFeatures.java | 10 + .../languages/features/SpringFeatures.java | 18 + .../languages/features/SwaggerFeatures.java | 9 + .../languages/features/SwaggerUIFeatures.java | 9 + .../features/UseGenericResponseFeatures.java | 9 + .../org.openapitools.codegen.CodegenConfig | 1 + 18 files changed, 829 insertions(+), 48 deletions(-) create mode 100644 modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaClientCodegen.java create mode 100644 modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/BeanValidationExtendedFeatures.java create mode 100644 modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/BeanValidationFeatures.java create mode 100644 modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/CXFFeatures.java create mode 100644 modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/CXFServerFeatures.java create mode 100644 modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/GzipFeatures.java create mode 100644 modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/GzipTestFeatures.java create mode 100644 modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/JbossFeature.java create mode 100644 modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/LoggingFeatures.java create mode 100644 modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/LoggingTestFeatures.java create mode 100644 modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/OptionalFeatures.java create mode 100644 modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/PerformBeanValidationFeatures.java create mode 100644 modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/SpringFeatures.java create mode 100644 modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/SwaggerFeatures.java create mode 100644 modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/SwaggerUIFeatures.java create mode 100644 modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/UseGenericResponseFeatures.java diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java index e79b2922b352..002ce444360c 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java @@ -68,7 +68,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code protected boolean hideGenerationTimestamp = false; protected String apiDocPath = "docs/"; protected String modelDocPath = "docs/"; - protected boolean supportJava6= false; + protected boolean supportJava6 = false; public AbstractJavaCodegen() { super(); @@ -80,22 +80,22 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code apiDocTemplateFiles.put("api_doc.mustache", ".md"); setReservedWordsLowerCase( - Arrays.asList( - // used as internal variables, can collide with parameter names - "localVarPath", "localVarQueryParams", "localVarCollectionQueryParams", - "localVarHeaderParams", "localVarFormParams", "localVarPostBody", - "localVarAccepts", "localVarAccept", "localVarContentTypes", - "localVarContentType", "localVarAuthNames", "localReturnType", - "ApiClient", "ApiException", "ApiResponse", "Configuration", "StringUtil", + Arrays.asList( + // used as internal variables, can collide with parameter names + "localVarPath", "localVarQueryParams", "localVarCollectionQueryParams", + "localVarHeaderParams", "localVarFormParams", "localVarPostBody", + "localVarAccepts", "localVarAccept", "localVarContentTypes", + "localVarContentType", "localVarAuthNames", "localReturnType", + "ApiClient", "ApiException", "ApiResponse", "Configuration", "StringUtil", - // language reserved words - "abstract", "continue", "for", "new", "switch", "assert", - "default", "if", "package", "synchronized", "boolean", "do", "goto", "private", - "this", "break", "double", "implements", "protected", "throw", "byte", "else", - "import", "public", "throws", "case", "enum", "instanceof", "return", "transient", - "catch", "extends", "int", "short", "try", "char", "final", "interface", "static", - "void", "class", "finally", "long", "strictfp", "volatile", "const", "float", - "native", "super", "while", "null") + // language reserved words + "abstract", "continue", "for", "new", "switch", "assert", + "default", "if", "package", "synchronized", "boolean", "do", "goto", "private", + "this", "break", "double", "implements", "protected", "throw", "byte", "else", + "import", "public", "throws", "case", "enum", "instanceof", "return", "transient", + "catch", "extends", "int", "short", "try", "char", "final", "interface", "static", + "void", "class", "finally", "long", "strictfp", "volatile", "const", "float", + "native", "super", "while", "null") ); languageSpecificPrimitives = new HashSet( @@ -174,13 +174,13 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code this.setInvokerPackage((String) additionalProperties.get(CodegenConstants.INVOKER_PACKAGE)); } else if (additionalProperties.containsKey(CodegenConstants.API_PACKAGE)) { // guess from api package - String derviedInvokerPackage = deriveInvokerPackageName((String)additionalProperties.get(CodegenConstants.API_PACKAGE)); + String derviedInvokerPackage = deriveInvokerPackageName((String) additionalProperties.get(CodegenConstants.API_PACKAGE)); this.additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, derviedInvokerPackage); this.setInvokerPackage((String) additionalProperties.get(CodegenConstants.INVOKER_PACKAGE)); LOGGER.info("Invoker Package Name, originally not set, is now dervied from api package name: " + derviedInvokerPackage); } else if (additionalProperties.containsKey(CodegenConstants.MODEL_PACKAGE)) { // guess from model package - String derviedInvokerPackage = deriveInvokerPackageName((String)additionalProperties.get(CodegenConstants.MODEL_PACKAGE)); + String derviedInvokerPackage = deriveInvokerPackageName((String) additionalProperties.get(CodegenConstants.MODEL_PACKAGE)); this.additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, derviedInvokerPackage); this.setInvokerPackage((String) additionalProperties.get(CodegenConstants.INVOKER_PACKAGE)); LOGGER.info("Invoker Package Name, originally not set, is now dervied from model package name: " + derviedInvokerPackage); @@ -292,7 +292,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code this.setLibrary((String) additionalProperties.get(CodegenConstants.LIBRARY)); } - if(additionalProperties.containsKey(CodegenConstants.SERIALIZE_BIG_DECIMAL_AS_STRING)) { + if (additionalProperties.containsKey(CodegenConstants.SERIALIZE_BIG_DECIMAL_AS_STRING)) { this.setSerializeBigDecimalAsString(Boolean.valueOf(additionalProperties.get(CodegenConstants.SERIALIZE_BIG_DECIMAL_AS_STRING).toString())); } @@ -365,16 +365,16 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code // used later in recursive import in postProcessingModels importMapping.put("com.fasterxml.jackson.annotation.JsonProperty", "com.fasterxml.jackson.annotation.JsonCreator"); - if(additionalProperties.containsKey(JAVA8_MODE)) { + if (additionalProperties.containsKey(JAVA8_MODE)) { setJava8Mode(Boolean.parseBoolean(additionalProperties.get(JAVA8_MODE).toString())); - if ( java8Mode ) { + if (java8Mode) { additionalProperties.put("java8", "true"); } } - if(additionalProperties.containsKey(WITH_XML)) { + if (additionalProperties.containsKey(WITH_XML)) { setWithXml(Boolean.parseBoolean(additionalProperties.get(WITH_XML).toString())); - if ( withXml ) { + if (withXml) { additionalProperties.put(WITH_XML, "true"); } } @@ -435,7 +435,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code @Override public String escapeReservedWord(String name) { - if(this.reservedWordsMappings().containsKey(name)) { + if (this.reservedWordsMappings().containsKey(name)) { return this.reservedWordsMappings().get(name); } return "_" + name; @@ -503,8 +503,8 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code return "propertyClass"; } - if("_".equals(name)) { - name = "_u"; + if ("_".equals(name)) { + name = "_u"; } // if it's all uppper case, do nothing @@ -512,7 +512,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code return name; } - if(startsWithTwoUppercaseLetters(name)){ + if (startsWithTwoUppercaseLetters(name)) { name = name.substring(0, 2).toLowerCase() + name.substring(2); } @@ -530,7 +530,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code private boolean startsWithTwoUppercaseLetters(String name) { boolean startsWithTwoUppercaseLetters = false; - if(name.length() > 1) { + if (name.length() > 1) { startsWithTwoUppercaseLetters = name.substring(0, 2).equals(name.substring(0, 2).toUpperCase()); } return startsWithTwoUppercaseLetters; @@ -679,7 +679,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code return p.getDefault().toString(); } } - return "null"; + return "null"; } else if (p instanceof NumberSchema) { if (p.getDefault() != null) { if (SchemaTypeUtil.FLOAT_FORMAT.equals(p.getFormat())) { @@ -777,7 +777,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code @Override public String toExampleValue(Schema p) { - if(p.getExample() != null) { + if (p.getExample() != null) { return escapeText(p.getExample().toString()); } else { return super.toExampleValue(p); @@ -823,7 +823,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code @Override public CodegenModel fromModel(String name, Schema model, Map allDefinitions) { CodegenModel codegenModel = super.fromModel(name, model, allDefinitions); - if(codegenModel.description != null) { + if (codegenModel.description != null) { codegenModel.imports.add("ApiModel"); } if (codegenModel.discriminator != null && additionalProperties.containsKey("jackson")) { @@ -840,7 +840,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code @Override public void postProcessModelProperty(CodegenModel model, CodegenProperty property) { - if(serializeBigDecimalAsString) { + if (serializeBigDecimalAsString) { if (property.baseType.equals("BigDecimal")) { // we serialize BigDecimal as `string` to avoid precision loss property.vendorExtensions.put("extraAnnotation", "@JsonSerialize(using = ToStringSerializer.class)"); @@ -859,7 +859,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code } } - if(!BooleanUtils.toBoolean(model.isEnum)) { + if (!BooleanUtils.toBoolean(model.isEnum)) { // needed by all pojos, but not enums model.imports.add("ApiModelProperty"); model.imports.add("ApiModel"); @@ -867,7 +867,8 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code } @Override - public void postProcessParameter(CodegenParameter parameter) { } + public void postProcessParameter(CodegenParameter parameter) { + } @Override public Map postProcessModels(Map objs) { @@ -882,7 +883,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code // if the import package happens to be found in the importMapping (key) // add the corresponding import package to the list if (importMapping.containsKey(_import)) { - Map newImportMap= new HashMap(); + Map newImportMap = new HashMap(); newImportMap.put("import", importMapping.get(_import)); listIterator.add(newImportMap); } @@ -897,10 +898,10 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code // imported in the template already. List> imports = (List>) objs.get("imports"); Pattern pattern = Pattern.compile("java\\.util\\.(List|ArrayList|Map|HashMap)"); - for (Iterator> itr = imports.iterator(); itr.hasNext();) { + for (Iterator> itr = imports.iterator(); itr.hasNext(); ) { String _import = itr.next().get("import"); if (pattern.matcher(_import).matches()) { - itr.remove(); + itr.remove(); } } return objs; @@ -908,19 +909,19 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code @Override public void preprocessOpenAPI(OpenAPI openAPI) { - if (openAPI == null || openAPI.getPaths() == null){ + if (openAPI == null || openAPI.getPaths() == null) { return; } for (String pathname : openAPI.getPaths().keySet()) { PathItem path = openAPI.getPaths().get(pathname); - if (path.readOperations() == null){ + if (path.readOperations() == null) { continue; } for (Operation operation : path.readOperations()) { - if (hasBodyParameter(operation) || hasFormParameter(operation)){ + if (hasBodyParameter(operation) || hasFormParameter(operation)) { String defaultContentType = hasFormParameter(operation) ? "application/x-www-form-urlencoded" : "application/json"; List consumes = new ArrayList(getConsumesInfo(operation)); - String contentType = consumes == null || consumes.isEmpty() ? defaultContentType : consumes.get(0); + String contentType = consumes == null || consumes.isEmpty() ? defaultContentType : consumes.get(0); operation.getExtensions().put("x-contentType", contentType); } String accepts = getAccept(operation); @@ -980,7 +981,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code // number if ("Integer".equals(datatype) || "Long".equals(datatype) || - "Float".equals(datatype) || "Double".equals(datatype)) { + "Float".equals(datatype) || "Double".equals(datatype)) { String varName = "NUMBER_" + value; varName = varName.replaceAll("-", "MINUS_"); varName = varName.replaceAll("\\+", "PLUS_"); @@ -1027,7 +1028,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code // Because the child models extend the parents, the enums will be available via the parent. // Only bother with reconciliation if the parent model has enums. - if (!parentCodegenModel.hasEnums) { + if (!parentCodegenModel.hasEnums) { return codegenModel; } @@ -1055,10 +1056,10 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code } } - if(removedChildEnum) { + if (removedChildEnum) { // If we removed an entry from this model's vars, we need to ensure hasMore is updated int count = 0, numVars = codegenProperties.size(); - for(CodegenProperty codegenProperty : codegenProperties) { + for (CodegenProperty codegenProperty : codegenProperties) { count += 1; codegenProperty.hasMore = (count < numVars) ? true : false; } @@ -1070,7 +1071,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code private static String sanitizePackageName(String packageName) { packageName = packageName.trim(); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'. packageName = packageName.replaceAll("[^a-zA-Z0-9_\\.]", "_"); - if(Strings.isNullOrEmpty(packageName)) { + if (Strings.isNullOrEmpty(packageName)) { return "invalidPackageName"; } return packageName; @@ -1200,7 +1201,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code StringBuilder sb = new StringBuilder(); String delim = ""; - for (String p : Arrays.copyOf(parts, parts.length-1)) { + for (String p : Arrays.copyOf(parts, parts.length - 1)) { sb.append(delim).append(p); delim = "."; } @@ -1221,7 +1222,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code booleanValue = Boolean.valueOf(additionalProperties.get(propertyKey).toString()); } - return booleanValue; + return booleanValue; } public void writePropertyBack(String propertyKey, boolean value) { diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaClientCodegen.java new file mode 100644 index 000000000000..516cd130e9be --- /dev/null +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaClientCodegen.java @@ -0,0 +1,611 @@ +package org.openapitools.codegen.languages; + +import static java.util.Collections.sort; + +import com.google.common.collect.LinkedListMultimap; + +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.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.util.*; +import java.util.regex.Pattern; + +public class JavaClientCodegen extends AbstractJavaCodegen + implements BeanValidationFeatures, PerformBeanValidationFeatures, + GzipFeatures { + static final String MEDIA_TYPE = "mediaType"; + + @SuppressWarnings("hiding") + private static 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 DO_NOT_USE_RX = "doNotUseRx"; + public static final String USE_PLAY_WS = "usePlayWS"; + public static final String PLAY_VERSION = "playVersion"; + public static final String PARCELABLE_MODEL = "parcelableModel"; + public static final String USE_RUNTIME_EXCEPTION = "useRuntimeException"; + + public static final String PLAY_24 = "play24"; + public static final String PLAY_25 = "play25"; + + public static final String RETROFIT_1 = "retrofit"; + public static final String RETROFIT_2 = "retrofit2"; + public static final String REST_ASSURED = "rest-assured"; + + protected String gradleWrapperPackage = "gradle.wrapper"; + protected boolean useRxJava = false; + protected boolean useRxJava2 = false; + protected boolean doNotUseRx = true; // backwards compatibility for swagger configs that specify neither rx1 nor rx2 (mustache does not allow for boolean operators so we need this extra field) + protected boolean usePlayWS = false; + protected String playVersion = PLAY_25; + protected boolean parcelableModel = false; + protected boolean useBeanValidation = false; + protected boolean performBeanValidation = false; + protected boolean useGzipFeature = false; + protected boolean useRuntimeException = false; + + + public JavaClientCodegen() { + super(); + outputFolder = "generated-code" + File.separator + "java"; + embeddedTemplateDir = templateDir = "Java"; + invokerPackage = "io.swagger.client"; + artifactId = "swagger-java-client"; + apiPackage = "io.swagger.client.api"; + modelPackage = "io.swagger.client.model"; + + cliOptions.add(CliOption.newBoolean(USE_RX_JAVA, "Whether to use the RxJava adapter with the retrofit2 library.")); + cliOptions.add(CliOption.newBoolean(USE_RX_JAVA2, "Whether to use the RxJava2 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\", \"play25\")")); + cliOptions.add(CliOption.newBoolean(SUPPORT_JAVA6, "Whether to support Java6 with the Jersey1 library.")); + 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")); + + supportedLibraries.put("jersey1", "HTTP client: Jersey client 1.19.4. JSON processing: Jackson 2.8.9. Enable Java6 support using '-DsupportJava6=true'. Enable gzip request encoding using '-DuseGzipFeature=true'."); + supportedLibraries.put("feign", "HTTP client: OpenFeign 9.4.0. JSON processing: Jackson 2.8.9"); + supportedLibraries.put("jersey2", "HTTP client: Jersey client 2.25.1. JSON processing: Jackson 2.8.9"); + supportedLibraries.put("okhttp-gson", "HTTP client: OkHttp 2.7.5. JSON processing: Gson 2.8.1. Enable Parcelable models on Android using '-DparcelableModel=true'. Enable gzip request encoding using '-DuseGzipFeature=true'."); + supportedLibraries.put(RETROFIT_1, "HTTP client: OkHttp 2.7.5. JSON processing: Gson 2.3.1 (Retrofit 1.9.0). IMPORTANT NOTE: retrofit1.x is no longer actively maintained so please upgrade to 'retrofit2' instead."); + supportedLibraries.put(RETROFIT_2, "HTTP client: OkHttp 3.8.0. JSON processing: Gson 2.6.1 (Retrofit 2.3.0). Enable the RxJava adapter using '-DuseRxJava[2]=true'. (RxJava 1.x or 2.x)"); + supportedLibraries.put("resttemplate", "HTTP client: Spring RestTemplate 4.3.9-RELEASE. JSON processing: Jackson 2.8.9"); + supportedLibraries.put("resteasy", "HTTP client: Resteasy client 3.1.3.Final. JSON processing: Jackson 2.8.9"); + supportedLibraries.put("vertx", "HTTP client: VertX client 3.2.4. JSON processing: Jackson 2.8.9"); + supportedLibraries.put("google-api-client", "HTTP client: Google API client 1.23.0. JSON processing: Jackson 2.8.9"); + supportedLibraries.put("rest-assured", "HTTP client: rest-assured : 3.0.6. JSON processing: Gson 2.6.1. Only for Java8"); + + 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"); + + } + + @Override + public CodegenType getTag() { + return CodegenType.CLIENT; + } + + @Override + public String getName() { + return "java"; + } + + @Override + public String getHelp() { + return "Generates a Java client library."; + } + + @Override + public void processOpts() { + super.processOpts(); + + 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."); + } else if (additionalProperties.containsKey(USE_RX_JAVA)) { + this.setUseRxJava(Boolean.valueOf(additionalProperties.get(USE_RX_JAVA).toString())); + } + if (additionalProperties.containsKey(USE_RX_JAVA2)) { + this.setUseRxJava2(Boolean.valueOf(additionalProperties.get(USE_RX_JAVA2).toString())); + } + if (!useRxJava && !useRxJava2) { + additionalProperties.put(DO_NOT_USE_RX, true); + } + if (additionalProperties.containsKey(USE_PLAY_WS)) { + this.setUsePlayWS(Boolean.valueOf(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); + + if (additionalProperties.containsKey(PARCELABLE_MODEL)) { + this.setParcelableModel(Boolean.valueOf(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)); + } + + final String invokerFolder = (sourceFolder + '/' + invokerPackage).replace(".", "/"); + final String authFolder = (sourceFolder + '/' + invokerPackage + ".auth").replace(".", "/"); + final String apiFolder = (sourceFolder + '/' + apiPackage).replace(".", "/"); + + //Common files + writeOptional(outputFolder, new SupportingFile("pom.mustache", "", "pom.xml")); + writeOptional(outputFolder, new SupportingFile("README.mustache", "", "README.md")); + writeOptional(outputFolder, new SupportingFile("build.gradle.mustache", "", "build.gradle")); + writeOptional(outputFolder, new SupportingFile("build.sbt.mustache", "", "build.sbt")); + writeOptional(outputFolder, new SupportingFile("settings.gradle.mustache", "", "settings.gradle")); + writeOptional(outputFolder, new SupportingFile("gradle.properties.mustache", "", "gradle.properties")); + writeOptional(outputFolder, new SupportingFile("manifest.mustache", projectFolder, "AndroidManifest.xml")); + supportingFiles.add(new SupportingFile("travis.mustache", "", ".travis.yml")); + supportingFiles.add(new SupportingFile("ApiClient.mustache", invokerFolder, "ApiClient.java")); + if (!("resttemplate".equals(getLibrary()) || REST_ASSURED.equals(getLibrary()))) { + supportingFiles.add(new SupportingFile("StringUtil.mustache", invokerFolder, "StringUtil.java")); + } + + // google-api-client doesn't use the Swagger auth, because it uses Google Credential directly (HttpRequestInitializer) + if (!("google-api-client".equals(getLibrary()) || REST_ASSURED.equals(getLibrary()))) { + supportingFiles.add(new SupportingFile("auth/HttpBasicAuth.mustache", authFolder, "HttpBasicAuth.java")); + supportingFiles.add(new SupportingFile("auth/ApiKeyAuth.mustache", authFolder, "ApiKeyAuth.java")); + supportingFiles.add(new SupportingFile("auth/OAuth.mustache", authFolder, "OAuth.java")); + supportingFiles.add(new SupportingFile("auth/OAuthFlow.mustache", authFolder, "OAuthFlow.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")); + } + + //TODO: add doc to retrofit1 and feign + if ("feign".equals(getLibrary()) || "retrofit".equals(getLibrary())) { + modelDocTemplateFiles.remove("model_doc.mustache"); + apiDocTemplateFiles.remove("api_doc.mustache"); + } + + if (!("feign".equals(getLibrary()) || "resttemplate".equals(getLibrary()) || usesAnyRetrofitLibrary() || "google-api-client".equals(getLibrary()) || REST_ASSURED.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")); + supportingFiles.add(new SupportingFile("auth/Authentication.mustache", authFolder, "Authentication.java")); + } + + if ("feign".equals(getLibrary())) { + additionalProperties.put("jackson", "true"); + supportingFiles.add(new SupportingFile("ParamExpander.mustache", invokerFolder, "ParamExpander.java")); + supportingFiles.add(new SupportingFile("EncodingUtils.mustache", invokerFolder, "EncodingUtils.java")); + } else if ("okhttp-gson".equals(getLibrary()) || StringUtils.isEmpty(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")); + additionalProperties.put("gson", "true"); + } else if (usesAnyRetrofitLibrary()) { + supportingFiles.add(new SupportingFile("auth/OAuthOkHttpClient.mustache", authFolder, "OAuthOkHttpClient.java")); + supportingFiles.add(new SupportingFile("CollectionFormats.mustache", invokerFolder, "CollectionFormats.java")); + additionalProperties.put("gson", "true"); + if ("retrofit2".equals(getLibrary()) && !usePlayWS) { + supportingFiles.add(new SupportingFile("JSON.mustache", invokerFolder, "JSON.java")); + } + } else if ("jersey2".equals(getLibrary())) { + supportingFiles.add(new SupportingFile("JSON.mustache", invokerFolder, "JSON.java")); + supportingFiles.add(new SupportingFile("ApiResponse.mustache", invokerFolder, "ApiResponse.java")); + additionalProperties.put("jackson", "true"); + } else if ("resteasy".equals(getLibrary())) { + supportingFiles.add(new SupportingFile("JSON.mustache", invokerFolder, "JSON.java")); + additionalProperties.put("jackson", "true"); + } else if ("jersey1".equals(getLibrary())) { + additionalProperties.put("jackson", "true"); + } else if ("resttemplate".equals(getLibrary())) { + additionalProperties.put("jackson", "true"); + supportingFiles.add(new SupportingFile("auth/Authentication.mustache", authFolder, "Authentication.java")); + } else if ("vertx".equals(getLibrary())) { + typeMapping.put("file", "AsyncFile"); + importMapping.put("AsyncFile", "io.vertx.core.file.AsyncFile"); + setJava8Mode(true); + additionalProperties.put("java8", "true"); + additionalProperties.put("jackson", "true"); + 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())) { + additionalProperties.put("jackson", "true"); + + } else if (REST_ASSURED.equals(getLibrary())) { + additionalProperties.put("gson", "true"); + apiTemplateFiles.put("api.mustache", ".java"); + supportingFiles.add(new SupportingFile("ResponseSpecBuilders.mustache", invokerFolder, "ResponseSpecBuilders.java")); + supportingFiles.add(new SupportingFile("JSON.mustache", invokerFolder, "JSON.java")); + supportingFiles.add(new SupportingFile("GsonObjectMapper.mustache", invokerFolder, "GsonObjectMapper.java")); + } 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.templateFile.startsWith("auth/")) { + iter.remove(); + } + } + + apiTemplateFiles.remove("api.mustache"); + + if (PLAY_24.equals(playVersion)) { + 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")); + } else { + 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")); + additionalProperties.put("java8", "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")); + + additionalProperties.put("jackson", "true"); + additionalProperties.remove("gson"); + } + + if (additionalProperties.containsKey("jackson")) { + supportingFiles.add(new SupportingFile("RFC3339DateFormat.mustache", invokerFolder, "RFC3339DateFormat.java")); + if ("threetenbp".equals(dateLibrary) && !usePlayWS) { + supportingFiles.add(new SupportingFile("CustomInstantDeserializer.mustache", invokerFolder, "CustomInstantDeserializer.java")); + } + } + } + + private boolean usesAnyRetrofitLibrary() { + return getLibrary() != null && getLibrary().contains(RETROFIT_1); + } + + private boolean usesRetrofit2Library() { + return getLibrary() != null && getLibrary().contains(RETROFIT_2); + } + + @SuppressWarnings("unchecked") + @Override + public Map postProcessOperations(Map objs) { + super.postProcessOperations(objs); + if (usesAnyRetrofitLibrary()) { + Map operations = (Map) objs.get("operations"); + if (operations != null) { + List ops = (List) operations.get("operation"); + for (CodegenOperation operation : ops) { + if (operation.hasConsumes == Boolean.TRUE) { + + if (isMultipartType(operation.consumes)) { + operation.isMultipart = Boolean.TRUE; + } else { + operation.prioritizedContentTypes = prioritizeContentTypes(operation.consumes); + } + } + if (usesRetrofit2Library() && StringUtils.isNotEmpty(operation.path) && operation.path.startsWith("/")) { + operation.path = operation.path.substring(1); + } + + // sorting operation parameters to make sure path params are parsed before query params + if (operation.allParams != null) { + sort(operation.allParams, new Comparator() { + @Override + public int compare(CodegenParameter one, CodegenParameter another) { + if (one.isPathParam && another.isQueryParam) { + return -1; + } + if (one.isQueryParam && another.isPathParam) { + return 1; + } + + return 0; + } + }); + Iterator iterator = operation.allParams.iterator(); + while (iterator.hasNext()) { + CodegenParameter param = iterator.next(); + param.hasMore = iterator.hasNext(); + } + } + } + } + + } + + // camelize path variables for Feign client + if ("feign".equals(getLibrary())) { + Map operations = (Map) objs.get("operations"); + List operationList = (List) operations.get("operation"); + for (CodegenOperation op : operationList) { + String path = op.path; + String[] items = path.split("/", -1); + + for (int i = 0; i < items.length; ++i) { + if (items[i].matches("^\\{(.*)\\}$")) { // wrap in {} + // camelize path variable + items[i] = "{" + camelize(items[i].substring(1, items[i].length() - 1), true) + "}"; + } + } + op.path = StringUtils.join(items, "/"); + } + } + + return objs; + } + + @Override + public String apiFilename(String templateName, String tag) { + if ("vertx".equals(getLibrary())) { + String suffix = apiTemplateFiles().get(templateName); + String subFolder = ""; + if (templateName.startsWith("rx")) { + subFolder = "/rxjava"; + } + return apiFileFolder() + subFolder + '/' + toApiFilename(tag) + suffix; + } else { + return super.apiFilename(templateName, tag); + } + } + + /** + * Prioritizes consumes mime-type list by moving json-vendor and json mime-types up front, but + * otherwise preserves original consumes definition order. + * [application/vnd...+json,... application/json, ..as is..] + * + * @param consumes consumes mime-type list + * @return + */ + static List> prioritizeContentTypes(List> consumes) { + if (consumes.size() <= 1) + return consumes; + + List> prioritizedContentTypes = new ArrayList<>(consumes.size()); + + List> jsonVendorMimeTypes = new ArrayList<>(consumes.size()); + List> jsonMimeTypes = new ArrayList<>(consumes.size()); + + for (Map consume : consumes) { + if (isJsonVendorMimeType(consume.get(MEDIA_TYPE))) { + jsonVendorMimeTypes.add(consume); + } else if (isJsonMimeType(consume.get(MEDIA_TYPE))) { + jsonMimeTypes.add(consume); + } else + prioritizedContentTypes.add(consume); + + consume.put("hasMore", "true"); + } + + prioritizedContentTypes.addAll(0, jsonMimeTypes); + prioritizedContentTypes.addAll(0, jsonVendorMimeTypes); + + prioritizedContentTypes.get(prioritizedContentTypes.size() - 1).put("hasMore", null); + + return prioritizedContentTypes; + } + + private static boolean isMultipartType(List> consumes) { + Map firstType = consumes.get(0); + if (firstType != null) { + if ("multipart/form-data".equals(firstType.get(MEDIA_TYPE))) { + return true; + } + } + return false; + } + + @Override + public void postProcessModelProperty(CodegenModel model, CodegenProperty property) { + super.postProcessModelProperty(model, property); + if (!BooleanUtils.toBoolean(model.isEnum)) { + //final String lib = getLibrary(); + //Needed imports for Jackson based libraries + if (additionalProperties.containsKey("jackson")) { + model.imports.add("JsonProperty"); + model.imports.add("JsonValue"); + } + if (additionalProperties.containsKey("gson")) { + model.imports.add("SerializedName"); + model.imports.add("TypeAdapter"); + model.imports.add("JsonAdapter"); + model.imports.add("JsonReader"); + model.imports.add("JsonWriter"); + model.imports.add("IOException"); + } + } else { // enum class + //Needed imports for Jackson's JsonCreator + if (additionalProperties.containsKey("jackson")) { + model.imports.add("JsonValue"); + model.imports.add("JsonCreator"); + } + } + } + + @SuppressWarnings("unchecked") + @Override + public Map postProcessAllModels(Map objs) { + Map allProcessedModels = super.postProcessAllModels(objs); + if (!additionalProperties.containsKey("gsonFactoryMethod")) { + List allModels = new ArrayList(); + for (String name : allProcessedModels.keySet()) { + Map models = (Map) allProcessedModels.get(name); + try { + allModels.add(((List) models.get("models")).get(0)); + } catch (Exception e) { + e.printStackTrace(); + } + } + additionalProperties.put("parent", modelInheritanceSupportInGson(allModels)); + } + return allProcessedModels; + } + + @Override + public Map postProcessModelsEnum(Map objs) { + objs = super.postProcessModelsEnum(objs); + //Needed import for Gson based libraries + if (additionalProperties.containsKey("gson")) { + List> imports = (List>) objs.get("imports"); + List models = (List) objs.get("models"); + for (Object _mo : models) { + Map mo = (Map) _mo; + CodegenModel cm = (CodegenModel) mo.get("model"); + // for enum model + if (Boolean.TRUE.equals(cm.isEnum) && cm.allowableValues != null) { + cm.imports.add(importMapping.get("SerializedName")); + Map item = new HashMap(); + item.put("import", importMapping.get("SerializedName")); + imports.add(item); + } + } + } + return objs; + } + + private List> modelInheritanceSupportInGson(List allModels) { + LinkedListMultimap byParent = LinkedListMultimap.create(); + for (Object m : allModels) { + Map entry = (Map) m; + CodegenModel parent = ((CodegenModel) entry.get("model")).parentModel; + if (null != parent) { + byParent.put(parent, ((CodegenModel) entry.get("model"))); + } + } + List> parentsList = new ArrayList<>(); + for (CodegenModel parentModel : byParent.keySet()) { + List> childrenList = new ArrayList<>(); + Map parent = new HashMap<>(); + parent.put("classname", parentModel.classname); + List childrenModels = byParent.get(parentModel); + for (CodegenModel model : childrenModels) { + Map child = new HashMap<>(); + child.put("name", model.name); + child.put("classname", model.classname); + childrenList.add(child); + } + parent.put("children", childrenList); + parent.put("discriminator", parentModel.discriminator); + parentsList.add(parent); + } + return parentsList; + } + + public void setUseRxJava(boolean useRxJava) { + this.useRxJava = useRxJava; + doNotUseRx = false; + } + + public void setUseRxJava2(boolean useRxJava2) { + this.useRxJava2 = useRxJava2; + doNotUseRx = false; + } + + public void setDoNotUseRx(boolean doNotUseRx) { + this.doNotUseRx = doNotUseRx; + } + + public void setUsePlayWS(boolean usePlayWS) { + this.usePlayWS = usePlayWS; + } + + public void setPlayVersion(String playVersion) { + this.playVersion = playVersion; + } + + public void setParcelableModel(boolean parcelableModel) { + this.parcelableModel = parcelableModel; + } + + public void setUseBeanValidation(boolean useBeanValidation) { + this.useBeanValidation = useBeanValidation; + } + + public void setPerformBeanValidation(boolean performBeanValidation) { + this.performBeanValidation = performBeanValidation; + } + + public void setUseGzipFeature(boolean useGzipFeature) { + this.useGzipFeature = useGzipFeature; + } + + public void setUseRuntimeException(boolean useRuntimeException) { + this.useRuntimeException = useRuntimeException; + } + + final private static Pattern JSON_MIME_PATTERN = Pattern.compile("(?i)application\\/json(;.*)?"); + final private static Pattern JSON_VENDOR_MIME_PATTERN = Pattern.compile("(?i)application\\/vnd.(.*)+json(;.*)?"); + + /** + * Check if the given MIME is a JSON MIME. + * JSON MIME examples: + * application/json + * application/json; charset=UTF8 + * APPLICATION/JSON + */ + static boolean isJsonMimeType(String mime) { + return mime != null && (JSON_MIME_PATTERN.matcher(mime).matches()); + } + + /** + * Check if the given MIME is a JSON Vendor MIME. + * JSON MIME examples: + * application/vnd.mycompany+json + * application/vnd.mycompany.resourceA.version1+json + */ + static boolean isJsonVendorMimeType(String mime) { + return mime != null && JSON_VENDOR_MIME_PATTERN.matcher(mime).matches(); + } + +} diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/BeanValidationExtendedFeatures.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/BeanValidationExtendedFeatures.java new file mode 100644 index 000000000000..aeb731b70cff --- /dev/null +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/BeanValidationExtendedFeatures.java @@ -0,0 +1,11 @@ +package org.openapitools.codegen.languages.features; + +public interface BeanValidationExtendedFeatures { + + // Language (implementing Client/Server) supports automatic BeanValidation (1.1) + public static final String USE_BEANVALIDATION_FEATURE = "useBeanValidationFeature"; + + public void setUseBeanValidationFeature(boolean useBeanValidationFeature); + + +} diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/BeanValidationFeatures.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/BeanValidationFeatures.java new file mode 100644 index 000000000000..0e3bdc004206 --- /dev/null +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/BeanValidationFeatures.java @@ -0,0 +1,10 @@ +package org.openapitools.codegen.languages.features; + +public interface BeanValidationFeatures { + + // Language supports generating BeanValidation-Annotations + public static final String USE_BEANVALIDATION = "useBeanValidation"; + + public void setUseBeanValidation(boolean useBeanValidation); + +} diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/CXFFeatures.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/CXFFeatures.java new file mode 100644 index 000000000000..00ec1eb62c65 --- /dev/null +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/CXFFeatures.java @@ -0,0 +1,9 @@ +package org.openapitools.codegen.languages.features; + +/** + * Features supported by CXF 3 (client + server) + */ +public interface CXFFeatures extends LoggingFeatures, GzipFeatures, BeanValidationFeatures { + + +} diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/CXFServerFeatures.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/CXFServerFeatures.java new file mode 100644 index 000000000000..799b10d6b5e6 --- /dev/null +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/CXFServerFeatures.java @@ -0,0 +1,29 @@ +package org.openapitools.codegen.languages.features; + +/** + * Features supported by CXF 3 server + */ +public interface CXFServerFeatures + extends CXFFeatures, SwaggerFeatures, SpringFeatures, JbossFeature, BeanValidationExtendedFeatures, SwaggerUIFeatures { + + public static final String USE_WADL_FEATURE = "useWadlFeature"; + + public static final String USE_MULTIPART_FEATURE = "useMultipartFeature"; + + public static final String ADD_CONSUMES_PRODUCES_JSON = "addConsumesProducesJson"; + + public static final String USE_ANNOTATED_BASE_PATH = "useAnnotatedBasePath"; + + public static final String GENERATE_NON_SPRING_APPLICATION = "generateNonSpringApplication"; + + public void setUseWadlFeature(boolean useWadlFeature); + + public void setUseMultipartFeature(boolean useMultipartFeature); + + public void setAddConsumesProducesJson(boolean addConsumesProducesJson); + + public void setUseAnnotatedBasePath(boolean useAnnotatedBasePath); + + public void setGenerateNonSpringApplication(boolean generateNonSpringApplication); + +} diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/GzipFeatures.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/GzipFeatures.java new file mode 100644 index 000000000000..9c919ea16122 --- /dev/null +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/GzipFeatures.java @@ -0,0 +1,9 @@ +package org.openapitools.codegen.languages.features; + +public interface GzipFeatures { + + public static final String USE_GZIP_FEATURE = "useGzipFeature"; + + public void setUseGzipFeature(boolean useGzipFeature); + +} diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/GzipTestFeatures.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/GzipTestFeatures.java new file mode 100644 index 000000000000..e05e72a8c6c0 --- /dev/null +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/GzipTestFeatures.java @@ -0,0 +1,9 @@ +package org.openapitools.codegen.languages.features; + +public interface GzipTestFeatures { + + public static final String USE_GZIP_FEATURE_FOR_TESTS = "useGzipFeatureForTests"; + + public void setUseGzipFeatureForTests(boolean useGzipFeatureForTests); + +} diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/JbossFeature.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/JbossFeature.java new file mode 100644 index 000000000000..69d42d7c57fd --- /dev/null +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/JbossFeature.java @@ -0,0 +1,9 @@ +package org.openapitools.codegen.languages.features; + +public interface JbossFeature { + + public static final String GENERATE_JBOSS_DEPLOYMENT_DESCRIPTOR = "generateJbossDeploymentDescriptor"; + + public void setGenerateJbossDeploymentDescriptor(boolean generateJbossDeploymentDescriptor); + +} diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/LoggingFeatures.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/LoggingFeatures.java new file mode 100644 index 000000000000..f3bd0f694697 --- /dev/null +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/LoggingFeatures.java @@ -0,0 +1,9 @@ +package org.openapitools.codegen.languages.features; + +public interface LoggingFeatures extends BeanValidationFeatures { + + public static final String USE_LOGGING_FEATURE = "useLoggingFeature"; + + public void setUseLoggingFeature(boolean useLoggingFeature); + +} diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/LoggingTestFeatures.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/LoggingTestFeatures.java new file mode 100644 index 000000000000..50fbe5b388e4 --- /dev/null +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/LoggingTestFeatures.java @@ -0,0 +1,8 @@ +package org.openapitools.codegen.languages.features; + +public interface LoggingTestFeatures { + public static final String USE_LOGGING_FEATURE_FOR_TESTS = "useLoggingFeatureForTests"; + + public void setUseLoggingFeatureForTests(boolean useLoggingFeatureForTests); + +} diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/OptionalFeatures.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/OptionalFeatures.java new file mode 100644 index 000000000000..f2de76420a3a --- /dev/null +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/OptionalFeatures.java @@ -0,0 +1,10 @@ +package org.openapitools.codegen.languages.features; + +public interface OptionalFeatures { + + // Language supports generating Optional Types + String USE_OPTIONAL = "useOptional"; + + void setUseOptional(boolean useOptional); + +} diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/PerformBeanValidationFeatures.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/PerformBeanValidationFeatures.java new file mode 100644 index 000000000000..74b6886ec06b --- /dev/null +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/PerformBeanValidationFeatures.java @@ -0,0 +1,10 @@ +package org.openapitools.codegen.languages.features; + +public interface PerformBeanValidationFeatures { + + // Language supports performing BeanValidation + public static final String PERFORM_BEANVALIDATION = "performBeanValidation"; + + public void setPerformBeanValidation(boolean performBeanValidation); + +} diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/SpringFeatures.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/SpringFeatures.java new file mode 100644 index 000000000000..691fdd40eef8 --- /dev/null +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/SpringFeatures.java @@ -0,0 +1,18 @@ +package org.openapitools.codegen.languages.features; + +public interface SpringFeatures extends BeanValidationFeatures { + + public static final String GENERATE_SPRING_APPLICATION = "generateSpringApplication"; + + public static final String GENERATE_SPRING_BOOT_APPLICATION = "generateSpringBootApplication"; + + public static final String USE_SPRING_ANNOTATION_CONFIG = "useSpringAnnotationConfig"; + + public void setGenerateSpringApplication(boolean useGenerateSpringApplication); + + public void setGenerateSpringBootApplication(boolean generateSpringBootApplication); + + public void setUseSpringAnnotationConfig(boolean useSpringAnnotationConfig); + + +} diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/SwaggerFeatures.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/SwaggerFeatures.java new file mode 100644 index 000000000000..f158a9cae73c --- /dev/null +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/SwaggerFeatures.java @@ -0,0 +1,9 @@ +package org.openapitools.codegen.languages.features; + +public interface SwaggerFeatures { + + public static final String USE_SWAGGER_FEATURE = "useSwaggerFeature"; + + public void setUseSwaggerFeature(boolean useSwaggerFeature); + +} diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/SwaggerUIFeatures.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/SwaggerUIFeatures.java new file mode 100644 index 000000000000..ec0e05576b0d --- /dev/null +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/SwaggerUIFeatures.java @@ -0,0 +1,9 @@ +package org.openapitools.codegen.languages.features; + +public interface SwaggerUIFeatures extends CXFFeatures { + + public static final String USE_SWAGGER_UI = "useSwaggerUI"; + + public void setUseSwaggerUI(boolean useSwaggerUI); + +} diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/UseGenericResponseFeatures.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/UseGenericResponseFeatures.java new file mode 100644 index 000000000000..272c8c0efb5c --- /dev/null +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/features/UseGenericResponseFeatures.java @@ -0,0 +1,9 @@ +package org.openapitools.codegen.languages.features; + +public interface UseGenericResponseFeatures { + + // Language supports generating generic Jaxrs or native return types + public static final String USE_GENERIC_RESPONSE = "useGenericResponse"; + + public void setUseGenericResponse(boolean useGenericResponse); +} diff --git a/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig b/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig index 8e88190041d2..dc8852d8c83d 100644 --- a/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig +++ b/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig @@ -30,6 +30,7 @@ org.openapitools.codegen.languages.KotlinClientCodegen org.openapitools.codegen.languages.KotlinServerCodegen org.openapitools.codegen.languages.HaskellHttpClientCodegen org.openapitools.codegen.languages.HaskellServantCodegen +org.openapitools.codegen.languages.JavaClientCodegen org.openapitools.codegen.languages.JavascriptClientCodegen org.openapitools.codegen.languages.JavascriptClosureAngularClientCodegen org.openapitools.codegen.languages.LuaClientCodegen