11 changed files with 950 additions and 239 deletions
@ -0,0 +1,182 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2002-2009 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.util.xml; |
||||||
|
|
||||||
|
import javax.xml.namespace.QName; |
||||||
|
import javax.xml.stream.XMLStreamConstants; |
||||||
|
import javax.xml.stream.XMLStreamException; |
||||||
|
import javax.xml.stream.XMLStreamReader; |
||||||
|
|
||||||
|
import org.springframework.util.Assert; |
||||||
|
|
||||||
|
/** |
||||||
|
* Abstract base class for <code>XMLStreamReader</code>s. |
||||||
|
* |
||||||
|
* @author Arjen Poutsma |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
abstract class AbstractXMLStreamReader implements XMLStreamReader { |
||||||
|
|
||||||
|
public String getElementText() throws XMLStreamException { |
||||||
|
if (getEventType() != XMLStreamConstants.START_ELEMENT) { |
||||||
|
throw new XMLStreamException("parser must be on START_ELEMENT to read next text", getLocation()); |
||||||
|
} |
||||||
|
int eventType = next(); |
||||||
|
StringBuilder builder = new StringBuilder(); |
||||||
|
while (eventType != XMLStreamConstants.END_ELEMENT) { |
||||||
|
if (eventType == XMLStreamConstants.CHARACTERS || eventType == XMLStreamConstants.CDATA || |
||||||
|
eventType == XMLStreamConstants.SPACE || eventType == XMLStreamConstants.ENTITY_REFERENCE) { |
||||||
|
builder.append(getText()); |
||||||
|
} |
||||||
|
else if (eventType == XMLStreamConstants.PROCESSING_INSTRUCTION || |
||||||
|
eventType == XMLStreamConstants.COMMENT) { |
||||||
|
// skipping
|
||||||
|
} |
||||||
|
else if (eventType == XMLStreamConstants.END_DOCUMENT) { |
||||||
|
throw new XMLStreamException("unexpected end of document when reading element text content", |
||||||
|
getLocation()); |
||||||
|
} |
||||||
|
else if (eventType == XMLStreamConstants.START_ELEMENT) { |
||||||
|
throw new XMLStreamException("element text content may not contain START_ELEMENT", getLocation()); |
||||||
|
} |
||||||
|
else { |
||||||
|
throw new XMLStreamException("Unexpected event type " + eventType, getLocation()); |
||||||
|
} |
||||||
|
eventType = next(); |
||||||
|
} |
||||||
|
return builder.toString(); |
||||||
|
} |
||||||
|
|
||||||
|
public String getAttributeLocalName(int index) { |
||||||
|
return getAttributeName(index).getLocalPart(); |
||||||
|
} |
||||||
|
|
||||||
|
public String getAttributeNamespace(int index) { |
||||||
|
return getAttributeName(index).getNamespaceURI(); |
||||||
|
} |
||||||
|
|
||||||
|
public String getAttributePrefix(int index) { |
||||||
|
return getAttributeName(index).getPrefix(); |
||||||
|
} |
||||||
|
|
||||||
|
public String getNamespaceURI() { |
||||||
|
int eventType = getEventType(); |
||||||
|
if (eventType == XMLStreamConstants.START_ELEMENT || eventType == XMLStreamConstants.END_ELEMENT) { |
||||||
|
return getName().getNamespaceURI(); |
||||||
|
} |
||||||
|
else { |
||||||
|
throw new IllegalStateException("parser must be on START_ELEMENT or END_ELEMENT state"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public String getNamespaceURI(String prefix) { |
||||||
|
Assert.notNull(prefix, "No prefix given"); |
||||||
|
return getNamespaceContext().getNamespaceURI(prefix); |
||||||
|
} |
||||||
|
|
||||||
|
public boolean hasText() { |
||||||
|
int eventType = getEventType(); |
||||||
|
return eventType == XMLStreamConstants.SPACE || eventType == XMLStreamConstants.CHARACTERS || |
||||||
|
eventType == XMLStreamConstants.COMMENT || eventType == XMLStreamConstants.CDATA || |
||||||
|
eventType == XMLStreamConstants.ENTITY_REFERENCE; |
||||||
|
} |
||||||
|
|
||||||
|
public String getPrefix() { |
||||||
|
int eventType = getEventType(); |
||||||
|
if (eventType == XMLStreamConstants.START_ELEMENT || eventType == XMLStreamConstants.END_ELEMENT) { |
||||||
|
return getName().getPrefix(); |
||||||
|
} |
||||||
|
else { |
||||||
|
throw new IllegalStateException("parser must be on START_ELEMENT or END_ELEMENT state"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public boolean hasName() { |
||||||
|
int eventType = getEventType(); |
||||||
|
return eventType == XMLStreamConstants.START_ELEMENT || eventType == XMLStreamConstants.END_ELEMENT; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isWhiteSpace() { |
||||||
|
return getEventType() == XMLStreamConstants.SPACE; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isStartElement() { |
||||||
|
return getEventType() == XMLStreamConstants.START_ELEMENT; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isEndElement() { |
||||||
|
return getEventType() == XMLStreamConstants.END_ELEMENT; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isCharacters() { |
||||||
|
return getEventType() == XMLStreamConstants.CHARACTERS; |
||||||
|
} |
||||||
|
|
||||||
|
public int nextTag() throws XMLStreamException { |
||||||
|
int eventType = next(); |
||||||
|
while (eventType == XMLStreamConstants.CHARACTERS && isWhiteSpace() || |
||||||
|
eventType == XMLStreamConstants.CDATA && isWhiteSpace() || eventType == XMLStreamConstants.SPACE || |
||||||
|
eventType == XMLStreamConstants.PROCESSING_INSTRUCTION || eventType == XMLStreamConstants.COMMENT) { |
||||||
|
eventType = next(); |
||||||
|
} |
||||||
|
if (eventType != XMLStreamConstants.START_ELEMENT && eventType != XMLStreamConstants.END_ELEMENT) { |
||||||
|
throw new XMLStreamException("expected start or end tag", getLocation()); |
||||||
|
} |
||||||
|
return eventType; |
||||||
|
} |
||||||
|
|
||||||
|
public void require(int expectedType, String namespaceURI, String localName) throws XMLStreamException { |
||||||
|
int eventType = getEventType(); |
||||||
|
if (eventType != expectedType) { |
||||||
|
throw new XMLStreamException("Expected [" + expectedType + "] but read [" + eventType + "]"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public String getAttributeValue(String namespaceURI, String localName) { |
||||||
|
for (int i = 0; i < getAttributeCount(); i++) { |
||||||
|
QName name = getAttributeName(i); |
||||||
|
if (name.getNamespaceURI().equals(namespaceURI) && name.getLocalPart().equals(localName)) { |
||||||
|
return getAttributeValue(i); |
||||||
|
} |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean hasNext() throws XMLStreamException { |
||||||
|
return getEventType() != END_DOCUMENT; |
||||||
|
} |
||||||
|
|
||||||
|
public String getLocalName() { |
||||||
|
return getName().getLocalPart(); |
||||||
|
} |
||||||
|
|
||||||
|
public char[] getTextCharacters() { |
||||||
|
return getText().toCharArray(); |
||||||
|
} |
||||||
|
|
||||||
|
public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length) |
||||||
|
throws XMLStreamException { |
||||||
|
char[] source = getTextCharacters(); |
||||||
|
length = Math.min(length, source.length); |
||||||
|
System.arraycopy(source, sourceStart, target, targetStart, length); |
||||||
|
return length; |
||||||
|
} |
||||||
|
|
||||||
|
public int getTextLength() { |
||||||
|
return getText().length(); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,59 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2002-2009 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.util.xml; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
|
||||||
|
import org.xml.sax.InputSource; |
||||||
|
|
||||||
|
import org.springframework.core.io.Resource; |
||||||
|
|
||||||
|
/** |
||||||
|
* Convenient utility methods for dealing with SAX. |
||||||
|
* |
||||||
|
* @author Arjen Poutsma |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public abstract class SaxUtils { |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates a SAX <code>InputSource</code> from the given resource. Sets the system identifier to the resource's |
||||||
|
* <code>URL</code>, if available. |
||||||
|
* |
||||||
|
* @param resource the resource |
||||||
|
* @return the input source created from the resource |
||||||
|
* @throws IOException if an I/O exception occurs |
||||||
|
* @see InputSource#setSystemId(String) |
||||||
|
* @see #getSystemId(org.springframework.core.io.Resource) |
||||||
|
*/ |
||||||
|
public static InputSource createInputSource(Resource resource) throws IOException { |
||||||
|
InputSource inputSource = new InputSource(resource.getInputStream()); |
||||||
|
inputSource.setSystemId(getSystemId(resource)); |
||||||
|
return inputSource; |
||||||
|
} |
||||||
|
|
||||||
|
/** Retrieves the URL from the given resource as System ID. Returns <code>null</code> if it cannot be openened. */ |
||||||
|
private static String getSystemId(Resource resource) { |
||||||
|
try { |
||||||
|
return resource.getURI().toString(); |
||||||
|
} |
||||||
|
catch (IOException e) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,284 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2002-2009 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.util.xml; |
||||||
|
|
||||||
|
import javax.xml.stream.XMLEventReader; |
||||||
|
import javax.xml.stream.XMLEventWriter; |
||||||
|
import javax.xml.stream.XMLStreamException; |
||||||
|
import javax.xml.stream.XMLStreamReader; |
||||||
|
import javax.xml.stream.XMLStreamWriter; |
||||||
|
import javax.xml.transform.Result; |
||||||
|
import javax.xml.transform.Source; |
||||||
|
import javax.xml.transform.stax.StAXResult; |
||||||
|
import javax.xml.transform.stax.StAXSource; |
||||||
|
|
||||||
|
import org.xml.sax.ContentHandler; |
||||||
|
import org.xml.sax.XMLReader; |
||||||
|
|
||||||
|
import org.springframework.util.Assert; |
||||||
|
|
||||||
|
/** |
||||||
|
* Convenience methods for working with the StAX API. |
||||||
|
* |
||||||
|
* In particular, methods for using StAX in combination with the TrAX API (<code>javax.xml.transform</code>), and |
||||||
|
* converting StAX readers/writers into SAX readers/handlers and vice-versa. |
||||||
|
* |
||||||
|
* @author Arjen Poutsma |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public abstract class StaxUtils { |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates a StAX {@link Source} for the given {@link XMLStreamReader}. Returns a {@link StAXSource} under JAXP 1.4 or |
||||||
|
* higher, or a {@link StaxSource} otherwise. |
||||||
|
* |
||||||
|
* @param streamReader the StAX stream reader |
||||||
|
* @return a source wrapping <code>streamReader</code> |
||||||
|
*/ |
||||||
|
public static Source createStaxSource(XMLStreamReader streamReader) { |
||||||
|
if (JaxpVersion.isAtLeastJaxp14()) { |
||||||
|
return Jaxp14StaxHandler.createStaxSource(streamReader); |
||||||
|
} |
||||||
|
else { |
||||||
|
return new StaxSource(streamReader); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates a StAX {@link Source} for the given {@link XMLEventReader}. Returns a {@link StAXSource} under JAXP 1.4 or |
||||||
|
* higher, or a {@link StaxSource} otherwise. |
||||||
|
* |
||||||
|
* @param eventReader the StAX event reader |
||||||
|
* @return a source wrapping <code>streamReader</code> |
||||||
|
* @throws XMLStreamException in case of StAX errors |
||||||
|
*/ |
||||||
|
public static Source createStaxSource(XMLEventReader eventReader) throws XMLStreamException { |
||||||
|
if (JaxpVersion.isAtLeastJaxp14()) { |
||||||
|
return Jaxp14StaxHandler.createStaxSource(eventReader); |
||||||
|
} |
||||||
|
else { |
||||||
|
return new StaxSource(eventReader); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Indicates whether the given {@link javax.xml.transform.Source} is a StAX Source. |
||||||
|
* |
||||||
|
* @return <code>true</code> if <code>source</code> is a Spring {@link org.springframework.util.xml.StaxSource} or JAXP |
||||||
|
* 1.4 {@link javax.xml.transform.stax.StAXSource}; <code>false</code> otherwise. |
||||||
|
*/ |
||||||
|
public static boolean isStaxSource(Source source) { |
||||||
|
if (source instanceof StaxSource) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
else if (JaxpVersion.isAtLeastJaxp14()) { |
||||||
|
return Jaxp14StaxHandler.isStaxSource(source); |
||||||
|
} |
||||||
|
else { |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Indicates whether the given {@link javax.xml.transform.Result} is a StAX Result. |
||||||
|
* |
||||||
|
* @return <code>true</code> if <code>result</code> is a Spring {@link org.springframework.util.xml.StaxResult} or JAXP |
||||||
|
* 1.4 {@link javax.xml.transform.stax.StAXResult}; <code>false</code> otherwise. |
||||||
|
*/ |
||||||
|
public static boolean isStaxResult(Result result) { |
||||||
|
if (result instanceof StaxResult) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
else if (JaxpVersion.isAtLeastJaxp14()) { |
||||||
|
return Jaxp14StaxHandler.isStaxResult(result); |
||||||
|
} |
||||||
|
else { |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the {@link javax.xml.stream.XMLStreamReader} for the given StAX Source. |
||||||
|
* |
||||||
|
* @param source a Spring {@link org.springframework.util.xml.StaxSource} or {@link javax.xml.transform.stax.StAXSource} |
||||||
|
* @return the {@link javax.xml.stream.XMLStreamReader} |
||||||
|
* @throws IllegalArgumentException if <code>source</code> is neither a Spring-WS {@link org.springframework.util.xml.StaxSource} |
||||||
|
* or {@link javax.xml.transform.stax.StAXSource} |
||||||
|
*/ |
||||||
|
public static XMLStreamReader getXMLStreamReader(Source source) { |
||||||
|
if (source instanceof StaxSource) { |
||||||
|
return ((StaxSource) source).getXMLStreamReader(); |
||||||
|
} |
||||||
|
else if (JaxpVersion.isAtLeastJaxp14()) { |
||||||
|
return Jaxp14StaxHandler.getXMLStreamReader(source); |
||||||
|
} |
||||||
|
else { |
||||||
|
throw new IllegalArgumentException("Source '" + source + "' is neither StaxSource nor StAXSource"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the {@link javax.xml.stream.XMLEventReader} for the given StAX Source. |
||||||
|
* |
||||||
|
* @param source a Spring {@link org.springframework.util.xml.StaxSource} or {@link javax.xml.transform.stax.StAXSource} |
||||||
|
* @return the {@link javax.xml.stream.XMLEventReader} |
||||||
|
* @throws IllegalArgumentException if <code>source</code> is neither a Spring {@link org.springframework.util.xml.StaxSource} |
||||||
|
* or {@link javax.xml.transform.stax.StAXSource} |
||||||
|
*/ |
||||||
|
public static XMLEventReader getXMLEventReader(Source source) { |
||||||
|
if (source instanceof StaxSource) { |
||||||
|
return ((StaxSource) source).getXMLEventReader(); |
||||||
|
} |
||||||
|
else if (JaxpVersion.isAtLeastJaxp14()) { |
||||||
|
return Jaxp14StaxHandler.getXMLEventReader(source); |
||||||
|
} |
||||||
|
else { |
||||||
|
throw new IllegalArgumentException("Source '" + source + "' is neither StaxSource nor StAXSource"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the {@link javax.xml.stream.XMLStreamWriter} for the given StAX Result. |
||||||
|
* |
||||||
|
* @param result a Spring {@link org.springframework.util.xml.StaxResult} or {@link javax.xml.transform.stax.StAXResult} |
||||||
|
* @return the {@link javax.xml.stream.XMLStreamReader} |
||||||
|
* @throws IllegalArgumentException if <code>source</code> is neither a Spring {@link org.springframework.util.xml.StaxResult} |
||||||
|
* or {@link javax.xml.transform.stax.StAXResult} |
||||||
|
*/ |
||||||
|
public static XMLStreamWriter getXMLStreamWriter(Result result) { |
||||||
|
if (result instanceof StaxResult) { |
||||||
|
return ((StaxResult) result).getXMLStreamWriter(); |
||||||
|
} |
||||||
|
else if (JaxpVersion.isAtLeastJaxp14()) { |
||||||
|
return Jaxp14StaxHandler.getXMLStreamWriter(result); |
||||||
|
} |
||||||
|
else { |
||||||
|
throw new IllegalArgumentException("Result '" + result + "' is neither StaxResult nor StAXResult"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the {@link XMLEventWriter} for the given StAX Result. |
||||||
|
* |
||||||
|
* @param result a Spring {@link org.springframework.util.xml.StaxResult} or {@link javax.xml.transform.stax.StAXResult} |
||||||
|
* @return the {@link javax.xml.stream.XMLStreamReader} |
||||||
|
* @throws IllegalArgumentException if <code>source</code> is neither a Spring {@link org.springframework.util.xml.StaxResult} |
||||||
|
* or {@link javax.xml.transform.stax.StAXResult} |
||||||
|
*/ |
||||||
|
public static XMLEventWriter getXMLEventWriter(Result result) { |
||||||
|
if (result instanceof StaxResult) { |
||||||
|
return ((StaxResult) result).getXMLEventWriter(); |
||||||
|
} |
||||||
|
else if (JaxpVersion.isAtLeastJaxp14()) { |
||||||
|
return Jaxp14StaxHandler.getXMLEventWriter(result); |
||||||
|
} |
||||||
|
else { |
||||||
|
throw new IllegalArgumentException("Result '" + result + "' is neither StaxResult nor StAXResult"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates a SAX {@link ContentHandler} that writes to the given StAX {@link XMLStreamWriter}. |
||||||
|
* |
||||||
|
* @param streamWriter the StAX stream writer |
||||||
|
* @return a content handler writing to the <code>streamWriter</code> |
||||||
|
*/ |
||||||
|
public static ContentHandler createContentHandler(XMLStreamWriter streamWriter) { |
||||||
|
return new StaxStreamContentHandler(streamWriter); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates a SAX {@link ContentHandler} that writes events to the given StAX {@link XMLEventWriter}. |
||||||
|
* |
||||||
|
* @param eventWriter the StAX event writer |
||||||
|
* @return a content handler writing to the <code>eventWriter</code> |
||||||
|
*/ |
||||||
|
public static ContentHandler createContentHandler(XMLEventWriter eventWriter) { |
||||||
|
return new StaxEventContentHandler(eventWriter); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates a SAX {@link XMLReader} that reads from the given StAX {@link XMLStreamReader}. |
||||||
|
* |
||||||
|
* @param streamReader the StAX stream reader |
||||||
|
* @return a XMLReader reading from the <code>streamWriter</code> |
||||||
|
*/ |
||||||
|
public static XMLReader createXMLReader(XMLStreamReader streamReader) { |
||||||
|
return new StaxStreamXMLReader(streamReader); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates a SAX {@link XMLReader} that reads from the given StAX {@link XMLEventReader}. |
||||||
|
* |
||||||
|
* @param eventReader the StAX event reader |
||||||
|
* @return a XMLReader reading from the <code>eventWriter</code> |
||||||
|
*/ |
||||||
|
public static XMLReader createXMLReader(XMLEventReader eventReader) { |
||||||
|
return new StaxEventXMLReader(eventReader); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns a {@link XMLStreamReader} that reads from a {@link XMLEventReader}. Useful, because the StAX |
||||||
|
* <code>XMLInputFactory</code> allows one to create a event reader from a stream reader, but not vice-versa. |
||||||
|
* |
||||||
|
* @return a stream reader that reads from an event reader |
||||||
|
*/ |
||||||
|
public static XMLStreamReader createEventStreamReader(XMLEventReader eventReader) throws XMLStreamException { |
||||||
|
return new XMLEventStreamReader(eventReader); |
||||||
|
} |
||||||
|
|
||||||
|
/** Inner class to avoid a static JAXP 1.4 dependency. */ |
||||||
|
private static class Jaxp14StaxHandler { |
||||||
|
|
||||||
|
private static Source createStaxSource(XMLStreamReader streamReader) { |
||||||
|
return new StAXSource(streamReader); |
||||||
|
} |
||||||
|
|
||||||
|
private static Source createStaxSource(XMLEventReader eventReader) throws XMLStreamException { |
||||||
|
return new StAXSource(eventReader); |
||||||
|
} |
||||||
|
|
||||||
|
private static boolean isStaxSource(Source source) { |
||||||
|
return source instanceof StAXSource; |
||||||
|
} |
||||||
|
|
||||||
|
private static boolean isStaxResult(Result result) { |
||||||
|
return result instanceof StAXResult; |
||||||
|
} |
||||||
|
|
||||||
|
private static XMLStreamReader getXMLStreamReader(Source source) { |
||||||
|
Assert.isInstanceOf(StAXSource.class, source); |
||||||
|
return ((StAXSource) source).getXMLStreamReader(); |
||||||
|
} |
||||||
|
|
||||||
|
private static XMLEventReader getXMLEventReader(Source source) { |
||||||
|
Assert.isInstanceOf(StAXSource.class, source); |
||||||
|
return ((StAXSource) source).getXMLEventReader(); |
||||||
|
} |
||||||
|
|
||||||
|
private static XMLStreamWriter getXMLStreamWriter(Result result) { |
||||||
|
Assert.isInstanceOf(StAXResult.class, result); |
||||||
|
return ((StAXResult) result).getXMLStreamWriter(); |
||||||
|
} |
||||||
|
|
||||||
|
private static XMLEventWriter getXMLEventWriter(Result result) { |
||||||
|
Assert.isInstanceOf(StAXResult.class, result); |
||||||
|
return ((StAXResult) result).getXMLEventWriter(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,254 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2002-2009 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.util.xml; |
||||||
|
|
||||||
|
import java.util.Iterator; |
||||||
|
import javax.xml.namespace.NamespaceContext; |
||||||
|
import javax.xml.namespace.QName; |
||||||
|
import javax.xml.stream.Location; |
||||||
|
import javax.xml.stream.XMLEventReader; |
||||||
|
import javax.xml.stream.XMLStreamException; |
||||||
|
import javax.xml.stream.events.Attribute; |
||||||
|
import javax.xml.stream.events.Namespace; |
||||||
|
import javax.xml.stream.events.ProcessingInstruction; |
||||||
|
import javax.xml.stream.events.StartDocument; |
||||||
|
import javax.xml.stream.events.XMLEvent; |
||||||
|
|
||||||
|
/** |
||||||
|
* Implementation of the <code>XMLStreamReader</code> interface that wraps a <code>XMLEventReader</code>. Useful, |
||||||
|
* because the StAX <code>XMLInputFactory</code> allows one to create a event reader from a stream reader, but not |
||||||
|
* vice-versa. |
||||||
|
* |
||||||
|
* @author Arjen Poutsma |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
class XMLEventStreamReader extends AbstractXMLStreamReader { |
||||||
|
|
||||||
|
private XMLEvent event; |
||||||
|
|
||||||
|
private final XMLEventReader eventReader; |
||||||
|
|
||||||
|
XMLEventStreamReader(XMLEventReader eventReader) throws XMLStreamException { |
||||||
|
this.eventReader = eventReader; |
||||||
|
event = eventReader.nextEvent(); |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isStandalone() { |
||||||
|
if (event.isStartDocument()) { |
||||||
|
return ((StartDocument) event).isStandalone(); |
||||||
|
} |
||||||
|
else { |
||||||
|
throw new IllegalStateException(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public String getVersion() { |
||||||
|
if (event.isStartDocument()) { |
||||||
|
return ((StartDocument) event).getVersion(); |
||||||
|
} |
||||||
|
else { |
||||||
|
throw new IllegalStateException(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public int getTextStart() { |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
public String getText() { |
||||||
|
if (event.isCharacters()) { |
||||||
|
return event.asCharacters().getData(); |
||||||
|
} |
||||||
|
else { |
||||||
|
throw new IllegalStateException(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public String getPITarget() { |
||||||
|
if (event.isProcessingInstruction()) { |
||||||
|
return ((ProcessingInstruction) event).getTarget(); |
||||||
|
} |
||||||
|
else { |
||||||
|
throw new IllegalStateException(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public String getPIData() { |
||||||
|
if (event.isProcessingInstruction()) { |
||||||
|
return ((ProcessingInstruction) event).getData(); |
||||||
|
} |
||||||
|
else { |
||||||
|
throw new IllegalStateException(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public int getNamespaceCount() { |
||||||
|
Iterator namespaces; |
||||||
|
if (event.isStartElement()) { |
||||||
|
namespaces = event.asStartElement().getNamespaces(); |
||||||
|
} |
||||||
|
else if (event.isEndElement()) { |
||||||
|
namespaces = event.asEndElement().getNamespaces(); |
||||||
|
} |
||||||
|
else { |
||||||
|
throw new IllegalStateException(); |
||||||
|
} |
||||||
|
return countIterator(namespaces); |
||||||
|
} |
||||||
|
|
||||||
|
public NamespaceContext getNamespaceContext() { |
||||||
|
if (event.isStartElement()) { |
||||||
|
return event.asStartElement().getNamespaceContext(); |
||||||
|
} |
||||||
|
else { |
||||||
|
throw new IllegalStateException(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public QName getName() { |
||||||
|
if (event.isStartElement()) { |
||||||
|
return event.asStartElement().getName(); |
||||||
|
} |
||||||
|
else if (event.isEndElement()) { |
||||||
|
return event.asEndElement().getName(); |
||||||
|
} |
||||||
|
else { |
||||||
|
throw new IllegalStateException(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public Location getLocation() { |
||||||
|
return event.getLocation(); |
||||||
|
} |
||||||
|
|
||||||
|
public int getEventType() { |
||||||
|
return event.getEventType(); |
||||||
|
} |
||||||
|
|
||||||
|
public String getEncoding() { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
public String getCharacterEncodingScheme() { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
public int getAttributeCount() { |
||||||
|
if (!event.isStartElement()) { |
||||||
|
throw new IllegalStateException(); |
||||||
|
} |
||||||
|
Iterator attributes = event.asStartElement().getAttributes(); |
||||||
|
return countIterator(attributes); |
||||||
|
} |
||||||
|
|
||||||
|
public void close() throws XMLStreamException { |
||||||
|
eventReader.close(); |
||||||
|
} |
||||||
|
|
||||||
|
public QName getAttributeName(int index) { |
||||||
|
return getAttribute(index).getName(); |
||||||
|
} |
||||||
|
|
||||||
|
public String getAttributeType(int index) { |
||||||
|
return getAttribute(index).getDTDType(); |
||||||
|
} |
||||||
|
|
||||||
|
public String getAttributeValue(int index) { |
||||||
|
return getAttribute(index).getValue(); |
||||||
|
} |
||||||
|
|
||||||
|
public String getNamespacePrefix(int index) { |
||||||
|
return getNamespace(index).getPrefix(); |
||||||
|
} |
||||||
|
|
||||||
|
public String getNamespaceURI(int index) { |
||||||
|
return getNamespace(index).getNamespaceURI(); |
||||||
|
} |
||||||
|
|
||||||
|
public Object getProperty(String name) throws IllegalArgumentException { |
||||||
|
return eventReader.getProperty(name); |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isAttributeSpecified(int index) { |
||||||
|
return getAttribute(index).isSpecified(); |
||||||
|
} |
||||||
|
|
||||||
|
public int next() throws XMLStreamException { |
||||||
|
event = eventReader.nextEvent(); |
||||||
|
return event.getEventType(); |
||||||
|
} |
||||||
|
|
||||||
|
public boolean standaloneSet() { |
||||||
|
if (event.isStartDocument()) { |
||||||
|
return ((StartDocument) event).standaloneSet(); |
||||||
|
} |
||||||
|
else { |
||||||
|
throw new IllegalStateException(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private int countIterator(Iterator iterator) { |
||||||
|
int count = 0; |
||||||
|
while (iterator.hasNext()) { |
||||||
|
iterator.next(); |
||||||
|
count++; |
||||||
|
} |
||||||
|
return count; |
||||||
|
} |
||||||
|
|
||||||
|
private Attribute getAttribute(int index) { |
||||||
|
if (!event.isStartElement()) { |
||||||
|
throw new IllegalStateException(); |
||||||
|
} |
||||||
|
int count = 0; |
||||||
|
Iterator attributes = event.asStartElement().getAttributes(); |
||||||
|
while (attributes.hasNext()) { |
||||||
|
Attribute attribute = (Attribute) attributes.next(); |
||||||
|
if (count == index) { |
||||||
|
return attribute; |
||||||
|
} |
||||||
|
else { |
||||||
|
count++; |
||||||
|
} |
||||||
|
} |
||||||
|
throw new IllegalArgumentException(); |
||||||
|
} |
||||||
|
|
||||||
|
private Namespace getNamespace(int index) { |
||||||
|
Iterator namespaces; |
||||||
|
if (event.isStartElement()) { |
||||||
|
namespaces = event.asStartElement().getNamespaces(); |
||||||
|
} |
||||||
|
else if (event.isEndElement()) { |
||||||
|
namespaces = event.asEndElement().getNamespaces(); |
||||||
|
} |
||||||
|
else { |
||||||
|
throw new IllegalStateException(); |
||||||
|
} |
||||||
|
int count = 0; |
||||||
|
while (namespaces.hasNext()) { |
||||||
|
Namespace namespace = (Namespace) namespaces.next(); |
||||||
|
if (count == index) { |
||||||
|
return namespace; |
||||||
|
} |
||||||
|
else { |
||||||
|
count++; |
||||||
|
} |
||||||
|
} |
||||||
|
throw new IllegalArgumentException(); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,92 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2002-2009 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.util.xml; |
||||||
|
|
||||||
|
import java.io.StringReader; |
||||||
|
import java.io.StringWriter; |
||||||
|
import javax.xml.stream.XMLInputFactory; |
||||||
|
import javax.xml.stream.XMLOutputFactory; |
||||||
|
import javax.xml.stream.XMLStreamReader; |
||||||
|
import javax.xml.stream.XMLStreamWriter; |
||||||
|
import javax.xml.transform.dom.DOMResult; |
||||||
|
import javax.xml.transform.dom.DOMSource; |
||||||
|
import javax.xml.transform.sax.SAXResult; |
||||||
|
import javax.xml.transform.sax.SAXSource; |
||||||
|
import javax.xml.transform.stax.StAXResult; |
||||||
|
import javax.xml.transform.stax.StAXSource; |
||||||
|
import javax.xml.transform.stream.StreamResult; |
||||||
|
import javax.xml.transform.stream.StreamSource; |
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse; |
||||||
|
import static org.junit.Assert.assertTrue; |
||||||
|
import org.junit.Test; |
||||||
|
|
||||||
|
public class StaxUtilsTest { |
||||||
|
|
||||||
|
@Test |
||||||
|
public void isStaxSourceInvalid() throws Exception { |
||||||
|
assertFalse("A StAX Source", StaxUtils.isStaxSource(new DOMSource())); |
||||||
|
assertFalse("A StAX Source", StaxUtils.isStaxSource(new SAXSource())); |
||||||
|
assertFalse("A StAX Source", StaxUtils.isStaxSource(new StreamSource())); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void isStaxSource() throws Exception { |
||||||
|
XMLInputFactory inputFactory = XMLInputFactory.newInstance(); |
||||||
|
String expected = "<element/>"; |
||||||
|
XMLStreamReader streamReader = inputFactory.createXMLStreamReader(new StringReader(expected)); |
||||||
|
StaxSource source = new StaxSource(streamReader); |
||||||
|
|
||||||
|
assertTrue("Not a StAX Source", StaxUtils.isStaxSource(source)); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void isStaxSourceJaxp14() throws Exception { |
||||||
|
XMLInputFactory inputFactory = XMLInputFactory.newInstance(); |
||||||
|
String expected = "<element/>"; |
||||||
|
XMLStreamReader streamReader = inputFactory.createXMLStreamReader(new StringReader(expected)); |
||||||
|
StAXSource source = new StAXSource(streamReader); |
||||||
|
|
||||||
|
assertTrue("Not a StAX Source", StaxUtils.isStaxSource(source)); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void isStaxResultInvalid() throws Exception { |
||||||
|
assertFalse("A StAX Result", StaxUtils.isStaxResult(new DOMResult())); |
||||||
|
assertFalse("A StAX Result", StaxUtils.isStaxResult(new SAXResult())); |
||||||
|
assertFalse("A StAX Result", StaxUtils.isStaxResult(new StreamResult())); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void isStaxResult() throws Exception { |
||||||
|
XMLOutputFactory outputFactory = XMLOutputFactory.newInstance(); |
||||||
|
XMLStreamWriter streamWriter = outputFactory.createXMLStreamWriter(new StringWriter()); |
||||||
|
StaxResult result = new StaxResult(streamWriter); |
||||||
|
|
||||||
|
assertTrue("Not a StAX Result", StaxUtils.isStaxResult(result)); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void isStaxResultJaxp14() throws Exception { |
||||||
|
XMLOutputFactory outputFactory = XMLOutputFactory.newInstance(); |
||||||
|
XMLStreamWriter streamWriter = outputFactory.createXMLStreamWriter(new StringWriter()); |
||||||
|
StAXResult result = new StAXResult(streamWriter); |
||||||
|
|
||||||
|
assertTrue("Not a StAX Result", StaxUtils.isStaxResult(result)); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,62 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2002-2009 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.util.xml; |
||||||
|
|
||||||
|
import java.io.StringReader; |
||||||
|
import java.io.StringWriter; |
||||||
|
import javax.xml.stream.XMLEventReader; |
||||||
|
import javax.xml.stream.XMLInputFactory; |
||||||
|
import javax.xml.transform.Transformer; |
||||||
|
import javax.xml.transform.TransformerFactory; |
||||||
|
import javax.xml.transform.stream.StreamResult; |
||||||
|
|
||||||
|
import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual; |
||||||
|
import org.junit.Before; |
||||||
|
import org.junit.Test; |
||||||
|
|
||||||
|
public class XMLEventStreamReaderTest { |
||||||
|
|
||||||
|
private static final String XML = |
||||||
|
"<?pi content?><root xmlns='namespace'><prefix:child xmlns:prefix='namespace2'>content</prefix:child></root>" |
||||||
|
; |
||||||
|
|
||||||
|
private XMLEventStreamReader streamReader; |
||||||
|
|
||||||
|
@Before |
||||||
|
public void createStreamReader() throws Exception { |
||||||
|
XMLInputFactory inputFactory = XMLInputFactory.newInstance(); |
||||||
|
XMLEventReader eventReader = inputFactory.createXMLEventReader(new StringReader(XML)); |
||||||
|
streamReader = new XMLEventStreamReader(eventReader); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void readAll() throws Exception { |
||||||
|
while (streamReader.hasNext()) { |
||||||
|
streamReader.next(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void readCorrect() throws Exception { |
||||||
|
Transformer transformer = TransformerFactory.newInstance().newTransformer(); |
||||||
|
StaxSource source = new StaxSource(streamReader); |
||||||
|
StringWriter writer = new StringWriter(); |
||||||
|
transformer.transform(source, new StreamResult(writer)); |
||||||
|
assertXMLEqual(XML, writer.toString()); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
Loading…
Reference in new issue