diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/ReleaseStrategyFactoryBean.java b/spring-integration-core/src/main/java/org/springframework/integration/config/ReleaseStrategyFactoryBean.java index 2d75453be3..46d788c359 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/ReleaseStrategyFactoryBean.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/ReleaseStrategyFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2014 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. @@ -17,26 +17,32 @@ package org.springframework.integration.config; import java.lang.reflect.Method; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + import org.springframework.beans.factory.FactoryBean; -import org.springframework.integration.aggregator.ReleaseStrategy; import org.springframework.integration.aggregator.MethodInvokingReleaseStrategy; +import org.springframework.integration.aggregator.ReleaseStrategy; import org.springframework.integration.aggregator.SequenceSizeReleaseStrategy; import org.springframework.util.StringUtils; /** * Convenience factory for XML configuration of a {@link ReleaseStrategy}. Encapsulates the knowledge of the default * strategy and search algorithms for POJO and annotated methods. - * + * * @author Dave Syer - * + * @author Gary Russell + * */ public class ReleaseStrategyFactoryBean implements FactoryBean { + private static final Log logger = LogFactory.getLog(ReleaseStrategyFactoryBean.class); + private ReleaseStrategy delegate = new SequenceSizeReleaseStrategy(); /** * Create a factory and set up the delegate which clients of the factory will see as its product. - * + * * @param target the target object (null if default strategy is acceptable) */ public ReleaseStrategyFactoryBean(Object target) { @@ -45,36 +51,50 @@ public class ReleaseStrategyFactoryBean implements FactoryBean /** * Create a factory and set up the delegate which clients of the factory will see as its product. - * + * * @param target the target object (null if default strategy is acceptable) * @param methodName the method name to invoke in the target (null if it can be inferred) */ public ReleaseStrategyFactoryBean(Object target, String methodName) { if (target instanceof ReleaseStrategy && !StringUtils.hasText(methodName)) { - delegate = (ReleaseStrategy) target; + this.delegate = (ReleaseStrategy) target; return; } if (target != null) { if (StringUtils.hasText(methodName)) { - delegate = new MethodInvokingReleaseStrategy(target, methodName); + this.delegate = new MethodInvokingReleaseStrategy(target, methodName); } else { Method method = AnnotationFinder.findAnnotatedMethod(target, org.springframework.integration.annotation.ReleaseStrategy.class); if (method != null) { - delegate = new MethodInvokingReleaseStrategy(target, method); + this.delegate = new MethodInvokingReleaseStrategy(target, method); } + else { + if (logger.isWarnEnabled()) { + logger.warn("No annotated method found; falling back to SequenceSizeReleaseStrategy, target:" + + target + ", methodName:" + methodName); + } + } + } + } + else { + if (logger.isWarnEnabled()) { + logger.warn("No target supplied; falling back to SequenceSizeReleaseStrategy"); } } } + @Override public ReleaseStrategy getObject() throws Exception { - return delegate; + return this.delegate; } + @Override public Class getObjectType() { return ReleaseStrategy.class; } + @Override public boolean isSingleton() { return true; } diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/ReleaseStrategyFactoryBeanTests.java b/spring-integration-core/src/test/java/org/springframework/integration/config/ReleaseStrategyFactoryBeanTests.java new file mode 100644 index 0000000000..0fdf1901ec --- /dev/null +++ b/spring-integration-core/src/test/java/org/springframework/integration/config/ReleaseStrategyFactoryBeanTests.java @@ -0,0 +1,136 @@ +/* + * Copyright 2014 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.config; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Collection; + +import org.junit.Test; + +import org.springframework.integration.aggregator.MethodInvokingReleaseStrategy; +import org.springframework.integration.aggregator.ReleaseStrategy; +import org.springframework.integration.aggregator.SequenceSizeReleaseStrategy; +import org.springframework.integration.store.MessageGroup; +import org.springframework.integration.test.util.TestUtils; + +/** + * @author Gary Russell + * @since 3.0.2 + * + */ +public class ReleaseStrategyFactoryBeanTests { + + public void testRefWithMethod() throws Exception { + Foo foo = new Foo(); + ReleaseStrategyFactoryBean factory = new ReleaseStrategyFactoryBean(foo, "doRelease"); + ReleaseStrategy delegate = factory.getObject(); + assertThat(delegate, instanceOf(MethodInvokingReleaseStrategy.class)); + assertThat(TestUtils.getPropertyValue(delegate, "adapter.delegate.targetObject", Foo.class), is(foo)); + } + + @Test + public void testRefWithMethodWithDifferentAnnotatedMethod() throws Exception { + Bar bar = new Bar(); + ReleaseStrategyFactoryBean factory = new ReleaseStrategyFactoryBean(bar, "doRelease2"); + ReleaseStrategy delegate = factory.getObject(); + assertThat(delegate, instanceOf(MethodInvokingReleaseStrategy.class)); + assertThat(TestUtils.getPropertyValue(delegate, "adapter.delegate.targetObject", Bar.class), is(bar)); + assertThat(TestUtils.getPropertyValue(delegate, "adapter.delegate.handlerMethod.expression.expression", String.class), + equalTo("#target.doRelease2(messages)")); + } + + @Test + public void testRefWithNoMethodWithAnnotation() throws Exception { + Bar bar = new Bar(); + ReleaseStrategyFactoryBean factory = new ReleaseStrategyFactoryBean(bar); + ReleaseStrategy delegate = factory.getObject(); + assertThat(delegate, instanceOf(MethodInvokingReleaseStrategy.class)); + assertThat(TestUtils.getPropertyValue(delegate, "adapter.delegate.targetObject", Bar.class), is(bar)); + } + + @Test + public void testNoRefNoMethod() throws Exception { + ReleaseStrategyFactoryBean factory = new ReleaseStrategyFactoryBean(null); + ReleaseStrategy delegate = factory.getObject(); + assertThat(delegate, instanceOf(SequenceSizeReleaseStrategy.class)); + } + + @Test + public void testRefWithNoMethodNoAnnotation() throws Exception { + Foo foo = new Foo(); + ReleaseStrategyFactoryBean factory = new ReleaseStrategyFactoryBean(foo); + ReleaseStrategy delegate = factory.getObject(); + assertThat(delegate, instanceOf(SequenceSizeReleaseStrategy.class)); + } + + @Test + public void testRefThatImplements() throws Exception { + Baz baz = new Baz(); + ReleaseStrategyFactoryBean factory = new ReleaseStrategyFactoryBean(baz); + ReleaseStrategy delegate = factory.getObject(); + assertThat((Baz) delegate, is(baz)); + } + + @Test + public void testRefThatImplementsWithDifferentMethod() throws Exception { + Baz baz = new Baz(); + ReleaseStrategyFactoryBean factory = new ReleaseStrategyFactoryBean(baz, "doRelease2"); + ReleaseStrategy delegate = factory.getObject(); + assertThat(delegate, instanceOf(MethodInvokingReleaseStrategy.class)); + assertThat(TestUtils.getPropertyValue(delegate, "adapter.delegate.targetObject", Baz.class), is(baz)); + assertThat(TestUtils.getPropertyValue(delegate, "adapter.delegate.handlerMethod.expression.expression", String.class), + equalTo("#target.doRelease2(messages)")); + } + + public class Foo { + + boolean doRelease(Collection foo) { + return true; + } + + } + + public class Bar { + + @org.springframework.integration.annotation.ReleaseStrategy + public boolean doRelease(Collection bar) { + return true; + } + + public boolean doRelease2(Collection bar) { + return true; + } + + } + + public class Baz implements ReleaseStrategy { + + @Override + public boolean canRelease(MessageGroup group) { + return true; + } + + public boolean doRelease2(Collection bar) { + return true; + } + + } + +}