From 596b82489b7875ad2500943bb5a848012d61a738 Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Mon, 20 Dec 2010 09:24:34 +0000 Subject: [PATCH] SWS-672 - Allow MarshallingPayloadMethodProcessor to have a null marshaller or unmarshaller --- .../MarshallingPayloadMethodProcessor.java | 68 +++++++++++++++---- ...MarshallingPayloadMethodProcessorTest.java | 53 ++++++++++++++- 2 files changed, 108 insertions(+), 13 deletions(-) diff --git a/core/src/main/java/org/springframework/ws/server/endpoint/adapter/method/MarshallingPayloadMethodProcessor.java b/core/src/main/java/org/springframework/ws/server/endpoint/adapter/method/MarshallingPayloadMethodProcessor.java index 80eaf816..9598efe7 100644 --- a/core/src/main/java/org/springframework/ws/server/endpoint/adapter/method/MarshallingPayloadMethodProcessor.java +++ b/core/src/main/java/org/springframework/ws/server/endpoint/adapter/method/MarshallingPayloadMethodProcessor.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -16,7 +16,6 @@ package org.springframework.ws.server.endpoint.adapter.method; -import org.springframework.beans.factory.InitializingBean; import org.springframework.core.MethodParameter; import org.springframework.oxm.GenericMarshaller; import org.springframework.oxm.GenericUnmarshaller; @@ -34,15 +33,33 @@ import org.springframework.ws.support.MarshallingUtils; * @author Arjen Poutsma * @since 2.0 */ -public class MarshallingPayloadMethodProcessor extends AbstractPayloadMethodProcessor implements InitializingBean { +public class MarshallingPayloadMethodProcessor extends AbstractPayloadMethodProcessor { private Marshaller marshaller; private Unmarshaller unmarshaller; + /** + * Creates a new {@code MarshallingPayloadMethodProcessor}. The {@link Marshaller} and {@link Unmarshaller} must be + * injected using properties. + * + * @see #setMarshaller(Marshaller) + * @see #setUnmarshaller(Unmarshaller) + */ public MarshallingPayloadMethodProcessor() { } + /** + * Creates a new {@code MarshallingPayloadMethodProcessor} with the given marshaller. If the given {@link + * Marshaller} also implements the {@link Unmarshaller} interface, it is used for both marshalling and + * unmarshalling. Otherwise, an exception is thrown. + *

+ * Note that all {@link Marshaller} implementations in Spring also implement the {@link Unmarshaller} interface, so + * that you can safely use this constructor. + * + * @param marshaller object used as marshaller and unmarshaller + * @throws IllegalArgumentException when {@code marshaller} does not implement the {@link Unmarshaller} interface + */ public MarshallingPayloadMethodProcessor(Marshaller marshaller) { Assert.notNull(marshaller, "marshaller must not be null"); Assert.isInstanceOf(Unmarshaller.class, marshaller); @@ -50,6 +67,12 @@ public class MarshallingPayloadMethodProcessor extends AbstractPayloadMethodProc setUnmarshaller((Unmarshaller) marshaller); } + /** + * Creates a new {@code MarshallingPayloadMethodProcessor} with the given marshaller and unmarshaller. + * + * @param marshaller the marshaller to use + * @param unmarshaller the unmarshaller to use + */ public MarshallingPayloadMethodProcessor(Marshaller marshaller, Unmarshaller unmarshaller) { Assert.notNull(marshaller, "marshaller must not be null"); Assert.notNull(unmarshaller, "unmarshaller must not be null"); @@ -57,30 +80,41 @@ public class MarshallingPayloadMethodProcessor extends AbstractPayloadMethodProc setUnmarshaller(unmarshaller); } + /** + * Returns the marshaller used for transforming objects into XML. + */ public Marshaller getMarshaller() { return marshaller; } + /** + * Sets the marshaller used for transforming objects into XML. + */ public void setMarshaller(Marshaller marshaller) { this.marshaller = marshaller; } + /** + * Returns the unmarshaller used for transforming XML into objects. + */ public Unmarshaller getUnmarshaller() { return unmarshaller; } + /** + * Sets the unmarshaller used for transforming XML into objects. + */ public void setUnmarshaller(Unmarshaller unmarshaller) { this.unmarshaller = unmarshaller; } - public void afterPropertiesSet() throws Exception { - Assert.notNull(marshaller, "marshaller is required"); - Assert.notNull(unmarshaller, "unmarshaller is required"); - } - @Override protected boolean supportsRequestPayloadParameter(MethodParameter parameter) { - if (unmarshaller instanceof GenericUnmarshaller) { + Unmarshaller unmarshaller = getUnmarshaller(); + if (unmarshaller == null) { + return false; + } + else if (unmarshaller instanceof GenericUnmarshaller) { return ((GenericUnmarshaller) unmarshaller).supports(parameter.getGenericParameterType()); } else { @@ -89,8 +123,11 @@ public class MarshallingPayloadMethodProcessor extends AbstractPayloadMethodProc } public Object resolveArgument(MessageContext messageContext, MethodParameter parameter) throws Exception { + Unmarshaller unmarshaller = getUnmarshaller(); + Assert.state(unmarshaller != null, "unmarshaller must not be null"); + WebServiceMessage request = messageContext.getRequest(); - Object argument = MarshallingUtils.unmarshal(getUnmarshaller(), request); + Object argument = MarshallingUtils.unmarshal(unmarshaller, request); if (logger.isDebugEnabled()) { logger.debug("Unmarshalled payload request to [" + argument + "]"); } @@ -99,7 +136,11 @@ public class MarshallingPayloadMethodProcessor extends AbstractPayloadMethodProc @Override protected boolean supportsResponsePayloadReturnType(MethodParameter returnType) { - if (marshaller instanceof GenericMarshaller) { + Marshaller marshaller = getMarshaller(); + if (marshaller == null) { + return false; + } + else if (marshaller instanceof GenericMarshaller) { GenericMarshaller genericMarshaller = (GenericMarshaller) marshaller; return genericMarshaller.supports(returnType.getGenericParameterType()); } @@ -110,11 +151,14 @@ public class MarshallingPayloadMethodProcessor extends AbstractPayloadMethodProc public void handleReturnValue(MessageContext messageContext, MethodParameter returnType, Object returnValue) throws Exception { + Marshaller marshaller = getMarshaller(); + Assert.state(marshaller != null, "marshaller must not be null"); + if (logger.isDebugEnabled()) { logger.debug("Marshalling [" + returnValue + "] to response payload"); } WebServiceMessage response = messageContext.getResponse(); - MarshallingUtils.marshal(getMarshaller(), returnValue, response); + MarshallingUtils.marshal(marshaller, returnValue, response); } } diff --git a/core/src/test/java/org/springframework/ws/server/endpoint/adapter/method/MarshallingPayloadMethodProcessorTest.java b/core/src/test/java/org/springframework/ws/server/endpoint/adapter/method/MarshallingPayloadMethodProcessorTest.java index 6ddac3a6..9fcd7768 100644 --- a/core/src/test/java/org/springframework/ws/server/endpoint/adapter/method/MarshallingPayloadMethodProcessorTest.java +++ b/core/src/test/java/org/springframework/ws/server/endpoint/adapter/method/MarshallingPayloadMethodProcessorTest.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -76,6 +76,19 @@ public class MarshallingPayloadMethodProcessorTest extends AbstractMethodArgumen verify(marshaller, unmarshaller); } + @Test + public void supportsParameterNoUnmarshallerSupported() { + processor = new MarshallingPayloadMethodProcessor(); + processor.setMarshaller(marshaller); + + replay(marshaller, unmarshaller); + + assertFalse("processor supports parameter with no unmarshaller set", + processor.supportsParameter(supportedParameter)); + + verify(marshaller, unmarshaller); + } + @Test public void supportsReturnTypeSupported() { expect(marshaller.supports(isA(Type.class))).andReturn(true); @@ -98,6 +111,20 @@ public class MarshallingPayloadMethodProcessorTest extends AbstractMethodArgumen verify(marshaller, unmarshaller); } + @Test + public void supportsReturnTypeNoMarshaller() { + processor = new MarshallingPayloadMethodProcessor(); + processor.setUnmarshaller(unmarshaller); + + replay(marshaller, unmarshaller); + + assertFalse("processor supports return type with no marshaller set", + processor.supportsReturnType(supportedReturnType)); + + verify(marshaller, unmarshaller); + } + + @Test public void resolveArgument() throws Exception { MyObject expected = new MyObject(); @@ -113,6 +140,17 @@ public class MarshallingPayloadMethodProcessorTest extends AbstractMethodArgumen verify(marshaller, unmarshaller); } + @Test(expected = IllegalStateException.class) + public void resolveArgumentNoUnmarshaller() throws Exception { + processor = new MarshallingPayloadMethodProcessor(); + processor.setMarshaller(marshaller); + + replay(marshaller, unmarshaller); + MessageContext messageContext = createMockMessageContext(); + + processor.resolveArgument(messageContext, supportedParameter); + } + @Test public void handleReturnValue() throws Exception { MyObject returnValue = new MyObject(); @@ -127,6 +165,19 @@ public class MarshallingPayloadMethodProcessorTest extends AbstractMethodArgumen verify(marshaller, unmarshaller); } + @Test(expected = IllegalStateException.class) + public void handleReturnValueNoMarshaller() throws Exception { + processor = new MarshallingPayloadMethodProcessor(); + processor.setUnmarshaller(unmarshaller); + + MyObject returnValue = new MyObject(); + + replay(marshaller, unmarshaller); + MessageContext messageContext = createMockMessageContext(); + + processor.handleReturnValue(messageContext, supportedReturnType, returnValue); + } + @ResponsePayload public MyObject method(@RequestPayload MyObject object) { return object;