SWS-351 - Arbitrary parameter injection for @Endpoints

This commit is contained in:
Arjen Poutsma
2010-05-04 07:28:09 +00:00
parent 5d354f4f5b
commit 1ae679321d
6 changed files with 263 additions and 6 deletions

View File

@@ -0,0 +1,120 @@
/*
* Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* 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
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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;
import org.springframework.oxm.Marshaller;
import org.springframework.oxm.Unmarshaller;
import org.springframework.util.Assert;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.support.MarshallingUtils;
/**
* Implementation of {@link MethodArgumentResolver} and {@link MethodReturnValueHandler} that uses {@link Marshaller}
* and {@link Unmarshaller} to support marshalled objects.
*
* @author Arjen Poutsma
* @since 2.0
*/
public class MarshallingPayloadMethodProcessor extends AbstractPayloadMethodProcessor implements InitializingBean {
private Marshaller marshaller;
private Unmarshaller unmarshaller;
public MarshallingPayloadMethodProcessor() {
}
public MarshallingPayloadMethodProcessor(Marshaller marshaller) {
Assert.notNull(marshaller, "marshaller must not be null");
Assert.isInstanceOf(Unmarshaller.class, marshaller);
setMarshaller(marshaller);
setUnmarshaller((Unmarshaller) marshaller);
}
public MarshallingPayloadMethodProcessor(Marshaller marshaller, Unmarshaller unmarshaller) {
Assert.notNull(marshaller, "marshaller must not be null");
Assert.notNull(unmarshaller, "unmarshaller must not be null");
setMarshaller(marshaller);
setUnmarshaller(unmarshaller);
}
public Marshaller getMarshaller() {
return marshaller;
}
public void setMarshaller(Marshaller marshaller) {
this.marshaller = marshaller;
}
public Unmarshaller getUnmarshaller() {
return unmarshaller;
}
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) {
return ((GenericUnmarshaller) unmarshaller).supports(parameter.getGenericParameterType());
}
else {
return unmarshaller.supports(parameter.getParameterType());
}
}
public Object resolveArgument(MessageContext messageContext, MethodParameter parameter) throws Exception {
WebServiceMessage request = messageContext.getRequest();
Object requestObject = MarshallingUtils.unmarshal(getUnmarshaller(), request);
if (logger.isDebugEnabled()) {
logger.debug("Unmarshalled payload request to [" + requestObject + "]");
}
return requestObject;
}
@Override
protected boolean supportsResponsePayloadReturnType(MethodParameter returnType) {
if (marshaller instanceof GenericMarshaller) {
GenericMarshaller genericMarshaller = (GenericMarshaller) marshaller;
return genericMarshaller.supports(returnType.getGenericParameterType());
}
else {
return marshaller.supports(returnType.getParameterType());
}
}
public void handleReturnValue(MessageContext messageContext, MethodParameter returnType, Object returnValue)
throws Exception {
if (logger.isDebugEnabled()) {
logger.debug("Marshalling [" + returnValue + "] to response payload");
}
WebServiceMessage response = messageContext.getResponse();
MarshallingUtils.marshal(getMarshaller(), returnValue, response);
}
}

View File

