SWS-351 - Arbitrary parameter injection for @Endpoints
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user