From cb50b1565cf57e04abad986d9e24a6bb04122354 Mon Sep 17 00:00:00 2001 From: Artem Bilan Date: Fri, 7 Nov 2014 12:37:49 +0200 Subject: [PATCH] INT-3554: Add `Expression` Setters JIRA: https://jira.spring.io/browse/INT-3554 **Cherry-pick to 4.0.x** Polishing --- .../amqp/outbound/AmqpOutboundEndpoint.java | 63 +++++++++++++++---- .../amqp/config/OutboundGatewayTests.java | 14 +++-- .../ExpressionMessageProducerSupport.java | 25 +++++--- ...ressionEvaluatingRequestHandlerAdvice.java | 8 +++ ...licationEventListeningMessageProducer.java | 2 +- ...ionEventListeningMessageProducerTests.java | 1 + .../AbstractRemoteFileOutboundGateway.java | 18 +++++- .../RemoteFileOutboundGatewayTests.java | 2 + .../CacheListeningMessageProducerTests.java | 4 ++ .../ContinuousQueryMessageProducerTests.java | 1 + .../redis/outbound/RedisOutboundGateway.java | 16 ++++- 11 files changed, 127 insertions(+), 27 deletions(-) diff --git a/spring-integration-amqp/src/main/java/org/springframework/integration/amqp/outbound/AmqpOutboundEndpoint.java b/spring-integration-amqp/src/main/java/org/springframework/integration/amqp/outbound/AmqpOutboundEndpoint.java index c2224f5ed7..41c73df131 100644 --- a/spring-integration-amqp/src/main/java/org/springframework/integration/amqp/outbound/AmqpOutboundEndpoint.java +++ b/spring-integration-amqp/src/main/java/org/springframework/integration/amqp/outbound/AmqpOutboundEndpoint.java @@ -70,9 +70,9 @@ public class AmqpOutboundEndpoint extends AbstractReplyProducingMessageHandler private volatile String routingKey; - private volatile String exchangeNameExpression; + private volatile Expression exchangeNameExpression; - private volatile String routingKeyExpression; + private volatile Expression routingKeyExpression; private volatile ExpressionEvaluatingMessageProcessor routingKeyGenerator; @@ -80,7 +80,7 @@ public class AmqpOutboundEndpoint extends AbstractReplyProducingMessageHandler private volatile AmqpHeaderMapper headerMapper = new DefaultAmqpHeaderMapper(); - private volatile String confirmCorrelationExpression; + private volatile Expression confirmCorrelationExpression; private volatile ExpressionEvaluatingMessageProcessor correlationDataGenerator; @@ -109,7 +109,22 @@ public class AmqpOutboundEndpoint extends AbstractReplyProducingMessageHandler this.exchangeName = exchangeName; } + /** + * @deprecated in favor of {@link #setExpressionExchangeName}. Will be changed in a future release + * to use an {@link Expression} parameter. + * @param exchangeNameExpression the expression to set + */ + @Deprecated public void setExchangeNameExpression(String exchangeNameExpression) { + Assert.hasText(exchangeNameExpression); + this.exchangeNameExpression = expressionParser.parseExpression(exchangeNameExpression); + } + + /** + * Temporary, will be changed to {@link #setExchangeNameExpression} in a future release. + * @param exchangeNameExpression the expression to set + */ + public void setExpressionExchangeName(Expression exchangeNameExpression) { this.exchangeNameExpression = exchangeNameExpression; } @@ -118,7 +133,22 @@ public class AmqpOutboundEndpoint extends AbstractReplyProducingMessageHandler this.routingKey = routingKey; } + /** + * @deprecated in favor of {@link #setExpressionRoutingKey}. Will be changed in a future release + * to use an {@link Expression} parameter. + * @param routingKeyExpression the expression to set. + */ + @Deprecated public void setRoutingKeyExpression(String routingKeyExpression) { + Assert.hasText(routingKeyExpression); + setExpressionRoutingKey(expressionParser.parseExpression(routingKeyExpression)); + } + + /** + * Temporary, will be changed to {@code setRoutingKeyExpression} in a future release. + * @param routingKeyExpression the expression to set + */ + public void setExpressionRoutingKey(Expression routingKeyExpression) { this.routingKeyExpression = routingKeyExpression; } @@ -126,7 +156,18 @@ public class AmqpOutboundEndpoint extends AbstractReplyProducingMessageHandler this.expectReply = expectReply; } + /** + * @deprecated in favor of {@link #setExpressionConfirmCorrelation}. Will be changed in a future release + * to use {@link Expression} parameter. + * @param confirmCorrelationExpression the expression to set. + */ + @Deprecated public void setConfirmCorrelationExpression(String confirmCorrelationExpression) { + Assert.hasText(confirmCorrelationExpression); + setExpressionConfirmCorrelation(expressionParser.parseExpression(confirmCorrelationExpression)); + } + + public void setExpressionConfirmCorrelation(Expression confirmCorrelationExpression) { this.confirmCorrelationExpression = confirmCorrelationExpression; } @@ -169,25 +210,25 @@ public class AmqpOutboundEndpoint extends AbstractReplyProducingMessageHandler Assert.state(this.confirmCorrelationExpression == null || !this.expectReply, "Confirm correlation expression does not apply to a gateway"); BeanFactory beanFactory = this.getBeanFactory(); - if (exchangeNameExpression != null) { - Expression expression = expressionParser.parseExpression(this.exchangeNameExpression); - this.exchangeNameGenerator = new ExpressionEvaluatingMessageProcessor(expression, String.class); + if (this.exchangeNameExpression != null) { + this.exchangeNameGenerator = new ExpressionEvaluatingMessageProcessor(this.exchangeNameExpression, + String.class); if (beanFactory != null) { this.exchangeNameGenerator.setBeanFactory(beanFactory); } } Assert.state(routingKeyExpression == null || routingKey == null, "Either a routingKey or a routingKeyExpression can be provided, but not both"); - if (routingKeyExpression != null) { - Expression expression = expressionParser.parseExpression(this.routingKeyExpression); - this.routingKeyGenerator = new ExpressionEvaluatingMessageProcessor(expression, String.class); + if (this.routingKeyExpression != null) { + this.routingKeyGenerator = new ExpressionEvaluatingMessageProcessor(this.routingKeyExpression, + String.class); if (beanFactory != null) { this.routingKeyGenerator.setBeanFactory(beanFactory); } } if (this.confirmCorrelationExpression != null) { - Expression expression = expressionParser.parseExpression(this.confirmCorrelationExpression); - this.correlationDataGenerator = new ExpressionEvaluatingMessageProcessor(expression, Object.class); + this.correlationDataGenerator = + new ExpressionEvaluatingMessageProcessor(this.confirmCorrelationExpression, Object.class); Assert.isInstanceOf(RabbitTemplate.class, this.amqpTemplate, "RabbitTemplate implementation is required for publisher confirms"); ((RabbitTemplate) this.amqpTemplate).setConfirmCallback(this); diff --git a/spring-integration-amqp/src/test/java/org/springframework/integration/amqp/config/OutboundGatewayTests.java b/spring-integration-amqp/src/test/java/org/springframework/integration/amqp/config/OutboundGatewayTests.java index b04ef4444c..a49ac86bfc 100644 --- a/spring-integration-amqp/src/test/java/org/springframework/integration/amqp/config/OutboundGatewayTests.java +++ b/spring-integration-amqp/src/test/java/org/springframework/integration/amqp/config/OutboundGatewayTests.java @@ -53,7 +53,8 @@ import org.springframework.util.ClassUtils; */ public class OutboundGatewayTests { - private final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-context.xml", getClass()); + private final ClassPathXmlApplicationContext context = + new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-context.xml", getClass()); @Test public void testVanillaConfiguration() throws Exception { @@ -65,11 +66,12 @@ public class OutboundGatewayTests { public void testExpressionBasedConfiguration() throws Exception { assertTrue(context.getBeanFactory().containsBeanDefinition("expression")); Object target = context.getBean("expression"); - assertNotNull(ReflectionTestUtils.getField(ReflectionTestUtils.getField(target, "handler"), "routingKeyGenerator")); + assertNotNull(ReflectionTestUtils.getField(ReflectionTestUtils.getField(target, "handler"), + "routingKeyGenerator")); } - @SuppressWarnings("unchecked") @Test + @SuppressWarnings({"unchecked", "deprecation"}) public void testExpressionsBeanResolver() throws Exception { ApplicationContext context = mock(ApplicationContext.class); doAnswer(new Answer() { @@ -82,11 +84,13 @@ public class OutboundGatewayTests { when(context.getBean(ClassUtils.forName("org.springframework.integration.config.SpelPropertyAccessorRegistrar", context.getClassLoader()))) .thenThrow(NoSuchBeanDefinitionException.class); - IntegrationEvaluationContextFactoryBean integrationEvaluationContextFactoryBean = new IntegrationEvaluationContextFactoryBean(); + IntegrationEvaluationContextFactoryBean integrationEvaluationContextFactoryBean = + new IntegrationEvaluationContextFactoryBean(); integrationEvaluationContextFactoryBean.setApplicationContext(context); integrationEvaluationContextFactoryBean.afterPropertiesSet(); StandardEvaluationContext evalContext = integrationEvaluationContextFactoryBean.getObject(); - when(context.getBean(IntegrationContextUtils.INTEGRATION_EVALUATION_CONTEXT_BEAN_NAME, StandardEvaluationContext.class)) + when(context.getBean(IntegrationContextUtils.INTEGRATION_EVALUATION_CONTEXT_BEAN_NAME, + StandardEvaluationContext.class)) .thenReturn(evalContext); RabbitTemplate template = mock(RabbitTemplate.class); AmqpOutboundEndpoint endpoint = new AmqpOutboundEndpoint(template); diff --git a/spring-integration-core/src/main/java/org/springframework/integration/endpoint/ExpressionMessageProducerSupport.java b/spring-integration-core/src/main/java/org/springframework/integration/endpoint/ExpressionMessageProducerSupport.java index a493786451..0f221c6c40 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/endpoint/ExpressionMessageProducerSupport.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/endpoint/ExpressionMessageProducerSupport.java @@ -17,6 +17,7 @@ import org.springframework.expression.Expression; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.integration.expression.ExpressionUtils; import org.springframework.integration.expression.IntegrationEvaluationContextAware; +import org.springframework.util.Assert; /** * A {@link MessageProducerSupport} sub-class that provides {@linkplain #payloadExpression} @@ -30,19 +31,29 @@ import org.springframework.integration.expression.IntegrationEvaluationContextAw */ public abstract class ExpressionMessageProducerSupport extends MessageProducerSupport implements IntegrationEvaluationContextAware { - private final SpelExpressionParser parser = new SpelExpressionParser(); + private static final SpelExpressionParser PARSER = new SpelExpressionParser(); private volatile Expression payloadExpression; private volatile EvaluationContext evaluationContext; + /** + * @deprecated in favor of {@link #setExpressionPayload}. Will be changed in a future release + * to use an {@link Expression} parameter. + * @param payloadExpression the expression to set. + */ + @Deprecated public void setPayloadExpression(String payloadExpression) { - if (payloadExpression == null) { - this.payloadExpression = null; - } - else { - this.payloadExpression = this.parser.parseExpression(payloadExpression); - } + Assert.hasText(payloadExpression); + setExpressionPayload(PARSER.parseExpression(payloadExpression)); + } + + /** + * Temporary, will be changed to {@link #setPayloadExpression} in a future release. + * @param payloadExpression the expression to set. + */ + public void setExpressionPayload(Expression payloadExpression) { + this.payloadExpression = payloadExpression; } @Override diff --git a/spring-integration-core/src/main/java/org/springframework/integration/handler/advice/ExpressionEvaluatingRequestHandlerAdvice.java b/spring-integration-core/src/main/java/org/springframework/integration/handler/advice/ExpressionEvaluatingRequestHandlerAdvice.java index 45672ef5ff..0ab29c6a82 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/handler/advice/ExpressionEvaluatingRequestHandlerAdvice.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/handler/advice/ExpressionEvaluatingRequestHandlerAdvice.java @@ -67,11 +67,19 @@ public class ExpressionEvaluatingRequestHandlerAdvice extends AbstractRequestHan this.onSuccessExpression = new SpelExpressionParser().parseExpression(onSuccessExpression); } + public void setOnSuccessExpression(Expression onSuccessExpression) { + this.onSuccessExpression = onSuccessExpression; + } + public void setOnFailureExpression(String onFailureExpression) { Assert.notNull(onFailureExpression, "'onFailureExpression' must not be null"); this.onFailureExpression = new SpelExpressionParser().parseExpression(onFailureExpression); } + public void setOnFailureExpression(Expression onFailureExpression) { + this.onFailureExpression = onFailureExpression; + } + public void setSuccessChannel(MessageChannel successChannel) { Assert.notNull(successChannel,"'successChannel' must not be null"); this.successChannel = successChannel; diff --git a/spring-integration-event/src/main/java/org/springframework/integration/event/inbound/ApplicationEventListeningMessageProducer.java b/spring-integration-event/src/main/java/org/springframework/integration/event/inbound/ApplicationEventListeningMessageProducer.java index 8387e73ba4..cf6580c397 100644 --- a/spring-integration-event/src/main/java/org/springframework/integration/event/inbound/ApplicationEventListeningMessageProducer.java +++ b/spring-integration-event/src/main/java/org/springframework/integration/event/inbound/ApplicationEventListeningMessageProducer.java @@ -35,7 +35,7 @@ import org.springframework.util.Assert; /** * An inbound Channel Adapter that implements {@link ApplicationListener} and * passes Spring {@link ApplicationEvent ApplicationEvents} within messages. - * If a {@link #setPayloadExpression(String) payloadExpression} is provided, it will be evaluated against + * If a {@link #setPayloadExpression payloadExpression} is provided, it will be evaluated against * the ApplicationEvent instance to create the Message payload. Otherwise, the event itself will be the payload. * * @author Mark Fisher diff --git a/spring-integration-event/src/test/java/org/springframework/integration/event/inbound/ApplicationEventListeningMessageProducerTests.java b/spring-integration-event/src/test/java/org/springframework/integration/event/inbound/ApplicationEventListeningMessageProducerTests.java index 88e5bb2fd7..a622746bb5 100644 --- a/spring-integration-event/src/test/java/org/springframework/integration/event/inbound/ApplicationEventListeningMessageProducerTests.java +++ b/spring-integration-event/src/test/java/org/springframework/integration/event/inbound/ApplicationEventListeningMessageProducerTests.java @@ -134,6 +134,7 @@ public class ApplicationEventListeningMessageProducerTests { } @Test + @SuppressWarnings("deprecation") public void payloadExpressionEvaluatedAgainstApplicationEvent() { QueueChannel channel = new QueueChannel(); ApplicationEventListeningMessageProducer adapter = new ApplicationEventListeningMessageProducer(); diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/remote/gateway/AbstractRemoteFileOutboundGateway.java b/spring-integration-file/src/main/java/org/springframework/integration/file/remote/gateway/AbstractRemoteFileOutboundGateway.java index 2023927b45..dd482f137f 100644 --- a/spring-integration-file/src/main/java/org/springframework/integration/file/remote/gateway/AbstractRemoteFileOutboundGateway.java +++ b/spring-integration-file/src/main/java/org/springframework/integration/file/remote/gateway/AbstractRemoteFileOutboundGateway.java @@ -311,10 +311,24 @@ public abstract class AbstractRemoteFileOutboundGateway extends AbstractReply this.mputFilter = filter; } + /** + * @deprecated in favor of {@link #setExpressionRename}. Will be changed in a future release + * to use an {@link Expression} parameter. + * @param expression the expression to set. + */ + @Deprecated public void setRenameExpression(String expression) { Assert.notNull(expression, "'expression' cannot be null"); - this.renameProcessor = new ExpressionEvaluatingMessageProcessor( - new SpelExpressionParser().parseExpression(expression)); + setExpressionRename(new SpelExpressionParser().parseExpression(expression)); + } + + /** + * Temporary, will be changed to {@link #setRenameExpression} in a future release. + * @param expression the expression to set. + */ + public void setExpressionRename(Expression expression) { + Assert.notNull(expression, "'expression' cannot be null"); + this.renameProcessor = new ExpressionEvaluatingMessageProcessor(expression); } public void setLocalFilenameGeneratorExpression(Expression localFilenameGeneratorExpression) { diff --git a/spring-integration-file/src/test/java/org/springframework/integration/file/remote/gateway/RemoteFileOutboundGatewayTests.java b/spring-integration-file/src/test/java/org/springframework/integration/file/remote/gateway/RemoteFileOutboundGatewayTests.java index 715d297461..3fd442e47f 100644 --- a/spring-integration-file/src/test/java/org/springframework/integration/file/remote/gateway/RemoteFileOutboundGatewayTests.java +++ b/spring-integration-file/src/test/java/org/springframework/integration/file/remote/gateway/RemoteFileOutboundGatewayTests.java @@ -270,6 +270,7 @@ public class RemoteFileOutboundGatewayTests { } @Test + @SuppressWarnings("deprecation") public void testMoveWithExpression() throws Exception { SessionFactory sessionFactory = mock(SessionFactory.class); TestRemoteFileOutboundGateway gw = new TestRemoteFileOutboundGateway @@ -295,6 +296,7 @@ public class RemoteFileOutboundGatewayTests { } @Test + @SuppressWarnings("deprecation") public void testMoveWithMkDirs() throws Exception { SessionFactory sessionFactory = mock(SessionFactory.class); TestRemoteFileOutboundGateway gw = new TestRemoteFileOutboundGateway diff --git a/spring-integration-gemfire/src/test/java/org/springframework/integration/gemfire/inbound/CacheListeningMessageProducerTests.java b/spring-integration-gemfire/src/test/java/org/springframework/integration/gemfire/inbound/CacheListeningMessageProducerTests.java index 45ba92a563..4be1614911 100644 --- a/spring-integration-gemfire/src/test/java/org/springframework/integration/gemfire/inbound/CacheListeningMessageProducerTests.java +++ b/spring-integration-gemfire/src/test/java/org/springframework/integration/gemfire/inbound/CacheListeningMessageProducerTests.java @@ -40,6 +40,7 @@ import com.gemstone.gemfire.cache.Region; public class CacheListeningMessageProducerTests { @Test + @SuppressWarnings("deprecation") public void receiveNewValuePayloadForCreateEvent() throws Exception { CacheFactoryBean cacheFactoryBean = new CacheFactoryBean(); Cache cache = cacheFactoryBean.getObject(); @@ -66,6 +67,7 @@ public class CacheListeningMessageProducerTests { } @Test + @SuppressWarnings("deprecation") public void receiveNewValuePayloadForUpdateEvent() throws Exception { CacheFactoryBean cacheFactoryBean = new CacheFactoryBean(); Cache cache = cacheFactoryBean.getObject(); @@ -96,6 +98,7 @@ public class CacheListeningMessageProducerTests { } @Test + @SuppressWarnings("deprecation") public void receiveOldValuePayloadForDestroyEvent() throws Exception { CacheFactoryBean cacheFactoryBean = new CacheFactoryBean(); Cache cache = cacheFactoryBean.getObject(); @@ -125,6 +128,7 @@ public class CacheListeningMessageProducerTests { } @Test + @SuppressWarnings("deprecation") public void receiveOldValuePayloadForInvalidateEvent() throws Exception { CacheFactoryBean cacheFactoryBean = new CacheFactoryBean(); Cache cache = cacheFactoryBean.getObject(); diff --git a/spring-integration-gemfire/src/test/java/org/springframework/integration/gemfire/inbound/ContinuousQueryMessageProducerTests.java b/spring-integration-gemfire/src/test/java/org/springframework/integration/gemfire/inbound/ContinuousQueryMessageProducerTests.java index 072a35b241..1bb85c77de 100644 --- a/spring-integration-gemfire/src/test/java/org/springframework/integration/gemfire/inbound/ContinuousQueryMessageProducerTests.java +++ b/spring-integration-gemfire/src/test/java/org/springframework/integration/gemfire/inbound/ContinuousQueryMessageProducerTests.java @@ -85,6 +85,7 @@ public class ContinuousQueryMessageProducerTests { } @Test + @SuppressWarnings("deprecation") public void testPayloadExpression() { CqEvent cqEvent = event(Operation.CREATE, "hello"); cqMessageProducer.setPayloadExpression("newValue.toUpperCase() + ', WORLD'"); diff --git a/spring-integration-redis/src/main/java/org/springframework/integration/redis/outbound/RedisOutboundGateway.java b/spring-integration-redis/src/main/java/org/springframework/integration/redis/outbound/RedisOutboundGateway.java index 701c4daa2e..267000f20d 100644 --- a/spring-integration-redis/src/main/java/org/springframework/integration/redis/outbound/RedisOutboundGateway.java +++ b/spring-integration-redis/src/main/java/org/springframework/integration/redis/outbound/RedisOutboundGateway.java @@ -78,9 +78,23 @@ public class RedisOutboundGateway extends AbstractReplyProducingMessageHandler this.argumentsSerializer = (RedisSerializer) serializer; } + /** + * @deprecated in favor of {@link #setExpressionCommand}. Will be changed in a future release + * to use an {@link Expression} parameter. + * @param commandExpression the expression to set. + */ + @Deprecated public void setCommandExpression(String commandExpression) { Assert.hasText(commandExpression, "'commandExpression' must not be an empty string"); - this.commandExpression = PARSER.parseExpression(commandExpression); + setExpressionCommand(PARSER.parseExpression(commandExpression)); + } + + /** + * Temporary, will be changed to {@link #setCommandExpression} in a future release. + * @param commandExpression the expression to set. + */ + public void setExpressionCommand(Expression commandExpression) { + this.commandExpression = commandExpression; } public void setArgumentsStrategy(ArgumentsStrategy argumentsStrategy) {