Skip to content

Commit

Permalink
Add test for soap envelope reading
Browse files Browse the repository at this point in the history
  • Loading branch information
pdvrieze committed Aug 8, 2024
1 parent face808 commit ed596d9
Show file tree
Hide file tree
Showing 4 changed files with 806 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
/*
* Copyright (c) 2018.
*
* This file is part of ProcessManager.
*
* ProcessManager is free software: you can redistribute it and/or modify it under the terms of version 3 of the
* GNU Lesser General Public License as published by the Free Software Foundation.
*
* ProcessManager is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with ProcessManager. If not,
* see <http://www.gnu.org/licenses/>.
*/

package nl.adaptivity.xml.serialization.regressions

import io.github.pdvrieze.xmlutil.testutil.assertXmlEquals
import nl.adaptivity.xml.serialization.regressions.soap.Envelope
import nl.adaptivity.xmlutil.*
import nl.adaptivity.xmlutil.core.impl.multiplatform.StringWriter
import nl.adaptivity.xmlutil.serialization.XML
import nl.adaptivity.xmlutil.siblingsToFragment
import nl.adaptivity.xmlutil.util.CompactFragment
import nl.adaptivity.xmlutil.util.CompactFragmentSerializer
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.text.trim


/**
* Created by pdvrieze on 03/12/15.
*/
class TestSoapHelper {

@Test
fun testUnmarshalSoapResponse() {
val env = Envelope.deserialize(xmlStreaming.newReader(SOAP_RESPONSE1))
val bodyContent = env.body.child as CompactFragment
assertXmlEquals(SOAP_RESPONSE1_BODY, bodyContent.contentString)
}

@Test
fun testRoundtripSoapResponse() {
val xml: XML = XML { indent = 2; autoPolymorphic = true }
val serializer = Envelope.Serializer(CompactFragmentSerializer)
val env: Envelope<CompactFragment> = XML.decodeFromString(serializer, SOAP_RESPONSE1)
assertXmlEquals(SOAP_RESPONSE1_BODY, env.body.child.contentString.trim())

val serialized = XML.encodeToString(serializer, env)
assertXmlEquals(SOAP_RESPONSE1, serialized)
}

@Test
fun testRoundtripSoapResponse2() {
val xml: XML = XML { indent = 2; autoPolymorphic = true }
val serializer = Envelope.Serializer(CompactFragmentSerializer)
val env = Envelope.deserialize(xmlStreaming.newReader(SOAP_RESPONSE2))
val sw = StringWriter()
val out = xmlStreaming.newWriter(sw)
XML.Companion.encodeToWriter(out, env)
assertXmlEquals(SOAP_RESPONSE2, sw.toString())
}

@Test
fun testUnmarshalSoapResponse2() {
val dbf = xmlStreaming.genericDomImplementation
//dbf.setNamespaceAware = true

val doc = dbf.createDocument().also { d ->
val i =xmlStreaming.newReader(SOAP_RESPONSE1)
val o = xmlStreaming.newWriter(d)
while (i.hasNext()) { i.next(); i.writeCurrent(o) }
}

val env = Envelope.Companion.deserialize(xmlStreaming.newReader(doc))
val bodyContent = env.body.child as CompactFragment
assertXmlEquals(SOAP_RESPONSE1_BODY, bodyContent.contentString)
}

@Test
fun testXmlReaderFromDom() {
val input =
"<foo xmlns=\"urn:bar\"><rpc:result xmlns:rpc=\"http://www.w3.org/2003/05/soap-rpc\">result</rpc:result></foo>"

val dbf = xmlStreaming.genericDomImplementation
//dbf.setNamespaceAware = true

val doc = dbf.createDocument().also { d ->
val i =xmlStreaming.newReader(input)
val o = xmlStreaming.newWriter(d)
while (i.hasNext()) { i.next(); i.writeCurrent(o) }
}

val reader = xmlStreaming.newReader(doc)
assertFalse(reader.isStarted)

if (reader.next() == EventType.START_DOCUMENT) reader.next()

reader.require(EventType.START_ELEMENT, "urn:bar", "foo")
reader.next()
reader.require(EventType.START_ELEMENT, "http://www.w3.org/2003/05/soap-rpc", "result")
val parseResult = reader.siblingsToFragment()
assertEquals("<rpc:result xmlns:rpc=\"http://www.w3.org/2003/05/soap-rpc\">result</rpc:result>", parseResult.contentString)
assertFalse(parseResult.namespaces.iterator().hasNext(), "Unexpected namespaces: ${parseResult.namespaces.joinToString()}")
}

companion object {

private val SOAP_RESPONSE1_BODY = """<getProcessNodeInstanceSoapResponse>
<rpc:result xmlns:rpc="http://www.w3.org/2003/05/soap-rpc">result</rpc:result>
<result>
<pe:nodeInstance xmlns:pe="http://adaptivity.nl/ProcessEngine/" handle="18" nodeid="ac2" processinstance="5" state="Acknowledged">
<pe:predecessor>16</pe:predecessor>
<pe:body>
<env:Envelope xmlns="http://www.w3.org/2003/05/soap-envelope" xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:umh="http://adaptivity.nl/userMessageHandler" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" encodingStyle="http://www.w3.org/2003/05/soap-encoding">
<Body>
<umh:postTask xmlns="http://adaptivity.nl/userMessageHandler">
<repliesParam>
<jbi:endpointDescriptor xmlns:jbi="http://adaptivity.nl/jbi" endpointLocation="http://localhost:8080/ProcessEngine" endpointName="soap" serviceLocalName="ProcessEngine" serviceNS="http://adaptivity.nl/ProcessEngine/"/>
</repliesParam>
<taskParam>
<task instancehandle="5" owner="pdvrieze" remotehandle="18" summary="Task Bar">
<item type="label" value="Hi . Welcome!"/>
</task>
</taskParam>
</umh:postTask>
</Body>
</env:Envelope>
</pe:body>
</pe:nodeInstance>
</result>
</getProcessNodeInstanceSoapResponse>
"""
private val SOAP_RESPONSE1 =
"""<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Body soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding">$SOAP_RESPONSE1_BODY </soap:Body>
</soap:Envelope>
"""

private val SOAP_RESPONSE2 =
"<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\">\n" +
" <soap:Body soap:encodingStyle=\"http://www.w3.org/2003/05/soap-encoding\">" + ("<getProcessNodeInstanceSoapResponse>\n" +
" </getProcessNodeInstanceSoapResponse>\n" +
" ") +
" </soap:Body>\n" +
"</soap:Envelope>\n"
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
/*
* Copyright (c) 2018.
*
* This file is part of ProcessManager.
*
* ProcessManager is free software: you can redistribute it and/or modify it under the terms of version 3 of the
* GNU Lesser General Public License as published by the Free Software Foundation.
*
* ProcessManager is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with ProcessManager. If not,
* see <http://www.gnu.org/licenses/>.
*/

//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 in JDK 6
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2009.09.24 at 08:12:58 PM CEST
//


package nl.adaptivity.xml.serialization.regressions.soap

import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.KSerializer
import kotlinx.serialization.SerializationException
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.descriptors.buildClassSerialDescriptor
import kotlinx.serialization.descriptors.element
import kotlinx.serialization.encoding.*
import nl.adaptivity.serialutil.decodeElements
import nl.adaptivity.xmlutil.*
import nl.adaptivity.xmlutil.core.impl.multiplatform.name
import nl.adaptivity.xmlutil.serialization.XML
import nl.adaptivity.xmlutil.serialization.XmlElement
import nl.adaptivity.xmlutil.serialization.XmlValue
import nl.adaptivity.xmlutil.util.CompactFragment


/**
*
*
* Java class for Body complex type.
*
*
* The following schema fragment specifies the expected content contained within
* this class.
*
* ```
* <complexType name="Body">
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <any processContents='lax' maxOccurs="unbounded" minOccurs="0"/>
* </sequence>
* <anyAttribute processContents='lax' namespace='##other'/>
* </restriction>
* </complexContent>
* </complexType>
* ```
*
*/
class Body<T: Any>(
@XmlValue(true)
val child: T,
val encodingStyle: String? = "http://www.w3.org/2003/05/soap-encoding",
val otherAttributes: Map<QName, String> = emptyMap(),
) {
fun copy(
encodingStyle: String? = this.encodingStyle,
otherAttributes: Map<QName, String> = this.otherAttributes,
): Body<T> = Body(child, encodingStyle, otherAttributes)

fun <U: Any> copy(
child: U,
encodingStyle: String? = this.encodingStyle,
otherAttributes: Map<QName, String> = this.otherAttributes,
): Body<U> = Body(child, encodingStyle, otherAttributes)

class Serializer<T: Any>(private val contentSerializer: KSerializer<T>): XmlSerializer<Body<T>> {

@OptIn(ExperimentalSerializationApi::class, XmlUtilInternal::class)
override val descriptor: SerialDescriptor = buildClassSerialDescriptor(Body::class.name) {
annotations = SoapSerialObjects.bodyAnnotations
element<String>("encodingStyle", SoapSerialObjects.encodingStyleAnnotations, true)
element("otherAttributes", SoapSerialObjects.attrsSerializer.descriptor, isOptional = true)
element("child", contentSerializer.descriptor, SoapSerialObjects.valueAnnotations)
}.xml(
buildClassSerialDescriptor(Body::class.name) {
annotations = SoapSerialObjects.bodyAnnotations
element<String>("encodingStyle", SoapSerialObjects.encodingStyleAnnotations, true)
element("otherAttributes", SoapSerialObjects.attrsSerializer.descriptor, listOf(XmlElement(false)), isOptional = true)
element("child", contentSerializer.descriptor, SoapSerialObjects.valueAnnotations)
}
)

override fun deserialize(decoder: Decoder): Body<T> {
var encodingStyle: String? = null
var otherAttributes: Map<QName, String> = emptyMap()
lateinit var child: T
decoder.decodeStructure(descriptor) {
decodeElements(this) { idx ->
when (idx) {
0 -> encodingStyle = decodeStringElement(descriptor, idx)
1 -> otherAttributes = decodeSerializableElement(
descriptor, idx,
SoapSerialObjects.attrsSerializer, otherAttributes
)

2 -> child = decodeSerializableElement(descriptor, idx, contentSerializer)
}
}
}
return Body(child)
}

override fun deserializeXML(
decoder: Decoder,
input: XmlReader,
previousValue: Body<T>?,
isValueChild: Boolean
): Body<T> {
val descriptor = descriptor.getElementDescriptor(-1)
var encodingStyle: String? = null
var otherAttributes: Map<QName, String> = emptyMap()
lateinit var child: T
decoder.decodeStructure(descriptor) {
otherAttributes = input.attributes.filter {
when {
it.prefix == XMLConstants.XMLNS_ATTRIBUTE ||
(it.prefix == "" && it.localName == XMLConstants.XMLNS_ATTRIBUTE) -> false

it.namespaceUri != Envelope.NAMESPACE -> true
it.localName == "encodingStyle" -> {
encodingStyle = it.value; false
}

else -> true
}
}.associate { QName(it.namespaceUri, it.localName, it.prefix) to it.value }

child = decodeSerializableElement(descriptor, 2, contentSerializer, null)
if (input.nextTag() != EventType.END_ELEMENT) throw SerializationException("Extra content in body")
}
return Body(child)
}

override fun serialize(encoder: Encoder, value: Body<T>) {
encoder.encodeStructure(descriptor) {
value.encodingStyle?.also { style ->
encodeStringElement(descriptor, 0, style)
}
if (value.otherAttributes.isNotEmpty() || shouldEncodeElementDefault(descriptor, 1)) {
encodeSerializableElement(
descriptor,
1,
SoapSerialObjects.attrsSerializer,
value.otherAttributes
)
}
encodeSerializableElement(descriptor, 2, contentSerializer, value.child)
}
}

override fun serializeXML(encoder: Encoder, output: XmlWriter, value: Body<T>, isValueChild: Boolean) {
output.smartStartTag(ELEMENTNAME) {
value.encodingStyle?.also { style ->
output.attribute(Envelope.NAMESPACE, "encodingStyle", Envelope.PREFIX, style.toString())
}
for ((aName, aValue) in value.otherAttributes) {
output.writeAttribute(aName, aValue)
}
val child = value.child
when (child) {
is CompactFragment -> {
for (ns in child.namespaces) {
if (output.getNamespaceUri(ns.prefix) != ns.namespaceURI) {
output.namespaceAttr(ns)
}
}
child.serialize(output)
}

else -> (encoder as XML.XmlOutput).delegateFormat().encodeToWriter(output, contentSerializer, child)
}

}
}
}

companion object {

const val ELEMENTLOCALNAME = "Body"
val ELEMENTNAME = QName(Envelope.NAMESPACE, ELEMENTLOCALNAME, Envelope.PREFIX)

}

}
Loading

0 comments on commit ed596d9

Please sign in to comment.