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

org.http4k.format.Gson.kt Maven / Gradle / Ivy

There is a newer version: 5.31.0.0
Show newest version
package org.http4k.format

import com.google.gson.GsonBuilder
import com.google.gson.JsonArray
import com.google.gson.JsonElement
import com.google.gson.JsonNull
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import com.google.gson.JsonPrimitive
import org.http4k.core.Body
import org.http4k.lens.BiDiBodyLensSpec
import org.http4k.lens.BiDiWsMessageLensSpec
import org.http4k.lens.ContentNegotiation
import org.http4k.websocket.WsMessage
import java.math.BigDecimal
import java.math.BigInteger
import kotlin.reflect.KClass

class InvalidJsonException(messasge: String, cause: Throwable? = null) : Exception(messasge, cause)

open class ConfigurableGson(builder: GsonBuilder) : JsonLibAutoMarshallingJson() {
    override fun typeOf(value: JsonElement): JsonType =
        when {
            value.isJsonArray -> JsonType.Array
            value.isJsonNull -> JsonType.Null
            value.isJsonObject -> JsonType.Object
            value.isJsonPrimitive -> {
                val prim = value.asJsonPrimitive
                when {
                    prim.isBoolean -> JsonType.Boolean
                    prim.isNumber -> JsonType.Number
                    prim.isString -> JsonType.String
                    else -> throw IllegalArgumentException("Don't know now to translate $value")
                }
            }
            else -> throw IllegalArgumentException("Don't know now to translate $value")
        }

    private val compact = builder.create()
    private val pretty = builder.setPrettyPrinting().create()

    override fun String.asJsonObject(): JsonElement = JsonParser().parse(this).let { if(it.isJsonArray || it.isJsonObject) it else throw InvalidJsonException(
        "Could not convert to a JSON Object or Array. $this"
    ) }
    override fun String?.asJsonValue(): JsonElement = this?.let { JsonPrimitive(this) } ?: JsonNull.INSTANCE
    override fun Int?.asJsonValue(): JsonElement = this?.let { JsonPrimitive(this) } ?: JsonNull.INSTANCE
    override fun Double?.asJsonValue(): JsonElement = this?.let { JsonPrimitive(this) } ?: JsonNull.INSTANCE
    override fun Long?.asJsonValue(): JsonElement = this?.let { JsonPrimitive(this) } ?: JsonNull.INSTANCE
    override fun BigDecimal?.asJsonValue(): JsonElement = this?.let { JsonPrimitive(this) } ?: JsonNull.INSTANCE
    override fun BigInteger?.asJsonValue(): JsonElement = this?.let { JsonPrimitive(this) } ?: JsonNull.INSTANCE
    override fun Boolean?.asJsonValue(): JsonElement = this?.let { JsonPrimitive(this) } ?: JsonNull.INSTANCE
    override fun > T.asJsonArray(): JsonElement = fold(JsonArray()) { memo, o -> memo.add(o); memo }

    override fun JsonElement.asPrettyJsonString(): String = pretty.toJson(this)
    override fun JsonElement.asCompactJsonString(): String = compact.toJson(this)
    override fun >> LIST.asJsonObject(): JsonElement {
        val root = JsonObject()
        forEach { root.add(it.first, it.second) }
        return root
    }

    override fun fields(node: JsonElement): Iterable> {
        val fieldList = mutableListOf>()
        for ((key, value) in node.asJsonObject.entrySet()) {
            fieldList += key to value
        }
        return fieldList
    }

    override fun elements(value: JsonElement): Iterable = value.asJsonArray
    override fun text(value: JsonElement): String = value.asString

    override fun asJsonObject(a: Any): JsonElement = compact.toJsonTree(a)
    override fun  asA(s: String, c: KClass): T = compact.fromJson(s, c.java)
    override fun  asA(j: JsonElement, c: KClass): T = compact.fromJson(j, c.java)

    inline fun  String.asA(): T = asA(this, T::class)
    inline fun  JsonElement.asA(): T = asA(this, T::class)

    inline fun  Body.Companion.auto(description: String? = null, contentNegotiation: ContentNegotiation = ContentNegotiation.None): BiDiBodyLensSpec = Body.json(description, contentNegotiation).map({ it.asA() }, { it.asJsonObject() })

    inline fun  WsMessage.Companion.auto(): BiDiWsMessageLensSpec = WsMessage.json().map({ it.asA() }, { it.asJsonObject() })
}

object Gson : ConfigurableGson(GsonBuilder().serializeNulls())




© 2015 - 2024 Weber Informatics LLC | Privacy Policy