diff --git a/core/pom.xml b/core/pom.xml index 96520a09..ac62c416 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -1,4 +1,6 @@ - + spring-ws org.springframework.ws @@ -48,10 +50,6 @@ - - org.springframework - spring-aop - org.springframework spring-mock diff --git a/core/src/main/java/org/springframework/ws/server/endpoint/AbstractDom4jPayloadEndpoint.java b/core/src/main/java/org/springframework/ws/server/endpoint/AbstractDom4jPayloadEndpoint.java index ce6a743f..e4e32a7e 100644 --- a/core/src/main/java/org/springframework/ws/server/endpoint/AbstractDom4jPayloadEndpoint.java +++ b/core/src/main/java/org/springframework/ws/server/endpoint/AbstractDom4jPayloadEndpoint.java @@ -38,9 +38,12 @@ import org.springframework.xml.transform.TransformerObjectSupport; public abstract class AbstractDom4jPayloadEndpoint extends TransformerObjectSupport implements PayloadEndpoint { public final Source invoke(Source request) throws Exception { - DocumentResult dom4jResult = new DocumentResult(); - transform(request, dom4jResult); - Element requestElement = dom4jResult.getDocument().getRootElement(); + Element requestElement = null; + if (request != null) { + DocumentResult dom4jResult = new DocumentResult(); + transform(request, dom4jResult); + requestElement = dom4jResult.getDocument().getRootElement(); + } Document responseDocument = DocumentHelper.createDocument(); Element responseElement = invokeInternal(requestElement, responseDocument); return responseElement != null ? new DocumentSource(responseElement) : null; diff --git a/core/src/main/java/org/springframework/ws/server/endpoint/AbstractDomPayloadEndpoint.java b/core/src/main/java/org/springframework/ws/server/endpoint/AbstractDomPayloadEndpoint.java index 3b4d996b..f43a63f1 100644 --- a/core/src/main/java/org/springframework/ws/server/endpoint/AbstractDomPayloadEndpoint.java +++ b/core/src/main/java/org/springframework/ws/server/endpoint/AbstractDomPayloadEndpoint.java @@ -63,10 +63,13 @@ public abstract class AbstractDomPayloadEndpoint extends TransformerObjectSuppor documentBuilderFactory = createDocumentBuilderFactory(); } DocumentBuilder documentBuilder = createDocumentBuilder(documentBuilderFactory); - Document requestDocument = documentBuilder.newDocument(); - DOMResult domResult = new DOMResult(requestDocument); - transform(request, domResult); - Element requestElement = (Element) requestDocument.getFirstChild(); + Element requestElement = null; + if (request != null) { + Document requestDocument = documentBuilder.newDocument(); + DOMResult domResult = new DOMResult(requestDocument); + transform(request, domResult); + requestElement = (Element) requestDocument.getFirstChild(); + } Document responseDocument = documentBuilder.newDocument(); Element responseElement = invokeInternal(requestElement, responseDocument); if (responseElement != null) { diff --git a/core/src/main/java/org/springframework/ws/server/endpoint/AbstractJDomPayloadEndpoint.java b/core/src/main/java/org/springframework/ws/server/endpoint/AbstractJDomPayloadEndpoint.java index 5c63582f..55cc69b6 100644 --- a/core/src/main/java/org/springframework/ws/server/endpoint/AbstractJDomPayloadEndpoint.java +++ b/core/src/main/java/org/springframework/ws/server/endpoint/AbstractJDomPayloadEndpoint.java @@ -37,9 +37,12 @@ import org.springframework.xml.transform.TransformerObjectSupport; public abstract class AbstractJDomPayloadEndpoint extends TransformerObjectSupport implements PayloadEndpoint { public final Source invoke(Source request) throws Exception { - JDOMResult jdomResult = new JDOMResult(); - transform(request, jdomResult); - Element requestElement = jdomResult.getDocument().getRootElement(); + Element requestElement = null; + if (request != null) { + JDOMResult jdomResult = new JDOMResult(); + transform(request, jdomResult); + requestElement = jdomResult.getDocument().getRootElement(); + } Element responseElement = invokeInternal(requestElement); return responseElement != null ? new JDOMSource(responseElement) : null; } diff --git a/core/src/main/java/org/springframework/ws/server/endpoint/AbstractSaxPayloadEndpoint.java b/core/src/main/java/org/springframework/ws/server/endpoint/AbstractSaxPayloadEndpoint.java index 500bff1c..2407fe62 100644 --- a/core/src/main/java/org/springframework/ws/server/endpoint/AbstractSaxPayloadEndpoint.java +++ b/core/src/main/java/org/springframework/ws/server/endpoint/AbstractSaxPayloadEndpoint.java @@ -37,31 +37,39 @@ import org.xml.sax.ContentHandler; public abstract class AbstractSaxPayloadEndpoint extends TransformerObjectSupport implements PayloadEndpoint { /** - * Invokes the provided ContentHandler and LexicalHandler on the given request. After - * parsing has been done, the provided response is returned. + * Invokes the provided ContentHandler on the given request. After parsing has been done, the provided + * response is returned. * * @see #createContentHandler() * @see #getResponse(org.xml.sax.ContentHandler) */ public final Source invoke(Source request) throws Exception { - ContentHandler contentHandler = createContentHandler(); - SAXResult result = new SAXResult(contentHandler); - transform(request, result); + ContentHandler contentHandler = null; + if (request != null) { + contentHandler = createContentHandler(); + SAXResult result = new SAXResult(contentHandler); + transform(request, result); + } return getResponse(contentHandler); } /** * Returns the SAX ContentHandler used to parse the incoming request payload. A new instance should be * created for each call, because of thread-safety. The content handler can be used to hold request-specific state. + *

+ * If an incoming message does not contain a payload, this method will not be invoked. * * @return a SAX content handler to be used for parsing */ protected abstract ContentHandler createContentHandler() throws Exception; /** - * Returns the response to be given, if any. This method is called after the request payload has been parse using - * the SAX ContentHandler. The passed ContentHandler is created by - * createContentHandler: it can be used to hold request-specific state. + * Returns the response to be given, if any. This method is called after the request payload has been parsed using + * the SAX ContentHandler. The passed ContentHandler is created by {@link + * #createContentHandler()}: it can be used to hold request-specific state. + *

+ * If an incoming message does not contain a payload, this method will be invoked with null as content + * handler. * * @param contentHandler the content handler used to parse the request */ diff --git a/core/src/main/java/org/springframework/ws/server/endpoint/AbstractXomPayloadEndpoint.java b/core/src/main/java/org/springframework/ws/server/endpoint/AbstractXomPayloadEndpoint.java index 549efaf4..a0d194ee 100644 --- a/core/src/main/java/org/springframework/ws/server/endpoint/AbstractXomPayloadEndpoint.java +++ b/core/src/main/java/org/springframework/ws/server/endpoint/AbstractXomPayloadEndpoint.java @@ -112,10 +112,12 @@ public abstract class AbstractXomPayloadEndpoint extends TransformerObjectSuppor private Source invokeUsingReflection(Source request) throws Exception { try { - Result xomResult = createXomResult(); - transform(request, xomResult); - Element requestElement = getRequestElement(xomResult); - + Element requestElement = null; + if (request != null) { + Result xomResult = createXomResult(); + transform(request, xomResult); + requestElement = getRequestElement(xomResult); + } Element responseElement = invokeInternal(requestElement); return responseElement != null ? createXomSource(responseElement) : null; } @@ -134,20 +136,21 @@ public abstract class AbstractXomPayloadEndpoint extends TransformerObjectSuppor } private Source invokeUsingTransformation(Source request) throws Exception { - logger.debug("Using transformations"); Element requestElement = null; - if (request instanceof DOMSource) { - requestElement = handleDomSource(request); - } - else if (request instanceof SAXSource) { - requestElement = handleSaxSource(request); - } - else if (request instanceof StreamSource) { - requestElement = handleStreamSource(request); - } - else { - throw new IllegalArgumentException( - "Source [" + request.getClass().getName() + "] is neither SAXSource, DOMSource, nor StreamSource"); + if (request != null) { + if (request instanceof DOMSource) { + requestElement = handleDomSource(request); + } + else if (request instanceof SAXSource) { + requestElement = handleSaxSource(request); + } + else if (request instanceof StreamSource) { + requestElement = handleStreamSource(request); + } + else { + throw new IllegalArgumentException("Source [" + request.getClass().getName() + + "] is neither SAXSource, DOMSource, nor StreamSource"); + } } Element responseElement = invokeInternal(requestElement); if (responseElement != null) { diff --git a/core/src/main/java/org/springframework/ws/server/endpoint/PayloadEndpoint.java b/core/src/main/java/org/springframework/ws/server/endpoint/PayloadEndpoint.java index c3c7ae67..782d2f5b 100644 --- a/core/src/main/java/org/springframework/ws/server/endpoint/PayloadEndpoint.java +++ b/core/src/main/java/org/springframework/ws/server/endpoint/PayloadEndpoint.java @@ -20,18 +20,18 @@ import javax.xml.transform.Source; /** * Defines the basic contract for Web Services interested in just the message payload. - * - *

The main entrypoint is {@link #invoke(Source)}, which gets invoked with the contents of the requesting message. + *

+ * The main entrypoint is {@link #invoke(Source)}, which gets invoked with the contents of the requesting message. * * @author Arjen Poutsma */ public interface PayloadEndpoint { /** - * Invokes an operation. + * Invokes the endpoint with the given request payload, and possibly returns a response. * - * @param request the request message - * @return the response message, may be null + * @param request the payload of the request message, may be null + * @return the payload of the response message, may be null to indicate no response * @throws Exception if an exception occurs */ Source invoke(Source request) throws Exception; diff --git a/core/src/test/java/org/springframework/ws/server/endpoint/AbstractPayloadEndpointTestCase.java b/core/src/test/java/org/springframework/ws/server/endpoint/AbstractPayloadEndpointTestCase.java index f59a0126..818da926 100644 --- a/core/src/test/java/org/springframework/ws/server/endpoint/AbstractPayloadEndpointTestCase.java +++ b/core/src/test/java/org/springframework/ws/server/endpoint/AbstractPayloadEndpointTestCase.java @@ -41,6 +41,12 @@ public abstract class AbstractPayloadEndpointTestCase extends AbstractEndpointTe assertNull("Response source returned", resultSource); } + public void testNoRequest() throws Exception { + endpoint = createNoRequestEndpoint(); + Source resultSource = endpoint.invoke(null); + assertNull("Response source returned", resultSource); + } + protected final void testSource(Source requestSource) throws Exception { Source responseSource = endpoint.invoke(requestSource); assertNotNull("No response source returned", responseSource); @@ -52,4 +58,6 @@ public abstract class AbstractPayloadEndpointTestCase extends AbstractEndpointTe protected abstract PayloadEndpoint createNoResponseEndpoint() throws Exception; protected abstract PayloadEndpoint createResponseEndpoint() throws Exception; + + protected abstract PayloadEndpoint createNoRequestEndpoint() throws Exception; } diff --git a/core/src/test/java/org/springframework/ws/server/endpoint/Dom4jPayloadEndpointTest.java b/core/src/test/java/org/springframework/ws/server/endpoint/Dom4jPayloadEndpointTest.java index 82cd71db..0a5581cb 100644 --- a/core/src/test/java/org/springframework/ws/server/endpoint/Dom4jPayloadEndpointTest.java +++ b/core/src/test/java/org/springframework/ws/server/endpoint/Dom4jPayloadEndpointTest.java @@ -43,5 +43,15 @@ public class Dom4jPayloadEndpointTest extends AbstractPayloadEndpointTestCase { }; } + protected PayloadEndpoint createNoRequestEndpoint() throws Exception { + return new AbstractDom4jPayloadEndpoint() { + + protected Element invokeInternal(Element requestElement, Document responseDocument) throws Exception { + assertNull("RequestElement passed", requestElement); + return null; + } + }; + } + } diff --git a/core/src/test/java/org/springframework/ws/server/endpoint/DomPayloadEndpointTest.java b/core/src/test/java/org/springframework/ws/server/endpoint/DomPayloadEndpointTest.java index cbf9257f..47ea5fcb 100644 --- a/core/src/test/java/org/springframework/ws/server/endpoint/DomPayloadEndpointTest.java +++ b/core/src/test/java/org/springframework/ws/server/endpoint/DomPayloadEndpointTest.java @@ -43,5 +43,13 @@ public class DomPayloadEndpointTest extends AbstractPayloadEndpointTestCase { }; } + protected PayloadEndpoint createNoRequestEndpoint() throws Exception { + return new AbstractDomPayloadEndpoint() { + protected Element invokeInternal(Element requestElement, Document responseDocument) throws Exception { + assertNull("RequestElement passed", requestElement); + return null; + } + }; + } } diff --git a/core/src/test/java/org/springframework/ws/server/endpoint/JDomPayloadEndpointTest.java b/core/src/test/java/org/springframework/ws/server/endpoint/JDomPayloadEndpointTest.java index 535e295c..6ca61960 100644 --- a/core/src/test/java/org/springframework/ws/server/endpoint/JDomPayloadEndpointTest.java +++ b/core/src/test/java/org/springframework/ws/server/endpoint/JDomPayloadEndpointTest.java @@ -41,4 +41,14 @@ public class JDomPayloadEndpointTest extends AbstractPayloadEndpointTestCase { } }; } + + protected PayloadEndpoint createNoRequestEndpoint() throws Exception { + return new AbstractJDomPayloadEndpoint() { + + protected Element invokeInternal(Element requestElement) throws Exception { + assertNull("RequestElement passed", requestElement); + return null; + } + }; + } } diff --git a/core/src/test/java/org/springframework/ws/server/endpoint/NonReflectiveXomPayloadEndpointTest.java b/core/src/test/java/org/springframework/ws/server/endpoint/NonReflectiveXomPayloadEndpointTest.java index 700954a2..ca80ed54 100644 --- a/core/src/test/java/org/springframework/ws/server/endpoint/NonReflectiveXomPayloadEndpointTest.java +++ b/core/src/test/java/org/springframework/ws/server/endpoint/NonReflectiveXomPayloadEndpointTest.java @@ -41,6 +41,16 @@ public class NonReflectiveXomPayloadEndpointTest extends AbstractPayloadEndpoint }; } + protected PayloadEndpoint createNoRequestEndpoint() throws Exception { + return new AbstractXomPayloadEndpoint(false) { + + protected Element invokeInternal(Element requestElement) throws Exception { + assertNull("RequestElement passed", requestElement); + return null; + } + }; + } + public void testStaxSourceEventReader() throws Exception { // overriden, because XOM doesn not support it } diff --git a/core/src/test/java/org/springframework/ws/server/endpoint/ReflectiveXomPayloadEndpointTest.java b/core/src/test/java/org/springframework/ws/server/endpoint/ReflectiveXomPayloadEndpointTest.java index ea6b6d9e..b4185893 100644 --- a/core/src/test/java/org/springframework/ws/server/endpoint/ReflectiveXomPayloadEndpointTest.java +++ b/core/src/test/java/org/springframework/ws/server/endpoint/ReflectiveXomPayloadEndpointTest.java @@ -41,5 +41,13 @@ public class ReflectiveXomPayloadEndpointTest extends AbstractPayloadEndpointTes }; } + protected PayloadEndpoint createNoRequestEndpoint() throws Exception { + return new AbstractXomPayloadEndpoint(true) { + protected Element invokeInternal(Element requestElement) throws Exception { + assertNull("RequestElement passed", requestElement); + return null; + } + }; + } } diff --git a/core/src/test/java/org/springframework/ws/server/endpoint/SaxPayloadEndpointTest.java b/core/src/test/java/org/springframework/ws/server/endpoint/SaxPayloadEndpointTest.java index 79b55af3..86e32478 100644 --- a/core/src/test/java/org/springframework/ws/server/endpoint/SaxPayloadEndpointTest.java +++ b/core/src/test/java/org/springframework/ws/server/endpoint/SaxPayloadEndpointTest.java @@ -52,6 +52,20 @@ public class SaxPayloadEndpointTest extends AbstractPayloadEndpointTestCase { }; } + protected PayloadEndpoint createNoRequestEndpoint() throws Exception { + return new AbstractSaxPayloadEndpoint() { + + protected ContentHandler createContentHandler() throws Exception { + fail("Not expected"); + return null; + } + + protected Source getResponse(ContentHandler contentHandler) throws Exception { + return null; + } + }; + } + private static class TestContentHandler extends DefaultHandler { public void endElement(String uri, String localName, String qName) throws SAXException {