From 433dd146df2984fc7426adfa8af73133242d8ed5 Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Sun, 28 Oct 2007 23:50:46 +0000 Subject: [PATCH] SWS-202 --- .../ws/soap/saaj/support/SaajXmlReader.java | 89 ++++++++++++++----- .../soap/saaj/support/SaajXmlReaderTest.java | 33 +++++-- .../xml/sax/AbstractXmlReader.java | 9 +- 3 files changed, 98 insertions(+), 33 deletions(-) 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 index 971bb532..23341a07 100644 --- 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 @@ -26,6 +26,8 @@ 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.SAXNotRecognizedException; +import org.xml.sax.SAXNotSupportedException; import org.xml.sax.helpers.AttributesImpl; /** @@ -39,8 +41,16 @@ import org.xml.sax.helpers.AttributesImpl; */ public class SaajXmlReader extends AbstractXmlReader { + private static final String NAMESPACES_FEATURE_NAME = "http://xml.org/sax/features/namespaces"; + + private static final String NAMESPACE_PREFIXES_FEATURE_NAME = "http://xml.org/sax/features/namespace-prefixes"; + private final Node startNode; + private boolean namespacesFeature = true; + + private boolean namespacePrefixesFeature = false; + /** * Constructs a new instance of the SaajXmlReader that reads from the given Node. * @@ -50,6 +60,30 @@ public class SaajXmlReader extends AbstractXmlReader { this.startNode = startNode; } + public boolean getFeature(String name) throws SAXNotRecognizedException, SAXNotSupportedException { + if (NAMESPACES_FEATURE_NAME.equals(name)) { + return namespacesFeature; + } + else if (NAMESPACE_PREFIXES_FEATURE_NAME.equals(name)) { + return namespacePrefixesFeature; + } + else { + return super.getFeature(name); + } + } + + public void setFeature(String name, boolean value) throws SAXNotRecognizedException, SAXNotSupportedException { + if (NAMESPACES_FEATURE_NAME.equals(name)) { + this.namespacesFeature = value; + } + else if (NAMESPACE_PREFIXES_FEATURE_NAME.equals(name)) { + this.namespacePrefixesFeature = value; + } + else { + super.setFeature(name, value); + } + } + /** * Parses the StAX XML reader passed at construction-time. *

@@ -94,35 +128,38 @@ public class SaajXmlReader extends AbstractXmlReader { } } - private void handleText(Text text) throws SAXException { - if (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); + if (namespacesFeature) { + 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)); + } + else { + getContentHandler().startElement("", "", elementName.getQualifiedName(), getAttributes(element)); } - 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); + if (namespacesFeature) { + getContentHandler() + .endElement(elementName.getURI(), elementName.getLocalName(), elementName.getQualifiedName()); + for (Iterator iterator = element.getNamespacePrefixes(); iterator.hasNext();) { + String prefix = (String) iterator.next(); + getContentHandler().endPrefixMapping(prefix); + } + } + else { + getContentHandler().endElement("", "", elementName.getQualifiedName()); } } } @@ -135,8 +172,20 @@ public class SaajXmlReader extends AbstractXmlReader { attributes.addAttribute(attributeName.getURI(), attributeName.getLocalName(), attributeName.getQualifiedName(), "CDATA", attributeValue); } + if (namespacePrefixesFeature || !namespacesFeature) { + for (Iterator iterator = element.getNamespacePrefixes(); iterator.hasNext();) { + String prefix = (String) iterator.next(); + String namespaceUri = element.getNamespaceURI(prefix); + attributes.addAttribute("", "", "xmlns:" + prefix, "CDATA", namespaceUri); + } + } return attributes; } - + private void handleText(Text text) throws SAXException { + if (getContentHandler() != null) { + char[] ch = text.getValue().toCharArray(); + getContentHandler().characters(ch, 0, ch.length); + } + } } 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 index 201ab9d4..66b9ff95 100644 --- 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 @@ -17,21 +17,22 @@ package org.springframework.ws.soap.saaj.support; import javax.xml.soap.MessageFactory; +import javax.xml.soap.SOAPEnvelope; 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.DOMResult; 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.w3c.dom.Document; import org.xml.sax.InputSource; public class SaajXmlReaderTest extends XMLTestCase { - private SaajXmlReader reader; + private SaajXmlReader saajReader; private SOAPMessage message; @@ -40,16 +41,30 @@ public class SaajXmlReaderTest extends XMLTestCase { protected void setUp() throws Exception { MessageFactory messageFactory = MessageFactory.newInstance(); message = messageFactory.createMessage(); - reader = new SaajXmlReader(message.getSOAPPart().getEnvelope()); + SOAPEnvelope envelope = message.getSOAPPart().getEnvelope(); + saajReader = new SaajXmlReader(envelope); transformer = TransformerFactory.newInstance().newTransformer(); } - public void testIt() throws Exception { - Result result = new StringResult(); - Source source = new SAXSource(reader, new InputSource()); + public void testNamespacesPrefixes() throws Exception { + saajReader.setFeature("http://xml.org/sax/features/namespaces", true); + saajReader.setFeature("http://xml.org/sax/features/namespace-prefixes", true); + DOMResult result = new DOMResult(); + Source source = new SAXSource(saajReader, new InputSource()); transformer.transform(source, result); - Result expected = new StringResult(); + DOMResult expected = new DOMResult(); transformer.transform(new DOMSource(message.getSOAPPart().getEnvelope()), expected); - assertXMLEqual(expected.toString(), result.toString()); + assertXMLEqual((Document) expected.getNode(), (Document) result.getNode()); + } + + public void testNamespacesNoPrefixes() throws Exception { + saajReader.setFeature("http://xml.org/sax/features/namespaces", true); + saajReader.setFeature("http://xml.org/sax/features/namespace-prefixes", false); + DOMResult result = new DOMResult(); + Source source = new SAXSource(saajReader, new InputSource()); + transformer.transform(source, result); + DOMResult expected = new DOMResult(); + transformer.transform(new DOMSource(message.getSOAPPart().getEnvelope()), expected); + assertXMLEqual((Document) expected.getNode(), (Document) result.getNode()); } } \ No newline at end of file diff --git a/xml/src/main/java/org/springframework/xml/sax/AbstractXmlReader.java b/xml/src/main/java/org/springframework/xml/sax/AbstractXmlReader.java index a24c32ae..7ef22bc3 100644 --- a/xml/src/main/java/org/springframework/xml/sax/AbstractXmlReader.java +++ b/xml/src/main/java/org/springframework/xml/sax/AbstractXmlReader.java @@ -21,6 +21,7 @@ import org.xml.sax.DTDHandler; import org.xml.sax.EntityResolver; import org.xml.sax.ErrorHandler; import org.xml.sax.SAXNotRecognizedException; +import org.xml.sax.SAXNotSupportedException; import org.xml.sax.XMLReader; import org.xml.sax.ext.LexicalHandler; @@ -93,7 +94,7 @@ public abstract class AbstractXmlReader implements XMLReader { * @throws org.xml.sax.SAXNotRecognizedException * always */ - public boolean getFeature(String name) throws SAXNotRecognizedException { + public boolean getFeature(String name) throws SAXNotRecognizedException, SAXNotSupportedException { throw new SAXNotRecognizedException(name); } @@ -102,7 +103,7 @@ public abstract class AbstractXmlReader implements XMLReader { * * @throws SAXNotRecognizedException always */ - public void setFeature(String name, boolean value) throws SAXNotRecognizedException { + public void setFeature(String name, boolean value) throws SAXNotRecognizedException, SAXNotSupportedException { throw new SAXNotRecognizedException(name); } @@ -110,7 +111,7 @@ public abstract class AbstractXmlReader implements XMLReader { * Throws a SAXNotRecognizedException exception when the given property does not signify a lexical * handler. The property name for a lexical handler is http://xml.org/sax/properties/lexical-handler. */ - public Object getProperty(String name) throws SAXNotRecognizedException { + public Object getProperty(String name) throws SAXNotRecognizedException, SAXNotSupportedException { if ("http://xml.org/sax/properties/lexical-handler".equals(name)) { return lexicalHandler; } @@ -123,7 +124,7 @@ public abstract class AbstractXmlReader implements XMLReader { * Throws a SAXNotRecognizedException exception when the given property does not signify a lexical * handler. The property name for a lexical handler is http://xml.org/sax/properties/lexical-handler. */ - public void setProperty(String name, Object value) throws SAXNotRecognizedException { + public void setProperty(String name, Object value) throws SAXNotRecognizedException, SAXNotSupportedException { if ("http://xml.org/sax/properties/lexical-handler".equals(name)) { lexicalHandler = (LexicalHandler) value; }