diff --git a/org.springframework.core/src/main/java/org/springframework/util/xml/AbstractStaxXMLReader.java b/org.springframework.core/src/main/java/org/springframework/util/xml/AbstractStaxXMLReader.java index 93289e5eff9cbab821b5715843b645609d7b44b7..379436d1b08a3012e886c467bf41eada9a6b15e5 100644 --- a/org.springframework.core/src/main/java/org/springframework/util/xml/AbstractStaxXMLReader.java +++ b/org.springframework.core/src/main/java/org/springframework/util/xml/AbstractStaxXMLReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2010 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. @@ -20,7 +20,6 @@ import javax.xml.namespace.QName; import javax.xml.stream.Location; import javax.xml.stream.XMLStreamException; -import org.xml.sax.ContentHandler; import org.xml.sax.InputSource; import org.xml.sax.Locator; import org.xml.sax.SAXException; @@ -108,17 +107,6 @@ abstract class AbstractStaxXMLReader extends AbstractXMLReader { return this.namespacePrefixesFeature; } - /** - * Sett the SAX Locator based on the given StAX Location. - * @param location the location - * @see ContentHandler#setDocumentLocator(org.xml.sax.Locator) - */ - protected void setLocator(Location location) { - if (getContentHandler() != null) { - getContentHandler().setDocumentLocator(new StaxLocator(location)); - } - } - /** * Convert a QName to a qualified name, as used by DOM and SAX. * The returned string has a format of prefix:localName if the diff --git a/org.springframework.core/src/main/java/org/springframework/util/xml/StaxEventXMLReader.java b/org.springframework.core/src/main/java/org/springframework/util/xml/StaxEventXMLReader.java index 1d10757a86b1ee88634cee85771848223ce7d8c6..48f64e190ac44dd8f7371c850dd0def6fca2833f 100644 --- a/org.springframework.core/src/main/java/org/springframework/util/xml/StaxEventXMLReader.java +++ b/org.springframework.core/src/main/java/org/springframework/util/xml/StaxEventXMLReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2010 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. @@ -18,6 +18,7 @@ package org.springframework.util.xml; import java.util.Iterator; import javax.xml.namespace.QName; +import javax.xml.stream.Location; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamException; @@ -31,11 +32,13 @@ import javax.xml.stream.events.EntityReference; import javax.xml.stream.events.Namespace; import javax.xml.stream.events.NotationDeclaration; import javax.xml.stream.events.ProcessingInstruction; +import javax.xml.stream.events.StartDocument; import javax.xml.stream.events.StartElement; import javax.xml.stream.events.XMLEvent; import org.xml.sax.Attributes; import org.xml.sax.SAXException; +import org.xml.sax.ext.Locator2; import org.xml.sax.helpers.AttributesImpl; import org.springframework.util.StringUtils; @@ -86,10 +89,14 @@ class StaxEventXMLReader extends AbstractStaxXMLReader { while (reader.hasNext() && elementDepth >= 0) { XMLEvent event = reader.nextEvent(); if (!event.isStartDocument() && !event.isEndDocument() && !documentStarted) { - handleStartDocument(); + handleStartDocument(event); documentStarted = true; } switch (event.getEventType()) { + case XMLStreamConstants.START_DOCUMENT: + handleStartDocument(event); + documentStarted = true; + break; case XMLStreamConstants.START_ELEMENT: elementDepth++; handleStartElement(event.asStartElement()); @@ -108,11 +115,6 @@ class StaxEventXMLReader extends AbstractStaxXMLReader { case XMLStreamConstants.CDATA: handleCharacters(event.asCharacters()); break; - case XMLStreamConstants.START_DOCUMENT: - setLocator(event.getLocation()); - handleStartDocument(); - documentStarted = true; - break; case XMLStreamConstants.END_DOCUMENT: handleEndDocument(); documentEnded = true; @@ -140,6 +142,51 @@ class StaxEventXMLReader extends AbstractStaxXMLReader { } + private void handleStartDocument(final XMLEvent event) throws SAXException { + if (getContentHandler() != null) { + final Location location = event.getLocation(); + getContentHandler().setDocumentLocator(new Locator2() { + + public int getColumnNumber() { + return location.getColumnNumber(); + } + + public int getLineNumber() { + return location.getLineNumber(); + } + + public String getPublicId() { + return location.getPublicId(); + } + + public String getSystemId() { + return location.getSystemId(); + } + + public String getXMLVersion() { + if (event.isStartDocument()) { + StartDocument startDocument = (StartDocument) event; + String version = startDocument.getVersion(); + return StringUtils.hasLength(version) ? version : "1.0"; + } + return null; + } + + public String getEncoding() { + if (event.isStartDocument()) { + StartDocument startDocument = (StartDocument) event; + if (startDocument.encodingSet()) { + return startDocument.getCharacterEncodingScheme(); + } + } + return null; + } + }); + + getContentHandler().startDocument(); + } + } + private void handleStartElement(StartElement startElement) throws SAXException { if (getContentHandler() != null) { QName qName = startElement.getName(); @@ -174,12 +221,6 @@ class StaxEventXMLReader extends AbstractStaxXMLReader { } } - private void handleEndDocument() throws SAXException { - if (getContentHandler() != null) { - getContentHandler().endDocument(); - } - } - private void handleEndElement(EndElement endElement) throws SAXException { if (getContentHandler() != null) { QName qName = endElement.getName(); @@ -197,6 +238,12 @@ class StaxEventXMLReader extends AbstractStaxXMLReader { } } + private void handleEndDocument() throws SAXException { + if (getContentHandler() != null) { + getContentHandler().endDocument(); + } + } + private void handleNotationDeclaration(NotationDeclaration declaration) throws SAXException { if (getDTDHandler() != null) { getDTDHandler().notationDecl(declaration.getName(), declaration.getPublicId(), declaration.getSystemId()); @@ -216,12 +263,6 @@ class StaxEventXMLReader extends AbstractStaxXMLReader { } } - private void handleStartDocument() throws SAXException { - if (getContentHandler() != null) { - getContentHandler().startDocument(); - } - } - private void handleComment(Comment comment) throws SAXException { if (getLexicalHandler() != null) { char[] ch = comment.getText().toCharArray(); diff --git a/org.springframework.core/src/main/java/org/springframework/util/xml/StaxStreamXMLReader.java b/org.springframework.core/src/main/java/org/springframework/util/xml/StaxStreamXMLReader.java index 22a9c4e2f633ce4fbe451732ffa2122b6ca1afee..39594b157af8f542a7a4f872a0aa71e1eb6d25cb 100644 --- a/org.springframework.core/src/main/java/org/springframework/util/xml/StaxStreamXMLReader.java +++ b/org.springframework.core/src/main/java/org/springframework/util/xml/StaxStreamXMLReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2010 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. @@ -17,12 +17,14 @@ package org.springframework.util.xml; import javax.xml.namespace.QName; +import javax.xml.stream.Location; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import org.xml.sax.Attributes; import org.xml.sax.SAXException; +import org.xml.sax.ext.Locator2; import org.xml.sax.helpers.AttributesImpl; import org.springframework.util.StringUtils; @@ -91,7 +93,6 @@ class StaxStreamXMLReader extends AbstractStaxXMLReader { handleCharacters(); break; case XMLStreamConstants.START_DOCUMENT: - setLocator(reader.getLocation()); handleStartDocument(); documentStarted = true; break; @@ -123,6 +124,35 @@ class StaxStreamXMLReader extends AbstractStaxXMLReader { private void handleStartDocument() throws SAXException { if (getContentHandler() != null) { + final Location location = reader.getLocation(); + + getContentHandler().setDocumentLocator(new Locator2() { + + public int getColumnNumber() { + return location.getColumnNumber(); + } + + public int getLineNumber() { + return location.getLineNumber(); + } + + public String getPublicId() { + return location.getPublicId(); + } + + public String getSystemId() { + return location.getSystemId(); + } + + public String getXMLVersion() { + String version = reader.getVersion(); + return StringUtils.hasLength(version) ? version : "1.0"; + } + + public String getEncoding() { + return reader.getEncoding(); + } + }); getContentHandler().startDocument(); if (reader.standaloneSet()) { setStandalone(reader.isStandalone()); diff --git a/org.springframework.core/src/main/java/org/springframework/util/xml/XMLEventStreamReader.java b/org.springframework.core/src/main/java/org/springframework/util/xml/XMLEventStreamReader.java index ac20b03f524b8391238cf6f8a67c5dcff86b6e3e..cafbd8723615b2aace2525e1930697aab9666db7 100644 --- a/org.springframework.core/src/main/java/org/springframework/util/xml/XMLEventStreamReader.java +++ b/org.springframework.core/src/main/java/org/springframework/util/xml/XMLEventStreamReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2010 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. @@ -61,7 +61,7 @@ class XMLEventStreamReader extends AbstractXMLStreamReader { return ((StartDocument) event).getVersion(); } else { - throw new IllegalStateException(); + return null; } } diff --git a/org.springframework.core/src/test/java/org/springframework/util/xml/StaxSourceTests.java b/org.springframework.core/src/test/java/org/springframework/util/xml/StaxSourceTests.java index 61089718b1df220dbce47f530416534c1dd70c2d..a2b668fa6d3607f8657f829d176195a8ba43e2ef 100644 --- a/org.springframework.core/src/test/java/org/springframework/util/xml/StaxSourceTests.java +++ b/org.springframework.core/src/test/java/org/springframework/util/xml/StaxSourceTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2010 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. @@ -18,16 +18,21 @@ package org.springframework.util.xml; import java.io.StringReader; import java.io.StringWriter; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamReader; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMResult; import javax.xml.transform.stream.StreamResult; import static org.custommonkey.xmlunit.XMLAssert.*; import org.junit.Before; import org.junit.Test; +import org.w3c.dom.Document; +import org.xml.sax.InputSource; public class StaxSourceTests { @@ -37,15 +42,20 @@ public class StaxSourceTests { private XMLInputFactory inputFactory; + private DocumentBuilder documentBuilder; + @Before - public void createsetUp() throws Exception { + public void setUp() throws Exception { TransformerFactory transformerFactory = TransformerFactory.newInstance(); transformer = transformerFactory.newTransformer(); inputFactory = XMLInputFactory.newInstance(); + DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + documentBuilderFactory.setNamespaceAware(true); + documentBuilder = documentBuilderFactory.newDocumentBuilder(); } @Test - public void streamReaderSource() throws Exception { + public void streamReaderSourceToStreamResult() throws Exception { XMLStreamReader streamReader = inputFactory.createXMLStreamReader(new StringReader(XML)); StaxSource source = new StaxSource(streamReader); assertEquals("Invalid streamReader returned", streamReader, source.getXMLStreamReader()); @@ -56,7 +66,20 @@ public class StaxSourceTests { } @Test - public void eventReaderSource() throws Exception { + public void streamReaderSourceToDOMResult() throws Exception { + XMLStreamReader streamReader = inputFactory.createXMLStreamReader(new StringReader(XML)); + StaxSource source = new StaxSource(streamReader); + assertEquals("Invalid streamReader returned", streamReader, source.getXMLStreamReader()); + assertNull("EventReader returned", source.getXMLEventReader()); + + Document expected = documentBuilder.parse(new InputSource(new StringReader(XML))); + Document result = documentBuilder.newDocument(); + transformer.transform(source, new DOMResult(result)); + assertXMLEqual("Invalid result", expected, result); + } + + @Test + public void eventReaderSourceToStreamResult() throws Exception { XMLEventReader eventReader = inputFactory.createXMLEventReader(new StringReader(XML)); StaxSource source = new StaxSource(eventReader); assertEquals("Invalid eventReader returned", eventReader, source.getXMLEventReader()); @@ -65,4 +88,17 @@ public class StaxSourceTests { transformer.transform(source, new StreamResult(writer)); assertXMLEqual("Invalid result", XML, writer.toString()); } + + @Test + public void eventReaderSourceToDOMResult() throws Exception { + XMLEventReader eventReader = inputFactory.createXMLEventReader(new StringReader(XML)); + StaxSource source = new StaxSource(eventReader); + assertEquals("Invalid eventReader returned", eventReader, source.getXMLEventReader()); + assertNull("StreamReader returned", source.getXMLStreamReader()); + + Document expected = documentBuilder.parse(new InputSource(new StringReader(XML))); + Document result = documentBuilder.newDocument(); + transformer.transform(source, new DOMResult(result)); + assertXMLEqual("Invalid result", expected, result); + } } \ No newline at end of file diff --git a/org.springframework.core/src/test/java/org/springframework/util/xml/StaxStreamXMLReaderTests.java b/org.springframework.core/src/test/java/org/springframework/util/xml/StaxStreamXMLReaderTests.java index 980764e3ef17fc431170b5028f1251278f681503..f9a00625d0481460a6d5eb6b33d1a273c86a84cd 100644 --- a/org.springframework.core/src/test/java/org/springframework/util/xml/StaxStreamXMLReaderTests.java +++ b/org.springframework.core/src/test/java/org/springframework/util/xml/StaxStreamXMLReaderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2010 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. @@ -24,7 +24,7 @@ import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import org.easymock.MockControl; -import static org.junit.Assert.assertEquals; +import static org.junit.Assert.*; import org.junit.Test; import org.xml.sax.ContentHandler; import org.xml.sax.InputSource; @@ -55,6 +55,8 @@ public class StaxStreamXMLReaderTests extends AbstractStaxXMLReaderTestCase { mockControl.setDefaultMatcher(new SaxArgumentMatcher()); ContentHandler contentHandlerMock = (ContentHandler) mockControl.getMock(); + contentHandlerMock.setDocumentLocator(null); + mockControl.setMatcher(MockControl.ALWAYS_MATCHER); contentHandlerMock.startDocument(); contentHandlerMock.startElement("http://springframework.org/spring-ws", "child", "child", new AttributesImpl()); contentHandlerMock.endElement("http://springframework.org/spring-ws", "child", "child");