diff --git a/core/src/main/java/org/springframework/ws/server/endpoint/adapter/method/SourcePayloadMethodProcessor.java b/core/src/main/java/org/springframework/ws/server/endpoint/adapter/method/SourcePayloadMethodProcessor.java index 6be530cf..50c8009b 100644 --- a/core/src/main/java/org/springframework/ws/server/endpoint/adapter/method/SourcePayloadMethodProcessor.java +++ b/core/src/main/java/org/springframework/ws/server/endpoint/adapter/method/SourcePayloadMethodProcessor.java @@ -17,13 +17,18 @@ package org.springframework.ws.server.endpoint.adapter.method; import java.io.ByteArrayInputStream; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamReader; import javax.xml.transform.Source; import javax.xml.transform.dom.DOMResult; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.sax.SAXSource; +import javax.xml.transform.stax.StAXSource; import javax.xml.transform.stream.StreamSource; import org.springframework.core.MethodParameter; +import org.springframework.xml.JaxpVersion; +import org.springframework.xml.transform.StaxSource; import org.w3c.dom.Document; import org.w3c.dom.Node; @@ -36,8 +41,11 @@ import org.xml.sax.InputSource; * @author Arjen Poutsma * @since 2.0 */ +@SuppressWarnings("Since15") public class SourcePayloadMethodProcessor extends AbstractPayloadSourceMethodProcessor { + private XMLInputFactory inputFactory = createXmlInputFactory(); + // MethodArgumentResolver @Override @@ -55,14 +63,18 @@ public class SourcePayloadMethodProcessor extends AbstractPayloadSourceMethodPro DOMResult domResult = new DOMResult(); transform(requestPayload, domResult); Node node = domResult.getNode(); - if (node instanceof Document) { - Document document = (Document) node; - return new DOMSource(document.getDocumentElement()); + if (node.getNodeType() == Node.DOCUMENT_NODE) { + return new DOMSource(((Document) node).getDocumentElement()); } else { return new DOMSource(domResult.getNode()); } } + else if (StaxSource.class.isAssignableFrom(parameterType)) { + ByteArrayInputStream bis = convertToByteArrayInputStream(requestPayload); + XMLStreamReader streamReader = inputFactory.createXMLStreamReader(bis); + return new StaxSource(streamReader); + } else if (SAXSource.class.isAssignableFrom(parameterType)) { ByteArrayInputStream bis = convertToByteArrayInputStream(requestPayload); InputSource inputSource = new InputSource(bis); @@ -72,8 +84,12 @@ public class SourcePayloadMethodProcessor extends AbstractPayloadSourceMethodPro ByteArrayInputStream bis = convertToByteArrayInputStream(requestPayload); return new StreamSource(bis); } - // should not happen - throw new UnsupportedOperationException(); + else if (JaxpVersion.isAtLeastJaxp14() && Jaxp14StaxHandler.isStaxSource(parameterType)) { + ByteArrayInputStream bis = convertToByteArrayInputStream(requestPayload); + XMLStreamReader streamReader = inputFactory.createXMLStreamReader(bis); + return Jaxp14StaxHandler.createStaxSource(streamReader); + } + throw new IllegalArgumentException("Unknown Source type: " + parameterType); } // MethodReturnValueHandler @@ -92,4 +108,30 @@ public class SourcePayloadMethodProcessor extends AbstractPayloadSourceMethodPro return Source.class.isAssignableFrom(parameter.getParameterType()); } + /** + * Create a {@code XMLInputFactory} that this resolver will use to create {@link javax.xml.stream.XMLStreamReader} + * and {@link javax.xml.stream.XMLEventReader} objects. + *

+ * Can be overridden in subclasses, adding further initialization of the factory. The resulting factory is cached, + * so this method will only be called once. + * + * @return the created factory + */ + protected XMLInputFactory createXmlInputFactory() { + return XMLInputFactory.newInstance(); + } + + /** Inner class to avoid a static JAXP 1.4 dependency. */ + private static class Jaxp14StaxHandler { + + private static boolean isStaxSource(Class clazz) { + return StAXSource.class.isAssignableFrom(clazz); + } + + private static Source createStaxSource(XMLStreamReader streamReader) { + return new StAXSource(streamReader); + } + + } + } diff --git a/core/src/test/java/org/springframework/ws/server/endpoint/adapter/method/SourcePayloadMethodProcessorTest.java b/core/src/test/java/org/springframework/ws/server/endpoint/adapter/method/SourcePayloadMethodProcessorTest.java index 354750e8..31775be3 100644 --- a/core/src/test/java/org/springframework/ws/server/endpoint/adapter/method/SourcePayloadMethodProcessorTest.java +++ b/core/src/test/java/org/springframework/ws/server/endpoint/adapter/method/SourcePayloadMethodProcessorTest.java @@ -19,14 +19,17 @@ package org.springframework.ws.server.endpoint.adapter.method; import javax.xml.transform.Source; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.sax.SAXSource; +import javax.xml.transform.stax.StAXSource; import javax.xml.transform.stream.StreamSource; import org.springframework.core.MethodParameter; import org.springframework.ws.server.endpoint.annotation.RequestPayload; import org.springframework.ws.server.endpoint.annotation.ResponsePayload; +import org.springframework.xml.transform.StaxSource; import org.springframework.xml.transform.StringSource; /** @author Arjen Poutsma */ +@SuppressWarnings("Since15") public class SourcePayloadMethodProcessorTest extends AbstractPayloadMethodProcessorTestCase { @Override @@ -36,20 +39,22 @@ public class SourcePayloadMethodProcessorTest extends AbstractPayloadMethodProce @Override protected MethodParameter[] createSupportedParameters() throws NoSuchMethodException { - return new MethodParameter[] { - new MethodParameter(getClass().getMethod("source", Source.class), 0), - new MethodParameter(getClass().getMethod("dom", DOMSource.class), 0), - new MethodParameter(getClass().getMethod("sax", SAXSource.class), 0), - new MethodParameter(getClass().getMethod("stream", StreamSource.class), 0)}; + return new MethodParameter[]{new MethodParameter(getClass().getMethod("source", Source.class), 0), + new MethodParameter(getClass().getMethod("dom", DOMSource.class), 0), + new MethodParameter(getClass().getMethod("stax1", StaxSource.class), 0), + new MethodParameter(getClass().getMethod("sax", SAXSource.class), 0), + new MethodParameter(getClass().getMethod("stream", StreamSource.class), 0), + new MethodParameter(getClass().getMethod("stax2", StAXSource.class), 0)}; } @Override protected MethodParameter[] createSupportedReturnTypes() throws NoSuchMethodException { - return new MethodParameter[] { - new MethodParameter(getClass().getMethod("source", Source.class), -1), - new MethodParameter(getClass().getMethod("dom", DOMSource.class), -1), - new MethodParameter(getClass().getMethod("sax", SAXSource.class), -1), - new MethodParameter(getClass().getMethod("stream", StreamSource.class), -1)}; + return new MethodParameter[]{new MethodParameter(getClass().getMethod("source", Source.class), -1), + new MethodParameter(getClass().getMethod("dom", DOMSource.class), -1), + new MethodParameter(getClass().getMethod("stax1", StaxSource.class), -1), + new MethodParameter(getClass().getMethod("sax", SAXSource.class), -1), + new MethodParameter(getClass().getMethod("stream", StreamSource.class), -1), + new MethodParameter(getClass().getMethod("stax2", StAXSource.class), -1)}; } @Override @@ -67,6 +72,11 @@ public class SourcePayloadMethodProcessorTest extends AbstractPayloadMethodProce return source; } + @ResponsePayload + public StaxSource stax1(@RequestPayload StaxSource source) { + return source; + } + @ResponsePayload public SAXSource sax(@RequestPayload SAXSource source) { return source; @@ -76,4 +86,9 @@ public class SourcePayloadMethodProcessorTest extends AbstractPayloadMethodProce public StreamSource stream(@RequestPayload StreamSource source) { return source; } + + @ResponsePayload + public StAXSource stax2(@RequestPayload StAXSource source) { + return source; + } } diff --git a/xml/src/main/java/org/springframework/xml/JaxpVersion.java b/xml/src/main/java/org/springframework/xml/JaxpVersion.java index ec9efc21..b5c77463 100644 --- a/xml/src/main/java/org/springframework/xml/JaxpVersion.java +++ b/xml/src/main/java/org/springframework/xml/JaxpVersion.java @@ -1,5 +1,5 @@ /* - * Copyright 2006 the original author or authors. + * Copyright 2005-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. @@ -47,18 +47,19 @@ public abstract class JaxpVersion { private static int jaxpVersion = JAXP_10; static { + ClassLoader classLoader = JaxpVersion.class.getClassLoader(); try { - ClassUtils.forName(JAXP_14_CLASS_NAME); + ClassUtils.forName(JAXP_14_CLASS_NAME, classLoader); jaxpVersion = JAXP_14; } catch (ClassNotFoundException ex1) { try { - ClassUtils.forName(JAXP_13_CLASS_NAME); + ClassUtils.forName(JAXP_13_CLASS_NAME, classLoader); jaxpVersion = JAXP_13; } catch (ClassNotFoundException ex2) { try { - ClassUtils.forName(JAXP_11_CLASS_NAME); + ClassUtils.forName(JAXP_11_CLASS_NAME, classLoader); jaxpVersion = JAXP_11; } catch (ClassNotFoundException ex3) {