INT-1639 Externalize SpEL Evaluation Context

Allow modification of context property accessors and
functions.

Polishing

- Fix tests to ensure the EvaluationContextFactoryBean is
available when necessary.

Polishing - Use Utility for ALL EvaluationContexts

Add Test Showing Custom Function

See SpelTransformerIntegrationTests-context.xml

Polishing

Polishing -fix Remote Sync

Polishing - Emit WARN if No BeanFactory

Polishing - Do Not Override ConversionService

Kludge to Prevent Warning When No BeanFactory

Expressions for method invoking in the MessagingMethodInvokerHelper
don't need a BeanFactory - suppress the warning.

Polishing - PR Comments - Invert Boolean
This commit is contained in:
Gary Russell
2013-08-21 15:05:21 -04:00
committed by Mark Fisher
parent 351af6b16b
commit 7f008b58c2
53 changed files with 983 additions and 360 deletions

View File

@@ -22,15 +22,20 @@ import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.integration.Message;
import org.springframework.integration.amqp.outbound.AmqpOutboundEndpoint;
import org.springframework.integration.config.IntegrationEvaluationContextFactoryBean;
import org.springframework.integration.context.IntegrationContextUtils;
import org.springframework.integration.handler.MessageProcessor;
import org.springframework.integration.message.GenericMessage;
import org.springframework.integration.test.util.TestUtils;
@@ -60,20 +65,27 @@ public class OutboundGatewayTests {
@SuppressWarnings("unchecked")
@Test
public void testExpressionsBeanResolver() {
BeanFactory bf = mock(BeanFactory.class);
public void testExpressionsBeanResolver() throws Exception {
ApplicationContext context = mock(ApplicationContext.class);
doAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
return invocation.getArguments()[0] + "bar";
}
}).when(bf).getBean(anyString());
}).when(context).getBean(anyString());
when(context.containsBean(IntegrationContextUtils.INTEGRATION_EVALUATION_CONTEXT_BEAN_NAME)).thenReturn(true);
IntegrationEvaluationContextFactoryBean integrationEvaluationContextFactoryBean = new IntegrationEvaluationContextFactoryBean();
integrationEvaluationContextFactoryBean.setApplicationContext(context);
integrationEvaluationContextFactoryBean.afterPropertiesSet();
StandardEvaluationContext evalContext = integrationEvaluationContextFactoryBean.getObject();
when(context.getBean(IntegrationContextUtils.INTEGRATION_EVALUATION_CONTEXT_BEAN_NAME, StandardEvaluationContext.class))
.thenReturn(evalContext);
RabbitTemplate template = mock(RabbitTemplate.class);
AmqpOutboundEndpoint endpoint = new AmqpOutboundEndpoint(template);
endpoint.setRoutingKeyExpression("@foo");
endpoint.setExchangeNameExpression("@bar");
endpoint.setConfirmCorrelationExpression("@baz");
endpoint.setBeanFactory(bf);
endpoint.setBeanFactory(context);
endpoint.afterPropertiesSet();
Message<?> message = new GenericMessage<String>("Hello, world!");
assertEquals("foobar", TestUtils.getPropertyValue(endpoint, "routingKeyGenerator", MessageProcessor.class)

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2013 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.
@@ -24,7 +24,9 @@ import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.support.AopUtils;
import org.springframework.context.expression.MapAccessor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.expression.EvaluationException;
@@ -37,6 +39,7 @@ import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.integration.Message;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.core.MessagingTemplate;
import org.springframework.integration.expression.ExpressionUtils;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.integration.support.channel.ChannelResolver;
import org.springframework.util.Assert;
@@ -47,11 +50,11 @@ import org.springframework.util.StringUtils;
* payload of the published Message can be derived from arguments or any return
* value or exception resulting from the method invocation. That mapping is the
* responsibility of the EL expression provided by the {@link PublisherMetadataSource}.
*
*
* @author Mark Fisher
* @since 2.0
*/
public class MessagePublishingInterceptor implements MethodInterceptor {
public class MessagePublishingInterceptor implements MethodInterceptor, BeanFactoryAware {
private final MessagingTemplate messagingTemplate = new MessagingTemplate();
@@ -61,6 +64,8 @@ public class MessagePublishingInterceptor implements MethodInterceptor {
private volatile ChannelResolver channelResolver;
private volatile BeanFactory beanFactory;
private final ParameterNameDiscoverer parameterNameDiscoverer = new LocalVariableTableParameterNameDiscoverer();
@@ -83,10 +88,14 @@ public class MessagePublishingInterceptor implements MethodInterceptor {
this.channelResolver = channelResolver;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
public final Object invoke(final MethodInvocation invocation) throws Throwable {
Assert.notNull(this.metadataSource, "PublisherMetadataSource is required.");
final StandardEvaluationContext context = new StandardEvaluationContext();
context.addPropertyAccessor(new MapAccessor());
final StandardEvaluationContext context = ExpressionUtils.createStandardEvaluationContext(this.beanFactory);
Class<?> targetClass = AopUtils.getTargetClass(invocation.getThis());
final Method method = AopUtils.getMostSpecificMethod(invocation.getMethod(), targetClass);
String[] argumentNames = this.resolveArgumentNames(method);

View File

@@ -74,6 +74,7 @@ public class PublisherAnnotationAdvisor extends AbstractPointcutAdvisor implemen
public void setBeanFactory(BeanFactory beanFactory) {
this.interceptor.setChannelResolver(new BeanFactoryChannelResolver(beanFactory));
this.interceptor.setBeanFactory(beanFactory);
}
public Advice getAdvice() {

View File

@@ -0,0 +1,134 @@
/*
* Copyright 2013 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 java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.context.expression.MapAccessor;
import org.springframework.core.convert.ConversionService;
import org.springframework.expression.BeanResolver;
import org.springframework.expression.PropertyAccessor;
import org.springframework.expression.TypeConverter;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.expression.spel.support.StandardTypeConverter;
import org.springframework.integration.context.IntegrationContextUtils;
import org.springframework.util.Assert;
/**
* @author Artem Bilan
* @author Gary Russell
* @since 3.0
*/
public class IntegrationEvaluationContextFactoryBean implements FactoryBean<StandardEvaluationContext>,
ApplicationContextAware, BeanFactoryAware, InitializingBean {
private volatile List<PropertyAccessor> propertyAccessors = new ArrayList<PropertyAccessor>();
private TypeConverter typeConverter = new StandardTypeConverter();
private volatile Map<String, Method> functions = new LinkedHashMap<String, Method>();
private ApplicationContext applicationContext;
private BeanFactory beanFactory;
private BeanResolver beanResolver;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
@Override
public void afterPropertiesSet() throws Exception {
this.beanResolver = new BeanFactoryResolver(this.applicationContext != null ? this.applicationContext : this.beanFactory);
this.loadDefaultPropertyAccessors(this.propertyAccessors);
if (this.applicationContext != null) {
ConversionService conversionService = IntegrationContextUtils.getConversionService(this.applicationContext);
if (conversionService != null) {
this.typeConverter = new StandardTypeConverter(conversionService);
}
}
}
public void setPropertyAccessors(PropertyAccessor... accessors) {
Assert.noNullElements(accessors, "Cannot have null elements in accessors");
List<PropertyAccessor> propertyAccessors = new ArrayList<PropertyAccessor>();
loadDefaultPropertyAccessors(propertyAccessors);
for (PropertyAccessor accessor : accessors) {
propertyAccessors.add(accessor);
}
this.propertyAccessors = propertyAccessors;
}
private void loadDefaultPropertyAccessors(List<PropertyAccessor> propertyAccessors) {
propertyAccessors.add(new MapAccessor());
}
public void setFunctions(Map<String, Method> functionsArg) {
Map<String, Method> functions = new LinkedHashMap<String, Method>();
for (Entry<String, Method> function : functionsArg.entrySet()) {
Assert.notNull(function.getValue(), "Method cannot be null");
functions.put(function.getKey(), function.getValue());
}
this.functions = functions;
}
@Override
public StandardEvaluationContext getObject() throws Exception {
StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
for (PropertyAccessor propertyAccessor : this.propertyAccessors) {
evaluationContext.addPropertyAccessor(propertyAccessor);
}
evaluationContext.setBeanResolver(this.beanResolver);
evaluationContext.setTypeConverter(this.typeConverter);
for (Entry<String, Method> functionEntry : this.functions.entrySet()) {
evaluationContext.registerFunction(functionEntry.getKey(), functionEntry.getValue());
}
return evaluationContext;
}
@Override
public Class<?> getObjectType() {
return StandardEvaluationContext.class;
}
@Override
public boolean isSingleton() {
return false;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2013 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.
@@ -32,15 +32,18 @@ import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.integration.channel.NullChannel;
import org.springframework.integration.config.IntegrationEvaluationContextFactoryBean;
import org.springframework.integration.context.IntegrationContextUtils;
import org.springframework.integration.expression.IntegrationEvaluationContextAwareBeanPostProcessor;
/**
* A {@link BeanFactoryPostProcessor} implementation that provides default beans for the error handling and task
* scheduling if those beans have not already been explicitly defined within the registry. It also registers a single
* null channel with the bean name "nullChannel".
*
*
* @author Mark Fisher
* @author Oleg Zhurakousky
* @author Artem Bilan
*/
class DefaultConfiguringBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@@ -61,6 +64,10 @@ class DefaultConfiguringBeanFactoryPostProcessor implements BeanFactoryPostProce
this.registerTaskScheduler(registry);
}
this.registerIdGeneratorConfigurer(registry);
if (!beanFactory.containsBean(IntegrationContextUtils.INTEGRATION_EVALUATION_CONTEXT_BEAN_NAME)) {
this.registerIntegrationEvaluationContext(registry);
beanFactory.addBeanPostProcessor(new IntegrationEvaluationContextAwareBeanPostProcessor(beanFactory));
}
}
else if (logger.isWarnEnabled()) {
logger.warn("BeanFactory is not a BeanDefinitionRegistry. The default '"
@@ -71,6 +78,16 @@ class DefaultConfiguringBeanFactoryPostProcessor implements BeanFactoryPostProce
}
}
private void registerIntegrationEvaluationContext(BeanDefinitionRegistry registry) {
BeanDefinitionBuilder integrationEvaluationContextBuilder = BeanDefinitionBuilder.genericBeanDefinition(
IntegrationEvaluationContextFactoryBean.class);
integrationEvaluationContextBuilder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
BeanDefinitionHolder integrationEvaluationContextHolder = new BeanDefinitionHolder(
integrationEvaluationContextBuilder.getBeanDefinition(),
IntegrationContextUtils.INTEGRATION_EVALUATION_CONTEXT_BEAN_NAME);
BeanDefinitionReaderUtils.registerBeanDefinition(integrationEvaluationContextHolder, registry);
}
private void registerIdGeneratorConfigurer(BeanDefinitionRegistry registry) {
String listenerClassName = "org.springframework.integration.config.IdGeneratorConfigurer";
String[] definitionNames = registry.getBeanDefinitionNames();
@@ -113,7 +130,7 @@ class DefaultConfiguringBeanFactoryPostProcessor implements BeanFactoryPostProce
}
/**
* Register an error channel in the given BeanDefinitionRegistry.
* Register an error channel in the given BeanDefinitionRegistry.
*/
private void registerErrorChannel(BeanDefinitionRegistry registry) {
if (logger.isInfoEnabled()) {
@@ -139,7 +156,7 @@ class DefaultConfiguringBeanFactoryPostProcessor implements BeanFactoryPostProce
}
/**
* Register a TaskScheduler in the given BeanDefinitionRegistry.
* Register a TaskScheduler in the given BeanDefinitionRegistry.
*/
private void registerTaskScheduler(BeanDefinitionRegistry registry) {
if (logger.isInfoEnabled()) {

View File

@@ -18,6 +18,7 @@ package org.springframework.integration.context;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.core.convert.ConversionService;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.store.metadata.MetadataStore;
import org.springframework.scheduling.TaskScheduler;
@@ -28,6 +29,7 @@ import org.springframework.util.Assert;
*
* @author Mark Fisher
* @author Josh Long
* @author Artem Bilan
*/
public abstract class IntegrationContextUtils {
@@ -41,6 +43,7 @@ public abstract class IntegrationContextUtils {
public static final String INTEGRATION_CONVERSION_SERVICE_BEAN_NAME = "integrationConversionService";
public static final String INTEGRATION_EVALUATION_CONTEXT_BEAN_NAME = "integrationEvaluationContext";
/**
* Return the {@link MetadataStore} bean whose name is "metadataStore".
@@ -85,6 +88,14 @@ public abstract class IntegrationContextUtils {
return getBeanOfType(beanFactory, INTEGRATION_CONVERSION_SERVICE_BEAN_NAME, ConversionService.class);
}
/**
* Return the instance of {@link StandardEvaluationContext} bean whose name is "integrationEvaluationContext" .
* @param beanFactory BeanFactory for lookup, must not be null.
*/
public static StandardEvaluationContext getEvaluationContext(BeanFactory beanFactory) {
return getBeanOfType(beanFactory, INTEGRATION_EVALUATION_CONTEXT_BEAN_NAME, StandardEvaluationContext.class);
}
private static <T> T getBeanOfType(BeanFactory beanFactory, String beanName, Class<T> type) {
Assert.notNull(beanFactory, "BeanFactory must not be null");
if (!beanFactory.containsBean(beanName)) {

View File

@@ -140,7 +140,7 @@ public abstract class IntegrationObjectSupport implements BeanNameAware, NamedCo
this.taskScheduler = taskScheduler;
}
protected final ConversionService getConversionService() {
public final ConversionService getConversionService() {
if (this.conversionService == null && this.beanFactory != null) {
synchronized (this) {
if (this.conversionService == null) {

View File

@@ -12,9 +12,11 @@
*/
package org.springframework.integration.endpoint;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.integration.endpoint.MessageProducerSupport;
import org.springframework.integration.expression.ExpressionUtils;
import org.springframework.integration.expression.IntegrationEvaluationContextAware;
/**
* A {@link MessageProducerSupport} sub-class that provides {@linkplain #payloadExpression}
@@ -22,15 +24,18 @@ import org.springframework.integration.endpoint.MessageProducerSupport;
*
* @author David Turanski
* @author Artem Bilan
* @author Gary Russell
* @since 2.1
*
*/
public abstract class ExpressionMessageProducerSupport extends MessageProducerSupport {
public abstract class ExpressionMessageProducerSupport extends MessageProducerSupport implements IntegrationEvaluationContextAware {
private final SpelExpressionParser parser = new SpelExpressionParser();
private volatile Expression payloadExpression;
private volatile EvaluationContext evaluationContext;
public void setPayloadExpression(String payloadExpression) {
if (payloadExpression == null) {
this.payloadExpression = null;
@@ -40,10 +45,23 @@ public abstract class ExpressionMessageProducerSupport extends MessageProducerSu
}
}
@Override
public void setIntegrationEvaluationContext(EvaluationContext evaluationContext) {
this.evaluationContext = evaluationContext;
}
@Override
protected void onInit() {
super.onInit();
if (this.evaluationContext == null) {
this.evaluationContext = ExpressionUtils.createStandardEvaluationContext(this.getBeanFactory());
}
}
protected Object evaluatePayloadExpression(Object payload){
Object evaluationResult = payload;
if (payloadExpression != null) {
evaluationResult = payloadExpression.getValue(payload);
evaluationResult = payloadExpression.getValue(this.evaluationContext, payload);
}
return evaluationResult;
}

View File

@@ -16,11 +16,12 @@
package org.springframework.integration.expression;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.context.expression.MapAccessor;
import org.springframework.core.convert.ConversionService;
import org.springframework.expression.BeanResolver;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.expression.spel.support.StandardTypeConverter;
import org.springframework.integration.context.IntegrationContextUtils;
@@ -36,26 +37,7 @@ import org.springframework.integration.context.IntegrationContextUtils;
*/
public abstract class ExpressionUtils {
/**
* Create a {@link StandardEvaluationContext} with a {@link MapAccessor} in its
* property accessor property.
* @return the evaluation context.
*/
public static StandardEvaluationContext createStandardEvaluationContext() {
return createStandardEvaluationContext(null, null);
}
/**
* Create a {@link StandardEvaluationContext} with a {@link MapAccessor} in its
* property accessor property and the supplied {@link BeanResolver} in its
* beanResolver property.
* @param beanResolver the bean resolver.
* @return the evaluation context.
*/
public static StandardEvaluationContext createStandardEvaluationContext(BeanResolver beanResolver) {
return createStandardEvaluationContext(beanResolver, null);
}
private static final Log logger = LogFactory.getLog(ExpressionUtils.class);
/**
* Create a {@link StandardEvaluationContext} with a {@link MapAccessor} in its
* property accessor property and the supplied {@link ConversionService} in its
@@ -63,26 +45,9 @@ public abstract class ExpressionUtils {
* @param conversionService the conversion service.
* @return the evaluation context.
*/
public static StandardEvaluationContext createStandardEvaluationContext(ConversionService conversionService) {
return createStandardEvaluationContext(null, conversionService);
}
/**
* Create a {@link StandardEvaluationContext} with a {@link MapAccessor} in its
* property accessor property, the supplied {@link BeanResolver} in its
* beanResolver property, and the supplied {@link ConversionService} in its
* conversionService property.
* @param beanResolver the bean resolver.
* @param conversionService the conversion service.
* @return the evaluation context.
*/
public static StandardEvaluationContext createStandardEvaluationContext(BeanResolver beanResolver,
ConversionService conversionService) {
private static StandardEvaluationContext createStandardEvaluationContext(ConversionService conversionService) {
StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
evaluationContext.addPropertyAccessor(new MapAccessor());
if (beanResolver != null) {
evaluationContext.setBeanResolver(beanResolver);
}
if (conversionService != null) {
evaluationContext.setTypeConverter(new StandardTypeConverter(conversionService));
}
@@ -90,14 +55,39 @@ public abstract class ExpressionUtils {
}
/**
* Creates {@link BeanFactoryResolver}, extracts {@link ConversionService} and delegates to
* {@link #createStandardEvaluationContext(BeanResolver, ConversionService)}
*
* @param beanFactory the beanFactory.
* @return the evaluation context.
* Used to create a context with no BeanFactory, usually in tests.
* @return The evaluation context.
*/
public static StandardEvaluationContext createStandardEvaluationContext() {
return doCreateContext(null);
}
/**
* Obtains the context from the beanFactory if not null; emits a warning if the beanFactory
* is null.
* @param beanFactory
* @return The evaluation context.
*/
public static StandardEvaluationContext createStandardEvaluationContext(BeanFactory beanFactory) {
return createStandardEvaluationContext(new BeanFactoryResolver(beanFactory),
IntegrationContextUtils.getConversionService(beanFactory));
if (beanFactory == null) {
logger.warn("Creating EvaluationContext with no beanFactory", new RuntimeException("No beanfactory"));
}
return doCreateContext(beanFactory);
}
private static StandardEvaluationContext doCreateContext(BeanFactory beanFactory) {
ConversionService conversionService = null;
StandardEvaluationContext evaluationContext = null;
if (beanFactory != null) {
evaluationContext = IntegrationContextUtils.getEvaluationContext(beanFactory);
}
if (evaluationContext == null) {
if (beanFactory != null) {
conversionService = IntegrationContextUtils.getConversionService(beanFactory);
}
evaluationContext = createStandardEvaluationContext(conversionService);
}
return evaluationContext;
}
}

View File

@@ -0,0 +1,29 @@
/*
* Copyright 2013 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.expression;
import org.springframework.expression.EvaluationContext;
/**
* @author Artem Bilan
* @since 3.0
*/
public interface IntegrationEvaluationContextAware {
void setIntegrationEvaluationContext(EvaluationContext evaluationContext);
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright 2013 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.expression;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.integration.context.IntegrationContextUtils;
/**
* @author Artem Bilan
* @since 3.0
*/
public class IntegrationEvaluationContextAwareBeanPostProcessor implements BeanPostProcessor {
private final BeanFactory beanFactory;
public IntegrationEvaluationContextAwareBeanPostProcessor(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof IntegrationEvaluationContextAware) {
StandardEvaluationContext evaluationContext = IntegrationContextUtils.getEvaluationContext(this.beanFactory);
((IntegrationEvaluationContextAware) bean).setIntegrationEvaluationContext(evaluationContext);
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}

View File

@@ -28,11 +28,9 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.core.MethodParameter;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.expression.BeanResolver;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
@@ -42,6 +40,7 @@ import org.springframework.integration.MessagingException;
import org.springframework.integration.annotation.Header;
import org.springframework.integration.annotation.Headers;
import org.springframework.integration.annotation.Payload;
import org.springframework.integration.expression.ExpressionUtils;
import org.springframework.integration.mapping.InboundMessageMapper;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.util.Assert;
@@ -87,9 +86,9 @@ class GatewayMethodInboundMessageMapper implements InboundMessageMapper<Object[]
private final Map<String, Expression> parameterPayloadExpressions = new HashMap<String, Expression>();
private final StandardEvaluationContext staticEvaluationContext = new StandardEvaluationContext();
private volatile StandardEvaluationContext payloadExpressionEvaluationContext;
private volatile BeanResolver beanResolver;
private volatile BeanFactory beanFactory;
public GatewayMethodInboundMessageMapper(Method method) {
@@ -111,8 +110,8 @@ class GatewayMethodInboundMessageMapper implements InboundMessageMapper<Object[]
public void setBeanFactory(final BeanFactory beanFactory) {
if (beanFactory != null) {
this.beanResolver = new BeanFactoryResolver(beanFactory);
this.staticEvaluationContext.setBeanResolver(beanResolver);
this.beanFactory = beanFactory;
this.payloadExpressionEvaluationContext = ExpressionUtils.createStandardEvaluationContext(beanFactory);
}
}
@@ -209,12 +208,9 @@ class GatewayMethodInboundMessageMapper implements InboundMessageMapper<Object[]
}
private StandardEvaluationContext createMethodInvocationEvaluationContext(Object[] arguments) {
StandardEvaluationContext context = new StandardEvaluationContext();
StandardEvaluationContext context = ExpressionUtils.createStandardEvaluationContext(this.beanFactory);
context.setVariable("args", arguments);
context.setVariable("method", this.method.getName());
if (this.beanResolver != null) {
context.setBeanResolver(this.beanResolver);
}
return context;
}
@@ -224,7 +220,7 @@ class GatewayMethodInboundMessageMapper implements InboundMessageMapper<Object[]
expression = PARSER.parseExpression(expressionString);
this.parameterPayloadExpressions.put(expressionString, expression);
}
return expression.getValue(this.staticEvaluationContext, argumentValue);
return expression.getValue(this.payloadExpressionEvaluationContext, argumentValue);
}
private Annotation findMappingAnnotation(Annotation[] annotations) {

View File

@@ -210,12 +210,7 @@ public class DelayHandler extends AbstractReplyProducingMessageHandler implement
this.delayExpression = expressionParser.parseExpression("headers['" + this.delayHeaderName + "']");
}
}
if (this.getBeanFactory() != null) {
this.evaluationContext = ExpressionUtils.createStandardEvaluationContext(this.getBeanFactory());
}
else {
this.evaluationContext = ExpressionUtils.createStandardEvaluationContext();
}
this.evaluationContext = ExpressionUtils.createStandardEvaluationContext(this.getBeanFactory());
this.releaseHandler = this.createReleaseMessageTask();
}

View File

@@ -18,13 +18,13 @@ import java.io.StringWriter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.expression.MapAccessor;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.integration.Message;
import org.springframework.integration.dispatcher.AggregateMessageDeliveryException;
import org.springframework.integration.expression.ExpressionUtils;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -54,7 +54,7 @@ public class LoggingHandler extends AbstractMessageHandler {
private volatile Level level;
private final EvaluationContext evaluationContext;
private volatile EvaluationContext evaluationContext;
private volatile Log messageLogger = this.logger;
@@ -74,9 +74,7 @@ public class LoggingHandler extends AbstractMessageHandler {
+ "'. The (case-insensitive) supported values are: "
+ StringUtils.arrayToCommaDelimitedString(Level.values()));
}
StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
evaluationContext.addPropertyAccessor(new MapAccessor());
this.evaluationContext = evaluationContext;
this.evaluationContext = ExpressionUtils.createStandardEvaluationContext();
this.expression = EXPRESSION_PARSER.parseExpression("payload");
}
@@ -123,6 +121,12 @@ public class LoggingHandler extends AbstractMessageHandler {
return "logging-channel-adapter";
}
@Override
protected void onInit() throws Exception {
super.onInit();
this.evaluationContext = ExpressionUtils.createStandardEvaluationContext(this.getBeanFactory());
}
@Override
protected void handleMessageInternal(Message<?> message) throws Exception {
switch (this.level) {

View File

@@ -15,7 +15,6 @@
*/
package org.springframework.integration.handler.advice;
import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
@@ -172,13 +171,7 @@ public class ExpressionEvaluatingRequestHandlerAdvice extends AbstractRequestHan
}
protected StandardEvaluationContext createEvaluationContext(){
if (this.getBeanFactory() != null) {
return ExpressionUtils.createStandardEvaluationContext(new BeanFactoryResolver(this.getBeanFactory()),
this.getConversionService());
}
else {
return ExpressionUtils.createStandardEvaluationContext(this.getConversionService());
}
return ExpressionUtils.createStandardEvaluationContext(this.getBeanFactory());
}
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2013 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.
@@ -19,7 +19,6 @@ import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.classify.Classifier;
import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
@@ -37,7 +36,7 @@ import org.springframework.util.Assert;
*/
public class SpelExpressionRetryStateGenerator implements RetryStateGenerator, BeanFactoryAware {
private final StandardEvaluationContext evaluationContext;
private volatile StandardEvaluationContext evaluationContext;
private final Expression keyExpression;
@@ -62,7 +61,7 @@ public class SpelExpressionRetryStateGenerator implements RetryStateGenerator, B
}
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.evaluationContext.setBeanResolver(new BeanFactoryResolver(beanFactory));
this.evaluationContext = ExpressionUtils.createStandardEvaluationContext(beanFactory);
}
public void setClassifier(Classifier<? super Throwable, Boolean> classifier) {

View File

@@ -14,7 +14,6 @@ package org.springframework.integration.transaction;
import java.util.Map.Entry;
import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.integration.Message;
@@ -180,13 +179,7 @@ public class ExpressionEvaluatingTransactionSynchronizationProcessor extends Int
return evaluationContextToUse;
}
protected StandardEvaluationContext createEvaluationContext(){
if (this.getBeanFactory() != null) {
return ExpressionUtils.createStandardEvaluationContext(new BeanFactoryResolver(this.getBeanFactory()),
this.getConversionService());
}
else {
return ExpressionUtils.createStandardEvaluationContext(this.getConversionService());
}
protected StandardEvaluationContext createEvaluationContext() {
return ExpressionUtils.createStandardEvaluationContext(this.getBeanFactory());
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2013 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.
@@ -20,10 +20,8 @@ import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.Lifecycle;
import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.context.expression.MapAccessor;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.SpelParserConfiguration;
import org.springframework.expression.spel.standard.SpelExpressionParser;
@@ -31,6 +29,8 @@ import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.integration.Message;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.MessageHandlingException;
import org.springframework.integration.expression.ExpressionUtils;
import org.springframework.integration.expression.IntegrationEvaluationContextAware;
import org.springframework.integration.gateway.MessagingGatewaySupport;
import org.springframework.integration.handler.AbstractReplyProducingMessageHandler;
import org.springframework.integration.support.MessageBuilder;
@@ -46,17 +46,18 @@ import org.springframework.util.ReflectionUtils;
* @author Mark Fisher
* @author Gunnar Hillert
* @author Gary Russell
* @author Artem Bilan
* @since 2.1
*/
public class ContentEnricher extends AbstractReplyProducingMessageHandler implements Lifecycle {
public class ContentEnricher extends AbstractReplyProducingMessageHandler implements Lifecycle, IntegrationEvaluationContextAware {
private final Map<Expression, Expression> propertyExpressions = new HashMap<Expression, Expression>();
private final SpelExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
private final StandardEvaluationContext sourceEvaluationContext = new StandardEvaluationContext();
private EvaluationContext sourceEvaluationContext;
private final StandardEvaluationContext targetEvaluationContext = new StandardEvaluationContext();
private EvaluationContext targetEvaluationContext;
private volatile boolean shouldClonePayload = false;
@@ -69,7 +70,7 @@ public class ContentEnricher extends AbstractReplyProducingMessageHandler implem
private volatile Gateway gateway = null;
private volatile Long requestTimeout;
private volatile Long replyTimeout;
/**
@@ -111,20 +112,20 @@ public class ContentEnricher extends AbstractReplyProducingMessageHandler implem
}
/**
* Set the timeout value for sending request messages. If not explicitly
* Set the timeout value for sending request messages. If not explicitly
* configured, the default is one second.
*
*
* @param requestTimeout the timeout value in milliseconds. Must not be null.
*/
public void setRequestTimeout(Long requestTimeout) {
Assert.notNull(requestTimeout, "requestTimeout must not be null");
this.requestTimeout = requestTimeout;
}
/**
* Set the timeout value for receiving reply messages. If not explicitly
* Set the timeout value for receiving reply messages. If not explicitly
* configured, the default is one second.
*
*
* @param replyTimeout the timeout value in milliseconds. Must not be null.
*/
public void setReplyTimeout(Long replyTimeout) {
@@ -168,6 +169,10 @@ public class ContentEnricher extends AbstractReplyProducingMessageHandler implem
this.shouldClonePayload = shouldClonePayload;
}
@Override
public void setIntegrationEvaluationContext(EvaluationContext evaluationContext) {
this.sourceEvaluationContext = evaluationContext;
}
/**
* Initializes the Content Enricher. Will instantiate an internal Gateway if
@@ -182,29 +187,34 @@ public class ContentEnricher extends AbstractReplyProducingMessageHandler implem
if (this.requestChannel != null) {
this.gateway = new Gateway();
this.gateway.setRequestChannel(requestChannel);
if (this.requestTimeout != null) {
this.gateway.setRequestTimeout(this.requestTimeout);
}
if (this.replyTimeout != null) {
this.gateway.setReplyTimeout(this.replyTimeout);
}
if (replyChannel != null) {
this.gateway.setReplyChannel(replyChannel);
}
this.gateway.afterPropertiesSet();
}
this.sourceEvaluationContext.addPropertyAccessor(new MapAccessor());
this.targetEvaluationContext.addPropertyAccessor(new MapAccessor());
BeanFactory beanFactory = this.getBeanFactory();
if (beanFactory != null) {
this.sourceEvaluationContext.setBeanResolver(new BeanFactoryResolver(beanFactory));
if (this.sourceEvaluationContext == null) {
this.sourceEvaluationContext = ExpressionUtils.createStandardEvaluationContext(this.getBeanFactory());
}
StandardEvaluationContext targetContext = ExpressionUtils.createStandardEvaluationContext(this.getBeanFactory());
// bean resolution is NOT allowed for the target of the enrichment
targetContext.setBeanResolver(null);
this.targetEvaluationContext = targetContext;
}
@Override
protected Object handleRequestMessage(Message<?> requestMessage) {
final Object requestPayload = requestMessage.getPayload();
@@ -249,7 +259,6 @@ public class ContentEnricher extends AbstractReplyProducingMessageHandler implem
return targetPayload;
}
/**
* Lifecycle implementation. If no requestChannel is defined, this method
* has no effect as in that case no Gateway is initialized.
@@ -283,7 +292,6 @@ public class ContentEnricher extends AbstractReplyProducingMessageHandler implem
}
}
/**
* Internal gateway implementation for request/reply handling.
* Simply exposes the sendAndReceiveMessage method.

View File

@@ -1,11 +1,11 @@
/*
* Copyright 2002-2011 the original author or authors.
*
* Copyright 2002-2013 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.
@@ -18,10 +18,9 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.context.expression.MapAccessor;
import org.springframework.core.convert.ConversionService;
import org.springframework.expression.BeanResolver;
import org.springframework.expression.EvaluationException;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
@@ -29,47 +28,41 @@ import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.integration.Message;
import org.springframework.integration.MessageHandlingException;
import org.springframework.integration.expression.ExpressionUtils;
/**
* @author Mark Fisher
* @author Dave Syer
* @author Oleg Zhurakousky
*
* @author Artem Bilan
* @author Gary Russell
*
* @since 2.0
*/
public abstract class AbstractExpressionEvaluator implements BeanFactoryAware {
public abstract class AbstractExpressionEvaluator implements BeanFactoryAware, InitializingBean {
private final Log logger = LogFactory.getLog(this.getClass());
private final StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
private volatile StandardEvaluationContext evaluationContext;
private final ExpressionParser expressionParser = new SpelExpressionParser();
private final BeanFactoryTypeConverter typeConverter = new BeanFactoryTypeConverter();
private volatile BeanResolver beanResolver;
public AbstractExpressionEvaluator() {
this.evaluationContext.setTypeConverter(this.typeConverter);
this.evaluationContext.addPropertyAccessor(new MapAccessor());
}
private volatile BeanFactory beanFactory;
/**
* Specify a BeanFactory in order to enable resolution via <code>@beanName</code> in the expression.
*/
public void setBeanFactory(final BeanFactory beanFactory) {
if (beanFactory != null) {
this.beanFactory = beanFactory;
this.typeConverter.setBeanFactory(beanFactory);
if (beanResolver == null) {
if (this.evaluationContext != null && this.evaluationContext.getBeanResolver() == null) {
this.evaluationContext.setBeanResolver(new BeanFactoryResolver(beanFactory));
}
}
}
public void setBeanResolver(BeanResolver beanResolver) {
this.beanResolver = beanResolver;
this.evaluationContext.setBeanResolver(beanResolver);
}
public void setConversionService(ConversionService conversionService) {
if (conversionService != null) {
@@ -77,7 +70,32 @@ public abstract class AbstractExpressionEvaluator implements BeanFactoryAware {
}
}
@Override
public void afterPropertiesSet() throws Exception {
getEvaluationContext();
}
protected StandardEvaluationContext getEvaluationContext() {
return this.getEvaluationContext(true);
}
/**
* Emits a WARN log if the beanFactory field is null, unless the argument is false.
* @param beanFactoryRequired set to false to suppress the warning.
* @return The evaluation context.
*/
protected final StandardEvaluationContext getEvaluationContext(boolean beanFactoryRequired) {
if (this.evaluationContext == null) {
if (this.beanFactory == null && !beanFactoryRequired) {
this.evaluationContext = ExpressionUtils.createStandardEvaluationContext();
}
else {
this.evaluationContext = ExpressionUtils.createStandardEvaluationContext(this.beanFactory);
}
if (this.typeConverter != null) {
this.evaluationContext.setTypeConverter(this.typeConverter);
}
}
return this.evaluationContext;
}
@@ -107,7 +125,7 @@ public abstract class AbstractExpressionEvaluator implements BeanFactoryAware {
}
protected <T> T evaluateExpression(String expression, Object input, Class<T> expectedType) {
return this.expressionParser.parseExpression(expression).getValue(this.evaluationContext, input, expectedType);
return this.expressionParser.parseExpression(expression).getValue(this.getEvaluationContext(), input, expectedType);
}
protected Object evaluateExpression(Expression expression, Object input) {
@@ -115,15 +133,15 @@ public abstract class AbstractExpressionEvaluator implements BeanFactoryAware {
}
protected <T> T evaluateExpression(Expression expression, Class<T> expectedType) {
return expression.getValue(this.evaluationContext, expectedType);
return expression.getValue(this.getEvaluationContext(), expectedType);
}
protected Object evaluateExpression(Expression expression) {
return expression.getValue(this.evaluationContext);
return expression.getValue(this.getEvaluationContext());
}
protected <T> T evaluateExpression(Expression expression, Object input, Class<T> expectedType) {
return expression.getValue(this.evaluationContext, input, expectedType);
return expression.getValue(this.getEvaluationContext(), input, expectedType);
}
}

View File

@@ -36,6 +36,7 @@ import java.util.concurrent.atomic.AtomicReference;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.framework.Advised;
import org.springframework.aop.support.AopUtils;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
@@ -158,7 +159,7 @@ public class MessagingMethodInvokerHelper<T> extends AbstractExpressionEvaluator
this.targetObject = targetObject;
this.handlerMethods = Collections.<Class<?>, HandlerMethod> singletonMap(handlerMethod.getTargetParameterType()
.getObjectType(), handlerMethod);
this.prepareEvaluationContext(this.getEvaluationContext(), method, annotationType);
this.prepareEvaluationContext(this.getEvaluationContext(false), method, annotationType);
this.setDisplayString(targetObject, method);
}
@@ -170,7 +171,7 @@ public class MessagingMethodInvokerHelper<T> extends AbstractExpressionEvaluator
this.targetObject = targetObject;
this.requiresReply = expectedType != null;
this.handlerMethods = this.findHandlerMethodsForTarget(targetObject, annotationType, methodName, requiresReply);
this.prepareEvaluationContext(this.getEvaluationContext(), methodName, annotationType);
this.prepareEvaluationContext(this.getEvaluationContext(false), methodName, annotationType);
this.setDisplayString(targetObject, methodName);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2013 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.
@@ -24,14 +24,18 @@ import org.junit.Test;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.context.support.StaticApplicationContext;
import org.springframework.expression.EvaluationContext;
import org.springframework.integration.Message;
import org.springframework.integration.annotation.Header;
import org.springframework.integration.annotation.Payload;
import org.springframework.integration.annotation.Publisher;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.config.IntegrationEvaluationContextFactoryBean;
import org.springframework.integration.context.IntegrationContextUtils;
/**
* @author Mark Fisher
* @author Gary Russell
* @since 2.0
*/
public class PublisherExpressionTests {
@@ -40,8 +44,14 @@ public class PublisherExpressionTests {
@Before
public void setup() {
public void setup() throws Exception {
context.registerSingleton("testChannel", QueueChannel.class);
IntegrationEvaluationContextFactoryBean factory = new IntegrationEvaluationContextFactoryBean();
factory.setBeanFactory(context);
factory.afterPropertiesSet();
EvaluationContext ec = factory.getObject();
context.getBeanFactory().registerSingleton(IntegrationContextUtils.INTEGRATION_EVALUATION_CONTEXT_BEAN_NAME, ec);
context.getBeanFactory().registerSingleton("foo", "foo");
}
@@ -56,8 +66,8 @@ public class PublisherExpressionTests {
TestBean proxy = (TestBean) pf.getProxy();
proxy.test("123");
Message<?> message = testChannel.receive(0);
assertNotNull(message);
assertEquals("hello", message.getPayload());
assertNotNull(message);
assertEquals("hellofoo", message.getPayload());
assertEquals("123", message.getHeaders().get("foo"));
}
@@ -70,7 +80,7 @@ public class PublisherExpressionTests {
static class TestBeanImpl implements TestBean {
@Publisher
@Payload("#return")
@Payload("#return + @foo")
public String test(@Header("foo") String foo) {
return "hello";
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2013 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,11 +17,13 @@
package org.springframework.integration.config.xml;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@@ -67,6 +69,7 @@ public class LoggingChannelAdapterParserTests {
assertEquals(Ordered.LOWEST_PRECEDENCE, TestUtils.getPropertyValue(loggingHandler, "order"));
assertEquals("INFO", TestUtils.getPropertyValue(loggingHandler, "level").toString());
assertEquals("payload.foo", TestUtils.getPropertyValue(loggingHandler, "expression.expression"));
assertNotNull(TestUtils.getPropertyValue(loggingHandler, "evaluationContext.beanResolver"));
}
@Test

View File

@@ -0,0 +1,96 @@
/*
* Copyright 2013 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.expression;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import org.junit.Test;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.support.ConversionServiceFactoryBean;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.expression.TypeConverter;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.integration.config.IntegrationEvaluationContextFactoryBean;
import org.springframework.integration.context.IntegrationContextUtils;
import org.springframework.integration.test.util.TestUtils;
/**
* @author Gary Russell
* @since 3.0
*
*/
public class ExpressionUtilsTests {
@Test
public void testEvaluationContext() {
GenericApplicationContext context = new GenericApplicationContext();
context.registerBeanDefinition(IntegrationContextUtils.INTEGRATION_EVALUATION_CONTEXT_BEAN_NAME,
new RootBeanDefinition(IntegrationEvaluationContextFactoryBean.class));
context.registerBeanDefinition(IntegrationContextUtils.INTEGRATION_CONVERSION_SERVICE_BEAN_NAME,
new RootBeanDefinition(ConversionServiceFactoryBean.class));
context.refresh();
StandardEvaluationContext evalContext = ExpressionUtils.createStandardEvaluationContext(context);
assertNotNull(evalContext.getBeanResolver());
assertNotNull(evalContext.getTypeConverter());
IntegrationEvaluationContextFactoryBean factory = context.getBean("&" + IntegrationContextUtils.INTEGRATION_EVALUATION_CONTEXT_BEAN_NAME,
IntegrationEvaluationContextFactoryBean.class);
assertSame(evalContext.getTypeConverter(), TestUtils.getPropertyValue(factory, "typeConverter"));
}
@Test
public void testEvaluationContextDefaultTypeConverter() {
GenericApplicationContext context = new GenericApplicationContext();
context.registerBeanDefinition(IntegrationContextUtils.INTEGRATION_EVALUATION_CONTEXT_BEAN_NAME,
new RootBeanDefinition(IntegrationEvaluationContextFactoryBean.class));
context.refresh();
StandardEvaluationContext evalContext = ExpressionUtils.createStandardEvaluationContext(context);
assertNotNull(evalContext.getBeanResolver());
TypeConverter typeConverter = evalContext.getTypeConverter();
assertNotNull(typeConverter);
assertSame(TestUtils.getPropertyValue(typeConverter, "defaultConversionService"), TestUtils.getPropertyValue(typeConverter, "conversionService"));
}
@Test
public void testEvaluationContextNoFactoryBean() {
GenericApplicationContext context = new GenericApplicationContext();
context.registerBeanDefinition(IntegrationContextUtils.INTEGRATION_CONVERSION_SERVICE_BEAN_NAME,
new RootBeanDefinition(ConversionServiceFactoryBean.class));
context.refresh();
StandardEvaluationContext evalContext = ExpressionUtils.createStandardEvaluationContext(context);
assertNull(evalContext.getBeanResolver());
TypeConverter typeConverter = evalContext.getTypeConverter();
assertNotNull(typeConverter);
assertNotSame(TestUtils.getPropertyValue(typeConverter, "defaultConversionService"),
TestUtils.getPropertyValue(typeConverter, "conversionService"));
assertSame(context.getBean(IntegrationContextUtils.INTEGRATION_CONVERSION_SERVICE_BEAN_NAME),
TestUtils.getPropertyValue(typeConverter, "conversionService"));
}
@Test
public void testEvaluationContextNoBeanFactory() {
StandardEvaluationContext evalContext = ExpressionUtils.createStandardEvaluationContext();
assertNull(evalContext.getBeanResolver());
TypeConverter typeConverter = evalContext.getTypeConverter();
assertNotNull(typeConverter);
assertSame(TestUtils.getPropertyValue(typeConverter, "defaultConversionService"),
TestUtils.getPropertyValue(typeConverter, "conversionService"));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2013 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.
@@ -34,9 +34,12 @@ import org.springframework.integration.annotation.Header;
import org.springframework.integration.annotation.Headers;
import org.springframework.integration.annotation.Payload;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.config.IntegrationEvaluationContextFactoryBean;
import org.springframework.integration.context.IntegrationContextUtils;
/**
* @author Mark Fisher
* @author Gary Russell
* @since 2.0
*/
public class GatewayProxyMessageMappingTests {
@@ -52,6 +55,11 @@ public class GatewayProxyMessageMappingTests {
factoryBean.setServiceInterface(TestGateway.class);
factoryBean.setDefaultRequestChannel(channel);
factoryBean.setBeanName("testGateway");
GenericApplicationContext context = new GenericApplicationContext();
context.registerBeanDefinition(IntegrationContextUtils.INTEGRATION_EVALUATION_CONTEXT_BEAN_NAME,
new RootBeanDefinition(IntegrationEvaluationContextFactoryBean.class));
context.refresh();
factoryBean.setBeanFactory(context);
factoryBean.afterPropertiesSet();
this.gateway = (TestGateway) factoryBean.getObject();
}
@@ -136,6 +144,8 @@ public class GatewayProxyMessageMappingTests {
gatewayDefinition.getPropertyValues().add("serviceInterface", TestGateway.class);
context.registerBeanDefinition("testGateway", gatewayDefinition);
context.registerBeanDefinition("testBean", new RootBeanDefinition(TestBean.class));
context.registerBeanDefinition(IntegrationContextUtils.INTEGRATION_EVALUATION_CONTEXT_BEAN_NAME,
new RootBeanDefinition(IntegrationEvaluationContextFactoryBean.class));
context.refresh();
TestGateway gateway = context.getBean("testGateway", TestGateway.class);
gateway.payloadAnnotationAtMethodLevelUsingBeanResolver("foo");
@@ -160,6 +170,8 @@ public class GatewayProxyMessageMappingTests {
gatewayDefinition.getPropertyValues().add("serviceInterface", TestGateway.class);
context.registerBeanDefinition("testGateway", gatewayDefinition);
context.registerBeanDefinition("testBean", new RootBeanDefinition(TestBean.class));
context.registerBeanDefinition(IntegrationContextUtils.INTEGRATION_EVALUATION_CONTEXT_BEAN_NAME,
new RootBeanDefinition(IntegrationEvaluationContextFactoryBean.class));
context.refresh();
TestGateway gateway = context.getBean("testGateway", TestGateway.class);
gateway.payloadAnnotationWithExpressionUsingBeanResolver("foo");

View File

@@ -21,12 +21,13 @@ import java.util.Arrays;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hamcrest.Description;
import org.hamcrest.TypeSafeMatcher;
import org.junit.Rule;
import org.junit.Test;
import org.hamcrest.TypeSafeMatcher;
import org.junit.rules.ExpectedException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.context.support.StaticApplicationContext;
@@ -38,6 +39,8 @@ import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.SpelParserConfiguration;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.integration.Message;
import org.springframework.integration.config.IntegrationEvaluationContextFactoryBean;
import org.springframework.integration.context.IntegrationContextUtils;
import org.springframework.integration.message.GenericMessage;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.integration.test.util.TestUtils;
@@ -69,7 +72,7 @@ public class ExpressionEvaluatingMessageProcessorTests {
@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void testProcessMessageWithParameterCoercion() {
public void testProcessMessageWithParameterCoercion() throws Exception {
@SuppressWarnings("unused")
class TestTarget {
public String stringify(int number) {
@@ -78,6 +81,7 @@ public class ExpressionEvaluatingMessageProcessorTests {
}
Expression expression = expressionParser.parseExpression("#target.stringify(payload)");
ExpressionEvaluatingMessageProcessor processor = new ExpressionEvaluatingMessageProcessor(expression);
processor.afterPropertiesSet();
EvaluationContext evaluationContext = TestUtils.getPropertyValue(processor, "evaluationContext", EvaluationContext.class);
evaluationContext.setVariable("target", new TestTarget());
assertEquals("2", processor.processMessage(new GenericMessage<String>("2")));
@@ -85,7 +89,7 @@ public class ExpressionEvaluatingMessageProcessorTests {
@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void testProcessMessageWithVoidResult() {
public void testProcessMessageWithVoidResult() throws Exception {
@SuppressWarnings("unused")
class TestTarget {
public void ping(String input) {
@@ -93,6 +97,7 @@ public class ExpressionEvaluatingMessageProcessorTests {
}
Expression expression = expressionParser.parseExpression("#target.ping(payload)");
ExpressionEvaluatingMessageProcessor processor = new ExpressionEvaluatingMessageProcessor(expression);
processor.afterPropertiesSet();
EvaluationContext evaluationContext = TestUtils.getPropertyValue(processor, "evaluationContext", EvaluationContext.class);
evaluationContext.setVariable("target", new TestTarget());
assertEquals(null, processor.processMessage(new GenericMessage<String>("2")));
@@ -100,7 +105,7 @@ public class ExpressionEvaluatingMessageProcessorTests {
@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void testProcessMessageWithParameterCoercionToNonPrimitive() {
public void testProcessMessageWithParameterCoercionToNonPrimitive() throws Exception {
class TestTarget {
@SuppressWarnings("unused")
public String find(Resource[] resources) {
@@ -110,7 +115,13 @@ public class ExpressionEvaluatingMessageProcessorTests {
}
Expression expression = expressionParser.parseExpression("#target.find(payload)");
ExpressionEvaluatingMessageProcessor processor = new ExpressionEvaluatingMessageProcessor(expression);
processor.setBeanFactory(new GenericApplicationContext().getBeanFactory());
ConfigurableListableBeanFactory beanFactory = new GenericApplicationContext().getBeanFactory();
processor.setBeanFactory(beanFactory);
IntegrationEvaluationContextFactoryBean factoryBean = new IntegrationEvaluationContextFactoryBean();
factoryBean.setBeanFactory(beanFactory);
beanFactory.registerSingleton(IntegrationContextUtils.INTEGRATION_EVALUATION_CONTEXT_BEAN_NAME,
factoryBean.getObject());
processor.afterPropertiesSet();
EvaluationContext evaluationContext = TestUtils.getPropertyValue(processor, "evaluationContext", EvaluationContext.class);
evaluationContext.setVariable("target", new TestTarget());
String result = (String) processor.processMessage(new GenericMessage<String>("classpath*:*.properties"));
@@ -146,28 +157,34 @@ public class ExpressionEvaluatingMessageProcessorTests {
@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void testProcessMessageWithBeanAsMethodArgument() {
public void testProcessMessageWithBeanAsMethodArgument() throws Exception {
StaticApplicationContext context = new StaticApplicationContext();
BeanDefinition beanDefinition = new RootBeanDefinition(String.class);
beanDefinition.getConstructorArgumentValues().addGenericArgumentValue("bar");
context.registerBeanDefinition("testString", beanDefinition);
context.registerBeanDefinition(IntegrationContextUtils.INTEGRATION_EVALUATION_CONTEXT_BEAN_NAME,
new RootBeanDefinition(IntegrationEvaluationContextFactoryBean.class));
Expression expression = expressionParser.parseExpression("payload.concat(@testString)");
ExpressionEvaluatingMessageProcessor processor = new ExpressionEvaluatingMessageProcessor(expression);
processor.setBeanFactory(context);
processor.afterPropertiesSet();
GenericMessage<String> message = new GenericMessage<String>("foo");
assertEquals("foobar", processor.processMessage(message));
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void testProcessMessageWithMethodCallOnBean() {
public void testProcessMessageWithMethodCallOnBean() throws Exception {
StaticApplicationContext context = new StaticApplicationContext();
BeanDefinition beanDefinition = new RootBeanDefinition(String.class);
beanDefinition.getConstructorArgumentValues().addGenericArgumentValue("bar");
context.registerBeanDefinition(IntegrationContextUtils.INTEGRATION_EVALUATION_CONTEXT_BEAN_NAME,
new RootBeanDefinition(IntegrationEvaluationContextFactoryBean.class));
context.registerBeanDefinition("testString", beanDefinition);
Expression expression = expressionParser.parseExpression("@testString.concat(payload)");
ExpressionEvaluatingMessageProcessor processor = new ExpressionEvaluatingMessageProcessor(expression);
processor.setBeanFactory(context);
processor.afterPropertiesSet();
GenericMessage<String> message = new GenericMessage<String>("foo");
assertEquals("barfoo", processor.processMessage(message));
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2013 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.
@@ -29,6 +29,7 @@ import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.expression.Expression;
import org.springframework.expression.common.LiteralExpression;
@@ -52,28 +53,29 @@ import org.springframework.scheduling.support.PeriodicTrigger;
/**
* @author Mark Fisher
* @author Gunnar Hillert
*
* @author Artem Bilan
*
* @since 2.1
*/
public class ContentEnricherTests {
private ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
private final ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
@Before
public void init() throws Exception {
taskScheduler.setPoolSize(2);
taskScheduler.afterPropertiesSet();
}
/**
* In this test a {@link Target} message is passed into an {@link ContentEnricher}.
* The Enricher passes the message to a "request-channel" that is backed by a
* {@link QueueChannel}. The consumer of the "request-channel" takes a long
* time to execute, longer actually than the specified "replyTimeout" set on
* In this test a {@link Target} message is passed into a {@link ContentEnricher}.
* The Enricher passes the message to a "request-channel" that is backed by a
* {@link QueueChannel}. The consumer of the "request-channel" takes a long
* time to execute, longer actually than the specified "replyTimeout" set on
* the {@link ContentEnricher}.
*
*
* Due to the occurring replyTimeout, a Null replyMessage is returned and because
* "requiresReply" is set to "true" on the {@link ContentEnricher}, a
* "requiresReply" is set to "true" on the {@link ContentEnricher}, a
* {@link ReplyRequiredException} is raised.
*/
@Test
@@ -81,26 +83,26 @@ public class ContentEnricherTests {
final long requestTimeout = 500L;
final long replyTimeout = 700L;
final DirectChannel replyChannel = new DirectChannel();
final QueueChannel requestChannel = new QueueChannel(1);
final ContentEnricher enricher = new ContentEnricher();
enricher.setRequestChannel(requestChannel);
enricher.setReplyChannel(replyChannel);
enricher.setOutputChannel(new NullChannel());
enricher.setOutputChannel(new NullChannel());
enricher.setRequestTimeout(requestTimeout);
enricher.setReplyTimeout(replyTimeout);
final ExpressionFactoryBean expressionFactoryBean = new ExpressionFactoryBean("payload");
expressionFactoryBean.setSingleton(false);
expressionFactoryBean.afterPropertiesSet();
final Map<String, Expression> expressions = new HashMap<String, Expression>();
expressions.put("name", new LiteralExpression("cartman"));
expressions.put("child.name", expressionFactoryBean.getObject());
enricher.setPropertyExpressions(expressions);
enricher.setRequiresReply(true);
enricher.setBeanName("Enricher");
@@ -117,45 +119,45 @@ public class ContentEnricherTests {
}
return new Target("child");
}
};
handler.afterPropertiesSet();
final PollingConsumer consumer = new PollingConsumer(requestChannel, handler);
final TestErrorHandler errorHandler = new TestErrorHandler();
consumer.setTrigger(new PeriodicTrigger(0));
consumer.setErrorHandler(errorHandler);
consumer.setTaskScheduler(taskScheduler);
consumer.setBeanFactory(mock(BeanFactory.class));
consumer.afterPropertiesSet();
consumer.start();
final Target target = new Target("replace me");
Message<?> requestMessage = MessageBuilder.withPayload(target).setReplyChannel(replyChannel).build();
try {
enricher.handleMessage(requestMessage);
} catch (ReplyRequiredException e) {
assertEquals("No reply produced by handler 'Enricher', and its 'requiresReply' property is set to true.", e.getMessage());
return;
}
fail("ReplyRequiredException expected.");
}
@Test
public void requestChannelSendTimingOut() {
final String requestChannelName = "Request_Channel";
final long requestTimeout = 200L;
QueueChannel replyChannel = new QueueChannel();
QueueChannel requestChannel = new RendezvousChannel();
requestChannel.setBeanName(requestChannelName);
ContentEnricher enricher = new ContentEnricher();
enricher.setRequestChannel(requestChannel);
enricher.setRequestTimeout(requestTimeout);
@@ -163,17 +165,17 @@ public class ContentEnricherTests {
Target target = new Target("replace me");
Message<?> requestMessage = MessageBuilder.withPayload(target).setReplyChannel(replyChannel).build();
try {
enricher.handleMessage(requestMessage);
} catch (MessageDeliveryException e) {
assertEquals("failed to send message to channel '" + requestChannelName
assertEquals("failed to send message to channel '" + requestChannelName
+ "' within timeout: " + requestTimeout, e.getMessage());
return;
}
}
@Test
public void simpleProperty() {
QueueChannel replyChannel = new QueueChannel();
@@ -203,52 +205,52 @@ public class ContentEnricherTests {
@Test
public void setReplyChannelWithoutRequestChannel() {
QueueChannel replyChannel = new QueueChannel();
ContentEnricher enricher = new ContentEnricher();
enricher.setReplyChannel(replyChannel);
try {
try {
enricher.afterPropertiesSet();
} catch (IllegalArgumentException e) {
assertEquals("If the replyChannel is set, then the requestChannel must not be null", e.getMessage());
return;
}
fail("Expected an exception.");
}
@Test
public void setNullReplyTimeout() {
ContentEnricher enricher = new ContentEnricher();
try {
enricher.setReplyTimeout(null);
} catch (IllegalArgumentException e) {
assertEquals("replyTimeout must not be null", e.getMessage());
return;
}
fail("Expected an exception.");
}
@Test
public void setNullRequestTimeout() {
ContentEnricher enricher = new ContentEnricher();
try {
enricher.setRequestTimeout(null);
} catch (IllegalArgumentException e) {
assertEquals("requestTimeout must not be null", e.getMessage());
return;
}
fail("Expected an exception.");
}
@Test
public void testSimplePropertyWithoutUsingRequestChannel() {
QueueChannel replyChannel = new QueueChannel();
@@ -257,6 +259,7 @@ public class ContentEnricherTests {
Map<String, Expression> propertyExpressions = new HashMap<String, Expression>();
propertyExpressions.put("name", parser.parseExpression("'just a static string'"));
enricher.setPropertyExpressions(propertyExpressions);
enricher.afterPropertiesSet();
Target target = new Target("replace me");
Message<?> requestMessage = MessageBuilder.withPayload(target).setReplyChannel(replyChannel).build();
enricher.handleMessage(requestMessage);
@@ -490,6 +493,7 @@ public class ContentEnricherTests {
this.child = child;
}
@Override
public Object clone() {
Target clone = new Target(this.name);
clone.setChild(this.child);
@@ -531,9 +535,10 @@ public class ContentEnricherTests {
this.name = name;
}
@Override
public Object clone() {
throw new IllegalStateException("Cloning not possible");
}
}
}
}

View File

@@ -2,10 +2,10 @@
<beans:beans xmlns="http://www.springframework.org/schema/integration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration.xsd">
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<channel id="output">
<queue/>
@@ -21,4 +21,23 @@
<transformer expression="null"/>
</chain>
<beans:bean id="integrationEvaluationContext" class="org.springframework.integration.config.IntegrationEvaluationContextFactoryBean">
<beans:property name="propertyAccessors">
<util:list>
<beans:bean class="org.springframework.integration.transformer.SpelTransformerIntegrationTests$FooAccessor"/>
</util:list>
</beans:property>
<beans:property name="functions">
<util:map>
<beans:entry key="bar"
value="#{T(org.springframework.integration.transformer.SpelTransformerIntegrationTests$BarFunction).getMethod('bar', T(org.springframework.integration.Message))}"/>
</util:map>
</beans:property>
</beans:bean>
<channel id="fooin" />
<transformer id="foo" input-channel="fooin" expression="payload.bar" />
<channel id="functionIn" />
<transformer id="bar" input-channel="functionIn" expression="#bar(#root)" />
</beans:beans>

View File

@@ -17,7 +17,9 @@
package org.springframework.integration.transformer;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import org.hamcrest.Matchers;
import org.junit.Test;
@@ -25,14 +27,22 @@ import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.expression.AccessException;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.PropertyAccessor;
import org.springframework.expression.TypedValue;
import org.springframework.integration.Message;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.core.PollableChannel;
import org.springframework.integration.handler.AbstractReplyProducingMessageHandler;
import org.springframework.integration.handler.ReplyRequiredException;
import org.springframework.integration.message.GenericMessage;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.util.Assert;
/**
* @author Mark Fisher
@@ -54,6 +64,12 @@ public class SpelTransformerIntegrationTests {
@Autowired
private MessageChannel transformerChainInput;
@Autowired @Qualifier("foo.handler")
private AbstractReplyProducingMessageHandler fooHandler;
@Autowired @Qualifier("bar.handler")
private AbstractReplyProducingMessageHandler barHandler;
@Test
public void simple() {
@@ -81,12 +97,90 @@ public class SpelTransformerIntegrationTests {
}
}
@Test
public void testCustomAccessor() {
QueueChannel outputChannel = new QueueChannel();
fooHandler.setOutputChannel(outputChannel);
Foo foo = new Foo("baz");
fooHandler.handleMessage(new GenericMessage<Foo>(foo));
Message<?> reply = outputChannel.receive(0);
assertNotNull(reply);
assertTrue(reply.getPayload() instanceof String);
assertEquals("baz", reply.getPayload());
}
@Test
public void testCustomFunction() {
QueueChannel outputChannel = new QueueChannel();
barHandler.setOutputChannel(outputChannel);
barHandler.handleMessage(new GenericMessage<String>("foo"));
Message<?> reply = outputChannel.receive(0);
assertNotNull(reply);
assertEquals("bar", reply.getPayload());
}
static class TestBean {
public String getFoo() {
return "test";
}
}
public static class Foo {
private String bar;
public Foo(String bar) {
this.bar = bar;
}
public String obtainBar() {
return bar;
}
public void updateBar(String bar) {
this.bar = bar;
}
}
public static class FooAccessor implements PropertyAccessor {
@Override
public Class<?>[] getSpecificTargetClasses() {
return new Class[] {Foo.class};
}
@Override
public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
return "bar".equals(name);
}
@Override
public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
Assert.isInstanceOf(Foo.class, target);
return new TypedValue(((Foo) target).obtainBar(), TypeDescriptor.valueOf(String.class));
}
@Override
public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
return "bar".equals(name);
}
@Override
public void write(EvaluationContext context, Object target, String name, Object newValue)
throws AccessException {
Assert.isInstanceOf(Foo.class, target);
Assert.isInstanceOf(String.class, newValue);
((Foo) target).updateBar((String) newValue);
}
}
public static class BarFunction {
public static String bar(Message<?> message) {
return "bar";
}
}
}

View File

@@ -39,6 +39,7 @@ import org.springframework.context.event.ContextClosedEvent;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.ContextStartedEvent;
import org.springframework.context.event.ContextStoppedEvent;
import org.springframework.context.event.SimpleApplicationEventMulticaster;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.GenericApplicationContext;
@@ -138,9 +139,24 @@ public class ApplicationEventListeningMessageProducerTests {
ApplicationEventListeningMessageProducer adapter = new ApplicationEventListeningMessageProducer();
adapter.setPayloadExpression("'received: ' + source");
adapter.setOutputChannel(channel);
adapter.start();
GenericApplicationContext ctx = TestUtils.createTestApplicationContext();
ConfigurableListableBeanFactory beanFactory = ctx.getBeanFactory();
beanFactory.registerSingleton(AbstractApplicationContext.APPLICATION_EVENT_MULTICASTER_BEAN_NAME,
new SimpleApplicationEventMulticaster(beanFactory));
adapter.setBeanFactory(beanFactory);
beanFactory.registerSingleton("testListenerMessageProducer", adapter);
adapter.afterPropertiesSet();
ctx.refresh();
Message<?> message1 = channel.receive(0);
assertNull(message1);
// ContextRefreshedEvent
assertNotNull(message1);
assertTrue(message1.getPayload().toString()
.contains("org.springframework.integration.test.util.TestUtils$TestApplicationContext"));
adapter.onApplicationEvent(new TestApplicationEvent1());
adapter.onApplicationEvent(new TestApplicationEvent2());
Message<?> message2 = channel.receive(20);

View File

@@ -26,15 +26,13 @@ import java.nio.charset.Charset;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.context.expression.MapAccessor;
import org.springframework.expression.Expression;
import org.springframework.expression.common.LiteralExpression;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.integration.Message;
import org.springframework.integration.MessageHandlingException;
import org.springframework.integration.core.MessageHandler;
import org.springframework.integration.expression.ExpressionUtils;
import org.springframework.integration.file.support.FileExistsMode;
import org.springframework.integration.handler.AbstractReplyProducingMessageHandler;
import org.springframework.integration.support.MessageBuilder;
@@ -84,7 +82,7 @@ public class FileWritingMessageHandler extends AbstractReplyProducingMessageHand
private volatile FileNameGenerator fileNameGenerator = new DefaultFileNameGenerator();
private final StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
private volatile StandardEvaluationContext evaluationContext;
private final Expression destinationDirectoryExpression;
@@ -220,13 +218,7 @@ public class FileWritingMessageHandler extends AbstractReplyProducingMessageHand
super.onInit();
this.evaluationContext.addPropertyAccessor(new MapAccessor());
final BeanFactory beanFactory = this.getBeanFactory();
if (beanFactory != null) {
this.evaluationContext.setBeanResolver(new BeanFactoryResolver(beanFactory));
}
this.evaluationContext = ExpressionUtils.createStandardEvaluationContext(this.getBeanFactory());
if (this.destinationDirectoryExpression instanceof LiteralExpression) {
final File directory = new File(this.destinationDirectoryExpression.getValue(

View File

@@ -27,10 +27,12 @@ import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.integration.MessagingException;
import org.springframework.integration.expression.IntegrationEvaluationContextAware;
import org.springframework.integration.file.filters.FileListFilter;
import org.springframework.integration.file.remote.session.Session;
import org.springframework.integration.file.remote.session.SessionFactory;
@@ -48,13 +50,15 @@ import org.springframework.util.ObjectUtils;
* @author Josh Long
* @author Mark Fisher
* @author Oleg Zhurakousky
* @author Gary Russell
* @since 2.0
*/
public abstract class AbstractInboundFileSynchronizer<F> implements InboundFileSynchronizer, InitializingBean {
public abstract class AbstractInboundFileSynchronizer<F> implements InboundFileSynchronizer,
InitializingBean, IntegrationEvaluationContextAware {
protected final Log logger = LogFactory.getLog(this.getClass());
private final StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
private volatile EvaluationContext evaluationContext;
private volatile String remoteFileSeparator = "/";
@@ -86,6 +90,7 @@ public abstract class AbstractInboundFileSynchronizer<F> implements InboundFileS
*/
private volatile boolean deleteRemoteFiles;
private volatile BeanFactory beanFactory;
/**
* Create a synchronizer with the {@link SessionFactory} used to acquire {@link Session} instances.
@@ -125,8 +130,14 @@ public abstract class AbstractInboundFileSynchronizer<F> implements InboundFileS
this.deleteRemoteFiles = deleteRemoteFiles;
}
@Override
public void setIntegrationEvaluationContext(EvaluationContext evaluationContext) {
this.evaluationContext = evaluationContext;
}
public final void afterPropertiesSet() {
Assert.notNull(this.remoteDirectory, "remoteDirectory must not be null");
Assert.notNull(this.evaluationContext, "evaluationContext must not be null");
}
protected final List<F> filterFiles(F[] files) {

View File

@@ -45,21 +45,29 @@
directory="${java.io.tmpdir}"/>
<file:outbound-channel-adapter id="usageChannel"
filename-generator-expression="'fileToAppend.txt'"
filename-generator-expression="@fooString"
mode="APPEND"
directory="test">
directory-expression="@barString">
<file:request-handler-advice-chain>
<bean class="org.springframework.integration.file.config.FileOutboundChannelAdapterParserTests$FooAdvice" />
</file:request-handler-advice-chain>
</file:outbound-channel-adapter>
<bean id="fooString" class="java.lang.String">
<constructor-arg value="fileToAppend.txt"/>
</bean>
<bean id="barString" class="java.lang.String">
<constructor-arg value="test"/>
</bean>
<file:outbound-channel-adapter id="usageChannelWithFailMode"
filename-generator-expression="'fileToAppend.txt'"
filename-generator-expression="'fileToFail.txt'"
mode="FAIL"
directory="test"/>
<file:outbound-channel-adapter id="usageChannelWithIgnoreMode"
filename-generator-expression="'fileToAppend.txt'"
filename-generator-expression="'fileToIgnore.txt'"
mode="IGNORE"
directory="test"/>

View File

@@ -29,6 +29,7 @@ import java.nio.charset.Charset;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.expression.Expression;
@@ -189,14 +190,14 @@ public class FileOutboundChannelAdapterParserTests {
String actualFileContent = new String(FileCopyUtils.copyToByteArray(testFile));
assertEquals(expectedFileContent, actualFileContent);
assertEquals(4, adviceCalled);
testFile.delete();
}
@Test
public void adapterUsageWithFailMode() throws Exception{
String expectedFileContent = "Initial File Content:String content:byte[] content:File content";
File testFile = new File("test/fileToAppend.txt");
File testFile = new File("test/fileToFail.txt");
if (testFile.exists()){
testFile.delete();
}
@@ -207,15 +208,12 @@ public class FileOutboundChannelAdapterParserTests {
usageChannelWithFailMode.send(new GenericMessage<String>("String content:"));
}
catch (MessagingException e) {
assertTrue(e.getMessage().contains("The destination file already exists at"));
testFile.delete();
return;
}
Assert.fail("Was expecting an Exception to be thrown.");
String actualFileContent = new String(FileCopyUtils.copyToByteArray(testFile));
assertEquals(expectedFileContent, actualFileContent);
}
@Test
@@ -224,7 +222,7 @@ public class FileOutboundChannelAdapterParserTests {
String expectedFileContent = "Initial File Content:";
File testFile = new File("test/fileToAppend.txt");
File testFile = new File("test/fileToIgnore.txt");
if (testFile.exists()){
testFile.delete();
}
@@ -234,6 +232,7 @@ public class FileOutboundChannelAdapterParserTests {
String actualFileContent = new String(FileCopyUtils.copyToByteArray(testFile));
assertEquals(expectedFileContent, actualFileContent);
testFile.delete();
}

View File

@@ -24,7 +24,7 @@
filename-pattern="*.txt"
local-directory="."
remote-file-separator=""
local-filename-generator-expression="#this.toUpperCase() + '.a'"
local-filename-generator-expression="#this.toUpperCase() + '.a' + @fooString"
comparator="comparator"
temporary-file-suffix=".foo"
local-filter="acceptAllFilter"
@@ -34,6 +34,10 @@
</int:poller>
</int-ftp:inbound-channel-adapter>
<bean id="fooString" class="java.lang.String">
<constructor-arg value="foo" />
</bean>
<bean id="acceptAllFilter" class="org.springframework.integration.file.filters.AcceptAllFileListFilter" />
<int:transaction-synchronization-factory id="syncFactory">

View File

@@ -24,10 +24,12 @@ import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Comparator;
import java.util.Map;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.atomic.AtomicReference;
import org.junit.Test;
@@ -39,11 +41,14 @@ import org.springframework.integration.endpoint.SourcePollingChannelAdapter;
import org.springframework.integration.file.filters.FileListFilter;
import org.springframework.integration.file.remote.session.CachingSessionFactory;
import org.springframework.integration.file.remote.session.Session;
import org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizer;
import org.springframework.integration.ftp.filters.FtpSimplePatternFileListFilter;
import org.springframework.integration.ftp.inbound.FtpInboundFileSynchronizer;
import org.springframework.integration.ftp.inbound.FtpInboundFileSynchronizingMessageSource;
import org.springframework.integration.ftp.session.DefaultFtpSessionFactory;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.ReflectionUtils.MethodCallback;
/**
* @author Oleg Zhurakousky
@@ -82,6 +87,18 @@ public class FtpInboundChannelAdapterParserTests {
assertTrue(DefaultFtpSessionFactory.class.isAssignableFrom(sessionFactory.getClass()));
FileListFilter<?> acceptAllFilter = ac.getBean("acceptAllFilter", FileListFilter.class);
assertTrue(TestUtils.getPropertyValue(inbound, "fileSource.scanner.filter.fileFilters", Collection.class).contains(acceptAllFilter));
final AtomicReference<Method> genMethod = new AtomicReference<Method>();
ReflectionUtils.doWithMethods(AbstractInboundFileSynchronizer.class, new MethodCallback() {
@Override
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
if ("generateLocalFileName".equals(method.getName())) {
method.setAccessible(true);
genMethod.set(method);
}
}
});
assertEquals("FOO.afoo", genMethod.get().invoke(fisync, "foo"));
}
@Test

View File

@@ -16,6 +16,17 @@
package org.springframework.integration.ftp.inbound;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.File;
import java.io.OutputStream;
import java.util.ArrayList;
@@ -32,23 +43,14 @@ import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.SpelParserConfiguration;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.integration.Message;
import org.springframework.integration.expression.ExpressionUtils;
import org.springframework.integration.ftp.filters.FtpRegexPatternFileListFilter;
import org.springframework.integration.ftp.session.AbstractFtpSessionFactory;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
/**
* @author Oleg Zhurakousky
* @author Gunnar Hillert
* @author Gary Russell
* @since 2.0
*/
public class FtpInboundRemoteFileSystemSynchronizerTests {
@@ -80,6 +82,7 @@ public class FtpInboundRemoteFileSystemSynchronizerTests {
synchronizer.setDeleteRemoteFiles(true);
synchronizer.setRemoteDirectory("remote-test-dir");
synchronizer.setFilter(new FtpRegexPatternFileListFilter(".*\\.test$"));
synchronizer.setIntegrationEvaluationContext(ExpressionUtils.createStandardEvaluationContext());
ExpressionParser expressionParser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
Expression expression = expressionParser.parseExpression("#this.toUpperCase() + '.a'");

View File

@@ -1,11 +1,11 @@
/*
* Copyright 2002-2011 the original author or authors.
*
* Copyright 2002-2013 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.
@@ -17,11 +17,13 @@ import static org.mockito.Mockito.mock;
import org.junit.Before;
import org.junit.Test;
import org.springframework.data.gemfire.listener.ContinuousQueryListenerContainer;
import org.springframework.integration.Message;
import org.springframework.integration.MessagingException;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.core.MessageHandler;
import org.springframework.integration.expression.ExpressionUtils;
import com.gemstone.gemfire.cache.Operation;
import com.gemstone.gemfire.cache.query.CqEvent;
@@ -30,6 +32,7 @@ import com.gemstone.gemfire.cache.query.internal.CqQueryImpl;
/**
* @author David Turanski
* @author Artem Bilan
* @since 2.1
*/
public class ContinuousQueryMessageProducerTests {
@@ -45,6 +48,7 @@ public class ContinuousQueryMessageProducerTests {
cqMessageProducer = new ContinuousQueryMessageProducer(queryListenerContainer, "");
DirectChannel outputChannel = new DirectChannel();
cqMessageProducer.setOutputChannel(outputChannel);
cqMessageProducer.setIntegrationEvaluationContext(ExpressionUtils.createStandardEvaluationContext());
handler = new CqMessageHandler();
outputChannel.subscribe(handler);
}
@@ -140,7 +144,7 @@ public class ContinuousQueryMessageProducerTests {
/*
* (non-Javadoc)
*
*
* @see
* org.springframework.integration.core.MessageHandler#handleMessage
* (org.springframework.integration.Message)

View File

@@ -28,7 +28,6 @@ import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.http.HttpEntity;
@@ -549,14 +548,8 @@ public abstract class HttpRequestHandlingEndpointSupport extends MessagingGatewa
return httpStatus;
}
protected StandardEvaluationContext createEvaluationContext(){
if (this.getBeanFactory() != null) {
return ExpressionUtils.createStandardEvaluationContext(new BeanFactoryResolver(this.getBeanFactory()),
this.getConversionService());
}
else {
return ExpressionUtils.createStandardEvaluationContext(this.getConversionService());
}
protected StandardEvaluationContext createEvaluationContext() {
return ExpressionUtils.createStandardEvaluationContext(this.getBeanFactory());
}
private void validateSupportedMethods() {

View File

@@ -28,8 +28,6 @@ import java.util.Map;
import javax.xml.transform.Source;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.context.expression.MapAccessor;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.ConverterRegistry;
@@ -50,6 +48,7 @@ import org.springframework.integration.Message;
import org.springframework.integration.MessageHandlingException;
import org.springframework.integration.MessagingException;
import org.springframework.integration.core.MessageHandler;
import org.springframework.integration.expression.ExpressionUtils;
import org.springframework.integration.handler.AbstractReplyProducingMessageHandler;
import org.springframework.integration.http.support.DefaultHttpHeaderMapper;
import org.springframework.integration.mapping.HeaderMapper;
@@ -88,7 +87,7 @@ public class HttpRequestExecutingMessageHandler extends AbstractReplyProducingMe
private final RestTemplate restTemplate;
private final StandardEvaluationContext evaluationContext;
private volatile StandardEvaluationContext evaluationContext;
private final Expression uriExpression;
@@ -156,9 +155,6 @@ public class HttpRequestExecutingMessageHandler extends AbstractReplyProducingMe
Assert.notNull(uriExpression, "URI Expression is required");
this.restTemplate = (restTemplate == null ? new RestTemplate() : restTemplate);
this.uriExpression = uriExpression;
StandardEvaluationContext sec = new StandardEvaluationContext();
sec.addPropertyAccessor(new MapAccessor());
this.evaluationContext = sec;
}
/**
@@ -295,10 +291,8 @@ public class HttpRequestExecutingMessageHandler extends AbstractReplyProducingMe
@Override
public void onInit() {
super.onInit();
BeanFactory beanFactory = this.getBeanFactory();
if (beanFactory != null) {
this.evaluationContext.setBeanResolver(new BeanFactoryResolver(beanFactory));
}
this.evaluationContext = ExpressionUtils.createStandardEvaluationContext(this.getBeanFactory());
ConversionService conversionService = this.getConversionService();
if (conversionService == null){
conversionService = new GenericConversionService();

View File

@@ -44,8 +44,10 @@ import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
@@ -90,6 +92,8 @@ public class HttpRequestExecutingMessageHandlerTests {
MockRestTemplate template = new MockRestTemplate();
new DirectFieldAccessor(handler).setPropertyValue("restTemplate", template);
handler.setHttpMethod(HttpMethod.POST);
setBeanFactory(handler);
handler.afterPropertiesSet();
Map<String, String> form = new LinkedHashMap<String, String>();
form.put("a", "1");
form.put("b", "2");
@@ -122,6 +126,8 @@ public class HttpRequestExecutingMessageHandlerTests {
MockRestTemplate template = new MockRestTemplate();
new DirectFieldAccessor(handler).setPropertyValue("restTemplate", template);
handler.setHttpMethod(HttpMethod.POST);
setBeanFactory(handler);
handler.afterPropertiesSet();
Map<String, Object> form = new LinkedHashMap<String, Object>();
form.put("a", new City("Philadelphia"));
form.put("b", new City("Ambler"));
@@ -153,6 +159,8 @@ public class HttpRequestExecutingMessageHandlerTests {
MockRestTemplate template = new MockRestTemplate();
new DirectFieldAccessor(handler).setPropertyValue("restTemplate", template);
handler.setHttpMethod(HttpMethod.POST);
setBeanFactory(handler);
handler.afterPropertiesSet();
Map<Object, Object> form = new LinkedHashMap<Object, Object>();
form.put(1, new City("Philadelphia"));
form.put(2, new City("Ambler"));
@@ -185,6 +193,8 @@ public class HttpRequestExecutingMessageHandlerTests {
MockRestTemplate template = new MockRestTemplate();
new DirectFieldAccessor(handler).setPropertyValue("restTemplate", template);
handler.setHttpMethod(HttpMethod.POST);
setBeanFactory(handler);
handler.afterPropertiesSet();
Map<String, Object> form = new LinkedHashMap<String, Object>();
form.put("a", new String[] { "1", "2", "3" });
form.put("b", "4");
@@ -230,6 +240,8 @@ public class HttpRequestExecutingMessageHandlerTests {
MockRestTemplate template = new MockRestTemplate();
new DirectFieldAccessor(handler).setPropertyValue("restTemplate", template);
handler.setHttpMethod(HttpMethod.POST);
setBeanFactory(handler);
handler.afterPropertiesSet();
Map<String, Object> form = new LinkedHashMap<String, Object>();
form.put("a", new int[]{1,2,3});
form.put("b", "4");
@@ -277,6 +289,8 @@ public class HttpRequestExecutingMessageHandlerTests {
MockRestTemplate template = new MockRestTemplate();
new DirectFieldAccessor(handler).setPropertyValue("restTemplate", template);
handler.setHttpMethod(HttpMethod.POST);
setBeanFactory(handler);
handler.afterPropertiesSet();
Map<String, Object> form = new LinkedHashMap<String, Object>();
form.put("a", new Object[]{null, 4, null});
form.put("b", "4");
@@ -318,6 +332,8 @@ public class HttpRequestExecutingMessageHandlerTests {
MockRestTemplate template = new MockRestTemplate();
new DirectFieldAccessor(handler).setPropertyValue("restTemplate", template);
handler.setHttpMethod(HttpMethod.POST);
setBeanFactory(handler);
handler.afterPropertiesSet();
Map<String, Object> form = new LinkedHashMap<String, Object>();
List<Object> list = new ArrayList<Object>();
list.add(null);
@@ -363,6 +379,8 @@ public class HttpRequestExecutingMessageHandlerTests {
MockRestTemplate template = new MockRestTemplate();
new DirectFieldAccessor(handler).setPropertyValue("restTemplate", template);
handler.setHttpMethod(HttpMethod.POST);
setBeanFactory(handler);
handler.afterPropertiesSet();
Map<String, Object> form = new LinkedHashMap<String, Object>();
List<Object> list = new ArrayList<Object>();
list.add(null);
@@ -403,6 +421,8 @@ public class HttpRequestExecutingMessageHandlerTests {
MockRestTemplate template = new MockRestTemplate();
new DirectFieldAccessor(handler).setPropertyValue("restTemplate", template);
handler.setHttpMethod(HttpMethod.POST);
setBeanFactory(handler);
handler.afterPropertiesSet();
Map<String, Object> form = new LinkedHashMap<String, Object>();
List<String> listA = new ArrayList<String>();
listA.add("1");
@@ -446,6 +466,8 @@ public class HttpRequestExecutingMessageHandlerTests {
MockRestTemplate template = new MockRestTemplate();
new DirectFieldAccessor(handler).setPropertyValue("restTemplate", template);
handler.setHttpMethod(HttpMethod.POST);
setBeanFactory(handler);
handler.afterPropertiesSet();
Map<String, Object> form = new LinkedHashMap<String, Object>();
List<Object> listA = new ArrayList<Object>();
listA.add(new City("Philadelphia"));
@@ -489,6 +511,8 @@ public class HttpRequestExecutingMessageHandlerTests {
MockRestTemplate template = new MockRestTemplate();
new DirectFieldAccessor(handler).setPropertyValue("restTemplate", template);
handler.setHttpMethod(HttpMethod.POST);
setBeanFactory(handler);
handler.afterPropertiesSet();
Map<String, Object> form = new LinkedHashMap<String, Object>();
form.put("a", null);
form.put("b", "foo");
@@ -524,6 +548,8 @@ public class HttpRequestExecutingMessageHandlerTests {
MockRestTemplate template = new MockRestTemplate();
new DirectFieldAccessor(handler).setPropertyValue("restTemplate", template);
handler.setHttpMethod(HttpMethod.POST);
setBeanFactory(handler);
handler.afterPropertiesSet();
byte[] bytes = "Hello World".getBytes();
Message<?> message = MessageBuilder.withPayload(bytes).build();
@@ -538,7 +564,7 @@ public class HttpRequestExecutingMessageHandlerTests {
HttpEntity<?> request = template.lastRequestEntity.get();
Object body = request.getBody();
assertTrue(body instanceof byte[]);
assertEquals("Hello World", new String((byte[])bytes));
assertEquals("Hello World", new String(bytes));
assertEquals(MediaType.APPLICATION_OCTET_STREAM, request.getHeaders().getContentType());
}
@@ -548,6 +574,8 @@ public class HttpRequestExecutingMessageHandlerTests {
MockRestTemplate template = new MockRestTemplate();
new DirectFieldAccessor(handler).setPropertyValue("restTemplate", template);
handler.setHttpMethod(HttpMethod.POST);
setBeanFactory(handler);
handler.afterPropertiesSet();
Message<?> message = MessageBuilder.withPayload(mock(Source.class)).build();
Exception exception = null;
@@ -573,6 +601,7 @@ public class HttpRequestExecutingMessageHandlerTests {
new DirectFieldAccessor(handler).setPropertyValue("restTemplate", template);
handler.setHttpMethod(HttpMethod.GET);
handler.setExtractPayload(true);
setBeanFactory(handler);
handler.afterPropertiesSet();
// should not see a warn message since 'setExtractPayload' is not set explicitly
@@ -581,6 +610,7 @@ public class HttpRequestExecutingMessageHandlerTests {
template = new MockRestTemplate();
new DirectFieldAccessor(handler).setPropertyValue("restTemplate", template);
handler.setHttpMethod(HttpMethod.GET);
setBeanFactory(handler);
handler.afterPropertiesSet();
// should not see a warn message since HTTP method is not GET
@@ -590,6 +620,7 @@ public class HttpRequestExecutingMessageHandlerTests {
new DirectFieldAccessor(handler).setPropertyValue("restTemplate", template);
handler.setHttpMethod(HttpMethod.POST);
handler.setExtractPayload(true);
setBeanFactory(handler);
handler.afterPropertiesSet();
}
@@ -600,6 +631,8 @@ public class HttpRequestExecutingMessageHandlerTests {
MockRestTemplate template = new MockRestTemplate();
new DirectFieldAccessor(handler).setPropertyValue("restTemplate", template);
handler.setHttpMethod(HttpMethod.GET);
setBeanFactory(handler);
handler.afterPropertiesSet();
Message<?> message = MessageBuilder.withPayload(mock(Source.class)).build();
Exception exception = null;
@@ -705,6 +738,8 @@ public class HttpRequestExecutingMessageHandlerTests {
HttpRequestExecutingMessageHandler handler = new HttpRequestExecutingMessageHandler(
new SpelExpressionParser().parseExpression("headers['foo']"),
restTemplate);
setBeanFactory(handler);
handler.afterPropertiesSet();
String theURL = "http://bar/baz?foo#bar";
Message<?> message = MessageBuilder.withPayload("").setHeader("foo", theURL).build();
try {
@@ -721,6 +756,8 @@ public class HttpRequestExecutingMessageHandlerTests {
new SpelExpressionParser().parseExpression("'http://my.RabbitMQ.com/api/' + payload"),
restTemplate);
handler.setEncodeUri(false);
setBeanFactory(handler);
handler.afterPropertiesSet();
Message<?> message = MessageBuilder.withPayload("queues/%2f/si.test.queue?foo#bar").build();
try {
handler.handleRequestMessage(message);
@@ -779,6 +816,7 @@ public class HttpRequestExecutingMessageHandlerTests {
List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
converters.add(new SerializingHttpMessageConverter());
handler.setMessageConverters(converters);
setBeanFactory(handler);
handler.afterPropertiesSet();
RestTemplate restTemplate = TestUtils.getPropertyValue(handler, "restTemplate", RestTemplate.class);
@@ -813,6 +851,7 @@ public class HttpRequestExecutingMessageHandlerTests {
List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
converters.add(new SerializingHttpMessageConverter());
handler.setMessageConverters(converters);
setBeanFactory(handler);
handler.afterPropertiesSet();
RestTemplate restTemplate = TestUtils.getPropertyValue(handler, "restTemplate", RestTemplate.class);
@@ -836,6 +875,10 @@ public class HttpRequestExecutingMessageHandlerTests {
assertEquals("x-java-serialized-object", accept.get(0).getSubtype());
}
private void setBeanFactory(HttpRequestExecutingMessageHandler handler) {
handler.setBeanFactory(mock(BeanFactory.class));
}
private HttpHeaders setUpMocksToCaptureSentHeaders(RestTemplate restTemplate) throws IOException {
HttpHeaders headers = new HttpHeaders();

View File

@@ -52,6 +52,7 @@ public class UriVariableExpressionTests {
throw new RuntimeException("intentional");
}
});
handler.afterPropertiesSet();
Message<?> message = new GenericMessage<Object>("bar");
Exception exception = null;
try {

View File

@@ -26,14 +26,14 @@ import javax.sql.DataSource;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.context.expression.MapAccessor;
import org.springframework.expression.BeanResolver;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.common.LiteralExpression;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.integration.Message;
import org.springframework.integration.MessageHeaders;
import org.springframework.integration.expression.ExpressionUtils;
import org.springframework.integration.jdbc.storedproc.ProcedureParameter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
@@ -60,13 +60,15 @@ import com.google.common.cache.LoadingCache;
*
* @author Gunnar Hillert
* @author Artem Bilan
* @author Gary Russell
* @since 2.1
*
*/
@ManagedResource
public class StoredProcExecutor implements BeanFactoryAware, InitializingBean {
private final StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
private volatile EvaluationContext evaluationContext;
private volatile BeanFactory beanFactory = null;
private volatile int jdbcCallOperationsCacheSize = 10;
@@ -220,11 +222,7 @@ public class StoredProcExecutor implements BeanFactoryAware, InitializingBean {
this.jdbcCallOperationsCache.put(storedProcedureName, simpleJdbcCall);
}
this.evaluationContext.addPropertyAccessor(new MapAccessor());
if (this.beanFactory != null) {
this.evaluationContext.setBeanResolver(new BeanFactoryResolver(this.beanFactory));
}
this.evaluationContext = ExpressionUtils.createStandardEvaluationContext(beanFactory);
}

View File

@@ -33,10 +33,12 @@ import javax.mail.internet.MimeMessage;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.integration.context.IntegrationObjectSupport;
import org.springframework.integration.expression.ExpressionUtils;
import org.springframework.util.Assert;
/**
@@ -75,7 +77,7 @@ public abstract class AbstractMailReceiver extends IntegrationObjectSupport impl
private volatile Authenticator javaMailAuthenticator;
private final StandardEvaluationContext context = new StandardEvaluationContext();
private volatile StandardEvaluationContext evaluationContext;
private volatile Expression selectorExpression;
@@ -312,7 +314,7 @@ public abstract class AbstractMailReceiver extends IntegrationObjectSupport impl
for (int i = 0; i < messages.length; i++) {
MimeMessage message = (MimeMessage) messages[i];
if (this.selectorExpression != null) {
if (this.selectorExpression.getValue(this.context, message, Boolean.class)){
if (this.selectorExpression.getValue(this.evaluationContext, message, Boolean.class)) {
filteredMessages.add(message);
}
else {
@@ -381,6 +383,7 @@ public abstract class AbstractMailReceiver extends IntegrationObjectSupport impl
protected void onInit() throws Exception {
super.onInit();
this.folderOpenMode = Folder.READ_WRITE;
this.evaluationContext = ExpressionUtils.createStandardEvaluationContext(this.getBeanFactory());
this.initialized = true;
}

View File

@@ -24,6 +24,10 @@ import javax.mail.URLName;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.expression.Expression;
@@ -40,7 +44,7 @@ import org.springframework.util.StringUtils;
* @author Oleg Zhurakousky
* @since 1.0.3
*/
public class MailReceiverFactoryBean implements FactoryBean<MailReceiver>, DisposableBean {
public class MailReceiverFactoryBean implements FactoryBean<MailReceiver>, DisposableBean, BeanFactoryAware {
protected final Log logger = LogFactory.getLog(this.getClass());
@@ -70,6 +74,7 @@ public class MailReceiverFactoryBean implements FactoryBean<MailReceiver>, Dispo
private volatile SearchTermStrategy searchTermStrategy;
private volatile BeanFactory beanFactory;
public void setStoreUri(String storeUri) {
this.storeUri = storeUri;
@@ -115,6 +120,11 @@ public class MailReceiverFactoryBean implements FactoryBean<MailReceiver>, Dispo
this.searchTermStrategy = searchTermStrategy;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
public MailReceiver getObject() throws Exception {
if (this.receiver == null) {
this.receiver = this.createReceiver();
@@ -184,6 +194,9 @@ public class MailReceiverFactoryBean implements FactoryBean<MailReceiver>, Dispo
else if (isImap) {
((ImapMailReceiver) receiver).setShouldMarkMessagesAsRead(this.shouldMarkMessagesAsRead);
}
if (this.beanFactory != null) {
receiver.setBeanFactory(this.beanFactory);
}
receiver.afterPropertiesSet();
return receiver;
}

View File

@@ -28,6 +28,8 @@ import javax.mail.Authenticator;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.xml.sax.SAXParseException;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.BeanDefinitionStoreException;
@@ -45,7 +47,6 @@ import org.springframework.integration.mail.SearchTermStrategy;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.xml.sax.SAXParseException;
/**
* @author Mark Fisher
@@ -132,6 +133,7 @@ public class InboundChannelAdapterParserTests {
assertEquals(ImapMailReceiver.class, receiver.getClass());
Boolean value = (Boolean) new DirectFieldAccessor(receiver).getPropertyValue("shouldDeleteMessages");
assertTrue(value);
assertNotNull(TestUtils.getPropertyValue(receiver, "evaluationContext.beanResolver"));
}
@Test

View File

@@ -168,13 +168,8 @@ public class MongoDbMessageSource extends IntegrationObjectSupport
@Override
protected void onInit() throws Exception {
if (this.getBeanFactory() != null){
this.evaluationContext =
this.evaluationContext =
ExpressionUtils.createStandardEvaluationContext(this.getBeanFactory());
}
else {
this.evaluationContext = ExpressionUtils.createStandardEvaluationContext();
}
if (this.mongoTemplate == null){
this.mongoTemplate = new MongoTemplate(this.mongoDbFactory, this.mongoConverter);

View File

@@ -99,13 +99,8 @@ public class MongoDbStoringMessageHandler extends AbstractMessageHandler {
@Override
protected void onInit() throws Exception {
if (this.getBeanFactory() != null) {
this.evaluationContext =
this.evaluationContext =
ExpressionUtils.createStandardEvaluationContext(this.getBeanFactory());
}
else {
this.evaluationContext = ExpressionUtils.createStandardEvaluationContext();
}
if (this.mongoTemplate == null){
this.mongoTemplate = new MongoTemplate(this.mongoDbFactory, this.mongoConverter);
}

View File

@@ -142,13 +142,8 @@ public class RedisStoreMessageSource extends IntegrationObjectSupport
@Override
protected void onInit() throws Exception {
if (this.getBeanFactory() != null){
this.evaluationContext =
this.evaluationContext =
ExpressionUtils.createStandardEvaluationContext(this.getBeanFactory());
}
else {
this.evaluationContext = ExpressionUtils.createStandardEvaluationContext();
}
}
public RedisStore getResource() {

View File

@@ -23,6 +23,7 @@ import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.BoundSetOperations;
@@ -199,13 +200,8 @@ public class RedisStoreWritingMessageHandler extends AbstractMessageHandler {
@Override
protected void onInit() throws Exception {
if (this.getBeanFactory() != null) {
this.evaluationContext =
this.evaluationContext =
ExpressionUtils.createStandardEvaluationContext(this.getBeanFactory());
}
else {
this.evaluationContext = ExpressionUtils.createStandardEvaluationContext();
}
Assert.state(!this.mapKeyExpressionExplicitlySet ||
(this.collectionType == CollectionType.MAP || this.collectionType == CollectionType.PROPERTIES),
"'mapKeyExpression' can only be set for CollectionType.MAP or CollectionType.PROPERTIES");

View File

@@ -16,23 +16,6 @@
package org.springframework.integration.sftp.inbound;
import java.io.File;
import java.io.FileInputStream;
import java.util.Vector;
import org.junit.After;
import org.junit.Test;
import org.springframework.integration.Message;
import org.springframework.integration.file.remote.session.Session;
import org.springframework.integration.sftp.filters.SftpRegexPatternFileListFilter;
import org.springframework.integration.sftp.session.DefaultSftpSessionFactory;
import org.springframework.integration.sftp.session.SftpTestSessionFactory;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.ChannelSftp.LsEntry;
import com.jcraft.jsch.SftpATTRS;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -44,9 +27,28 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.File;
import java.io.FileInputStream;
import java.util.Vector;
import org.junit.After;
import org.junit.Test;
import org.springframework.integration.Message;
import org.springframework.integration.expression.ExpressionUtils;
import org.springframework.integration.file.remote.session.Session;
import org.springframework.integration.sftp.filters.SftpRegexPatternFileListFilter;
import org.springframework.integration.sftp.session.DefaultSftpSessionFactory;
import org.springframework.integration.sftp.session.SftpTestSessionFactory;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.ChannelSftp.LsEntry;
import com.jcraft.jsch.SftpATTRS;
/**
* @author Oleg Zhurakousky
* @author Gunnar Hillert
* @author Gary Russell
* @since 2.0
*/
public class SftpInboundRemoteFileSystemSynchronizerTests {
@@ -81,6 +83,7 @@ public class SftpInboundRemoteFileSystemSynchronizerTests {
synchronizer.setDeleteRemoteFiles(true);
synchronizer.setRemoteDirectory("remote-test-dir");
synchronizer.setFilter(new SftpRegexPatternFileListFilter(".*\\.test$"));
synchronizer.setIntegrationEvaluationContext(ExpressionUtils.createStandardEvaluationContext());
SftpInboundFileSynchronizingMessageSource ms =
new SftpInboundFileSynchronizingMessageSource(synchronizer);

View File

@@ -146,12 +146,7 @@ public abstract class AbstractWebServiceOutboundGateway extends AbstractReplyPro
@Override
public void onInit() {
super.onInit();
if (this.getBeanFactory() != null) {
this.evaluationContext = ExpressionUtils.createStandardEvaluationContext(this.getBeanFactory());
}
else {
this.evaluationContext = ExpressionUtils.createStandardEvaluationContext();
}
this.evaluationContext = ExpressionUtils.createStandardEvaluationContext(this.getBeanFactory());
Assert.state(this.destinationProvider == null || CollectionUtils.isEmpty(this.uriVariableExpressions),
"uri variables are not supported when a DestinationProvider is supplied.");
}

View File

@@ -32,16 +32,15 @@ import javax.xml.transform.stream.StreamSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Document;
import org.springframework.context.expression.MapAccessor;
import org.springframework.core.io.Resource;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.integration.Message;
import org.springframework.integration.MessageHeaders;
import org.springframework.integration.MessagingException;
import org.springframework.integration.expression.ExpressionUtils;
import org.springframework.integration.transformer.AbstractTransformer;
import org.springframework.integration.xml.result.DomResultFactory;
import org.springframework.integration.xml.result.ResultFactory;
@@ -84,7 +83,7 @@ public class XsltPayloadTransformer extends AbstractTransformer {
private final Templates templates;
private final StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
private volatile StandardEvaluationContext evaluationContext;
private Map<String, Expression> xslParameterMappings;
@@ -120,7 +119,6 @@ public class XsltPayloadTransformer extends AbstractTransformer {
public XsltPayloadTransformer(Templates templates, ResultTransformer resultTransformer) throws ParserConfigurationException {
this.templates = templates;
this.resultTransformer = resultTransformer;
this.evaluationContext.addPropertyAccessor(new MapAccessor());
}
@@ -163,10 +161,18 @@ public class XsltPayloadTransformer extends AbstractTransformer {
this.xsltParamHeaders = xsltParamHeaders;
}
@Override
public String getComponentType() {
return "xml:xslt-transformer";
}
@Override
protected void onInit() throws Exception {
super.onInit();
this.evaluationContext = ExpressionUtils.createStandardEvaluationContext(this.getBeanFactory());
}
@Override
protected Object doTransform(Message<?> message) throws Exception {
Transformer transformer = buildTransformer(message);

View File

@@ -17,6 +17,7 @@
package org.springframework.integration.xml.config;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import javax.xml.transform.dom.DOMResult;
@@ -24,8 +25,6 @@ import javax.xml.transform.dom.DOMResult;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.integration.xml.transformer.CustomTestResultFactory;
import org.w3c.dom.Document;
import org.springframework.context.ApplicationContext;
@@ -34,7 +33,10 @@ import org.springframework.integration.Message;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.core.PollableChannel;
import org.springframework.integration.message.GenericMessage;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.integration.xml.config.StubResultFactory.StubStringResult;
import org.springframework.integration.xml.transformer.CustomTestResultFactory;
import org.springframework.integration.xml.util.XmlTestUtil;
import org.springframework.xml.transform.StringResult;
@@ -45,13 +47,12 @@ import org.springframework.xml.transform.StringResult;
*/
public class XsltPayloadTransformerParserTests {
private String doc = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><order><orderItem>test</orderItem></order>";
private final String doc = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><order><orderItem>test</orderItem></order>";
private ApplicationContext applicationContext;
private PollableChannel output;
@Before
public void setUp() {
applicationContext = new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-context.xml", getClass());
@@ -68,6 +69,8 @@ public class XsltPayloadTransformerParserTests {
assertTrue("Payload was not a DOMResult", result.getPayload() instanceof DOMResult);
Document doc = (Document) ((DOMResult) result.getPayload()).getNode();
assertEquals("Wrong payload", "test", doc.getDocumentElement().getTextContent());
assertNotNull(TestUtils.getPropertyValue(applicationContext.getBean("xsltTransformerWithResource.handler"),
"transformer.evaluationContext.beanResolver"));
}
@Test