libeufin

Integration and sandbox testing for FinTech APIs and data formats
Log | Files | Refs | Submodules | README | LICENSE

commit e492d02140c9a35cd9ec551a5d8619831989fe47
parent f50906d1f48af0c5a5b190d06578103eaebdbe4d
Author: Marcello Stanisci <stanisci.m@gmail.com>
Date:   Fri, 11 Oct 2019 13:27:53 +0200

introduce helper downcast function

Diffstat:
Msandbox/src/main/kotlin/Main.kt | 44++++++++++++++++++++++++++++++++++++++++++++
Msandbox/src/main/kotlin/XML.kt | 4++--
Msandbox/src/test/kotlin/DomToJaxbTest.kt | 3++-
3 files changed, 48 insertions(+), 3 deletions(-)

diff --git a/sandbox/src/main/kotlin/Main.kt b/sandbox/src/main/kotlin/Main.kt @@ -39,13 +39,46 @@ import io.ktor.server.netty.Netty import org.jetbrains.exposed.sql.transactions.transaction import org.slf4j.LoggerFactory import org.w3c.dom.Document +import org.w3c.dom.Element import tech.libeufin.messages.ebics.hev.HEVResponseDataType +import tech.libeufin.messages.ebics.keyrequest.EbicsUnsecuredRequest +import tech.libeufin.messages.ebics.keyrequest.UnsecuredReqOrderDetailsType import java.text.DateFormat import javax.xml.bind.JAXBElement val logger = LoggerFactory.getLogger("tech.libeufin.sandbox") val xmlProcess = XML() +/** + * Sometimes, JAXB is not able to figure out to which type + * a certain XML node should be bound to. This happens when + * one element name can have multiple definitions therefore + * JAXB renders it as a abstract class. In that case, the + * object factory must be instructed about the subtype to create, + * and this is done via injecting the xsi:type attribute to the + * "overloaded" XML element. + * + * Alternative methods of addressing this? + * + * @param document the XML Document to modify + * @param node the name of the overloaded element (ideally this + * parameter should be a XPATH address) + * @param type the type to downcast @a node to + * @return the modified document + */ +fun downcastXml(document: Document, node: String, type: String) : Document { + + val x: Element = document.getElementsByTagName("OrderDetails")?.item(0) as Element + + x.setAttributeNS( + "http://www.w3.org/2001/XMLSchema-instance", + "type", + type + ) + + return document +} + private suspend fun ApplicationCall.adminCustomers() { val body = try { receive<CustomerRequest>() @@ -170,6 +203,17 @@ private suspend fun ApplicationCall.ebicsweb() { /* Manage request. */ + val bodyJaxb = xmlProcess.convertDomToJaxb<EbicsUnsecuredRequest>( + "tech.libeufin.messages.ebics.keyrequest", + downcastXml( + bodyDocument, + "OrderDetails", + "UnsecuredReqOrderDetailsType" + ) + ) + + logger.info("Serving a ${bodyJaxb.header.static.orderDetails.orderType} request") + respond( HttpStatusCode.NotImplemented, SandboxError("Not implemented") diff --git a/sandbox/src/main/kotlin/XML.kt b/sandbox/src/main/kotlin/XML.kt @@ -176,13 +176,13 @@ class XML { * @param document the document to convert into JAXB. * @return the JAXB object reflecting the original XML document. */ - fun convertDomToJaxb(packageName: String, document: Document): Any { + fun <T>convertDomToJaxb(packageName: String, document: Document) : T { val jc = JAXBContext.newInstance(packageName) /* Marshalling the object into the document. */ val m = jc.createUnmarshaller() - return m.unmarshal(document) // document "went" into Jaxb + return m.unmarshal(document) as T // document "went" into Jaxb } /** diff --git a/sandbox/src/test/kotlin/DomToJaxbTest.kt b/sandbox/src/test/kotlin/DomToJaxbTest.kt @@ -2,6 +2,7 @@ package tech.libeufin.sandbox import org.junit.Test import org.w3c.dom.Element +import tech.libeufin.messages.ebics.keyrequest.EbicsUnsecuredRequest import tech.libeufin.messages.ebics.keyrequest.OrderDetailsType import tech.libeufin.messages.ebics.keyrequest.UnsecuredReqOrderDetailsType @@ -22,7 +23,7 @@ class DomToJaxbTest { "UnsecuredReqOrderDetailsType" ) - processor.convertDomToJaxb( + processor.convertDomToJaxb<EbicsUnsecuredRequest>( "tech.libeufin.messages.ebics.keyrequest", iniDom) }