All Downloads are FREE. Search and download functionalities are using the official Maven repository.

name.remal.gradle_plugins.utils.newJsonRetrofitBuilder.kt Maven / Gradle / Ivy

There is a newer version: 1.9.2
Show newest version
package name.remal.gradle_plugins.utils

import com.fasterxml.jackson.databind.JavaType
import okhttp3.MediaType
import okhttp3.OkHttpClient
import okhttp3.RequestBody
import okhttp3.ResponseBody
import retrofit2.Converter
import retrofit2.Retrofit
import java.lang.reflect.Type
import java.nio.charset.StandardCharsets.UTF_8

fun newJsonRetrofitBuilder(httpClientConfigurer: (httpClientBuilder: OkHttpClient.Builder) -> OkHttpClient.Builder = { it }): Retrofit.Builder {
    return newRetrofitBuilder {
        httpClientConfigurer(it.addInterceptor {
            it.proceed(it.request().newBuilder()
                .addHeader("Accept", "application/json")
                .build())
        })
    }
        .addConverterFactory(JsonConverterFactory)
}

private object JsonConverterFactory : Converter.Factory() {

    override fun requestBodyConverter(type: Type, parameterAnnotations: Array, methodAnnotations: Array, retrofit: Retrofit): Converter<*, RequestBody>? {
        return JsonRequestBodyConverter(type)
    }

    override fun responseBodyConverter(type: Type, annotations: Array, retrofit: Retrofit): Converter? {
        return JsonResponseBodyConverter(type)
    }

}

private class JsonRequestBodyConverter(type: Type) : Converter {

    companion object {
        private val CHARSET = UTF_8
        private val MEDIA_TYPE = MediaType.get("application/json;charset=${CHARSET.name()}")
    }

    private val javaType = JSON_OBJECT_MAPPER.typeFactory.constructType(type)
    private val writer = JSON_OBJECT_MAPPER.writerFor(javaType)

    override fun convert(value: Any?): RequestBody? {
        val json = JSON_OBJECT_MAPPER.writeValueAsString(value)
        val bytes = json.toByteArray(CHARSET)
        return RequestBody.create(MEDIA_TYPE, bytes)
    }

}

private class JsonResponseBodyConverter(type: Type) : Converter {

    private val javaType = JSON_OBJECT_MAPPER.typeFactory.constructType(type)
    private val reader = JSON_OBJECT_MAPPER.readerFor(javaType)

    override fun convert(responseBody: ResponseBody): Any? {
        try {
            val content = responseBody.string()
            try {
                return reader.readValue(content)

            } catch (e: Throwable) {
                throw JsonParseException(content, javaType, e)
            }

        } finally {
            responseBody.close()
        }
    }

}

private class JsonParseException(content: String, javaType: JavaType, cause: Throwable) : RuntimeException(
    buildString {
        append("JSON can't be deserialized to ").append(javaType).append(": ")
        val maxLength = 1024
        if (content.length <= maxLength) {
            append(content)
        } else {
            append(content.substring(0, maxLength))
            append(" [ ... ").append(content.length - maxLength).append(" more characters ... ]")
        }
    },
    cause
)

internal fun  __parseWithRetrofitJsonObjectMapper(content: String, type: Class): T = JSON_OBJECT_MAPPER.readValue(content, type)




© 2015 - 2024 Weber Informatics LLC | Privacy Policy