SWS-351 - Arbitrary parameter injection for @Endpoints

This commit is contained in:
Arjen Poutsma
2010-05-07 08:01:42 +00:00
parent b66e20322b
commit f738427b74
8 changed files with 91 additions and 20 deletions

View File

@@ -30,8 +30,9 @@ import org.dom4j.io.DocumentResult;
import org.dom4j.io.DocumentSource;
/**
* Implementation of {@link org.springframework.ws.server.endpoint.adapter.method.MethodArgumentResolver} and {@link org.springframework.ws.server.endpoint.adapter.method.MethodReturnValueHandler} that supports dom4j
* {@linkplain Element elements}.
* Implementation of {@link org.springframework.ws.server.endpoint.adapter.method.MethodArgumentResolver
* MethodArgumentResolver} and {@link org.springframework.ws.server.endpoint.adapter.method.MethodReturnValueHandler
* MethodReturnValueHandler} that supports dom4j {@linkplain Element elements}.
*
* @author Arjen Poutsma
* @since 2.0

View File

@@ -28,8 +28,9 @@ import org.w3c.dom.Element;
import org.w3c.dom.Node;
/**
* Implementation of {@link org.springframework.ws.server.endpoint.adapter.method.MethodArgumentResolver} and {@link org.springframework.ws.server.endpoint.adapter.method.MethodReturnValueHandler} that supports W3C DOM
* {@linkplain Element elements}.
* Implementation of {@link org.springframework.ws.server.endpoint.adapter.method.MethodArgumentResolver
* MethodArgumentResolver} and {@link org.springframework.ws.server.endpoint.adapter.method.MethodReturnValueHandler
* MethodReturnValueHandler} that supports W3C DOM {@linkplain Element elements}.
*
* @author Arjen Poutsma
* @since 2.0

View File

@@ -30,8 +30,9 @@ import org.jdom.transform.JDOMSource;
import org.w3c.dom.Node;
/**
* Implementation of {@link org.springframework.ws.server.endpoint.adapter.method.MethodArgumentResolver} and {@link org.springframework.ws.server.endpoint.adapter.method.MethodReturnValueHandler} that supports JDOM
* {@linkplain Element elements}.
* Implementation of {@link org.springframework.ws.server.endpoint.adapter.method.MethodArgumentResolver
* MethodArgumentResolver} and {@link org.springframework.ws.server.endpoint.adapter.method.MethodReturnValueHandler
* MethodReturnValueHandler} that supports JDOM {@linkplain Element elements}.
*
* @author Arjen Poutsma
* @since 2.0

View File

@@ -36,8 +36,9 @@ import nu.xom.converters.DOMConverter;
import org.w3c.dom.DOMImplementation;
/**
* Implementation of {@link org.springframework.ws.server.endpoint.adapter.method.MethodArgumentResolver} and {@link org.springframework.ws.server.endpoint.adapter.method.MethodReturnValueHandler} that supports XOM {@linkplain
* Element elements}.
* Implementation of {@link org.springframework.ws.server.endpoint.adapter.method.MethodArgumentResolver
* MethodArgumentResolver} and {@link org.springframework.ws.server.endpoint.adapter.method.MethodReturnValueHandler
* MethodReturnValueHandler} that supports XOM {@linkplain Element elements}.
*
* @author Arjen Poutsma
* @since 2.0

View File

@@ -50,6 +50,13 @@ import org.xml.sax.XMLReader;
import org.xml.sax.ext.LexicalHandler;
/**
* Abstract base class for {@link org.springframework.ws.server.endpoint.adapter.method.MethodArgumentResolver
* MethodArgumentResolver} and {@link org.springframework.ws.server.endpoint.adapter.method.MethodReturnValueHandler
* MethodReturnValueHandler} implementations that use JAXB2. Creates {@link JAXBContext} object lazily, and offers
* {@linkplain #marshalToResponsePayload(org.springframework.ws.context.MessageContext, Class, Object) marshalling} and
* {@linkplain #unmarshalFromRequestPayload(org.springframework.ws.context.MessageContext, Class) unmarshalling}
* methods.
*
* @author Arjen Poutsma
* @since 2.0
*/
@@ -57,8 +64,19 @@ public abstract class AbstractJaxb2PayloadMethodProcessor extends AbstractPayloa
private final ConcurrentMap<Class, JAXBContext> jaxbContexts = new ConcurrentHashMap<Class, JAXBContext>();
protected void marshalToResponse(MessageContext messageContext, Class<?> clazz, Object jaxbElement)
/**
* Marshals the given {@code jaxbElement} to the response payload of the given message context.
*
* @param messageContext the message context to marshal to
* @param clazz the clazz to create a marshaller for
* @param jaxbElement the object to be marshalled
* @throws JAXBException in case of JAXB2 errors
*/
protected final void marshalToResponsePayload(MessageContext messageContext, Class<?> clazz, Object jaxbElement)
throws JAXBException {
Assert.notNull(messageContext, "'messageContext' must not be null");
Assert.notNull(clazz, "'clazz' must not be null");
Assert.notNull(jaxbElement, "'jaxbElement' must not be null");
if (logger.isDebugEnabled()) {
logger.debug("Marshalling [" + jaxbElement + "] to response payload");
}
@@ -77,7 +95,16 @@ public abstract class AbstractJaxb2PayloadMethodProcessor extends AbstractPayloa
return response != null ? response.getPayloadResult() : null;
}
protected Object unmarshalFromRequest(MessageContext messageContext, Class<?> clazz) throws JAXBException {
/**
* Unmarshals the request payload of the given message context.
*
* @param messageContext the message context to unmarshal from
* @param clazz the class to unmarshal
* @return the unmarshalled object, or {@code null} if the request has no payload
* @throws JAXBException in case of JAXB2 errors
*/
protected final Object unmarshalFromRequestPayload(MessageContext messageContext, Class<?> clazz)
throws JAXBException {
Source requestPayload = getRequestPayload(messageContext);
if (requestPayload == null) {
return null;
@@ -95,7 +122,15 @@ public abstract class AbstractJaxb2PayloadMethodProcessor extends AbstractPayloa
}
}
protected <T> JAXBElement<T> unmarshalElementFromRequest(MessageContext messageContext, Class<T> clazz)
/**
* Unmarshals the request payload of the given message context as {@link JAXBElement}.
*
* @param messageContext the message context to unmarshal from
* @param clazz the class to unmarshal
* @return the unmarshalled element, or {@code null} if the request has no payload
* @throws JAXBException in case of JAXB2 errors
*/
protected final <T> JAXBElement<T> unmarshalElementFromRequestPayload(MessageContext messageContext, Class<T> clazz)
throws JAXBException {
Source requestPayload = getRequestPayload(messageContext);
if (requestPayload == null) {

View File

@@ -24,7 +24,14 @@ import javax.xml.bind.JAXBException;
import org.springframework.core.MethodParameter;
import org.springframework.ws.context.MessageContext;
/** @author Arjen Poutsma */
/**
* Implementation of {@link org.springframework.ws.server.endpoint.adapter.method.MethodArgumentResolver
* MethodArgumentResolver} and {@link org.springframework.ws.server.endpoint.adapter.method.MethodReturnValueHandler
* MethodReturnValueHandler} that supports {@link JAXBElement} objects.
*
* @author Arjen Poutsma
* @since 2.0
*/
public class JaxbElementPayloadMethodProcessor extends AbstractJaxb2PayloadMethodProcessor {
@Override
@@ -38,7 +45,7 @@ public class JaxbElementPayloadMethodProcessor extends AbstractJaxb2PayloadMetho
throws JAXBException {
ParameterizedType parameterizedType = (ParameterizedType) parameter.getGenericParameterType();
Class<?> clazz = (Class) parameterizedType.getActualTypeArguments()[0];
return unmarshalElementFromRequest(messageContext, clazz);
return unmarshalElementFromRequestPayload(messageContext, clazz);
}
@Override
@@ -50,6 +57,6 @@ public class JaxbElementPayloadMethodProcessor extends AbstractJaxb2PayloadMetho
public void handleReturnValue(MessageContext messageContext, MethodParameter returnType, Object returnValue)
throws JAXBException {
JAXBElement<?> element = (JAXBElement<?>) returnValue;
marshalToResponse(messageContext, element.getDeclaredType(), element);
marshalToResponsePayload(messageContext, element.getDeclaredType(), element);
}
}

View File

@@ -24,7 +24,15 @@ import javax.xml.bind.annotation.XmlType;
import org.springframework.core.MethodParameter;
import org.springframework.ws.context.MessageContext;
/** @author Arjen Poutsma */
/**
* Implementation of {@link org.springframework.ws.server.endpoint.adapter.method.MethodArgumentResolver
* MethodArgumentResolver} and {@link org.springframework.ws.server.endpoint.adapter.method.MethodReturnValueHandler
* MethodReturnValueHandler} that supports parameters annotated with {@link XmlRootElement @XmlRootElement} or {@link
* XmlType @XmlType}, and return values annotated with {@link XmlRootElement @XmlRootElement}.
*
* @author Arjen Poutsma
* @since 2.0
*/
public class XmlRootElementPayloadMethodProcessor extends AbstractJaxb2PayloadMethodProcessor {
@Override
@@ -38,10 +46,10 @@ public class XmlRootElementPayloadMethodProcessor extends AbstractJaxb2PayloadMe
Class<?> parameterType = parameter.getParameterType();
if (parameterType.isAnnotationPresent(XmlRootElement.class)) {
return unmarshalFromRequest(messageContext, parameterType);
return unmarshalFromRequestPayload(messageContext, parameterType);
}
else {
JAXBElement<?> element = unmarshalElementFromRequest(messageContext, parameterType);
JAXBElement<?> element = unmarshalElementFromRequestPayload(messageContext, parameterType);
return element != null ? element.getValue() : null;
}
}
@@ -55,7 +63,7 @@ public class XmlRootElementPayloadMethodProcessor extends AbstractJaxb2PayloadMe
public void handleReturnValue(MessageContext messageContext, MethodParameter returnType, Object returnValue)
throws JAXBException {
Class<?> parameterType = returnType.getParameterType();
marshalToResponse(messageContext, parameterType, returnValue);
marshalToResponsePayload(messageContext, parameterType, returnValue);
}

View File

@@ -39,7 +39,6 @@ import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/** @author Arjen Poutsma */
public class JaxbElementPayloadMethodProcessorTest {
private JaxbElementPayloadMethodProcessor processor;
@@ -48,11 +47,14 @@ public class JaxbElementPayloadMethodProcessorTest {
private MethodParameter supportedReturnType;
private MethodParameter stringReturnType;
@Before
public void setUp() throws Exception {
processor = new JaxbElementPayloadMethodProcessor();
supportedParameter = new MethodParameter(getClass().getMethod("supported", JAXBElement.class), 0);
supportedReturnType = new MethodParameter(getClass().getMethod("supported", JAXBElement.class), -1);
stringReturnType = new MethodParameter(getClass().getMethod("string"), -1);
}
@Test
@@ -91,13 +93,28 @@ public class JaxbElementPayloadMethodProcessorTest {
assertXMLEqual("<type><string>Foo</string></type>", response.getPayloadAsString());
}
@Test
public void handleReturnValueString() throws JAXBException, IOException, SAXException {
MessageContext messageContext = new DefaultMessageContext(new MockWebServiceMessageFactory());
String s = "Foo";
JAXBElement<String> element = new JAXBElement<String>(new QName("string"), String.class, s);
processor.handleReturnValue(messageContext, stringReturnType, element);
assertTrue("context has no response", messageContext.hasResponse());
MockWebServiceMessage response = (MockWebServiceMessage) messageContext.getResponse();
assertXMLEqual("<string>Foo</string>", response.getPayloadAsString());
}
@ResponsePayload
public JAXBElement<MyType> supported(@RequestPayload JAXBElement<MyType> element) {
return element;
}
@ResponsePayload
public JAXBElement<String> string() {
return new JAXBElement<String>(new QName("string"), String.class, "Foo");
}
@XmlType
public static class MyType {