diff --git a/core/src/main/java/org/springframework/ws/server/endpoint/adapter/MessageEndpointAdapter.java b/core/src/main/java/org/springframework/ws/server/endpoint/adapter/MessageEndpointAdapter.java index 989b803e..df9727c2 100644 --- a/core/src/main/java/org/springframework/ws/server/endpoint/adapter/MessageEndpointAdapter.java +++ b/core/src/main/java/org/springframework/ws/server/endpoint/adapter/MessageEndpointAdapter.java @@ -18,10 +18,14 @@ package org.springframework.ws.server.endpoint.adapter; import org.springframework.ws.context.MessageContext; import org.springframework.ws.server.EndpointAdapter; +import org.springframework.ws.server.MessageDispatcher; import org.springframework.ws.server.endpoint.MessageEndpoint; +import org.springframework.ws.soap.server.SoapMessageDispatcher; /** * Adapter to use a MessageEndpoint as the endpoint for a EndpointInvocationChain. + *

+ * This adapter is registered by default by the {@link MessageDispatcher} and {@link SoapMessageDispatcher}. * * @author Arjen Poutsma * @see org.springframework.ws.server.EndpointInvocationChain diff --git a/sandbox/src/main/java/org/springframework/ws/server/endpoint/adapter/MessageMethodEndpointAdapter.java b/core/src/main/java/org/springframework/ws/server/endpoint/adapter/MessageMethodEndpointAdapter.java similarity index 88% rename from sandbox/src/main/java/org/springframework/ws/server/endpoint/adapter/MessageMethodEndpointAdapter.java rename to core/src/main/java/org/springframework/ws/server/endpoint/adapter/MessageMethodEndpointAdapter.java index d22eb593..6f79fe71 100644 --- a/sandbox/src/main/java/org/springframework/ws/server/endpoint/adapter/MessageMethodEndpointAdapter.java +++ b/core/src/main/java/org/springframework/ws/server/endpoint/adapter/MessageMethodEndpointAdapter.java @@ -19,7 +19,9 @@ package org.springframework.ws.server.endpoint.adapter; import java.lang.reflect.Method; import org.springframework.ws.context.MessageContext; +import org.springframework.ws.server.MessageDispatcher; import org.springframework.ws.server.endpoint.MethodEndpoint; +import org.springframework.ws.soap.server.SoapMessageDispatcher; /** * Adapter that supports endpoint methods that use marshalling. Supports methods with the following signature: @@ -28,6 +30,8 @@ import org.springframework.ws.server.endpoint.MethodEndpoint; * * I.e. methods that take a single {@link MessageContext} parameter, and return void. The method can have * any name, as long as it is mapped by an {@link org.springframework.ws.server.EndpointMapping}. + *

+ * This adapter is registered by default by the {@link MessageDispatcher} and {@link SoapMessageDispatcher}. * * @author Arjen Poutsma */ @@ -38,7 +42,6 @@ public class MessageMethodEndpointAdapter extends AbstractMethodEndpointAdapter Method method = methodEndpoint.getMethod(); return Void.TYPE.isAssignableFrom(method.getReturnType()) && method.getParameterTypes().length == 1 && MessageContext.class.isAssignableFrom(method.getParameterTypes()[0]); - } protected void invokeInternal(MessageContext messageContext, MethodEndpoint methodEndpoint) throws Exception { diff --git a/core/src/main/java/org/springframework/ws/server/endpoint/adapter/PayloadEndpointAdapter.java b/core/src/main/java/org/springframework/ws/server/endpoint/adapter/PayloadEndpointAdapter.java index 5506ebcb..ebf65c22 100644 --- a/core/src/main/java/org/springframework/ws/server/endpoint/adapter/PayloadEndpointAdapter.java +++ b/core/src/main/java/org/springframework/ws/server/endpoint/adapter/PayloadEndpointAdapter.java @@ -22,11 +22,15 @@ import javax.xml.transform.Transformer; import org.springframework.ws.WebServiceMessage; import org.springframework.ws.context.MessageContext; import org.springframework.ws.server.EndpointAdapter; +import org.springframework.ws.server.MessageDispatcher; import org.springframework.ws.server.endpoint.PayloadEndpoint; +import org.springframework.ws.soap.server.SoapMessageDispatcher; import org.springframework.xml.transform.TransformerObjectSupport; /** * Adapter to use a PayloadEndpoint as the endpoint for a EndpointInvocationChain. + *

+ * This adapter is registered by default by the {@link MessageDispatcher} and {@link SoapMessageDispatcher}. * * @author Arjen Poutsma * @see org.springframework.ws.server.endpoint.PayloadEndpoint diff --git a/sandbox/src/main/java/org/springframework/ws/server/endpoint/adapter/PayloadMethodEndpointAdapter.java b/core/src/main/java/org/springframework/ws/server/endpoint/adapter/PayloadMethodEndpointAdapter.java similarity index 91% rename from sandbox/src/main/java/org/springframework/ws/server/endpoint/adapter/PayloadMethodEndpointAdapter.java rename to core/src/main/java/org/springframework/ws/server/endpoint/adapter/PayloadMethodEndpointAdapter.java index 9da5e6d6..d802625b 100644 --- a/sandbox/src/main/java/org/springframework/ws/server/endpoint/adapter/PayloadMethodEndpointAdapter.java +++ b/core/src/main/java/org/springframework/ws/server/endpoint/adapter/PayloadMethodEndpointAdapter.java @@ -22,7 +22,9 @@ import javax.xml.transform.Transformer; import org.springframework.ws.WebServiceMessage; import org.springframework.ws.context.MessageContext; +import org.springframework.ws.server.MessageDispatcher; import org.springframework.ws.server.endpoint.MethodEndpoint; +import org.springframework.ws.soap.server.SoapMessageDispatcher; /** * Adapter that supports endpoint methods that use marshalling. Supports methods with the following signature: @@ -35,6 +37,8 @@ import org.springframework.ws.server.endpoint.MethodEndpoint; * * I.e. methods that take a single {@link Source} parameter, and return either void or a {@link Source}. * The method can have any name, as long as it is mapped by an {@link org.springframework.ws.server.EndpointMapping}. + *

+ * This adapter is registered by default by the {@link MessageDispatcher} and {@link SoapMessageDispatcher}. * * @author Arjen Poutsma */ diff --git a/sandbox/src/main/java/org/springframework/ws/server/endpoint/mapping/SimpleMethodEndpointMapping.java b/core/src/main/java/org/springframework/ws/server/endpoint/mapping/SimpleMethodEndpointMapping.java similarity index 57% rename from sandbox/src/main/java/org/springframework/ws/server/endpoint/mapping/SimpleMethodEndpointMapping.java rename to core/src/main/java/org/springframework/ws/server/endpoint/mapping/SimpleMethodEndpointMapping.java index 18fac8dc..18c7a19f 100644 --- a/sandbox/src/main/java/org/springframework/ws/server/endpoint/mapping/SimpleMethodEndpointMapping.java +++ b/core/src/main/java/org/springframework/ws/server/endpoint/mapping/SimpleMethodEndpointMapping.java @@ -17,29 +17,41 @@ package org.springframework.ws.server.endpoint.mapping; import java.lang.reflect.Method; -import javax.xml.transform.Transformer; +import javax.xml.namespace.QName; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMResult; -import javax.xml.transform.dom.DOMSource; import org.springframework.beans.factory.InitializingBean; import org.springframework.util.Assert; import org.springframework.ws.WebServiceMessage; import org.springframework.ws.context.MessageContext; -import org.w3c.dom.Element; -import org.w3c.dom.Node; +import org.springframework.ws.server.endpoint.mapping.support.PayloadRootUtils; /** - * Simple subclass of {@link AbstractMethodEndpointMapping} that maps to all methods that start with a prefix, and end - * with a suffix. Endpoint beans are registered using the endpoints property. + * Simple subclass of {@link AbstractMethodEndpointMapping} that maps from the local name of the request payload to + * methods.Endpoint beans are registered using the endpoints property; the endpoint methods that start with + * methodPrefix and end with methodSuffix will be registered. + *

+ * Endpoints typically have the following form: + *

+ * public class MyEndpoint{
+ * 

+ * public Source handleMyMessage(Source source) { + * ... + * } + * } + *

+ * This method will handle any message that has the MyMessage as a payload root local name. * * @author Arjen Poutsma + * @see #setEndpoints(Object[]) */ public class SimpleMethodEndpointMapping extends AbstractMethodEndpointMapping implements InitializingBean { + /** Default method prefix. */ public static final String DEFAULT_METHOD_PREFIX = "handle"; + /** Default method suffix. */ public static final String DEFAULT_METHOD_SUFFIX = ""; private Object[] endpoints; @@ -50,11 +62,23 @@ public class SimpleMethodEndpointMapping extends AbstractMethodEndpointMapping i private TransformerFactory transformerFactory; - /** Sets the endpoints */ + public Object[] getEndpoints() { + return endpoints; + } + + /** + * Sets the endpoints. The endpoint methods that start with methodPrefix and end with + * methodSuffix will be registered. + */ public void setEndpoints(Object[] endpoints) { this.endpoints = endpoints; } + /** Returns the method prefix. */ + public String getMethodPrefix() { + return methodPrefix; + } + /** * Sets the method prefix. All methods with names starting with this string will be registered. Default is * "handle". @@ -65,6 +89,11 @@ public class SimpleMethodEndpointMapping extends AbstractMethodEndpointMapping i this.methodPrefix = methodPrefix; } + /** Returns the method suffix. */ + public String getMethodSuffix() { + return methodSuffix; + } + /** * Sets the method suffix. All methods with names ending with this string will be registered. Default is "" (i.e. no * suffix). @@ -75,42 +104,31 @@ public class SimpleMethodEndpointMapping extends AbstractMethodEndpointMapping i this.methodSuffix = methodSuffix; } - public void afterPropertiesSet() throws Exception { - Assert.notEmpty(endpoints, "endpoints is required"); + public final void afterPropertiesSet() throws Exception { + Assert.notEmpty(getEndpoints(), "'endpoints' is required"); transformerFactory = TransformerFactory.newInstance(); - for (int i = 0; i < endpoints.length; i++) { - registerMethods(endpoints[i]); + for (int i = 0; i < getEndpoints().length; i++) { + registerMethods(getEndpoints()[i]); } } /** Returns the name of the given method, with the prefix and suffix stripped off. */ protected String getLookupKeyForMethod(Method method) { String methodName = method.getName(); - if (methodName.startsWith(methodPrefix) && methodName.endsWith(methodSuffix)) { - return methodName.substring(methodPrefix.length(), methodName.length() - methodSuffix.length()); + String prefix = getMethodPrefix(); + String suffix = getMethodSuffix(); + if (methodName.startsWith(prefix) && methodName.endsWith(suffix)) { + return methodName.substring(prefix.length(), methodName.length() - suffix.length()); } else { return null; } } + /** Returns the local part of the payload root element of the request. */ protected String getLookupKeyForMessage(MessageContext messageContext) throws TransformerException { - Element payloadElement = getMessagePayloadElement(messageContext.getRequest()); - return payloadElement.getLocalName(); + WebServiceMessage request = messageContext.getRequest(); + QName rootQName = PayloadRootUtils.getPayloadRootQName(request.getPayloadSource(), transformerFactory); + return rootQName.getLocalPart(); } - - private Element getMessagePayloadElement(WebServiceMessage message) throws TransformerException { - if (message.getPayloadSource() instanceof DOMSource) { - DOMSource domSource = (DOMSource) message.getPayloadSource(); - if (domSource.getNode().getNodeType() == Node.ELEMENT_NODE) { - return (Element) domSource.getNode(); - } - } - Transformer transformer = transformerFactory.newTransformer(); - DOMResult domResult = new DOMResult(); - transformer.transform(message.getPayloadSource(), domResult); - return (Element) domResult.getNode().getFirstChild(); - } - - } diff --git a/core/src/main/resources/org/springframework/ws/server/MessageDispatcher.properties b/core/src/main/resources/org/springframework/ws/server/MessageDispatcher.properties index 8eeecbfd..0c803ace 100644 --- a/core/src/main/resources/org/springframework/ws/server/MessageDispatcher.properties +++ b/core/src/main/resources/org/springframework/ws/server/MessageDispatcher.properties @@ -3,4 +3,6 @@ # Not meant to be customized by application developers. org.springframework.ws.server.EndpointAdapter=org.springframework.ws.server.endpoint.adapter.MessageEndpointAdapter,\ - org.springframework.ws.server.endpoint.adapter.PayloadEndpointAdapter \ No newline at end of file + org.springframework.ws.server.endpoint.adapter.PayloadEndpointAdapter,\ + org.springframework.ws.server.endpoint.adapter.MessageMethodEndpointAdapter,\ + org.springframework.ws.server.endpoint.adapter.PayloadMethodEndpointAdapter diff --git a/core/src/main/resources/org/springframework/ws/soap/server/SoapMessageDispatcher.properties b/core/src/main/resources/org/springframework/ws/soap/server/SoapMessageDispatcher.properties index 88856486..ae1537e5 100644 --- a/core/src/main/resources/org/springframework/ws/soap/server/SoapMessageDispatcher.properties +++ b/core/src/main/resources/org/springframework/ws/soap/server/SoapMessageDispatcher.properties @@ -3,5 +3,8 @@ # Not meant to be customized by application developers. org.springframework.ws.server.EndpointAdapter=org.springframework.ws.server.endpoint.adapter.MessageEndpointAdapter,\ - org.springframework.ws.server.endpoint.adapter.PayloadEndpointAdapter + org.springframework.ws.server.endpoint.adapter.PayloadEndpointAdapter,\ + org.springframework.ws.server.endpoint.adapter.MessageMethodEndpointAdapter,\ + org.springframework.ws.server.endpoint.adapter.PayloadMethodEndpointAdapter + org.springframework.ws.server.EndpointExceptionResolver=org.springframework.ws.soap.server.endpoint.SimpleSoapExceptionResolver \ No newline at end of file diff --git a/sandbox/src/test/java/org/springframework/ws/server/endpoint/adapter/MessageMethodEndpointAdapterTest.java b/core/src/test/java/org/springframework/ws/server/endpoint/adapter/MessageMethodEndpointAdapterTest.java similarity index 78% rename from sandbox/src/test/java/org/springframework/ws/server/endpoint/adapter/MessageMethodEndpointAdapterTest.java rename to core/src/test/java/org/springframework/ws/server/endpoint/adapter/MessageMethodEndpointAdapterTest.java index 1f35f01f..20c73915 100644 --- a/sandbox/src/test/java/org/springframework/ws/server/endpoint/adapter/MessageMethodEndpointAdapterTest.java +++ b/core/src/test/java/org/springframework/ws/server/endpoint/adapter/MessageMethodEndpointAdapterTest.java @@ -16,8 +16,6 @@ package org.springframework.ws.server.endpoint.adapter; -import java.lang.reflect.Method; - import junit.framework.TestCase; import org.springframework.ws.MockWebServiceMessageFactory; import org.springframework.ws.context.DefaultMessageContext; @@ -38,25 +36,22 @@ public class MessageMethodEndpointAdapterTest extends TestCase { } public void testSupported() throws NoSuchMethodException { - Method noResponse = getClass().getMethod("supported", new Class[]{MessageContext.class}); - MethodEndpoint methodEndpoint = new MethodEndpoint(this, noResponse); + MethodEndpoint methodEndpoint = new MethodEndpoint(this, "supported", new Class[]{MessageContext.class}); assertTrue("Method unsupported", adapter.supportsInternal(methodEndpoint)); } public void testUnsupportedMethodMultipleParams() throws NoSuchMethodException { - Method unsupported = getClass() - .getMethod("unsupportedMultipleParams", new Class[]{MessageContext.class, MessageContext.class}); - assertFalse("Method supported", adapter.supportsInternal(new MethodEndpoint(this, unsupported))); + assertFalse("Method supported", adapter.supportsInternal(new MethodEndpoint(this, "unsupportedMultipleParams", + new Class[]{MessageContext.class, MessageContext.class}))); } public void testUnsupportedMethodWrongParam() throws NoSuchMethodException { - Method unsupported = getClass().getMethod("unsupportedWrongParam", new Class[]{String.class}); - assertFalse("Method supported", adapter.supportsInternal(new MethodEndpoint(this, unsupported))); + assertFalse("Method supported", + adapter.supportsInternal(new MethodEndpoint(this, "unsupportedWrongParam", new Class[]{String.class}))); } public void testInvokeSupported() throws Exception { - Method supported = getClass().getMethod("supported", new Class[]{MessageContext.class}); - MethodEndpoint methodEndpoint = new MethodEndpoint(this, supported); + MethodEndpoint methodEndpoint = new MethodEndpoint(this, "supported", new Class[]{MessageContext.class}); assertFalse("Method invoked", supportedInvoked); adapter.invoke(messageContext, methodEndpoint); assertTrue("Method not invoked", supportedInvoked); diff --git a/sandbox/src/test/java/org/springframework/ws/server/endpoint/adapter/PayloadMethodEndpointAdapterTest.java b/core/src/test/java/org/springframework/ws/server/endpoint/adapter/PayloadMethodEndpointAdapterTest.java similarity index 78% rename from sandbox/src/test/java/org/springframework/ws/server/endpoint/adapter/PayloadMethodEndpointAdapterTest.java rename to core/src/test/java/org/springframework/ws/server/endpoint/adapter/PayloadMethodEndpointAdapterTest.java index e1336f4e..ea4aa2ef 100644 --- a/sandbox/src/test/java/org/springframework/ws/server/endpoint/adapter/PayloadMethodEndpointAdapterTest.java +++ b/core/src/test/java/org/springframework/ws/server/endpoint/adapter/PayloadMethodEndpointAdapterTest.java @@ -16,7 +16,6 @@ package org.springframework.ws.server.endpoint.adapter; -import java.lang.reflect.Method; import javax.xml.transform.Source; import junit.framework.TestCase; @@ -43,35 +42,32 @@ public class PayloadMethodEndpointAdapterTest extends TestCase { } public void testSupportedNoResponse() throws NoSuchMethodException { - Method noResponse = getClass().getMethod("noResponse", new Class[]{Source.class}); - MethodEndpoint methodEndpoint = new MethodEndpoint(this, noResponse); + MethodEndpoint methodEndpoint = new MethodEndpoint(this, "noResponse", new Class[]{Source.class}); assertTrue("Method unsupported", adapter.supportsInternal(methodEndpoint)); } public void testSupportedResponse() throws NoSuchMethodException { - Method response = getClass().getMethod("response", new Class[]{Source.class}); - MethodEndpoint methodEndpoint = new MethodEndpoint(this, response); + MethodEndpoint methodEndpoint = new MethodEndpoint(this, "response", new Class[]{Source.class}); assertTrue("Method unsupported", adapter.supportsInternal(methodEndpoint)); } public void testUnsupportedMethodMultipleParams() throws NoSuchMethodException { - Method unsupported = getClass().getMethod("unsupportedMultipleParams", new Class[]{Source.class, Source.class}); - assertFalse("Method supported", adapter.supportsInternal(new MethodEndpoint(this, unsupported))); + assertFalse("Method supported", adapter.supportsInternal( + new MethodEndpoint(this, "unsupportedMultipleParams", new Class[]{Source.class, Source.class}))); } public void testUnsupportedMethodWrongReturnType() throws NoSuchMethodException { - Method unsupported = getClass().getMethod("unsupportedWrongReturnType", new Class[]{Source.class}); - assertFalse("Method supported", adapter.supportsInternal(new MethodEndpoint(this, unsupported))); + assertFalse("Method supported", adapter.supportsInternal( + new MethodEndpoint(this, "unsupportedWrongReturnType", new Class[]{Source.class}))); } public void testUnsupportedMethodWrongParam() throws NoSuchMethodException { - Method unsupported = getClass().getMethod("unsupportedWrongParam", new Class[]{String.class}); - assertFalse("Method supported", adapter.supportsInternal(new MethodEndpoint(this, unsupported))); + assertFalse("Method supported", + adapter.supportsInternal(new MethodEndpoint(this, "unsupportedWrongParam", new Class[]{String.class}))); } public void testNoResponse() throws Exception { - Method noResponse = getClass().getMethod("noResponse", new Class[]{Source.class}); - MethodEndpoint methodEndpoint = new MethodEndpoint(this, noResponse); + MethodEndpoint methodEndpoint = new MethodEndpoint(this, "noResponse", new Class[]{Source.class}); assertFalse("Method invoked", noResponseInvoked); adapter.invoke(messageContext, methodEndpoint); assertTrue("Method not invoked", noResponseInvoked); @@ -80,8 +76,7 @@ public class PayloadMethodEndpointAdapterTest extends TestCase { public void testResponse() throws Exception { WebServiceMessage request = new MockWebServiceMessage(""); messageContext = new DefaultMessageContext(request, new MockWebServiceMessageFactory()); - Method response = getClass().getMethod("response", new Class[]{Source.class}); - MethodEndpoint methodEndpoint = new MethodEndpoint(this, response); + MethodEndpoint methodEndpoint = new MethodEndpoint(this, "response", new Class[]{Source.class}); assertFalse("Method invoked", responseInvoked); adapter.invoke(messageContext, methodEndpoint); assertTrue("Method not invoked", responseInvoked); @@ -89,7 +84,6 @@ public class PayloadMethodEndpointAdapterTest extends TestCase { public void noResponse(Source request) { noResponseInvoked = true; - } public Source response(Source request) { diff --git a/sandbox/src/test/java/org/springframework/ws/server/endpoint/mapping/SimpleMethodEndpointMappingTest.java b/core/src/test/java/org/springframework/ws/server/endpoint/mapping/SimpleMethodEndpointMappingTest.java similarity index 97% rename from sandbox/src/test/java/org/springframework/ws/server/endpoint/mapping/SimpleMethodEndpointMappingTest.java rename to core/src/test/java/org/springframework/ws/server/endpoint/mapping/SimpleMethodEndpointMappingTest.java index b029b4ba..c90d52ba 100644 --- a/sandbox/src/test/java/org/springframework/ws/server/endpoint/mapping/SimpleMethodEndpointMappingTest.java +++ b/core/src/test/java/org/springframework/ws/server/endpoint/mapping/SimpleMethodEndpointMappingTest.java @@ -37,6 +37,7 @@ public class SimpleMethodEndpointMappingTest extends TestCase { public void testRegistration() throws Exception { assertNotNull("Endpoint not registered", mapping.lookupEndpoint("MyRequest")); + assertNull("Endpoint registered", mapping.lookupEndpoint("request")); } public void testGetLookupKeyForMessageNoNamespace() throws Exception { diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 4f7c6ea5..82f71708 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -6,9 +6,13 @@ + Moved SimpleMethodEndpointMapping from sandbox + Moved PayloadMethodEndpointAdapter and MessageMethodEndpointAdapter from sandbox CommonsHttpMessageSender should expose setters for username and password - A MessageSender setter on WebServicesGatewaySupport - A SOAP:Fault does not set the the response code to 500 + A MessageSender setter on WebServicesGatewaySupport + A SOAP:Fault does not set the the response code to 500 Changing URL in CommonsHttpMessageSender