diff --git a/core/src/main/java/org/springframework/ws/soap/saaj/support/SaajXmlReader.java b/core/src/main/java/org/springframework/ws/soap/saaj/support/SaajXmlReader.java new file mode 100644 index 00000000..9d384ac0 --- /dev/null +++ b/core/src/main/java/org/springframework/ws/soap/saaj/support/SaajXmlReader.java @@ -0,0 +1,141 @@ +/* + * Copyright 2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ws.soap.saaj.support; + +import java.util.Iterator; +import javax.xml.soap.Name; +import javax.xml.soap.Node; +import javax.xml.soap.SOAPElement; +import javax.xml.soap.Text; + +import org.springframework.xml.sax.AbstractXmlReader; +import org.xml.sax.Attributes; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.AttributesImpl; + +/** + * SAX XMLReader that reads from a SAAJ Node. Consumes XMLEvents from an + * XMLEventReader, and calls the corresponding methods on the SAX callback interfaces. + * + * @author Arjen Poutsma + * @see javax.xml.soap.Node + * @see javax.xml.soap.SOAPElement + */ +public class SaajXmlReader extends AbstractXmlReader { + + private final Node startNode; + + /** + * Constructs a new instance of the SaajXmlReader that reads from the given Node. + * + * @param startNode the SAAJ Node to read from + */ + public SaajXmlReader(Node startNode) { + this.startNode = startNode; + } + + /** + * Parses the StAX XML reader passed at construction-time. + *

+ * Note that the given InputSource is not read, but ignored. + * + * @param ignored is ignored + * @throws org.xml.sax.SAXException A SAX exception, possibly wrapping a XMLStreamException + */ + public final void parse(InputSource ignored) throws SAXException { + parse(); + } + + /** + * Parses the StAX XML reader passed at construction-time. + *

+ * Note that the given system identifier is not read, but ignored. + * + * @param ignored is ignored + * @throws SAXException A SAX exception, possibly wrapping a XMLStreamException + */ + public final void parse(String ignored) throws SAXException { + parse(); + } + + private void parse() throws SAXException { + if (getContentHandler() != null) { + getContentHandler().startDocument(); + } + handleNode(startNode); + if (getContentHandler() != null) { + getContentHandler().endDocument(); + } + } + + private void handleNode(Node node) throws SAXException { + if (node instanceof SOAPElement) { + handleElement((SOAPElement) node); + } + else if (node instanceof Text) { + Text text = (Text) node; + handleText(text); + } + } + + private void handleText(Text text) throws SAXException { + if (!text.isComment() && getContentHandler() != null) { + char[] ch = text.getValue().toCharArray(); + getContentHandler().characters(ch, 0, ch.length); + } + } + + private void handleElement(SOAPElement element) throws SAXException { + Name elementName = element.getElementName(); + if (getContentHandler() != null) { + for (Iterator iterator = element.getNamespacePrefixes(); iterator.hasNext();) { + String prefix = (String) iterator.next(); + String namespaceUri = element.getNamespaceURI(prefix); + getContentHandler().startPrefixMapping(prefix, namespaceUri); + } + getContentHandler() + .startElement(elementName.getURI(), elementName.getLocalName(), elementName.getQualifiedName(), + getAttributes(element)); + } + for (Iterator iterator = element.getChildElements(); iterator.hasNext();) { + Node child = (Node) iterator.next(); + handleNode(child); + } + if (getContentHandler() != null) { + getContentHandler() + .endElement(elementName.getURI(), elementName.getLocalName(), elementName.getQualifiedName()); + for (Iterator iterator = element.getNamespacePrefixes(); iterator.hasNext();) { + String prefix = (String) iterator.next(); + getContentHandler().endPrefixMapping(prefix); + } + } + } + + private Attributes getAttributes(SOAPElement element) { + AttributesImpl attributes = new AttributesImpl(); + for (Iterator iterator = element.getAllAttributes(); iterator.hasNext();) { + Name attributeName = (Name) iterator.next(); + String attributeValue = element.getAttributeValue(attributeName); + attributes.addAttribute(attributeName.getURI(), attributeName.getLocalName(), + attributeName.getQualifiedName(), "CDATA", attributeValue); + } + return attributes; + } + + +} diff --git a/core/src/test/java/org/springframework/ws/soap/saaj/support/SaajXmlReaderTest.java b/core/src/test/java/org/springframework/ws/soap/saaj/support/SaajXmlReaderTest.java new file mode 100644 index 00000000..201ab9d4 --- /dev/null +++ b/core/src/test/java/org/springframework/ws/soap/saaj/support/SaajXmlReaderTest.java @@ -0,0 +1,55 @@ +/* + * Copyright 2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ws.soap.saaj.support; + +import javax.xml.soap.MessageFactory; +import javax.xml.soap.SOAPMessage; +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.sax.SAXSource; + +import org.custommonkey.xmlunit.XMLTestCase; +import org.springframework.xml.transform.StringResult; +import org.xml.sax.InputSource; + +public class SaajXmlReaderTest extends XMLTestCase { + + private SaajXmlReader reader; + + private SOAPMessage message; + + private Transformer transformer; + + protected void setUp() throws Exception { + MessageFactory messageFactory = MessageFactory.newInstance(); + message = messageFactory.createMessage(); + reader = new SaajXmlReader(message.getSOAPPart().getEnvelope()); + transformer = TransformerFactory.newInstance().newTransformer(); + } + + public void testIt() throws Exception { + Result result = new StringResult(); + Source source = new SAXSource(reader, new InputSource()); + transformer.transform(source, result); + Result expected = new StringResult(); + transformer.transform(new DOMSource(message.getSOAPPart().getEnvelope()), expected); + assertXMLEqual(expected.toString(), result.toString()); + } +} \ No newline at end of file