From e03a27ef465c0a4c6aefa34058d9555221b7edb7 Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Wed, 7 Jan 2009 12:00:39 +0000 Subject: [PATCH] Added Stax Source methods to TransformerUtils --- .../util/xml/TransformerUtils.java | 182 ++++++++++++++++-- .../util/xml/TransformerUtilsTests.java | 69 ++++++- 2 files changed, 237 insertions(+), 14 deletions(-) diff --git a/org.springframework.core/src/main/java/org/springframework/util/xml/TransformerUtils.java b/org.springframework.core/src/main/java/org/springframework/util/xml/TransformerUtils.java index 4b1f4c0033..9f7c6bd486 100644 --- a/org.springframework.core/src/main/java/org/springframework/util/xml/TransformerUtils.java +++ b/org.springframework.core/src/main/java/org/springframework/util/xml/TransformerUtils.java @@ -16,33 +16,41 @@ package org.springframework.util.xml; +import javax.xml.stream.XMLEventReader; +import javax.xml.stream.XMLEventWriter; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; import javax.xml.transform.OutputKeys; +import javax.xml.transform.Result; +import javax.xml.transform.Source; import javax.xml.transform.Transformer; +import javax.xml.transform.stax.StAXResult; +import javax.xml.transform.stax.StAXSource; import org.springframework.util.Assert; /** - * Contains common behavior relating to {@link javax.xml.transform.Transformer Transformers}. + * Contains common behavior relating to {@link javax.xml.transform.Transformer Transformers}, and the + * javax.xml.transform package in general. * * @author Rick Evans * @author Juergen Hoeller + * @author Arjen Poutsma * @since 2.5.5 */ public abstract class TransformerUtils { /** - * The indent amount of characters if - * {@link #enableIndenting(javax.xml.transform.Transformer) indenting is enabled}. + * The indent amount of characters if {@link #enableIndenting(javax.xml.transform.Transformer) indenting is enabled}. *

Defaults to "2". */ public static final int DEFAULT_INDENT_AMOUNT = 2; - /** - * Enable indenting for the supplied {@link javax.xml.transform.Transformer}. - *

If the underlying XSLT engine is Xalan, then the special output - * key indent-amount will be also be set to a value - * of {@link #DEFAULT_INDENT_AMOUNT} characters. + * Enable indenting for the supplied {@link javax.xml.transform.Transformer}.

If the underlying XSLT engine is + * Xalan, then the special output key indent-amount will be also be set to a value of {@link + * #DEFAULT_INDENT_AMOUNT} characters. + * * @param transformer the target transformer * @see javax.xml.transform.Transformer#setOutputProperty(String, String) * @see javax.xml.transform.OutputKeys#INDENT @@ -52,10 +60,10 @@ public abstract class TransformerUtils { } /** - * Enable indenting for the supplied {@link javax.xml.transform.Transformer}. - *

If the underlying XSLT engine is Xalan, then the special output - * key indent-amount will be also be set to a value - * of {@link #DEFAULT_INDENT_AMOUNT} characters. + * Enable indenting for the supplied {@link javax.xml.transform.Transformer}.

If the underlying XSLT engine is + * Xalan, then the special output key indent-amount will be also be set to a value of {@link + * #DEFAULT_INDENT_AMOUNT} characters. + * * @param transformer the target transformer * @param indentAmount the size of the indent (2 characters, 3 characters, etc.) * @see javax.xml.transform.Transformer#setOutputProperty(String, String) @@ -75,6 +83,7 @@ public abstract class TransformerUtils { /** * Disable indenting for the supplied {@link javax.xml.transform.Transformer}. + * * @param transformer the target transformer * @see javax.xml.transform.OutputKeys#INDENT */ @@ -83,4 +92,153 @@ public abstract class TransformerUtils { transformer.setOutputProperty(OutputKeys.INDENT, "no"); } + /** + * Indicates whether the given {@link Source} is a StAX Source. + * + * @return true if source is a Spring {@link StaxSource} or JAXP 1.4 {@link StAXSource}; + * false 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 Result} is a StAX Result. + * + * @return true if result is a Spring {@link StaxResult} or JAXP 1.4 {@link StAXResult}; + * false 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 XMLStreamReader} for the given StAX Source. + * + * @param source a Spring {@link StaxSource} or {@link StAXSource} + * @return the {@link XMLStreamReader} + * @throws IllegalArgumentException if source is neither a Spring-WS {@link StaxSource} or {@link + * 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 XMLEventReader} for the given StAX Source. + * + * @param source a Spring {@link StaxSource} or {@link StAXSource} + * @return the {@link XMLEventReader} + * @throws IllegalArgumentException if source is neither a Spring {@link StaxSource} or {@link + * 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 XMLStreamWriter} for the given StAX Result. + * + * @param result a Spring {@link StaxResult} or {@link StAXResult} + * @return the {@link XMLStreamReader} + * @throws IllegalArgumentException if source is neither a Spring {@link StaxResult} or {@link + * 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 StaxResult} or {@link StAXResult} + * @return the {@link XMLStreamReader} + * @throws IllegalArgumentException if source is neither a Spring {@link StaxResult} or {@link + * 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"); + } + } + + /** Inner class to avoid a static JAXP 1.4 dependency. */ + private static class Jaxp14StaxHandler { + + 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(); + } + } + + } diff --git a/org.springframework.core/src/test/java/org/springframework/util/xml/TransformerUtilsTests.java b/org.springframework.core/src/test/java/org/springframework/util/xml/TransformerUtilsTests.java index 21eb30b72b..b5ebc845d4 100644 --- a/org.springframework.core/src/test/java/org/springframework/util/xml/TransformerUtilsTests.java +++ b/org.springframework.core/src/test/java/org/springframework/util/xml/TransformerUtilsTests.java @@ -16,7 +16,13 @@ package org.springframework.util.xml; +import java.io.StringReader; +import java.io.StringWriter; import java.util.Properties; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; import javax.xml.transform.ErrorListener; import javax.xml.transform.OutputKeys; import javax.xml.transform.Result; @@ -24,9 +30,16 @@ import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.URIResolver; +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.assertEquals; -import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.*; import org.junit.Test; /** @@ -89,6 +102,58 @@ public class TransformerUtilsTests { TransformerUtils.enableIndenting(new StubTransformer(), 0); } + @Test + public void isStaxSourceInvalid() throws Exception { + assertFalse("A StAX Source", TransformerUtils.isStaxSource(new DOMSource())); + assertFalse("A StAX Source", TransformerUtils.isStaxSource(new SAXSource())); + assertFalse("A StAX Source", TransformerUtils.isStaxSource(new StreamSource())); + } + + @Test + public void isStaxSource() throws Exception { + XMLInputFactory inputFactory = XMLInputFactory.newInstance(); + String expected = ""; + XMLStreamReader streamReader = inputFactory.createXMLStreamReader(new StringReader(expected)); + StaxSource source = new StaxSource(streamReader); + + assertTrue("Not a StAX Source", TransformerUtils.isStaxSource(source)); + } + + @Test + public void isStaxSourceJaxp14() throws Exception { + XMLInputFactory inputFactory = XMLInputFactory.newInstance(); + String expected = ""; + XMLStreamReader streamReader = inputFactory.createXMLStreamReader(new StringReader(expected)); + StAXSource source = new StAXSource(streamReader); + + assertTrue("Not a StAX Source", TransformerUtils.isStaxSource(source)); + } + + @Test + public void isStaxResultInvalid() throws Exception { + assertFalse("A StAX Result", TransformerUtils.isStaxResult(new DOMResult())); + assertFalse("A StAX Result", TransformerUtils.isStaxResult(new SAXResult())); + assertFalse("A StAX Result", TransformerUtils.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", TransformerUtils.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", TransformerUtils.isStaxResult(result)); + } + private static class StubTransformer extends Transformer { private Properties outputProperties = new Properties();