From c14f95030479bda224c8b026a8d39dde4622c69e Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Wed, 6 Feb 2008 00:28:22 +0000 Subject: [PATCH] SWS-265 --- parent/pom.xml | 2 +- .../xml/sax/AbstractXmlReader.java | 6 +- .../xml/stream/AbstractStaxXmlReader.java | 60 +++++ .../xml/stream/StaxEventXmlReader.java | 76 +++++-- .../xml/stream/StaxStreamXmlReader.java | 110 +++++---- .../stream/AbstractStaxXmlReaderTestCase.java | 214 +++++++++++++----- .../xml/stream/StaxEventXmlReaderTest.java | 6 +- .../xml/stream/StaxStreamXmlReaderTest.java | 6 +- 8 files changed, 348 insertions(+), 132 deletions(-) diff --git a/parent/pom.xml b/parent/pom.xml index 162b5e95..282430a6 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -313,7 +313,7 @@ org.codehaus.woodstox wstx-asl - 3.2.3 + 3.2.4 stax 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 7ef22bc3..d2156828 100644 --- a/xml/src/main/java/org/springframework/xml/sax/AbstractXmlReader.java +++ b/xml/src/main/java/org/springframework/xml/sax/AbstractXmlReader.java @@ -80,14 +80,10 @@ public abstract class AbstractXmlReader implements XMLReader { this.errorHandler = errorHandler; } - public LexicalHandler getLexicalHandler() { + protected LexicalHandler getLexicalHandler() { return lexicalHandler; } - public void setLexicalHandler(LexicalHandler lexicalHandler) { - this.lexicalHandler = lexicalHandler; - } - /** * Throws a SAXNotRecognizedException exception. * diff --git a/xml/src/main/java/org/springframework/xml/stream/AbstractStaxXmlReader.java b/xml/src/main/java/org/springframework/xml/stream/AbstractStaxXmlReader.java index ac605958..d77dc495 100644 --- a/xml/src/main/java/org/springframework/xml/stream/AbstractStaxXmlReader.java +++ b/xml/src/main/java/org/springframework/xml/stream/AbstractStaxXmlReader.java @@ -23,6 +23,8 @@ import org.xml.sax.ContentHandler; import org.xml.sax.InputSource; import org.xml.sax.Locator; import org.xml.sax.SAXException; +import org.xml.sax.SAXNotRecognizedException; +import org.xml.sax.SAXNotSupportedException; import org.xml.sax.SAXParseException; import org.springframework.xml.sax.AbstractXmlReader; @@ -39,6 +41,64 @@ import org.springframework.xml.sax.AbstractXmlReader; */ public abstract class AbstractStaxXmlReader 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 static final String IS_STANDALONE_FEATURE_NAME = "http://xml.org/sax/features/is-standalone"; + + private boolean namespacesFeature = true; + + private boolean namespacePrefixesFeature = false; + + private Boolean isStandalone; + + 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 if (IS_STANDALONE_FEATURE_NAME.equals(name)) { + if (isStandalone != null) { + return isStandalone.booleanValue(); + } + else { + throw new SAXNotSupportedException("startDocument() callback not completed yet"); + } + } + 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); + } + } + + /** Indicates whether the SAX feature http://xml.org/sax/features/namespaces is turned on. */ + protected boolean hasNamespacesFeature() { + return namespacesFeature; + } + + /** Indicates whether the SAX feature http://xml.org/sax/features/namespaces-prefixes is turned on. */ + protected boolean hasNamespacePrefixesFeature() { + return namespacePrefixesFeature; + } + + protected void setStandalone(boolean standalone) { + isStandalone = (standalone) ? Boolean.TRUE : Boolean.FALSE; + } + /** * Parses the StAX XML reader passed at construction-time. *

diff --git a/xml/src/main/java/org/springframework/xml/stream/StaxEventXmlReader.java b/xml/src/main/java/org/springframework/xml/stream/StaxEventXmlReader.java index 1f5c6080..fe7ef0a0 100644 --- a/xml/src/main/java/org/springframework/xml/stream/StaxEventXmlReader.java +++ b/xml/src/main/java/org/springframework/xml/stream/StaxEventXmlReader.java @@ -17,6 +17,7 @@ package org.springframework.xml.stream; import java.util.Iterator; +import javax.xml.namespace.QName; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamException; @@ -30,11 +31,13 @@ import javax.xml.stream.events.ProcessingInstruction; import javax.xml.stream.events.StartElement; import javax.xml.stream.events.XMLEvent; -import org.springframework.xml.namespace.QNameUtils; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.AttributesImpl; +import org.springframework.util.StringUtils; +import org.springframework.xml.namespace.QNameUtils; + /** * SAX XMLReader that reads from a StAX XMLEventReader. Consumes XMLEvents from * an XMLEventReader, and calls the corresponding methods on the SAX callback interfaces. @@ -77,9 +80,8 @@ public class StaxEventXmlReader extends AbstractStaxXmlReader { boolean documentStarted = false; boolean documentEnded = false; int elementDepth = 0; - XMLEvent event = null; while (reader.hasNext() && elementDepth >= 0) { - event = reader.nextEvent(); + XMLEvent event = reader.nextEvent(); if (!event.isStartDocument() && !event.isEndDocument() && !documentStarted) { handleStartDocument(); documentStarted = true; @@ -133,7 +135,13 @@ public class StaxEventXmlReader extends AbstractStaxXmlReader { .ignorableWhitespace(characters.getData().toCharArray(), 0, characters.getData().length()); } else { + if (characters.isCData() && getLexicalHandler() != null) { + getLexicalHandler().startCDATA(); + } getContentHandler().characters(characters.getData().toCharArray(), 0, characters.getData().length()); + if (characters.isCData() && getLexicalHandler() != null) { + getLexicalHandler().endCDATA(); + } } } } @@ -146,13 +154,19 @@ public class StaxEventXmlReader extends AbstractStaxXmlReader { private void handleEndElement(EndElement endElement) throws SAXException { if (getContentHandler() != null) { - getContentHandler().endElement(endElement.getName().getNamespaceURI(), endElement.getName().getLocalPart(), - QNameUtils.toQualifiedName(endElement.getName())); - - for (Iterator i = endElement.getNamespaces(); i.hasNext();) { - Namespace namespace = (Namespace) i.next(); - getContentHandler().endPrefixMapping(namespace.getPrefix()); + QName qName = endElement.getName(); + if (hasNamespacesFeature()) { + getContentHandler() + .endElement(qName.getNamespaceURI(), qName.getLocalPart(), QNameUtils.toQualifiedName(qName)); + for (Iterator i = endElement.getNamespaces(); i.hasNext();) { + Namespace namespace = (Namespace) i.next(); + getContentHandler().endPrefixMapping(namespace.getPrefix()); + } } + else { + getContentHandler().endElement("", "", QNameUtils.toQualifiedName(qName)); + } + } } @@ -183,14 +197,19 @@ public class StaxEventXmlReader extends AbstractStaxXmlReader { private void handleStartElement(StartElement startElement) throws SAXException { if (getContentHandler() != null) { - for (Iterator i = startElement.getNamespaces(); i.hasNext();) { - Namespace namespace = (Namespace) i.next(); - getContentHandler().startPrefixMapping(namespace.getPrefix(), namespace.getNamespaceURI()); + QName qName = startElement.getName(); + if (hasNamespacesFeature()) { + for (Iterator i = startElement.getNamespaces(); i.hasNext();) { + Namespace namespace = (Namespace) i.next(); + getContentHandler().startPrefixMapping(namespace.getPrefix(), namespace.getNamespaceURI()); + } + getContentHandler().startElement(qName.getNamespaceURI(), qName.getLocalPart(), + QNameUtils.toQualifiedName(qName), getAttributes(startElement)); + } + else { + getContentHandler() + .startElement("", "", QNameUtils.toQualifiedName(qName), getAttributes(startElement)); } - - getContentHandler().startElement(startElement.getName().getNamespaceURI(), - startElement.getName().getLocalPart(), QNameUtils.toQualifiedName(startElement.getName()), - getAttributes(startElement)); } } @@ -199,11 +218,32 @@ public class StaxEventXmlReader extends AbstractStaxXmlReader { for (Iterator i = event.getAttributes(); i.hasNext();) { Attribute attribute = (Attribute) i.next(); - attributes.addAttribute(attribute.getName().getNamespaceURI(), attribute.getName().getLocalPart(), - QNameUtils.toQualifiedName(attribute.getName()), attribute.getDTDType(), attribute.getValue()); + QName qName = attribute.getName(); + String namespace = qName.getNamespaceURI(); + if (namespace == null || !hasNamespacesFeature()) { + namespace = ""; + } + attributes.addAttribute(namespace, qName.getLocalPart(), QNameUtils.toQualifiedName(qName), + attribute.getDTDType(), attribute.getValue()); + } + if (hasNamespacePrefixesFeature()) { + for (Iterator i = event.getNamespaces(); i.hasNext();) { + Namespace namespace = (Namespace) i.next(); + String prefix = namespace.getPrefix(); + String namespaceUri = namespace.getNamespaceURI(); + String qName; + if (StringUtils.hasLength(prefix)) { + qName = "xmlns:" + prefix; + } + else { + qName = "xmlns"; + } + attributes.addAttribute("", "", qName, "CDATA", namespaceUri); + } } return attributes; } + } diff --git a/xml/src/main/java/org/springframework/xml/stream/StaxStreamXmlReader.java b/xml/src/main/java/org/springframework/xml/stream/StaxStreamXmlReader.java index fe13b021..08dc26e3 100644 --- a/xml/src/main/java/org/springframework/xml/stream/StaxStreamXmlReader.java +++ b/xml/src/main/java/org/springframework/xml/stream/StaxStreamXmlReader.java @@ -21,11 +21,13 @@ import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; -import org.springframework.xml.namespace.QNameUtils; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.AttributesImpl; +import org.springframework.util.StringUtils; +import org.springframework.xml.namespace.QNameUtils; + /** * SAX XMLReader that reads from a StAX XMLStreamReader. Reads from an * XMLStreamReader, and calls the corresponding methods on the SAX callback interfaces. @@ -111,6 +113,55 @@ public class StaxStreamXmlReader extends AbstractStaxXmlReader { } + private void handleStartDocument() throws SAXException { + if (getContentHandler() != null) { + getContentHandler().startDocument(); + if (reader.standaloneSet()) { + setStandalone(reader.isStandalone()); + } + } + } + + private void handleStartElement() throws SAXException { + if (getContentHandler() != null) { + QName qName = reader.getName(); + if (hasNamespacesFeature()) { + for (int i = 0; i < reader.getNamespaceCount(); i++) { + String prefix = reader.getNamespacePrefix(i); + if (prefix == null) { + prefix = ""; + } + getContentHandler().startPrefixMapping(prefix, reader.getNamespaceURI(i)); + } + getContentHandler().startElement(qName.getNamespaceURI(), qName.getLocalPart(), + QNameUtils.toQualifiedName(qName), getAttributes()); + } + else { + getContentHandler().startElement("", "", QNameUtils.toQualifiedName(qName), getAttributes()); + } + } + } + + private void handleEndElement() throws SAXException { + if (getContentHandler() != null) { + QName qName = reader.getName(); + if (hasNamespacesFeature()) { + getContentHandler() + .endElement(qName.getNamespaceURI(), qName.getLocalPart(), QNameUtils.toQualifiedName(qName)); + for (int i = 0; i < reader.getNamespaceCount(); i++) { + String prefix = reader.getNamespacePrefix(i); + if (prefix == null) { + prefix = ""; + } + getContentHandler().endPrefixMapping(prefix); + } + } + else { + getContentHandler().endElement("", "", QNameUtils.toQualifiedName(qName)); + } + } + } + private void handleCharacters() throws SAXException { if (getContentHandler() != null) { if (reader.isWhiteSpace()) { @@ -130,67 +181,40 @@ public class StaxStreamXmlReader extends AbstractStaxXmlReader { } } - private void handleEndElement() throws SAXException { - if (getContentHandler() != null) { - QName qName = reader.getName(); - getContentHandler() - .endElement(qName.getNamespaceURI(), qName.getLocalPart(), QNameUtils.toQualifiedName(qName)); - for (int i = 0; i < reader.getNamespaceCount(); i++) { - String prefix = reader.getNamespacePrefix(i); - if (prefix == null) { - prefix = ""; - } - getContentHandler().endPrefixMapping(prefix); - } - } - } - private void handleProcessingInstruction() throws SAXException { if (getContentHandler() != null) { getContentHandler().processingInstruction(reader.getPITarget(), reader.getPIData()); } } - private void handleStartDocument() throws SAXException { - if (getContentHandler() != null) { - getContentHandler().startDocument(); - } - } - - private void handleStartElement() throws SAXException { - if (getContentHandler() != null) { - for (int i = 0; i < reader.getNamespaceCount(); i++) { - String prefix = reader.getNamespacePrefix(i); - if (prefix == null) { - prefix = ""; - } - getContentHandler().startPrefixMapping(prefix, reader.getNamespaceURI(i)); - } - - QName qName = reader.getName(); - getContentHandler().startElement(qName.getNamespaceURI(), qName.getLocalPart(), - QNameUtils.toQualifiedName(qName), getAttributes()); - } - } - private Attributes getAttributes() { AttributesImpl attributes = new AttributesImpl(); for (int i = 0; i < reader.getAttributeCount(); i++) { String namespace = reader.getAttributeNamespace(i); - if (namespace == null) { + if (namespace == null || !hasNamespacesFeature()) { namespace = ""; } String type = reader.getAttributeType(i); - if (type == null) { - type = ""; - } attributes.addAttribute(namespace, reader.getAttributeLocalName(i), QNameUtils.toQualifiedName(reader.getAttributeName(i)), type, reader.getAttributeValue(i)); } + if (hasNamespacePrefixesFeature()) { + for (int i = 0; i < reader.getNamespaceCount(); i++) { + String prefix = reader.getNamespacePrefix(i); + String namespaceUri = reader.getNamespaceURI(i); + String qName; + if (StringUtils.hasLength(prefix)) { + qName = "xmlns:" + prefix; + } + else { + qName = "xmlns"; + } + attributes.addAttribute("", "", qName, "CDATA", namespaceUri); + } + } return attributes; } - } diff --git a/xml/src/test/java/org/springframework/xml/stream/AbstractStaxXmlReaderTestCase.java b/xml/src/test/java/org/springframework/xml/stream/AbstractStaxXmlReaderTestCase.java index 1592fee0..22db5a23 100644 --- a/xml/src/test/java/org/springframework/xml/stream/AbstractStaxXmlReaderTestCase.java +++ b/xml/src/test/java/org/springframework/xml/stream/AbstractStaxXmlReaderTestCase.java @@ -17,8 +17,7 @@ package org.springframework.xml.stream; import java.io.IOException; -import java.io.Reader; -import java.io.StringReader; +import java.io.InputStream; import java.util.Arrays; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamException; @@ -28,75 +27,89 @@ import org.easymock.AbstractMatcher; import org.easymock.MockControl; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; -import org.xml.sax.DTDHandler; import org.xml.sax.InputSource; import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; +import org.xml.sax.helpers.AttributesImpl; import org.xml.sax.helpers.XMLReaderFactory; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; +import org.springframework.xml.sax.SaxUtils; + public abstract class AbstractStaxXmlReaderTestCase extends TestCase { protected static XMLInputFactory inputFactory = XMLInputFactory.newInstance(); - private static final String XML_DTD_HANDLER = - ""; + private Resource testContentHandler; - private static final String XML_CONTENT_HANDLER = - "content"; + private XMLReader standardReader; - private static final String XML_CONTENT_HANDLER_ATTS = ""; + private MockControl contentHandlerControl; - private XMLReader reader; + private ContentHandler contentHandler; protected void setUp() throws Exception { - reader = XMLReaderFactory.createXMLReader(); - reader.setFeature("http://xml.org/sax/features/namespaces", true); - reader.setFeature("http://xml.org/sax/features/namespace-prefixes", false); + standardReader = XMLReaderFactory.createXMLReader(); + contentHandlerControl = MockControl.createStrictControl(ContentHandler.class); + contentHandlerControl.setDefaultMatcher(new SaxArgumentMatcher()); + ContentHandler contentHandlerMock = (ContentHandler) contentHandlerControl.getMock(); + contentHandler = new CopyingContentHandler(contentHandlerMock); + standardReader.setContentHandler(contentHandler); + + testContentHandler = new ClassPathResource("testContentHandler.xml", getClass()); } - public void testContentHandler() throws SAXException, IOException, XMLStreamException { - // record the callbacks by parsing the XML with a regular SAX parser - MockControl control = MockControl.createStrictControl(ContentHandler.class); - control.setDefaultMatcher(new SaxArgumentMatcher()); - ContentHandler mock = (ContentHandler) control.getMock(); - reader.setContentHandler(mock); - reader.parse(new InputSource(new StringReader(XML_CONTENT_HANDLER))); - control.replay(); - AbstractStaxXmlReader staxXmlReader = createStaxXmlReader(new StringReader(XML_CONTENT_HANDLER)); - staxXmlReader.setContentHandler(mock); + public void testContentHandlerNamespacesNoPrefixes() throws SAXException, IOException, XMLStreamException { + standardReader.setFeature("http://xml.org/sax/features/namespaces", true); + standardReader.setFeature("http://xml.org/sax/features/namespace-prefixes", false); + + standardReader.parse(SaxUtils.createInputSource(testContentHandler)); + contentHandlerControl.replay(); + + AbstractStaxXmlReader staxXmlReader = createStaxXmlReader(testContentHandler.getInputStream()); + staxXmlReader.setFeature("http://xml.org/sax/features/namespaces", true); + staxXmlReader.setFeature("http://xml.org/sax/features/namespace-prefixes", false); + + staxXmlReader.setContentHandler(contentHandler); staxXmlReader.parse(new InputSource()); - control.verify(); + contentHandlerControl.verify(); } - public void testContentHandlerAttributes() throws SAXException, IOException, XMLStreamException { - MockControl control = MockControl.createStrictControl(ContentHandler.class); - control.setDefaultMatcher(new SaxArgumentMatcher()); - ContentHandler mock = (ContentHandler) control.getMock(); - reader.setContentHandler(mock); - reader.parse(new InputSource(new StringReader(XML_CONTENT_HANDLER_ATTS))); - control.replay(); - AbstractStaxXmlReader staxXmlReader = createStaxXmlReader(new StringReader(XML_CONTENT_HANDLER_ATTS)); - staxXmlReader.setContentHandler(mock); + public void testContentHandlerNamespacesPrefixes() throws SAXException, IOException, XMLStreamException { + standardReader.setFeature("http://xml.org/sax/features/namespaces", true); + standardReader.setFeature("http://xml.org/sax/features/namespace-prefixes", true); + + standardReader.parse(SaxUtils.createInputSource(testContentHandler)); + contentHandlerControl.replay(); + + AbstractStaxXmlReader staxXmlReader = createStaxXmlReader(testContentHandler.getInputStream()); + staxXmlReader.setFeature("http://xml.org/sax/features/namespaces", true); + staxXmlReader.setFeature("http://xml.org/sax/features/namespace-prefixes", true); + + staxXmlReader.setContentHandler(contentHandler); staxXmlReader.parse(new InputSource()); - control.verify(); + contentHandlerControl.verify(); } - public void testDtdHandler() throws IOException, SAXException, XMLStreamException { - // record the callbacks by parsing the XML with a regular SAX parser - MockControl control = MockControl.createStrictControl(DTDHandler.class); - control.setDefaultMatcher(new SaxArgumentMatcher()); - DTDHandler mock = (DTDHandler) control.getMock(); - reader.setDTDHandler(mock); - reader.parse(new InputSource(new StringReader(XML_DTD_HANDLER))); - control.replay(); - AbstractStaxXmlReader staxXmlReader = createStaxXmlReader(new StringReader(XML_DTD_HANDLER)); - staxXmlReader.setDTDHandler(mock); + public void testContentHandlerNoNamespacesPrefixes() throws SAXException, IOException, XMLStreamException { + standardReader.setFeature("http://xml.org/sax/features/namespaces", false); + standardReader.setFeature("http://xml.org/sax/features/namespace-prefixes", true); + + standardReader.parse(SaxUtils.createInputSource(testContentHandler)); + contentHandlerControl.replay(); + + AbstractStaxXmlReader staxXmlReader = createStaxXmlReader(testContentHandler.getInputStream()); + staxXmlReader.setFeature("http://xml.org/sax/features/namespaces", false); + staxXmlReader.setFeature("http://xml.org/sax/features/namespace-prefixes", true); + + staxXmlReader.setContentHandler(contentHandler); staxXmlReader.parse(new InputSource()); - control.verify(); + contentHandlerControl.verify(); } - protected abstract AbstractStaxXmlReader createStaxXmlReader(Reader reader) throws XMLStreamException; + protected abstract AbstractStaxXmlReader createStaxXmlReader(InputStream inputStream) throws XMLStreamException; /** Easymock ArgumentMatcher implementation that matches SAX arguments. */ protected static class SaxArgumentMatcher extends AbstractMatcher { @@ -139,22 +152,37 @@ public abstract class AbstractStaxXmlReaderTestCase extends TestCase { return false; } for (int i = 0; i < expectedAttributes.getLength(); i++) { - if (!expectedAttributes.getURI(i).equals(actualAttributes.getURI(i)) || - !expectedAttributes.getQName(i).equals(actualAttributes.getQName(i)) || - !expectedAttributes.getType(i).equals(actualAttributes.getType(i)) || - !expectedAttributes.getValue(i).equals(actualAttributes.getValue(i))) { + boolean found = false; + for (int j = 0; j < actualAttributes.getLength(); j++) { + if (expectedAttributes.getURI(i).equals(actualAttributes.getURI(j)) && + expectedAttributes.getQName(i).equals(actualAttributes.getQName(j)) && +// expectedAttributes.getLocalName(i).equals(actualAttributes.getLocalName(j)) && + expectedAttributes.getType(i).equals(actualAttributes.getType(j)) && + expectedAttributes.getValue(i).equals(actualAttributes.getValue(j))) { + found = true; + break; + } + } + if (!found) { return false; } } return true; } - else if (expected instanceof Locator) { - Locator expectedLocator = (Locator) expected; - Locator actualLocator = (Locator) actual; - return expectedLocator.getColumnNumber() == actualLocator.getColumnNumber() && - expectedLocator.getLineNumber() == actualLocator.getLineNumber(); + else { + return super.argumentMatches(expected, actual); + } + } + + public String toString(Object[] arguments) { + if (arguments != null && arguments.length == 3 && arguments[0] instanceof char[] && + arguments[1] instanceof Integer && arguments[2] instanceof Integer) { + return new String((char[]) arguments[0], ((Integer) arguments[1]).intValue(), + ((Integer) arguments[2]).intValue()); + } + else { + return super.toString(arguments); } - return super.argumentMatches(expected, actual); } protected String argumentToString(Object argument) { @@ -170,10 +198,19 @@ public abstract class AbstractStaxXmlReaderTestCase extends TestCase { Attributes attributes = (Attributes) argument; StringBuffer buffer = new StringBuffer("["); for (int i = 0; i < attributes.getLength(); i++) { - buffer.append('{'); - buffer.append(attributes.getURI(i)); - buffer.append('}'); - buffer.append(attributes.getQName(i)); + if (attributes.getURI(i).length() != 0) { + buffer.append('{'); + buffer.append(attributes.getURI(i)); + buffer.append('}'); + } +// if (attributes.getLocalName(i).length() != 0) { +// buffer.append('['); +// buffer.append(attributes.getLocalName(i)); +// buffer.append(']'); +// } + if (attributes.getQName(i).length() != 0) { + buffer.append(attributes.getQName(i)); + } buffer.append('='); buffer.append(attributes.getValue(i)); if (i < attributes.getLength() - 1) { @@ -198,5 +235,64 @@ public abstract class AbstractStaxXmlReaderTestCase extends TestCase { } } + private static class CopyingContentHandler implements ContentHandler { + + private ContentHandler wrappee; + + private CopyingContentHandler(ContentHandler wrappee) { + this.wrappee = wrappee; + } + + public void setDocumentLocator(Locator locator) { + wrappee.setDocumentLocator(locator); + } + + public void startDocument() throws SAXException { + wrappee.startDocument(); + } + + public void endDocument() throws SAXException { + wrappee.endDocument(); + } + + public void startPrefixMapping(String prefix, String uri) throws SAXException { + wrappee.startPrefixMapping(prefix, uri); + } + + public void endPrefixMapping(String prefix) throws SAXException { + wrappee.endPrefixMapping(prefix); + } + + public void startElement(String uri, String localName, String qName, Attributes attributes) + throws SAXException { + wrappee.startElement(uri, localName, qName, new AttributesImpl(attributes)); + } + + public void endElement(String uri, String localName, String qName) throws SAXException { + wrappee.endElement(uri, localName, qName); + } + + public void characters(char ch[], int start, int length) throws SAXException { + wrappee.characters(copy(ch), start, length); + } + + public void ignorableWhitespace(char ch[], int start, int length) throws SAXException { + } + + public void processingInstruction(String target, String data) throws SAXException { + wrappee.processingInstruction(target, data); + } + + public void skippedEntity(String name) throws SAXException { + wrappee.skippedEntity(name); + } + + } + + private static char[] copy(char[] ch) { + char[] copy = new char[ch.length]; + System.arraycopy(ch, 0, copy, 0, ch.length); + return copy; + } } diff --git a/xml/src/test/java/org/springframework/xml/stream/StaxEventXmlReaderTest.java b/xml/src/test/java/org/springframework/xml/stream/StaxEventXmlReaderTest.java index 24d108b4..e02793e7 100644 --- a/xml/src/test/java/org/springframework/xml/stream/StaxEventXmlReaderTest.java +++ b/xml/src/test/java/org/springframework/xml/stream/StaxEventXmlReaderTest.java @@ -16,7 +16,7 @@ package org.springframework.xml.stream; -import java.io.Reader; +import java.io.InputStream; import java.io.StringReader; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLInputFactory; @@ -31,8 +31,8 @@ public class StaxEventXmlReaderTest extends AbstractStaxXmlReaderTestCase { public static final String CONTENT = ""; - protected AbstractStaxXmlReader createStaxXmlReader(Reader reader) throws XMLStreamException { - return new StaxEventXmlReader(inputFactory.createXMLEventReader(reader)); + protected AbstractStaxXmlReader createStaxXmlReader(InputStream inputStream) throws XMLStreamException { + return new StaxEventXmlReader(inputFactory.createXMLEventReader(inputStream)); } public void testPartial() throws Exception { diff --git a/xml/src/test/java/org/springframework/xml/stream/StaxStreamXmlReaderTest.java b/xml/src/test/java/org/springframework/xml/stream/StaxStreamXmlReaderTest.java index 258b56f9..c8cb68f7 100644 --- a/xml/src/test/java/org/springframework/xml/stream/StaxStreamXmlReaderTest.java +++ b/xml/src/test/java/org/springframework/xml/stream/StaxStreamXmlReaderTest.java @@ -16,7 +16,7 @@ package org.springframework.xml.stream; -import java.io.Reader; +import java.io.InputStream; import java.io.StringReader; import javax.xml.namespace.QName; import javax.xml.stream.XMLInputFactory; @@ -32,8 +32,8 @@ public class StaxStreamXmlReaderTest extends AbstractStaxXmlReaderTestCase { public static final String CONTENT = ""; - protected AbstractStaxXmlReader createStaxXmlReader(Reader reader) throws XMLStreamException { - return new StaxStreamXmlReader(inputFactory.createXMLStreamReader(reader)); + protected AbstractStaxXmlReader createStaxXmlReader(InputStream inputStream) throws XMLStreamException { + return new StaxStreamXmlReader(inputFactory.createXMLStreamReader(inputStream)); } public void testPartial() throws Exception {