[Kotlin] update ApiClient to register all adapters for GsonBuilder (#18965)

* update api client to register type adapter

* update samples

* remove json array variable name
This commit is contained in:
William Cheng 2024-06-20 00:20:11 +08:00 committed by GitHub
parent cf303d4e03
commit 7747cc93e0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 243 additions and 236 deletions

View File

@ -163,6 +163,7 @@ import {{packageName}}.infrastructure.ITransformForStorage
{{/vars}} {{/vars}}
{{/hasEnums}} {{/hasEnums}}
{{#generateOneOfAnyOfWrappers}} {{#generateOneOfAnyOfWrappers}}
{{#gson}}
class CustomTypeAdapterFactory : TypeAdapterFactory { class CustomTypeAdapterFactory : TypeAdapterFactory {
override fun <T> create(gson: Gson, type: TypeToken<T>): TypeAdapter<T>? { override fun <T> create(gson: Gson, type: TypeToken<T>): TypeAdapter<T>? {
@ -249,24 +250,22 @@ import {{packageName}}.infrastructure.ITransformForStorage
throw IllegalArgumentException(String.format("Expected the field `{{{baseName}}}` to be an array in the JSON string but got `%s`", jsonObj["{{{baseName}}}"].toString())) throw IllegalArgumentException(String.format("Expected the field `{{{baseName}}}` to be an array in the JSON string but got `%s`", jsonObj["{{{baseName}}}"].toString()))
} }
val jsonArray{{name}} = jsonObj.getAsJsonArray("{{{baseName}}}")
// validate the required field `{{{baseName}}}` (array) // validate the required field `{{{baseName}}}` (array)
for (i in 0 until jsonArray{{name}}.size()) { for (i in 0 until jsonObj.getAsJsonArray("{{{baseName}}}").size()) {
{{{items.dataType}}}.validateJsonElement(jsonArray{{name}}.get(i)) {{{items.dataType}}}.validateJsonElement(jsonObj.getAsJsonArray("{{{baseName}}}").get(i))
} }
{{/required}} {{/required}}
{{^required}} {{^required}}
if (jsonObj["{{{baseName}}}"] != null && !jsonObj["{{{baseName}}}"].isJsonNull) { if (jsonObj["{{{baseName}}}"] != null && !jsonObj["{{{baseName}}}"].isJsonNull) {
val jsonArray{{name}} = jsonObj.getAsJsonArray("{{{baseName}}}") if (jsonObj.getAsJsonArray("{{{baseName}}}") != null) {
if (jsonArray{{name}} != null) {
// ensure the json data is an array // ensure the json data is an array
require(jsonObj["{{{baseName}}}"].isJsonArray) { require(jsonObj["{{{baseName}}}"].isJsonArray) {
String.format("Expected the field `{{{baseName}}}` to be an array in the JSON string but got `%s`", jsonObj["{{{baseName}}}"].toString()) String.format("Expected the field `{{{baseName}}}` to be an array in the JSON string but got `%s`", jsonObj["{{{baseName}}}"].toString())
} }
// validate the optional field `{{{baseName}}}` (array) // validate the optional field `{{{baseName}}}` (array)
for (i in 0 until jsonArray{{name}}.size()) { for (i in 0 until jsonObj.getAsJsonArray("{{{baseName}}}").size()) {
{{{items.dataType}}}.validateJsonElement(jsonArray{{name}}[i]) {{{items.dataType}}}.validateJsonElement(jsonObj.getAsJsonArray("{{{baseName}}}").get(i))
} }
} }
} }
@ -356,6 +355,7 @@ import {{packageName}}.infrastructure.ITransformForStorage
{{/discriminator}} {{/discriminator}}
} }
} }
{{/gson}}
{{/generateOneOfAnyOfWrappers}} {{/generateOneOfAnyOfWrappers}}
{{#vendorExtensions.x-has-data-class-body}} {{#vendorExtensions.x-has-data-class-body}}

View File

@ -64,7 +64,7 @@ import okhttp3.MediaType.Companion.toMediaType
private var baseUrl: String = defaultBasePath, private var baseUrl: String = defaultBasePath,
private val okHttpClientBuilder: OkHttpClient.Builder? = null, private val okHttpClientBuilder: OkHttpClient.Builder? = null,
{{^kotlinx_serialization}} {{^kotlinx_serialization}}
private val serializerBuilder: {{#gson}}GsonBuilder{{/gson}}{{#moshi}}Moshi.Builder{{/moshi}}{{#jackson}}ObjectMapper{{/jackson}} = Serializer.{{#gson}}gsonBuilder{{/gson}}{{#moshi}}moshiBuilder{{/moshi}}{{#jackson}}jacksonObjectMapper{{/jackson}}, private val serializerBuilder: {{#gson}}GsonBuilder{{/gson}}{{#moshi}}Moshi.Builder{{/moshi}}{{#jackson}}ObjectMapper{{/jackson}} = {{#generateOneOfAnyOfWrappers}}{{#gson}}registerTypeAdapterFactoryForAllModels({{/gson}}{{/generateOneOfAnyOfWrappers}}Serializer.{{#gson}}gsonBuilder{{/gson}}{{#generateOneOfAnyOfWrappers}}{{#gson}}){{/gson}}{{/generateOneOfAnyOfWrappers}}{{#moshi}}moshiBuilder{{/moshi}}{{#jackson}}jacksonObjectMapper{{/jackson}},
{{/kotlinx_serialization}} {{/kotlinx_serialization}}
private val callFactory: Call.Factory? = null, private val callFactory: Call.Factory? = null,
private val callAdapterFactories: List<CallAdapter.Factory> = listOf( private val callAdapterFactories: List<CallAdapter.Factory> = listOf(
@ -177,21 +177,6 @@ import okhttp3.MediaType.Companion.toMediaType
password: String password: String
) : this(baseUrl, okHttpClientBuilder, {{^kotlinx_serialization}}serializerBuilder, {{/kotlinx_serialization}}arrayOf(authName)) { ) : this(baseUrl, okHttpClientBuilder, {{^kotlinx_serialization}}serializerBuilder, {{/kotlinx_serialization}}arrayOf(authName)) {
setCredentials(username, password) setCredentials(username, password)
{{#generateOneOfAnyOfWrappers}}
{{^kotlinx_serialization}}
{{#gson}}
{{#models}}
{{#model}}
{{^isEnum}}
{{^hasChildren}}
serializerBuilder.registerTypeAdapterFactory({{modelPackage}}.{{{classname}}}.CustomTypeAdapterFactory())
{{/hasChildren}}
{{/isEnum}}
{{/model}}
{{/models}}
{{/gson}}
{{/kotlinx_serialization}}
{{/generateOneOfAnyOfWrappers}}
} }
{{/isBasicBasic}} {{/isBasicBasic}}
@ -204,21 +189,6 @@ import okhttp3.MediaType.Companion.toMediaType
bearerToken: String bearerToken: String
) : this(baseUrl, okHttpClientBuilder, {{^kotlinx_serialization}}serializerBuilder, {{/kotlinx_serialization}}arrayOf(authName)) { ) : this(baseUrl, okHttpClientBuilder, {{^kotlinx_serialization}}serializerBuilder, {{/kotlinx_serialization}}arrayOf(authName)) {
setBearerToken(bearerToken) setBearerToken(bearerToken)
{{#generateOneOfAnyOfWrappers}}
{{^kotlinx_serialization}}
{{#gson}}
{{#models}}
{{#model}}
{{^isEnum}}
{{^hasChildren}}
serializerBuilder.registerTypeAdapterFactory({{modelPackage}}.{{{classname}}}.CustomTypeAdapterFactory())
{{/hasChildren}}
{{/isEnum}}
{{/model}}
{{/models}}
{{/gson}}
{{/kotlinx_serialization}}
{{/generateOneOfAnyOfWrappers}}
} }
{{/isBasicBearer}} {{/isBasicBearer}}
@ -240,21 +210,6 @@ import okhttp3.MediaType.Companion.toMediaType
?.setClientSecret(secret) ?.setClientSecret(secret)
?.setUsername(username) ?.setUsername(username)
?.setPassword(password) ?.setPassword(password)
{{#generateOneOfAnyOfWrappers}}
{{^kotlinx_serialization}}
{{#gson}}
{{#models}}
{{#model}}
{{^isEnum}}
{{^hasChildren}}
serializerBuilder.registerTypeAdapterFactory({{modelPackage}}.{{{classname}}}.CustomTypeAdapterFactory())
{{/hasChildren}}
{{/isEnum}}
{{/model}}
{{/models}}
{{/gson}}
{{/kotlinx_serialization}}
{{/generateOneOfAnyOfWrappers}}
} }
{{/hasOAuthMethods}} {{/hasOAuthMethods}}
@ -391,6 +346,20 @@ import okhttp3.MediaType.Companion.toMediaType
return retrofitBuilder.callFactory(usedCallFactory).build().create(serviceClass) return retrofitBuilder.callFactory(usedCallFactory).build().create(serviceClass)
} }
{{#generateOneOfAnyOfWrappers}}
{{^kotlinx_serialization}}
{{#gson}}
/**
* Gets the serializer builder.
* @return serial builder
*/
fun getSerializerBuilder(): GsonBuilder {
return serializerBuilder
}
{{/gson}}
{{/kotlinx_serialization}}
{{/generateOneOfAnyOfWrappers}}
private fun normalizeBaseUrl() { private fun normalizeBaseUrl() {
if (!baseUrl.endsWith("/")) { if (!baseUrl.endsWith("/")) {
baseUrl += "/" baseUrl += "/"
@ -416,3 +385,28 @@ import okhttp3.MediaType.Companion.toMediaType
} }
} }
} }
{{#generateOneOfAnyOfWrappers}}
{{^kotlinx_serialization}}
{{#gson}}
/**
* Registers all models with the type adapter factory.
*
* @param gsonBuilder gson builder
* @return GSON builder
*/
fun registerTypeAdapterFactoryForAllModels(gsonBuilder: GsonBuilder): GsonBuilder {
{{#models}}
{{#model}}
{{^isEnum}}
{{^hasChildren}}
gsonBuilder.registerTypeAdapterFactory({{modelPackage}}.{{{classname}}}.CustomTypeAdapterFactory())
{{/hasChildren}}
{{/isEnum}}
{{/model}}
{{/models}}
return gsonBuilder
}
{{/gson}}
{{/kotlinx_serialization}}
{{/generateOneOfAnyOfWrappers}}

View File

@ -23,7 +23,7 @@ import retrofit2.converter.gson.GsonConverterFactory
class ApiClient( class ApiClient(
private var baseUrl: String = defaultBasePath, private var baseUrl: String = defaultBasePath,
private val okHttpClientBuilder: OkHttpClient.Builder? = null, private val okHttpClientBuilder: OkHttpClient.Builder? = null,
private val serializerBuilder: GsonBuilder = Serializer.gsonBuilder, private val serializerBuilder: GsonBuilder = registerTypeAdapterFactoryForAllModels(Serializer.gsonBuilder),
private val callFactory: Call.Factory? = null, private val callFactory: Call.Factory? = null,
private val callAdapterFactories: List<CallAdapter.Factory> = listOf( private val callAdapterFactories: List<CallAdapter.Factory> = listOf(
), ),
@ -112,17 +112,6 @@ class ApiClient(
?.setClientSecret(secret) ?.setClientSecret(secret)
?.setUsername(username) ?.setUsername(username)
?.setPassword(password) ?.setPassword(password)
serializerBuilder.registerTypeAdapterFactory(org.openapitools.client.models.ApiAnnotation.CustomTypeAdapterFactory())
serializerBuilder.registerTypeAdapterFactory(org.openapitools.client.models.ApiAnyOfUserOrPet.CustomTypeAdapterFactory())
serializerBuilder.registerTypeAdapterFactory(org.openapitools.client.models.ApiAnyOfUserOrPetOrArrayString.CustomTypeAdapterFactory())
serializerBuilder.registerTypeAdapterFactory(org.openapitools.client.models.ApiApiResponse.CustomTypeAdapterFactory())
serializerBuilder.registerTypeAdapterFactory(org.openapitools.client.models.ApiCategory.CustomTypeAdapterFactory())
serializerBuilder.registerTypeAdapterFactory(org.openapitools.client.models.ApiOrder.CustomTypeAdapterFactory())
serializerBuilder.registerTypeAdapterFactory(org.openapitools.client.models.ApiPet.CustomTypeAdapterFactory())
serializerBuilder.registerTypeAdapterFactory(org.openapitools.client.models.ApiTag.CustomTypeAdapterFactory())
serializerBuilder.registerTypeAdapterFactory(org.openapitools.client.models.ApiUser.CustomTypeAdapterFactory())
serializerBuilder.registerTypeAdapterFactory(org.openapitools.client.models.ApiUserOrPet.CustomTypeAdapterFactory())
serializerBuilder.registerTypeAdapterFactory(org.openapitools.client.models.ApiUserOrPetOrArrayString.CustomTypeAdapterFactory())
} }
/** /**
@ -218,6 +207,14 @@ class ApiClient(
return retrofitBuilder.callFactory(usedCallFactory).build().create(serviceClass) return retrofitBuilder.callFactory(usedCallFactory).build().create(serviceClass)
} }
/**
* Gets the serializer builder.
* @return serial builder
*/
fun getSerializerBuilder(): GsonBuilder {
return serializerBuilder
}
private fun normalizeBaseUrl() { private fun normalizeBaseUrl() {
if (!baseUrl.endsWith("/")) { if (!baseUrl.endsWith("/")) {
baseUrl += "/" baseUrl += "/"
@ -243,3 +240,24 @@ class ApiClient(
} }
} }
} }
/**
* Registers all models with the type adapter factory.
*
* @param gsonBuilder gson builder
* @return GSON builder
*/
fun registerTypeAdapterFactoryForAllModels(gsonBuilder: GsonBuilder): GsonBuilder {
gsonBuilder.registerTypeAdapterFactory(org.openapitools.client.models.ApiAnnotation.CustomTypeAdapterFactory())
gsonBuilder.registerTypeAdapterFactory(org.openapitools.client.models.ApiAnyOfUserOrPet.CustomTypeAdapterFactory())
gsonBuilder.registerTypeAdapterFactory(org.openapitools.client.models.ApiAnyOfUserOrPetOrArrayString.CustomTypeAdapterFactory())
gsonBuilder.registerTypeAdapterFactory(org.openapitools.client.models.ApiApiResponse.CustomTypeAdapterFactory())
gsonBuilder.registerTypeAdapterFactory(org.openapitools.client.models.ApiCategory.CustomTypeAdapterFactory())
gsonBuilder.registerTypeAdapterFactory(org.openapitools.client.models.ApiOrder.CustomTypeAdapterFactory())
gsonBuilder.registerTypeAdapterFactory(org.openapitools.client.models.ApiPet.CustomTypeAdapterFactory())
gsonBuilder.registerTypeAdapterFactory(org.openapitools.client.models.ApiTag.CustomTypeAdapterFactory())
gsonBuilder.registerTypeAdapterFactory(org.openapitools.client.models.ApiUser.CustomTypeAdapterFactory())
gsonBuilder.registerTypeAdapterFactory(org.openapitools.client.models.ApiUserOrPet.CustomTypeAdapterFactory())
gsonBuilder.registerTypeAdapterFactory(org.openapitools.client.models.ApiUserOrPetOrArrayString.CustomTypeAdapterFactory())
return gsonBuilder
}

View File

@ -156,16 +156,15 @@ data class ApiPet (
ApiCategory.validateJsonElement(jsonObj["category"]) ApiCategory.validateJsonElement(jsonObj["category"])
} }
if (jsonObj["tags"] != null && !jsonObj["tags"].isJsonNull) { if (jsonObj["tags"] != null && !jsonObj["tags"].isJsonNull) {
val jsonArraytags = jsonObj.getAsJsonArray("tags") if (jsonObj.getAsJsonArray("tags") != null) {
if (jsonArraytags != null) {
// ensure the json data is an array // ensure the json data is an array
require(jsonObj["tags"].isJsonArray) { require(jsonObj["tags"].isJsonArray) {
String.format("Expected the field `tags` to be an array in the JSON string but got `%s`", jsonObj["tags"].toString()) String.format("Expected the field `tags` to be an array in the JSON string but got `%s`", jsonObj["tags"].toString())
} }
// validate the optional field `tags` (array) // validate the optional field `tags` (array)
for (i in 0 until jsonArraytags.size()) { for (i in 0 until jsonObj.getAsJsonArray("tags").size()) {
ApiTag.validateJsonElement(jsonArraytags[i]) ApiTag.validateJsonElement(jsonObj.getAsJsonArray("tags").get(i))
} }
} }
} }

View File

@ -27,6 +27,8 @@ import com.google.gson.GsonBuilder
import io.kotlintest.matchers.types.shouldBeSameInstanceAs import io.kotlintest.matchers.types.shouldBeSameInstanceAs
import io.kotlintest.shouldNotBe import io.kotlintest.shouldNotBe
import org.junit.jupiter.api.Assertions.assertThrows import org.junit.jupiter.api.Assertions.assertThrows
import org.openapitools.client.infrastructure.ApiClient
import org.openapitools.client.infrastructure.registerTypeAdapterFactoryForAllModels
import java.io.IOException import java.io.IOException
import java.lang.RuntimeException import java.lang.RuntimeException
@ -34,13 +36,7 @@ class ApiUserOrPetTest : ShouldSpec() {
init { init {
should("test custom type adapter") { should("test custom type adapter") {
val gson = GsonBuilder() val gson = ApiClient().getSerializerBuilder().create()
.registerTypeAdapterFactory(ApiUser.CustomTypeAdapterFactory())
.registerTypeAdapterFactory(ApiCategory.CustomTypeAdapterFactory())
.registerTypeAdapterFactory(ApiPet.CustomTypeAdapterFactory())
.registerTypeAdapterFactory(ApiTag.CustomTypeAdapterFactory())
.registerTypeAdapterFactory(ApiUserOrPet.CustomTypeAdapterFactory())
.create()
// test Category // test Category
val categoryJson = "{\"id\":123,\"name\":\"category\"}" val categoryJson = "{\"id\":123,\"name\":\"category\"}"