diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/config/ServiceActivatorParser.java b/org.springframework.integration/src/main/java/org/springframework/integration/config/ServiceActivatorParser.java index 9d66415b13..9bd8add796 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/config/ServiceActivatorParser.java +++ b/org.springframework.integration/src/main/java/org/springframework/integration/config/ServiceActivatorParser.java @@ -16,9 +16,9 @@ package org.springframework.integration.config; -import org.springframework.integration.endpoint.DefaultServiceInvoker; import org.springframework.integration.endpoint.MessageEndpoint; import org.springframework.integration.endpoint.ServiceActivatorEndpoint; +import org.springframework.integration.message.MessageMappingMethodInvoker; /** * Parser for the <service-activator> element. @@ -34,7 +34,7 @@ public class ServiceActivatorParser extends AbstractEndpointParser { @Override protected Class getMethodInvokingAdapterClass() { - return DefaultServiceInvoker.class; + return MessageMappingMethodInvoker.class; } } diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/config/annotation/ServiceActivatorAnnotationPostProcessor.java b/org.springframework.integration/src/main/java/org/springframework/integration/config/annotation/ServiceActivatorAnnotationPostProcessor.java index 7d480127a3..a1d7616d2d 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/config/annotation/ServiceActivatorAnnotationPostProcessor.java +++ b/org.springframework.integration/src/main/java/org/springframework/integration/config/annotation/ServiceActivatorAnnotationPostProcessor.java @@ -21,9 +21,9 @@ import java.lang.reflect.Method; import org.springframework.integration.annotation.ServiceActivator; import org.springframework.integration.bus.MessageBus; import org.springframework.integration.endpoint.AbstractEndpoint; -import org.springframework.integration.endpoint.DefaultServiceInvoker; import org.springframework.integration.endpoint.ServiceActivatorEndpoint; -import org.springframework.integration.endpoint.ServiceInvoker; +import org.springframework.integration.message.MessageMappingMethodInvoker; +import org.springframework.integration.util.MethodInvoker; /** * Post-processor for Methods annotated with {@link ServiceActivator @ServiceActivator}. @@ -39,13 +39,13 @@ public class ServiceActivatorAnnotationPostProcessor extends AbstractMethodAnnot @Override protected Object createMethodInvokingAdapter(Object bean, Method method, ServiceActivator annotation) { - return new DefaultServiceInvoker(bean, method); + return new MessageMappingMethodInvoker(bean, method); } @Override protected AbstractEndpoint createEndpoint(Object originalBean, Object adapter) { - if (adapter instanceof ServiceInvoker) { - return new ServiceActivatorEndpoint((ServiceInvoker) adapter); + if (adapter instanceof MethodInvoker) { + return new ServiceActivatorEndpoint((MethodInvoker) adapter); } return null; } diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/endpoint/DefaultServiceInvoker.java b/org.springframework.integration/src/main/java/org/springframework/integration/endpoint/DefaultServiceInvoker.java deleted file mode 100644 index 3b5da4eaa1..0000000000 --- a/org.springframework.integration/src/main/java/org/springframework/integration/endpoint/DefaultServiceInvoker.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2002-2008 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.integration.endpoint; - -import java.lang.reflect.Method; - -import org.springframework.integration.message.Message; -import org.springframework.integration.message.MessageMappingMethodInvoker; - -/** - * @author Mark Fisher - */ -public class DefaultServiceInvoker extends MessageMappingMethodInvoker implements ServiceInvoker { - - public DefaultServiceInvoker(Object object, Method method) { - super(object, method); - } - - public DefaultServiceInvoker(Object object, String methodName) { - super(object, methodName); - } - - - public Object invoke(Message message) { - return this.invokeMethod(message); - } - -} diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/endpoint/ServiceActivatorEndpoint.java b/org.springframework.integration/src/main/java/org/springframework/integration/endpoint/ServiceActivatorEndpoint.java index 603793631c..025518cebf 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/endpoint/ServiceActivatorEndpoint.java +++ b/org.springframework.integration/src/main/java/org/springframework/integration/endpoint/ServiceActivatorEndpoint.java @@ -19,6 +19,8 @@ package org.springframework.integration.endpoint; import org.springframework.beans.factory.InitializingBean; import org.springframework.integration.handler.MessageHandler; import org.springframework.integration.message.Message; +import org.springframework.integration.message.MessageHandlingException; +import org.springframework.integration.util.MethodInvoker; import org.springframework.util.Assert; /** @@ -26,12 +28,12 @@ import org.springframework.util.Assert; */ public class ServiceActivatorEndpoint extends AbstractInOutEndpoint implements InitializingBean { - private final ServiceInvoker invoker; + private final MethodInvoker invoker; private final MessageHandler handler; - public ServiceActivatorEndpoint(ServiceInvoker invoker) { + public ServiceActivatorEndpoint(MethodInvoker invoker) { Assert.notNull(invoker, "invoker must not be null"); this.invoker = invoker; this.handler = null; @@ -53,7 +55,11 @@ public class ServiceActivatorEndpoint extends AbstractInOutEndpoint implements I @Override protected Object handle(Message message) { if (this.invoker != null) { - return this.invoker.invoke(message); + try { + return this.invoker.invokeMethod(message); + } catch (Exception e) { + throw new MessageHandlingException(message, "failure occurred in endpoint '" + this.getName() + "'", e); + } } return this.handler.handle(message); } diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/endpoint/ServiceInvoker.java b/org.springframework.integration/src/main/java/org/springframework/integration/endpoint/ServiceInvoker.java deleted file mode 100644 index c2b5bcec67..0000000000 --- a/org.springframework.integration/src/main/java/org/springframework/integration/endpoint/ServiceInvoker.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2002-2008 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.integration.endpoint; - -import org.springframework.integration.message.Message; - -/** - * @author Mark Fisher - */ -public interface ServiceInvoker { - - Object invoke(Message message); - -} diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/handler/MethodInvokingTarget.java b/org.springframework.integration/src/main/java/org/springframework/integration/handler/MethodInvokingTarget.java index 6c6121f62a..1a147ba221 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/handler/MethodInvokingTarget.java +++ b/org.springframework.integration/src/main/java/org/springframework/integration/handler/MethodInvokingTarget.java @@ -18,8 +18,8 @@ package org.springframework.integration.handler; import java.lang.reflect.Method; -import org.springframework.integration.endpoint.DefaultServiceInvoker; import org.springframework.integration.message.Message; +import org.springframework.integration.message.MessageMappingMethodInvoker; import org.springframework.integration.message.MessageTarget; import org.springframework.integration.message.MessagingException; @@ -28,7 +28,7 @@ import org.springframework.integration.message.MessagingException; * * @author Mark Fisher */ -public class MethodInvokingTarget extends DefaultServiceInvoker implements MessageTarget { +public class MethodInvokingTarget extends MessageMappingMethodInvoker implements MessageTarget { public MethodInvokingTarget(Object object, Method method) { super(object, method); diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/message/MessageMappingMethodInvoker.java b/org.springframework.integration/src/main/java/org/springframework/integration/message/MessageMappingMethodInvoker.java index acae956265..cb551368ce 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/message/MessageMappingMethodInvoker.java +++ b/org.springframework.integration/src/main/java/org/springframework/integration/message/MessageMappingMethodInvoker.java @@ -43,7 +43,7 @@ import org.springframework.util.StringUtils; * * @author Mark Fisher */ -public class MessageMappingMethodInvoker implements InitializingBean { +public class MessageMappingMethodInvoker implements MethodInvoker, InitializingBean { protected static final Log logger = LogFactory.getLog(MessageMappingMethodInvoker.class); @@ -121,28 +121,23 @@ public class MessageMappingMethodInvoker implements InitializingBean { } } - public Object invokeMethod(Message message) { - if (message == null || message.getPayload() == null) { - if (logger.isDebugEnabled()) { - logger.debug("received null message or payload"); - } - return null; - } + public Object invokeMethod(Object... args) { if (!this.initialized) { this.afterPropertiesSet(); } - if (this.invoker == null) { - return message.getPayload(); + if (ObjectUtils.isEmpty(args)) { + return null; } - Object args[] = null; - Object mappingResult = this.methodExpectsMessage - ? message : this.resolveParameters(message); - if (mappingResult != null && mappingResult.getClass().isArray() - && (Object.class.isAssignableFrom(mappingResult.getClass().getComponentType()))) { - args = (Object[]) mappingResult; - } - else { - args = new Object[] { mappingResult }; + Message message = null; + if (args.length == 1 && args[0] != null && (args[0] instanceof Message)) { + message = (Message) args[0]; + if (message.getPayload() == null) { + if (logger.isDebugEnabled()) { + logger.debug("received null payload"); + } + return null; + } + args = this.createArgumentArrayFromMessage(message); } try { Object result = null; @@ -151,8 +146,10 @@ public class MessageMappingMethodInvoker implements InitializingBean { } catch (NoSuchMethodException e) { try { - result = this.invoker.invokeMethod(message); - this.methodExpectsMessage = true; + if (message != null) { + result = this.invoker.invokeMethod(message); + this.methodExpectsMessage = true; + } } catch (NoSuchMethodException e2) { throw new MessageHandlingException(message, "unable to resolve method for args: " @@ -174,6 +171,20 @@ public class MessageMappingMethodInvoker implements InitializingBean { } } + private Object[] createArgumentArrayFromMessage(Message message) { + Object args[] = null; + Object mappingResult = this.methodExpectsMessage + ? message : this.resolveParameters(message); + if (mappingResult != null && mappingResult.getClass().isArray() + && (Object.class.isAssignableFrom(mappingResult.getClass().getComponentType()))) { + args = (Object[]) mappingResult; + } + else { + args = new Object[] { mappingResult }; + } + return args; + } + private Object[] resolveParameters(Message message) { if (this.parameterResolver != null) { return this.parameterResolver.resolveParameters(message); diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/config/annotation/MessagingAnnotationPostProcessorTests.java b/org.springframework.integration/src/test/java/org/springframework/integration/config/annotation/MessagingAnnotationPostProcessorTests.java index e48034a425..b6dca4e3de 100644 --- a/org.springframework.integration/src/test/java/org/springframework/integration/config/annotation/MessagingAnnotationPostProcessorTests.java +++ b/org.springframework.integration/src/test/java/org/springframework/integration/config/annotation/MessagingAnnotationPostProcessorTests.java @@ -45,13 +45,13 @@ import org.springframework.integration.channel.MessageChannel; import org.springframework.integration.channel.PollableChannel; import org.springframework.integration.channel.QueueChannel; import org.springframework.integration.endpoint.ServiceActivatorEndpoint; -import org.springframework.integration.endpoint.ServiceInvoker; import org.springframework.integration.message.Message; import org.springframework.integration.message.MessageSource; import org.springframework.integration.message.StringMessage; import org.springframework.integration.message.SubscribableSource; import org.springframework.integration.scheduling.PollingSchedule; import org.springframework.integration.scheduling.Schedule; +import org.springframework.integration.util.MethodInvoker; /** * @author Mark Fisher @@ -65,15 +65,15 @@ public class MessagingAnnotationPostProcessorTests { postProcessor.afterPropertiesSet(); HandlerAnnotatedBean bean = new HandlerAnnotatedBean(); Object result = postProcessor.postProcessAfterInitialization(bean, "testBean"); - assertTrue(result instanceof ServiceInvoker); + assertTrue(result instanceof MethodInvoker); } @Test - public void testSimpleHandlerWithContext() { + public void testSimpleHandlerWithContext() throws Exception { AbstractApplicationContext context = new ClassPathXmlApplicationContext( "serviceActivatorAnnotationPostProcessorTests.xml", this.getClass()); - ServiceInvoker invoker = (ServiceInvoker) context.getBean("testBean"); - String reply = (String) invoker.invoke(new StringMessage("world")); + MethodInvoker invoker = (MethodInvoker) context.getBean("testBean"); + String reply = (String) invoker.invokeMethod(new StringMessage("world")); assertEquals("hello world", reply); context.stop(); }