org.http4k.format.Xml.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of http4k-format-xml Show documentation
Show all versions of http4k-format-xml Show documentation
Http4k XML support using GSON as an underlying engine
package org.http4k.format
import com.google.gson.JsonElement
import org.http4k.asByteBuffer
import org.http4k.asString
import org.http4k.core.Body
import org.http4k.core.ContentType
import org.http4k.core.ContentType.Companion.APPLICATION_XML
import org.http4k.core.HttpMessage
import org.http4k.core.with
import org.http4k.lens.BiDiBodyLensSpec
import org.http4k.lens.BiDiLensSpec
import org.http4k.lens.ContentNegotiation
import org.http4k.lens.Meta
import org.http4k.lens.ParamMeta.ObjectParam
import org.http4k.lens.httpBodyRoot
import org.json.XML
import org.w3c.dom.Document
import java.io.InputStream
import java.io.StringWriter
import java.nio.ByteBuffer
import javax.xml.parsers.DocumentBuilderFactory
import javax.xml.transform.TransformerFactory
import javax.xml.transform.dom.DOMSource
import javax.xml.transform.stream.StreamResult
import kotlin.reflect.KClass
object Xml : AutoMarshallingXml() {
override val defaultContentType = APPLICATION_XML
override fun Any.asXmlString(): String = throw UnsupportedOperationException("")
override fun asA(input: String, target: KClass): T = Gson.asA(input.asXmlToJsonElement(), target)
override fun asA(input: InputStream, target: KClass): T = Gson.asA(input.reader().readText().asXmlToJsonElement(), target)
fun String.asXmlToJsonElement(): JsonElement = Gson.parse(XML.toJSONObject(this, true).toString())
@JvmName("stringAsXmlToJsonElement")
fun asXmlToJsonElement(input: String): JsonElement = input.asXmlToJsonElement()
fun String.asXmlDocument(): Document =
DocumentBuilderFactory
.newInstance()
.newDocumentBuilder()
.parse(byteInputStream())
fun Document.asXmlString(): String = StringWriter().let {
TransformerFactory.newInstance().newTransformer().transform(DOMSource(this), StreamResult(it))
it.toString()
}
/**
* Convenience function to write the object as XML to the message body and set the content type.
*/
inline fun R.xml(t: T): R = with(Body.auto().toLens() of t)
/**
* Convenience function to read an object as XML from the message body.
*/
inline fun HttpMessage.xml(): T = Body.auto().toLens()(this)
/**
* Convenience function to write the object as XML to the message body and set the content type.
*/
fun BiDiLensSpec.xml() = map({ it.asXmlDocument() }, { it.asXmlString() })
fun Body.Companion.xml(
description: String? = null,
contentNegotiation: ContentNegotiation = ContentNegotiation.None
): BiDiBodyLensSpec =
httpBodyRoot(
listOf(Meta(true, "body", ObjectParam, "body", description, emptyMap())),
APPLICATION_XML,
contentNegotiation
)
.map(Body::payload) { Body(it) }
.map(ByteBuffer::asString, String::asByteBuffer).map({ it.asXmlDocument() }, { it.asXmlString() })
}