@@ -32,8 +32,7 @@ import org.springframework.xml.transform.TransformerObjectSupport;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.soap.SOAPFactory;
/** @author Arjen Poutsma */
public class AbstractMethodArgumentResolverTest extends TransformerObjectSupport {
public class AbstractMethodArgumentResolverTestCase extends TransformerObjectSupport {
protected static final String NAMESPACE_URI = "http://springframework.org/ws";

View File

@@ -29,7 +29,7 @@ import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public abstract class AbstractPayloadMethodProcessorTestCase extends AbstractMethodArgumentResolverTest {
public abstract class AbstractPayloadMethodProcessorTestCase extends AbstractMethodArgumentResolverTestCase {
private AbstractPayloadSourceMethodProcessor processor;

View File

@@ -0,0 +1,138 @@
/*
* Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* 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
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.server.endpoint.adapter.method;
import java.lang.reflect.Type;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import org.springframework.core.MethodParameter;
import org.springframework.oxm.GenericMarshaller;
import org.springframework.oxm.GenericUnmarshaller;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.server.endpoint.annotation.RequestPayload;
import org.springframework.ws.server.endpoint.annotation.ResponsePayload;
import org.junit.Before;
import org.junit.Test;
import static org.easymock.EasyMock.*;
import static org.junit.Assert.*;
public class MarshallingPayloadMethodProcessorTest extends AbstractMethodArgumentResolverTestCase {
private MarshallingPayloadMethodProcessor processor;
private GenericMarshaller marshaller;
private GenericUnmarshaller unmarshaller;
private MethodParameter supportedParameter;
private MethodParameter supportedReturnType;
@Before
public void setUp() throws Exception {
marshaller = createMock("marshaller", GenericMarshaller.class);
unmarshaller = createMock("unmarshaller", GenericUnmarshaller.class);
processor = new MarshallingPayloadMethodProcessor(marshaller, unmarshaller);
supportedParameter = new MethodParameter(getClass().getMethod("method", MyObject.class), 0);
supportedReturnType = new MethodParameter(getClass().getMethod("method", MyObject.class), -1);
}
@Test
public void supportsParameterSupported() {
expect(unmarshaller.supports(isA(Type.class))).andReturn(true);
replay(marshaller, unmarshaller);
assertTrue("processor does not support supported parameter", processor.supportsParameter(supportedParameter));
verify(marshaller, unmarshaller);
}
@Test
public void supportsParameterUnsupported() {
expect(unmarshaller.supports(isA(Type.class))).andReturn(false);
replay(marshaller, unmarshaller);
assertFalse("processor supports unsupported parameter", processor.supportsParameter(supportedParameter));
verify(marshaller, unmarshaller);
}
@Test
public void supportsReturnTypeSupported() {
expect(marshaller.supports(isA(Type.class))).andReturn(true);
replay(marshaller, unmarshaller);
assertTrue("processor does not support supported return type", processor.supportsReturnType(supportedReturnType));
verify(marshaller, unmarshaller);
}
@Test
public void supportsReturnTypeUnsupported() {
expect(marshaller.supports(isA(Type.class))).andReturn(false);
replay(marshaller, unmarshaller);
assertFalse("processor supports unsupported parameter", processor.supportsReturnType(supportedReturnType));
verify(marshaller, unmarshaller);
}
@Test
public void resolveArgument() throws Exception {
MyObject expected = new MyObject();
expect(unmarshaller.unmarshal(isA(Source.class))).andReturn(expected);
replay(marshaller, unmarshaller);
MessageContext messageContext = createMockMessageContext();
Object result = processor.resolveArgument(messageContext, supportedParameter);
assertEquals("Invalid return argument", expected, result);
verify(marshaller, unmarshaller);
}
@Test
public void handleReturnValue() throws Exception {
MyObject returnValue = new MyObject();
marshaller.marshal(eq(returnValue), isA(Result.class));
replay(marshaller, unmarshaller);
MessageContext messageContext = createMockMessageContext();
processor.handleReturnValue(messageContext, supportedReturnType, returnValue);
verify(marshaller, unmarshaller);
}
@ResponsePayload
public MyObject method(@RequestPayload MyObject object) {
return object;
}
public static class MyObject {
}
}

View File

@@ -34,7 +34,7 @@ import static org.junit.Assert.*;
/** @author Arjen Poutsma */
@SuppressWarnings("Since15")
public class StaxPayloadMethodArgumentResolverTest extends AbstractMethodArgumentResolverTest {
public class StaxPayloadMethodArgumentResolverTest extends AbstractMethodArgumentResolverTestCase {
private StaxPayloadMethodArgumentResolver resolver;

View File

@@ -18,7 +18,7 @@ package org.springframework.ws.soap.server.endpoint.adapter.method;
import org.springframework.core.MethodParameter;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.server.endpoint.adapter.method.AbstractMethodArgumentResolverTest;
import org.springframework.ws.server.endpoint.adapter.method.AbstractMethodArgumentResolverTestCase;
import org.springframework.ws.soap.SoapBody;
import org.springframework.ws.soap.SoapEnvelope;
import org.springframework.ws.soap.SoapHeader;
@@ -31,7 +31,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/** @author Arjen Poutsma */
public class SoapMethodArgumentResolverTest extends AbstractMethodArgumentResolverTest {
public class SoapMethodArgumentResolverTest extends AbstractMethodArgumentResolverTestCase {
private SoapMethodArgumentResolver resolver;