From 520fdb71048490f794a9ebab7e5ca477878058ff Mon Sep 17 00:00:00 2001 From: Jan Weinschenker Date: Mon, 4 Nov 2019 10:24:54 +0100 Subject: [PATCH 1/7] fix: prevent classcast exception during execution of openapi-generator-maven-plugin. --- .../examples/kotlin.xml | 187 ++++++++++++++ .../languages/AbstractKotlinCodegen.java | 229 ++++++++++-------- 2 files changed, 317 insertions(+), 99 deletions(-) create mode 100644 modules/openapi-generator-maven-plugin/examples/kotlin.xml diff --git a/modules/openapi-generator-maven-plugin/examples/kotlin.xml b/modules/openapi-generator-maven-plugin/examples/kotlin.xml new file mode 100644 index 000000000000..9c6304677687 --- /dev/null +++ b/modules/openapi-generator-maven-plugin/examples/kotlin.xml @@ -0,0 +1,187 @@ + + 4.0.0 + org.openapitools + sample-project + jar + 1.0-SNAPSHOT + sample-project + http://maven.apache.org + + + + + org.openapitools + openapi-generator-maven-plugin + + 4.2.1-SNAPSHOT + + + + default + + generate + + + + ${project.basedir}/swagger.yaml + + + kotlin + + + + + + true + + + + + + remote + generate-sources + + generate + + + + https://raw.githubusercontent.com/OpenAPITools/openapi-generator/master/modules/openapi-generator/src/test/resources/2_0/petstore.yaml + + + + kotlin + + + + + + true + + + ${project.build.directory}/generated-sources/remote-openapi + remote.org.openapitools.client.api + remote.org.openapitools.client.model + remote.org.openapitools.client + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 1.7 + 1.7 + none + + + + + + + sonatype-snapshots + https://oss.sonatype.org/content/repositories/snapshots/ + + + + + + + io.swagger + swagger-annotations + ${swagger-annotations-version} + + + + + + + org.glassfish.jersey.core + jersey-client + ${jersey-version} + + + org.glassfish.jersey.media + jersey-media-multipart + ${jersey-version} + + + org.glassfish.jersey.media + jersey-media-json-jackson + ${jersey-version} + + + + + com.google.code.findbugs + jsr305 + 3.0.2 + + + + + com.fasterxml.jackson.jaxrs + jackson-jaxrs-base + ${jackson-version} + + + com.fasterxml.jackson.core + jackson-core + ${jackson-version} + + + com.fasterxml.jackson.core + jackson-annotations + ${jackson-version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson-version} + + + com.fasterxml.jackson.jaxrs + jackson-jaxrs-json-provider + ${jackson-version} + + + org.openapitools + jackson-databind-nullable + ${jackson-databind-nullable-version} + + + + + com.fasterxml.jackson.datatype + jackson-datatype-joda + ${jackson-version} + + + joda-time + joda-time + ${jodatime-version} + + + + + com.brsanthu + migbase64 + 2.2 + + + + + 1.5.8 + 2.27 + 2.8.9 + 0.2.0 + 2.7 + 1.0.0 + 4.8.1 + + diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractKotlinCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractKotlinCodegen.java index 57c45a76fb03..4aaae88d28d2 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractKotlinCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractKotlinCodegen.java @@ -32,7 +32,13 @@ import org.slf4j.LoggerFactory; import java.io.File; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; import java.util.stream.Collectors; import static org.openapitools.codegen.utils.StringUtils.*; @@ -70,104 +76,104 @@ public AbstractKotlinCodegen() { supportsInheritance = true; languageSpecificPrimitives = new HashSet(Arrays.asList( - "kotlin.Byte", - "kotlin.ByteArray", - "kotlin.Short", - "kotlin.Int", - "kotlin.Long", - "kotlin.Float", - "kotlin.Double", - "kotlin.Boolean", - "kotlin.Char", - "kotlin.String", - "kotlin.Array", - "kotlin.collections.List", - "kotlin.collections.Map", - "kotlin.collections.Set" + "kotlin.Byte", + "kotlin.ByteArray", + "kotlin.Short", + "kotlin.Int", + "kotlin.Long", + "kotlin.Float", + "kotlin.Double", + "kotlin.Boolean", + "kotlin.Char", + "kotlin.String", + "kotlin.Array", + "kotlin.collections.List", + "kotlin.collections.Map", + "kotlin.collections.Set" )); // this includes hard reserved words defined by https://github.com/JetBrains/kotlin/blob/master/core/descriptors/src/org/jetbrains/kotlin/renderer/KeywordStringsGenerated.java // as well as keywords from https://kotlinlang.org/docs/reference/keyword-reference.html reservedWords = new HashSet(Arrays.asList( - "abstract", - "annotation", - "as", - "break", - "case", - "catch", - "class", - "companion", - "const", - "constructor", - "continue", - "crossinline", - "data", - "delegate", - "do", - "else", - "enum", - "external", - "false", - "final", - "finally", - "for", - "fun", - "if", - "in", - "infix", - "init", - "inline", - "inner", - "interface", - "internal", - "is", - "it", - "lateinit", - "lazy", - "noinline", - "null", - "object", - "open", - "operator", - "out", - "override", - "package", - "private", - "protected", - "public", - "reified", - "return", - "sealed", - "super", - "suspend", - "tailrec", - "this", - "throw", - "true", - "try", - "typealias", - "typeof", - "val", - "var", - "vararg", - "when", - "while" + "abstract", + "annotation", + "as", + "break", + "case", + "catch", + "class", + "companion", + "const", + "constructor", + "continue", + "crossinline", + "data", + "delegate", + "do", + "else", + "enum", + "external", + "false", + "final", + "finally", + "for", + "fun", + "if", + "in", + "infix", + "init", + "inline", + "inner", + "interface", + "internal", + "is", + "it", + "lateinit", + "lazy", + "noinline", + "null", + "object", + "open", + "operator", + "out", + "override", + "package", + "private", + "protected", + "public", + "reified", + "return", + "sealed", + "super", + "suspend", + "tailrec", + "this", + "throw", + "true", + "try", + "typealias", + "typeof", + "val", + "var", + "vararg", + "when", + "while" )); defaultIncludes = new HashSet(Arrays.asList( - "kotlin.Byte", - "kotlin.ByteArray", - "kotlin.Short", - "kotlin.Int", - "kotlin.Long", - "kotlin.Float", - "kotlin.Double", - "kotlin.Boolean", - "kotlin.Char", - "kotlin.Array", - "kotlin.collections.List", - "kotlin.collections.Set", - "kotlin.collections.Map" + "kotlin.Byte", + "kotlin.ByteArray", + "kotlin.Short", + "kotlin.Int", + "kotlin.Long", + "kotlin.Float", + "kotlin.Double", + "kotlin.Boolean", + "kotlin.Char", + "kotlin.Array", + "kotlin.collections.List", + "kotlin.collections.Set", + "kotlin.collections.Map" )); typeMapping = new HashMap(); @@ -306,6 +312,7 @@ public void setSerializationLibrary(final String enumSerializationLibrary) { * returns the OpenAPI type for the property * * @param p OpenAPI property object + * * @return string presentation of the type **/ @Override @@ -328,6 +335,7 @@ public String getSchemaType(Schema p) { * Output the type declaration of the property * * @param p OpenAPI Property object + * * @return a string presentation of the property type */ @Override @@ -376,7 +384,8 @@ public void processOpts() { super.processOpts(); if (StringUtils.isEmpty(System.getenv("KOTLIN_POST_PROCESS_FILE"))) { - LOGGER.info("Environment variable KOTLIN_POST_PROCESS_FILE not defined so the Kotlin code may not be properly formatted. To define it, try 'export KOTLIN_POST_PROCESS_FILE=\"/usr/local/bin/ktlint -F\"' (Linux/Mac)"); + LOGGER.info( + "Environment variable KOTLIN_POST_PROCESS_FILE not defined so the Kotlin code may not be properly formatted. To define it, try 'export KOTLIN_POST_PROCESS_FILE=\"/usr/local/bin/ktlint -F\"' (Linux/Mac)"); LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI)."); } @@ -399,10 +408,12 @@ public void processOpts() { if (additionalProperties.containsKey(CodegenConstants.PACKAGE_NAME)) { this.setPackageName((String) additionalProperties.get(CodegenConstants.PACKAGE_NAME)); - if (!additionalProperties.containsKey(CodegenConstants.MODEL_PACKAGE)) + if (!additionalProperties.containsKey(CodegenConstants.MODEL_PACKAGE)) { this.setModelPackage(packageName + ".models"); - if (!additionalProperties.containsKey(CodegenConstants.API_PACKAGE)) + } + if (!additionalProperties.containsKey(CodegenConstants.API_PACKAGE)) { this.setApiPackage(packageName + ".apis"); + } } else { additionalProperties.put(CodegenConstants.PACKAGE_NAME, packageName); } @@ -434,19 +445,19 @@ public void processOpts() { } if (additionalProperties.containsKey(CodegenConstants.SERIALIZABLE_MODEL)) { - this.setSerializableModel(Boolean.valueOf((String) additionalProperties.get(CodegenConstants.SERIALIZABLE_MODEL))); + this.setSerializableModel(getBooleanOption(CodegenConstants.SERIALIZABLE_MODEL)); } else { additionalProperties.put(CodegenConstants.SERIALIZABLE_MODEL, serializableModel); } if (additionalProperties.containsKey(CodegenConstants.PARCELIZE_MODELS)) { - this.setParcelizeModels(Boolean.valueOf((String) additionalProperties.get(CodegenConstants.PARCELIZE_MODELS))); + this.setParcelizeModels(getBooleanOption(CodegenConstants.PARCELIZE_MODELS)); } else { additionalProperties.put(CodegenConstants.PARCELIZE_MODELS, parcelizeModels); } if (additionalProperties.containsKey(CodegenConstants.NON_PUBLIC_API)) { - this.setNonPublicApi(Boolean.valueOf((String) additionalProperties.get(CodegenConstants.NON_PUBLIC_API))); + this.setNonPublicApi(getBooleanOption(CodegenConstants.NON_PUBLIC_API)); } else { additionalProperties.put(CodegenConstants.NON_PUBLIC_API, nonPublicApi); } @@ -458,6 +469,18 @@ public void processOpts() { additionalProperties.put("modelDocPath", modelDocPath); } + private boolean getBooleanOption(String key) { + Object booleanValue = additionalProperties.get(key); + if (booleanValue instanceof Boolean) { + System.out.println("##### BOOLEAN"); + return (Boolean) booleanValue; + } else if (booleanValue instanceof String) { + System.out.println("##### STRING"); + return Boolean.parseBoolean((String) booleanValue); + } + return false; + } + public void setArtifactId(String artifactId) { this.artifactId = artifactId; } @@ -501,7 +524,7 @@ public boolean isSerializableModel() { public void setSerializableModel(boolean serializableModel) { this.serializableModel = serializableModel; } - + public boolean nonPublicApi() { return nonPublicApi; } @@ -523,6 +546,7 @@ public void setNeedsDataClassBody(boolean needsDataClassBody) { * * @param value enum variable name * @param datatype data type + * * @return the sanitized variable name for enum */ @Override @@ -585,6 +609,7 @@ public String toApiName(String name) { * Return the fully-qualified "Model" name for import * * @param name the name of the "Model" + * * @return the fully-qualified "Model" name for import */ @Override @@ -603,6 +628,7 @@ public String toModelImport(String name) { * In case the name belongs to the TypeSystem it won't be renamed. * * @param name the name of the model + * * @return capitalized model name */ @Override @@ -656,13 +682,15 @@ public String toModelName(final String name) { * Return the operation ID (method name) * * @param operationId operation ID + * * @return the sanitized method name */ @Override public String toOperationId(String operationId) { // throw exception if method name is empty - if (StringUtils.isEmpty(operationId)) + if (StringUtils.isEmpty(operationId)) { throw new RuntimeException("Empty method/operation name (operationId) not allowed"); + } operationId = camelize(sanitizeName(operationId), true); @@ -692,6 +720,7 @@ public String toModelFilename(String name) { * Provides a strongly typed declaration for simple arrays of some type and arrays of arrays of some type. * * @param arr Array schema + * * @return type declaration of array */ private String getArrayTypeDeclaration(ArraySchema arr) { @@ -714,6 +743,7 @@ private String getArrayTypeDeclaration(ArraySchema arr) { * Sanitize against Kotlin specific naming conventions, which may differ from those required by {@link DefaultCodegen#sanitizeName}. * * @param name string to be sanitize + * * @return sanitized string */ private String sanitizeKotlinSpecificNames(final String name) { @@ -782,6 +812,7 @@ protected boolean isReservedWord(String word) { * Check the type to see if it needs import the library/module/package * * @param type name of the type + * * @return true if the library/module/package of the corresponding type needs to be imported */ @Override From b55b30bc438444193b258ed7b8c2267acbb44cb2 Mon Sep 17 00:00:00 2001 From: Jan Weinschenker Date: Mon, 4 Nov 2019 10:37:37 +0100 Subject: [PATCH 2/7] style: revert styling to openapi defaults --- .../languages/AbstractKotlinCodegen.java | 213 ++++++++---------- 1 file changed, 96 insertions(+), 117 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractKotlinCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractKotlinCodegen.java index 4aaae88d28d2..5eb9d020aaa9 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractKotlinCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractKotlinCodegen.java @@ -32,13 +32,7 @@ import org.slf4j.LoggerFactory; import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Locale; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; import static org.openapitools.codegen.utils.StringUtils.*; @@ -76,104 +70,104 @@ public AbstractKotlinCodegen() { supportsInheritance = true; languageSpecificPrimitives = new HashSet(Arrays.asList( - "kotlin.Byte", - "kotlin.ByteArray", - "kotlin.Short", - "kotlin.Int", - "kotlin.Long", - "kotlin.Float", - "kotlin.Double", - "kotlin.Boolean", - "kotlin.Char", - "kotlin.String", - "kotlin.Array", - "kotlin.collections.List", - "kotlin.collections.Map", - "kotlin.collections.Set" + "kotlin.Byte", + "kotlin.ByteArray", + "kotlin.Short", + "kotlin.Int", + "kotlin.Long", + "kotlin.Float", + "kotlin.Double", + "kotlin.Boolean", + "kotlin.Char", + "kotlin.String", + "kotlin.Array", + "kotlin.collections.List", + "kotlin.collections.Map", + "kotlin.collections.Set" )); // this includes hard reserved words defined by https://github.com/JetBrains/kotlin/blob/master/core/descriptors/src/org/jetbrains/kotlin/renderer/KeywordStringsGenerated.java // as well as keywords from https://kotlinlang.org/docs/reference/keyword-reference.html reservedWords = new HashSet(Arrays.asList( - "abstract", - "annotation", - "as", - "break", - "case", - "catch", - "class", - "companion", - "const", - "constructor", - "continue", - "crossinline", - "data", - "delegate", - "do", - "else", - "enum", - "external", - "false", - "final", - "finally", - "for", - "fun", - "if", - "in", - "infix", - "init", - "inline", - "inner", - "interface", - "internal", - "is", - "it", - "lateinit", - "lazy", - "noinline", - "null", - "object", - "open", - "operator", - "out", - "override", - "package", - "private", - "protected", - "public", - "reified", - "return", - "sealed", - "super", - "suspend", - "tailrec", - "this", - "throw", - "true", - "try", - "typealias", - "typeof", - "val", - "var", - "vararg", - "when", - "while" + "abstract", + "annotation", + "as", + "break", + "case", + "catch", + "class", + "companion", + "const", + "constructor", + "continue", + "crossinline", + "data", + "delegate", + "do", + "else", + "enum", + "external", + "false", + "final", + "finally", + "for", + "fun", + "if", + "in", + "infix", + "init", + "inline", + "inner", + "interface", + "internal", + "is", + "it", + "lateinit", + "lazy", + "noinline", + "null", + "object", + "open", + "operator", + "out", + "override", + "package", + "private", + "protected", + "public", + "reified", + "return", + "sealed", + "super", + "suspend", + "tailrec", + "this", + "throw", + "true", + "try", + "typealias", + "typeof", + "val", + "var", + "vararg", + "when", + "while" )); defaultIncludes = new HashSet(Arrays.asList( - "kotlin.Byte", - "kotlin.ByteArray", - "kotlin.Short", - "kotlin.Int", - "kotlin.Long", - "kotlin.Float", - "kotlin.Double", - "kotlin.Boolean", - "kotlin.Char", - "kotlin.Array", - "kotlin.collections.List", - "kotlin.collections.Set", - "kotlin.collections.Map" + "kotlin.Byte", + "kotlin.ByteArray", + "kotlin.Short", + "kotlin.Int", + "kotlin.Long", + "kotlin.Float", + "kotlin.Double", + "kotlin.Boolean", + "kotlin.Char", + "kotlin.Array", + "kotlin.collections.List", + "kotlin.collections.Set", + "kotlin.collections.Map" )); typeMapping = new HashMap(); @@ -312,7 +306,6 @@ public void setSerializationLibrary(final String enumSerializationLibrary) { * returns the OpenAPI type for the property * * @param p OpenAPI property object - * * @return string presentation of the type **/ @Override @@ -335,7 +328,6 @@ public String getSchemaType(Schema p) { * Output the type declaration of the property * * @param p OpenAPI Property object - * * @return a string presentation of the property type */ @Override @@ -384,8 +376,7 @@ public void processOpts() { super.processOpts(); if (StringUtils.isEmpty(System.getenv("KOTLIN_POST_PROCESS_FILE"))) { - LOGGER.info( - "Environment variable KOTLIN_POST_PROCESS_FILE not defined so the Kotlin code may not be properly formatted. To define it, try 'export KOTLIN_POST_PROCESS_FILE=\"/usr/local/bin/ktlint -F\"' (Linux/Mac)"); + LOGGER.info("Environment variable KOTLIN_POST_PROCESS_FILE not defined so the Kotlin code may not be properly formatted. To define it, try 'export KOTLIN_POST_PROCESS_FILE=\"/usr/local/bin/ktlint -F\"' (Linux/Mac)"); LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI)."); } @@ -408,12 +399,10 @@ public void processOpts() { if (additionalProperties.containsKey(CodegenConstants.PACKAGE_NAME)) { this.setPackageName((String) additionalProperties.get(CodegenConstants.PACKAGE_NAME)); - if (!additionalProperties.containsKey(CodegenConstants.MODEL_PACKAGE)) { + if (!additionalProperties.containsKey(CodegenConstants.MODEL_PACKAGE)) this.setModelPackage(packageName + ".models"); - } - if (!additionalProperties.containsKey(CodegenConstants.API_PACKAGE)) { + if (!additionalProperties.containsKey(CodegenConstants.API_PACKAGE)) this.setApiPackage(packageName + ".apis"); - } } else { additionalProperties.put(CodegenConstants.PACKAGE_NAME, packageName); } @@ -470,12 +459,10 @@ public void processOpts() { } private boolean getBooleanOption(String key) { - Object booleanValue = additionalProperties.get(key); + final Object booleanValue = additionalProperties.get(key); if (booleanValue instanceof Boolean) { - System.out.println("##### BOOLEAN"); return (Boolean) booleanValue; } else if (booleanValue instanceof String) { - System.out.println("##### STRING"); return Boolean.parseBoolean((String) booleanValue); } return false; @@ -546,7 +533,6 @@ public void setNeedsDataClassBody(boolean needsDataClassBody) { * * @param value enum variable name * @param datatype data type - * * @return the sanitized variable name for enum */ @Override @@ -609,7 +595,6 @@ public String toApiName(String name) { * Return the fully-qualified "Model" name for import * * @param name the name of the "Model" - * * @return the fully-qualified "Model" name for import */ @Override @@ -628,7 +613,6 @@ public String toModelImport(String name) { * In case the name belongs to the TypeSystem it won't be renamed. * * @param name the name of the model - * * @return capitalized model name */ @Override @@ -682,15 +666,13 @@ public String toModelName(final String name) { * Return the operation ID (method name) * * @param operationId operation ID - * * @return the sanitized method name */ @Override public String toOperationId(String operationId) { // throw exception if method name is empty - if (StringUtils.isEmpty(operationId)) { + if (StringUtils.isEmpty(operationId)) throw new RuntimeException("Empty method/operation name (operationId) not allowed"); - } operationId = camelize(sanitizeName(operationId), true); @@ -720,7 +702,6 @@ public String toModelFilename(String name) { * Provides a strongly typed declaration for simple arrays of some type and arrays of arrays of some type. * * @param arr Array schema - * * @return type declaration of array */ private String getArrayTypeDeclaration(ArraySchema arr) { @@ -743,7 +724,6 @@ private String getArrayTypeDeclaration(ArraySchema arr) { * Sanitize against Kotlin specific naming conventions, which may differ from those required by {@link DefaultCodegen#sanitizeName}. * * @param name string to be sanitize - * * @return sanitized string */ private String sanitizeKotlinSpecificNames(final String name) { @@ -812,7 +792,6 @@ protected boolean isReservedWord(String word) { * Check the type to see if it needs import the library/module/package * * @param type name of the type - * * @return true if the library/module/package of the corresponding type needs to be imported */ @Override From 4e973980fe18fba6931d957d88ee91da4f924900 Mon Sep 17 00:00:00 2001 From: Jan Weinschenker Date: Wed, 6 Nov 2019 11:10:57 +0100 Subject: [PATCH 3/7] test: unit test coverage for handling boolean config options --- .../kotlin/AbstractKotlinCodegenTest.java | 47 +++++++++++++++++-- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/AbstractKotlinCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/AbstractKotlinCodegenTest.java index ff23d307d907..fe9991a9cf6b 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/AbstractKotlinCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/AbstractKotlinCodegenTest.java @@ -1,5 +1,6 @@ package org.openapitools.codegen.kotlin; +import org.openapitools.codegen.CodegenConstants; import org.openapitools.codegen.CodegenType; import org.openapitools.codegen.languages.AbstractKotlinCodegen; import org.testng.Assert; @@ -53,7 +54,7 @@ public void pascalCaseEnumConverter() { } @Test - public void toEnumValue(){ + public void toEnumValue() { assertEquals(codegen.toEnumValue("1", "kotlin.Int"), "1"); assertEquals(codegen.toEnumValue("1", "kotlin.Double"), "1.0"); assertEquals(codegen.toEnumValue("1.3", "kotlin.Double"), "1.3"); @@ -81,14 +82,14 @@ public String getHelp() { } @Test - public void isDataTypeString(){ + public void isDataTypeString() { assertFalse(codegen.isDataTypeString("kotlin.Int")); assertTrue(codegen.isDataTypeString("kotlin.String")); assertTrue(codegen.isDataTypeString("String")); } @Test - public void toModelNameShouldUseProvidedMapping() { + public void toModelNameShouldUseProvidedMapping() { codegen.importMapping().put("json_myclass", "com.test.MyClass"); assertEquals("com.test.MyClass", codegen.toModelName("json_myclass")); } @@ -155,5 +156,45 @@ public void apiTestFileFolder() { Assert.assertEquals(codegen.apiTestFileFolder(), "/User/open/api/tools/test/folder/org/openapitools/codegen/api".replace('/', File.separatorChar)); } + @Test + public void processOptsBooleanTrueFromString() { + codegen.additionalProperties().put(CodegenConstants.SERIALIZABLE_MODEL, "true"); + codegen.processOpts(); + Assert.assertTrue((boolean) codegen.additionalProperties().get(CodegenConstants.SERIALIZABLE_MODEL)); + } + + @Test + public void processOptsBooleanTrueFromBoolean() { + codegen.additionalProperties().put(CodegenConstants.SERIALIZABLE_MODEL, true); + codegen.processOpts(); + Assert.assertTrue((boolean) codegen.additionalProperties().get(CodegenConstants.SERIALIZABLE_MODEL)); + } + + @Test + public void processOptsBooleanFalseFromString() { + codegen.additionalProperties().put(CodegenConstants.SERIALIZABLE_MODEL, "false"); + codegen.processOpts(); + Assert.assertFalse((boolean) codegen.additionalProperties().get(CodegenConstants.SERIALIZABLE_MODEL)); + } + @Test + public void processOptsBooleanFalseFromBoolean() { + codegen.additionalProperties().put(CodegenConstants.SERIALIZABLE_MODEL, false); + codegen.processOpts(); + Assert.assertFalse((boolean) codegen.additionalProperties().get(CodegenConstants.SERIALIZABLE_MODEL)); + } + + @Test + public void processOptsBooleanFalseFromGarbage() { + codegen.additionalProperties().put(CodegenConstants.SERIALIZABLE_MODEL, "blibb"); + codegen.processOpts(); + Assert.assertFalse((boolean) codegen.additionalProperties().get(CodegenConstants.SERIALIZABLE_MODEL)); + } + + @Test + public void processOptsBooleanFalseFromNumeric() { + codegen.additionalProperties().put(CodegenConstants.SERIALIZABLE_MODEL, 42); + codegen.processOpts(); + Assert.assertFalse((boolean) codegen.additionalProperties().get(CodegenConstants.SERIALIZABLE_MODEL)); + } } \ No newline at end of file From d828cf622f728cfea1e566b57dcc3a5b455cd762 Mon Sep 17 00:00:00 2001 From: Jan Weinschenker Date: Wed, 6 Nov 2019 11:12:28 +0100 Subject: [PATCH 4/7] fix: replace option value with boolean, if it is a string literal boolean --- .../codegen/languages/AbstractKotlinCodegen.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractKotlinCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractKotlinCodegen.java index 5eb9d020aaa9..b861a390cf76 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractKotlinCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractKotlinCodegen.java @@ -460,12 +460,14 @@ public void processOpts() { private boolean getBooleanOption(String key) { final Object booleanValue = additionalProperties.get(key); + Boolean result = Boolean.FALSE; if (booleanValue instanceof Boolean) { - return (Boolean) booleanValue; + result = (Boolean) booleanValue; } else if (booleanValue instanceof String) { - return Boolean.parseBoolean((String) booleanValue); + result = Boolean.parseBoolean((String) booleanValue); } - return false; + additionalProperties.put(key, result); + return result; } public void setArtifactId(String artifactId) { From 5a430bf5ac7043e0e70334bb747e1346b5359172 Mon Sep 17 00:00:00 2001 From: Jan Weinschenker Date: Wed, 6 Nov 2019 12:54:31 +0100 Subject: [PATCH 5/7] style: use data type long --- .../openapitools/codegen/kotlin/AbstractKotlinCodegenTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/AbstractKotlinCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/AbstractKotlinCodegenTest.java index fe9991a9cf6b..90c8acff528e 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/AbstractKotlinCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/AbstractKotlinCodegenTest.java @@ -193,7 +193,7 @@ public void processOptsBooleanFalseFromGarbage() { @Test public void processOptsBooleanFalseFromNumeric() { - codegen.additionalProperties().put(CodegenConstants.SERIALIZABLE_MODEL, 42); + codegen.additionalProperties().put(CodegenConstants.SERIALIZABLE_MODEL, 42L); codegen.processOpts(); Assert.assertFalse((boolean) codegen.additionalProperties().get(CodegenConstants.SERIALIZABLE_MODEL)); } From af0a7f84747be79698d330b8dd0dbe9453638ebf Mon Sep 17 00:00:00 2001 From: Jan Weinschenker Date: Thu, 7 Nov 2019 09:23:38 +0100 Subject: [PATCH 6/7] test: add maven testfile kotlin.xml to travis build --- .travis.yml | 1 + .../openapi-generator-maven-plugin/examples/kotlin.xml | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2e034e8a7c8e..cc0654536bbf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -138,6 +138,7 @@ script: # test maven plugin - mvn clean compile -f modules/openapi-generator-maven-plugin/examples/java-client.xml - mvn clean compile -f modules/openapi-generator-maven-plugin/examples/multi-module/pom.xml + - mvn clean compile -f modules/openapi-generator-maven-plugin/examples/kotlin.xml # test gradle plugin - (cd modules/openapi-generator-gradle-plugin/samples/local-spec && ./gradlew buildGoSdk) - (cd modules/openapi-generator-gradle-plugin/samples/local-spec && ./gradlew openApiGenerate) diff --git a/modules/openapi-generator-maven-plugin/examples/kotlin.xml b/modules/openapi-generator-maven-plugin/examples/kotlin.xml index 9c6304677687..9336aa2311de 100644 --- a/modules/openapi-generator-maven-plugin/examples/kotlin.xml +++ b/modules/openapi-generator-maven-plugin/examples/kotlin.xml @@ -40,7 +40,7 @@ - remote + kotlin generate-sources generate @@ -61,10 +61,10 @@ true - ${project.build.directory}/generated-sources/remote-openapi - remote.org.openapitools.client.api - remote.org.openapitools.client.model - remote.org.openapitools.client + ${project.build.directory}/generated-sources/kotlin + kotlin.org.openapitools.client.api + kotlin.org.openapitools.client.model + kotlin.org.openapitools.client From 1baeb29e239243c09aae72e13639873503c918e6 Mon Sep 17 00:00:00 2001 From: Jan Weinschenker Date: Thu, 7 Nov 2019 09:40:41 +0100 Subject: [PATCH 7/7] test: runnable maven test of the kotlin generator --- .../examples/kotlin.xml | 62 +++++++++++++++++-- 1 file changed, 56 insertions(+), 6 deletions(-) diff --git a/modules/openapi-generator-maven-plugin/examples/kotlin.xml b/modules/openapi-generator-maven-plugin/examples/kotlin.xml index 9336aa2311de..83b54be3daba 100644 --- a/modules/openapi-generator-maven-plugin/examples/kotlin.xml +++ b/modules/openapi-generator-maven-plugin/examples/kotlin.xml @@ -7,6 +7,7 @@ 1.0-SNAPSHOT sample-project http://maven.apache.org + @@ -62,9 +63,9 @@ ${project.build.directory}/generated-sources/kotlin - kotlin.org.openapitools.client.api - kotlin.org.openapitools.client.model - kotlin.org.openapitools.client + kotlintest.org.openapitools.client.api + kotlintest.org.openapitools.client.model + kotlintest.org.openapitools.client @@ -74,12 +75,42 @@ maven-compiler-plugin 3.8.1 - 1.7 - 1.7 + 1.8 + 1.8 none + + kotlin-maven-plugin + org.jetbrains.kotlin + + ${kotlinJvmTarget} + + + + + compile + + compile + + + + ${project.build.directory}/generated-sources/kotlin/src/main/kotlin + + + + + + + + + kotlin-maven-plugin + org.jetbrains.kotlin + ${kotlin.version} + + + @@ -171,7 +202,22 @@ com.brsanthu migbase64 - 2.2 + ${migbase64.version} + + + com.squareup.moshi + moshi-kotlin + ${moshi-kotlin.version} + + + com.squareup.moshi + moshi-adapters + ${moshi-kotlin.version} + + + com.squareup.okhttp3 + okhttp + 4.2.2 @@ -183,5 +229,9 @@ 2.7 1.0.0 4.8.1 + 1.3.50 + 1.8 + 1.8.0 + 2.2