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

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

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

import com.fasterxml.jackson.core.JsonGenerator
import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.databind.DeserializationContext
import com.fasterxml.jackson.databind.JsonDeserializer
import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.databind.JsonSerializer
import com.fasterxml.jackson.databind.KeyDeserializer
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.SerializerProvider
import com.fasterxml.jackson.module.kotlin.KotlinModule
import dev.forkhandles.data.JsonNodeDataContainer
import dev.forkhandles.values.Value
import org.http4k.core.Body
import org.http4k.lens.BiDiBodyLensSpec
import org.http4k.lens.BiDiMapping
import org.http4k.lens.ContentNegotiation
import java.math.BigDecimal
import java.math.BigInteger

fun  KotlinModule.asConfigurable(mapper: T): AutoMappingConfiguration =
    object : AutoMappingConfiguration {
        override fun  int(mapping: BiDiMapping) = adapter(mapping, JsonGenerator::writeNumber, JsonParser::getIntValue)

        override fun  long(mapping: BiDiMapping) = adapter(mapping, JsonGenerator::writeNumber, JsonParser::getLongValue)

        override fun  double(mapping: BiDiMapping) = adapter(mapping, JsonGenerator::writeNumber, JsonParser::getDoubleValue)

        override fun  bigInteger(mapping: BiDiMapping) = adapter(mapping, JsonGenerator::writeNumber, JsonParser::getBigIntegerValue)

        override fun  bigDecimal(mapping: BiDiMapping) =
            adapter(mapping, JsonGenerator::writeNumber, JsonParser::getDecimalValue)

        override fun  boolean(mapping: BiDiMapping) = adapter(mapping, JsonGenerator::writeBoolean, JsonParser::getBooleanValue)

        override fun  text(mapping: BiDiMapping) =
            adapter(mapping, JsonGenerator::writeString, JsonParser::getText)
                .apply {
                    if (mapping.clazz.isEnum) {
                        addKeySerializer(mapping.clazz, object : JsonSerializer() {
                            override fun serialize(value: OUT, gen: JsonGenerator, serializers: SerializerProvider) =
                                gen.writeFieldName(mapping(value))
                        })
                        addKeyDeserializer(mapping.clazz, object : KeyDeserializer() {
                            override fun deserializeKey(key: String, ctxt: DeserializationContext) = mapping(key)
                        })
                    }
                }

        private fun  adapter(
            mapping: BiDiMapping,
            write: JsonGenerator.(IN) -> Unit,
            read: JsonParser.() -> IN
        ) =
            apply {
                addDeserializer(mapping.clazz, object : JsonDeserializer() {
                    override fun deserialize(p: JsonParser, ctxt: DeserializationContext): OUT =
                        mapping.invoke(p.read())
                })
                addSerializer(mapping.clazz, object : JsonSerializer() {
                    override fun serialize(value: OUT, gen: JsonGenerator, serializers: SerializerProvider) =
                        gen.write(mapping(value))
                })
            }

        override fun done(): T = mapper.apply { registerModule(this@asConfigurable) }
    }

/**
 * Prevent the unmarshalling of unknown values4k types.
 */
fun  AutoMappingConfiguration.prohibitUnknownValues(): AutoMappingConfiguration =
    text(BiDiMapping(
        Value::class.java,
        { error("no mapping for ${it.javaClass}") }, { error("no mapping for ${it.javaClass}") })
    )

/**
 * Custom lens to extract and inject Data4k DataContainer types from JSON bodies
 */
fun  Body.Companion.json(
    fn: (JsonNode) -> T,
    description: String? = null,
    contentNegotiation: ContentNegotiation = ContentNegotiation.None
): BiDiBodyLensSpec = Jackson.body(description, contentNegotiation).map(fn, JsonNodeDataContainer::unwrap)





© 2015 - 2024 Weber Informatics LLC | Privacy Policy