diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/build.gradle.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/build.gradle.mustache index a81f05ba3523..8cec3dbe7f3d 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-client/build.gradle.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-client/build.gradle.mustache @@ -57,6 +57,7 @@ dependencies { {{/moshi}} {{#gson}} compile "com.google.code.gson:gson:2.8.6" + compile "io.gsonfire:gson-fire:1.8.0" {{/gson}} {{#jackson}} compile "com.fasterxml.jackson.module:jackson-module-kotlin:2.10.2" diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/jvm-common/infrastructure/Serializer.kt.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/jvm-common/infrastructure/Serializer.kt.mustache index 7ccd50796773..36e9f2cb8edd 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-client/jvm-common/infrastructure/Serializer.kt.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-client/jvm-common/infrastructure/Serializer.kt.mustache @@ -10,6 +10,9 @@ import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory {{#gson}} import com.google.gson.Gson import com.google.gson.GsonBuilder +import com.google.gson.JsonElement +import io.gsonfire.GsonFireBuilder +import io.gsonfire.TypeSelector {{^threetenbp}} import java.time.LocalDate import java.time.LocalDateTime @@ -21,6 +24,14 @@ import org.threeten.bp.LocalDateTime import org.threeten.bp.OffsetDateTime {{/threetenbp}} import java.util.UUID +{{#models.0}} +import {{modelPackage}}.* +{{/models.0}} +import kotlin.collections.HashMap +import kotlin.collections.MutableMap +import kotlin.collections.get +import kotlin.collections.set +import kotlin.collections.toTypedArray {{/gson}} {{#jackson}} import com.fasterxml.jackson.databind.ObjectMapper @@ -53,17 +64,44 @@ import java.util.Date {{/moshi}} {{#gson}} @JvmStatic - val gsonBuilder: GsonBuilder = GsonBuilder() + var gsonBuilder = GsonFireBuilder(){{#models}}{{#model}}{{#discriminator}} + .registerTypeSelector<{{classname}}>({{classname}}::class.java, TypeSelector<{{classname}}?> { readElement -> + val classByDiscriminatorValue: MutableMap = HashMap() + {{#mappedModels}} + classByDiscriminatorValue["{{mappingName}}".toUpperCase()] = {{modelName}}::class.java + {{/mappedModels}} + + try { + return@TypeSelector getClassByDiscriminator( + classByDiscriminatorValue, + getDiscriminatorValue(readElement, "{{propertyName}}")) as Class? + } catch (ex: IllegalArgumentException) { return@TypeSelector {{classname}}::class.java} + }){{/discriminator}}{{/model}}{{/models}} + .createGsonBuilder() .registerTypeAdapter(Date::class.java, DateAdapter()) .registerTypeAdapter(OffsetDateTime::class.java, OffsetDateTimeAdapter()) .registerTypeAdapter(LocalDateTime::class.java, LocalDateTimeAdapter()) .registerTypeAdapter(LocalDate::class.java, LocalDateAdapter()) .registerTypeAdapter(ByteArray::class.java, ByteArrayAdapter()) - + @JvmStatic val gson: Gson by lazy { gsonBuilder.create() } + + fun getDiscriminatorValue(readElement: JsonElement, discriminatorField: String?): String? { + val element: JsonElement = readElement.getAsJsonObject().get(discriminatorField) + ?: throw IllegalArgumentException("missing discriminator field: <$discriminatorField>") + return element.getAsString() + } + + fun getClassByDiscriminator( + classByDiscriminatorValue: Map<*, *>, + discriminatorValue: String? + ): Class<*>? { + return classByDiscriminatorValue[discriminatorValue?.toUpperCase()] as Class<*>? + ?: throw IllegalArgumentException("cannot determine model class of name: <$discriminatorValue>") + } {{/gson}} {{#jackson}} @JvmStatic diff --git a/samples/client/petstore/kotlin-gson/build.gradle b/samples/client/petstore/kotlin-gson/build.gradle index ce9cb568dd7b..87b688f40b4f 100644 --- a/samples/client/petstore/kotlin-gson/build.gradle +++ b/samples/client/petstore/kotlin-gson/build.gradle @@ -30,6 +30,7 @@ test { dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" compile "com.google.code.gson:gson:2.8.6" + compile "io.gsonfire:gson-fire:1.8.0" compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" compile "com.squareup.okhttp3:okhttp:4.2.2" testCompile "io.kotlintest:kotlintest-runner-junit5:3.1.0" diff --git a/samples/client/petstore/kotlin-gson/src/main/kotlin/org/openapitools/client/infrastructure/Serializer.kt b/samples/client/petstore/kotlin-gson/src/main/kotlin/org/openapitools/client/infrastructure/Serializer.kt index 6465f1485531..a126a580bfa5 100644 --- a/samples/client/petstore/kotlin-gson/src/main/kotlin/org/openapitools/client/infrastructure/Serializer.kt +++ b/samples/client/petstore/kotlin-gson/src/main/kotlin/org/openapitools/client/infrastructure/Serializer.kt @@ -2,23 +2,47 @@ package org.openapitools.client.infrastructure import com.google.gson.Gson import com.google.gson.GsonBuilder +import com.google.gson.JsonElement +import io.gsonfire.GsonFireBuilder +import io.gsonfire.TypeSelector import java.time.LocalDate import java.time.LocalDateTime import java.time.OffsetDateTime import java.util.UUID +import org.openapitools.client.models.* +import kotlin.collections.HashMap +import kotlin.collections.MutableMap +import kotlin.collections.get +import kotlin.collections.set +import kotlin.collections.toTypedArray import java.util.Date object Serializer { @JvmStatic - val gsonBuilder: GsonBuilder = GsonBuilder() + var gsonBuilder = GsonFireBuilder() + .createGsonBuilder() .registerTypeAdapter(Date::class.java, DateAdapter()) .registerTypeAdapter(OffsetDateTime::class.java, OffsetDateTimeAdapter()) .registerTypeAdapter(LocalDateTime::class.java, LocalDateTimeAdapter()) .registerTypeAdapter(LocalDate::class.java, LocalDateAdapter()) .registerTypeAdapter(ByteArray::class.java, ByteArrayAdapter()) - + @JvmStatic val gson: Gson by lazy { gsonBuilder.create() } + + fun getDiscriminatorValue(readElement: JsonElement, discriminatorField: String?): String? { + val element: JsonElement = readElement.getAsJsonObject().get(discriminatorField) + ?: throw IllegalArgumentException("missing discriminator field: <$discriminatorField>") + return element.getAsString() + } + + fun getClassByDiscriminator( + classByDiscriminatorValue: Map<*, *>, + discriminatorValue: String? + ): Class<*>? { + return classByDiscriminatorValue[discriminatorValue?.toUpperCase()] as Class<*>? + ?: throw IllegalArgumentException("cannot determine model class of name: <$discriminatorValue>") + } } diff --git a/samples/client/petstore/kotlin-jvm-okhttp4-coroutines/build.gradle b/samples/client/petstore/kotlin-jvm-okhttp4-coroutines/build.gradle index ce9cb568dd7b..87b688f40b4f 100644 --- a/samples/client/petstore/kotlin-jvm-okhttp4-coroutines/build.gradle +++ b/samples/client/petstore/kotlin-jvm-okhttp4-coroutines/build.gradle @@ -30,6 +30,7 @@ test { dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" compile "com.google.code.gson:gson:2.8.6" + compile "io.gsonfire:gson-fire:1.8.0" compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" compile "com.squareup.okhttp3:okhttp:4.2.2" testCompile "io.kotlintest:kotlintest-runner-junit5:3.1.0" diff --git a/samples/client/petstore/kotlin-jvm-okhttp4-coroutines/src/main/kotlin/org/openapitools/client/infrastructure/Serializer.kt b/samples/client/petstore/kotlin-jvm-okhttp4-coroutines/src/main/kotlin/org/openapitools/client/infrastructure/Serializer.kt index 6465f1485531..a126a580bfa5 100644 --- a/samples/client/petstore/kotlin-jvm-okhttp4-coroutines/src/main/kotlin/org/openapitools/client/infrastructure/Serializer.kt +++ b/samples/client/petstore/kotlin-jvm-okhttp4-coroutines/src/main/kotlin/org/openapitools/client/infrastructure/Serializer.kt @@ -2,23 +2,47 @@ package org.openapitools.client.infrastructure import com.google.gson.Gson import com.google.gson.GsonBuilder +import com.google.gson.JsonElement +import io.gsonfire.GsonFireBuilder +import io.gsonfire.TypeSelector import java.time.LocalDate import java.time.LocalDateTime import java.time.OffsetDateTime import java.util.UUID +import org.openapitools.client.models.* +import kotlin.collections.HashMap +import kotlin.collections.MutableMap +import kotlin.collections.get +import kotlin.collections.set +import kotlin.collections.toTypedArray import java.util.Date object Serializer { @JvmStatic - val gsonBuilder: GsonBuilder = GsonBuilder() + var gsonBuilder = GsonFireBuilder() + .createGsonBuilder() .registerTypeAdapter(Date::class.java, DateAdapter()) .registerTypeAdapter(OffsetDateTime::class.java, OffsetDateTimeAdapter()) .registerTypeAdapter(LocalDateTime::class.java, LocalDateTimeAdapter()) .registerTypeAdapter(LocalDate::class.java, LocalDateAdapter()) .registerTypeAdapter(ByteArray::class.java, ByteArrayAdapter()) - + @JvmStatic val gson: Gson by lazy { gsonBuilder.create() } + + fun getDiscriminatorValue(readElement: JsonElement, discriminatorField: String?): String? { + val element: JsonElement = readElement.getAsJsonObject().get(discriminatorField) + ?: throw IllegalArgumentException("missing discriminator field: <$discriminatorField>") + return element.getAsString() + } + + fun getClassByDiscriminator( + classByDiscriminatorValue: Map<*, *>, + discriminatorValue: String? + ): Class<*>? { + return classByDiscriminatorValue[discriminatorValue?.toUpperCase()] as Class<*>? + ?: throw IllegalArgumentException("cannot determine model class of name: <$discriminatorValue>") + } }