Fixed SWS-129: SimpleMethodEndpointMapping moved from sandbox.

This commit is contained in:
Arjen Poutsma
2007-05-30 20:56:11 +00:00
parent 3226f21ef3
commit 435b5ebfad
11 changed files with 95 additions and 63 deletions

View File

@@ -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 <code>MessageEndpoint</code> as the endpoint for a <code>EndpointInvocationChain</code>.
* <p/>
* This adapter is registered by default by the {@link MessageDispatcher} and {@link SoapMessageDispatcher}.
*
* @author Arjen Poutsma
* @see org.springframework.ws.server.EndpointInvocationChain

View File

@@ -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;
* </pre>
* I.e. methods that take a single {@link MessageContext} parameter, and return <code>void</code>. The method can have
* any name, as long as it is mapped by an {@link org.springframework.ws.server.EndpointMapping}.
* <p/>
* 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 {

View File

@@ -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 <code>PayloadEndpoint</code> as the endpoint for a <code>EndpointInvocationChain</code>.
* <p/>
* This adapter is registered by default by the {@link MessageDispatcher} and {@link SoapMessageDispatcher}.
*
* @author Arjen Poutsma
* @see org.springframework.ws.server.endpoint.PayloadEndpoint

View File

@@ -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;
* </pre>
* I.e. methods that take a single {@link Source} parameter, and return either <code>void</code> or a {@link Source}.
* The method can have any name, as long as it is mapped by an {@link org.springframework.ws.server.EndpointMapping}.
* <p/>
* This adapter is registered by default by the {@link MessageDispatcher} and {@link SoapMessageDispatcher}.
*
* @author Arjen Poutsma
*/

View File

@@ -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 <code>endpoints</code> property.
* Simple subclass of {@link AbstractMethodEndpointMapping} that maps from the local name of the request payload to
* methods.Endpoint beans are registered using the <code>endpoints</code> property; the endpoint methods that start with
* <code>methodPrefix</code> and end with <code>methodSuffix</code> will be registered.
* <p/>
* Endpoints typically have the following form:
* <pre>
* public class MyEndpoint{
* <p/>
* public Source handleMyMessage(Source source) {
* ...
* }
* }
* </pre>
* This method will handle any message that has the <code>MyMessage</code> 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 <code>methodPrefix</code> and end with
* <code>methodSuffix</code> 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
* "<code>handle</code>".
@@ -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();
}
}

View File

@@ -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
org.springframework.ws.server.endpoint.adapter.PayloadEndpointAdapter,\
org.springframework.ws.server.endpoint.adapter.MessageMethodEndpointAdapter,\
org.springframework.ws.server.endpoint.adapter.PayloadMethodEndpointAdapter

View File

@@ -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

View File

@@ -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);

View File

@@ -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("<request/>");
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) {

View File

@@ -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 {

View File

@@ -6,9 +6,13 @@
</properties>
<body>
<release version="1.0-rc2">
<action dev="poutsma" type="add" issue="SWS-129">Moved SimpleMethodEndpointMapping from sandbox</action>
<action dev="poutsma" type="add">Moved PayloadMethodEndpointAdapter and MessageMethodEndpointAdapter from sandbox</action>
<action dev="poutsma" type="add" issue="SWS-123">CommonsHttpMessageSender should expose setters for username and password</action>
<action dev="poutsma" type="add" issue="SWS-122">A MessageSender setter on WebServicesGatewaySupport</action>
<action dev="poutsma" type="fix" issue="SWS-128">A SOAP:Fault does not set the the response code to 500</action>
<action dev="poutsma" type="add"
issue="SWS-122">A MessageSender setter on WebServicesGatewaySupport</action>
<action dev="poutsma" type="fix"
issue="SWS-128">A SOAP:Fault does not set the the response code to 500</action>
</release>
<release version="1.0-rc1" date="2007-05-21">
<action dev="poutsma" type="add" issue="SWS-98">Changing URL in CommonsHttpMessageSender</action>