INT-3427: Add JsonNodeToStringConverter
JIRA: https://jira.spring.io/browse/INT-3427 INT-3427: Workaround for String -> File converter INT-3427: PR comments
This commit is contained in:
committed by
Gary Russell
parent
f0ab3b03bd
commit
85866a2ea8
@@ -31,6 +31,7 @@ import org.springframework.beans.factory.ListableBeanFactory;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.config.PropertiesFactoryBean;
|
||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
@@ -63,13 +64,20 @@ public class IntegrationRegistrar implements ImportBeanDefinitionRegistrar, Bean
|
||||
|
||||
private static final Log logger = LogFactory.getLog(IntegrationRegistrar.class);
|
||||
|
||||
private final static IntegrationConverterInitializer INTEGRATION_CONVERTER_INITIALIZER =
|
||||
new IntegrationConverterInitializer();
|
||||
|
||||
private static final Set<Integer> registriesProcessed = new HashSet<Integer>();
|
||||
|
||||
private ClassLoader classLoader;
|
||||
|
||||
private volatile boolean jackson2Present;
|
||||
|
||||
@Override
|
||||
public void setBeanClassLoader(ClassLoader classLoader) {
|
||||
this.classLoader = classLoader;
|
||||
this.jackson2Present = ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", classLoader) &&
|
||||
ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", classLoader);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -99,13 +107,14 @@ public class IntegrationRegistrar implements ImportBeanDefinitionRegistrar, Bean
|
||||
* This method will auto-register a ChannelInitializer which could also be overridden by the user
|
||||
* by simply registering a ChannelInitializer {@code <bean>} with its {@code autoCreate} property
|
||||
* set to false to suppress channel creation.
|
||||
* It will also register a ChannelInitializer$AutoCreateCandidatesCollector which simply collects candidate channel names.
|
||||
*
|
||||
* @param registry The {@link BeanDefinitionRegistry} to register additional {@link org.springframework.beans.factory.config.BeanDefinition}s.
|
||||
* It will also register a ChannelInitializer$AutoCreateCandidatesCollector
|
||||
* which simply collects candidate channel names.
|
||||
* @param registry The {@link BeanDefinitionRegistry} to register additional {@link BeanDefinition}s.
|
||||
*/
|
||||
private void registerImplicitChannelCreator(BeanDefinitionRegistry registry) {
|
||||
if (!registry.containsBeanDefinition(IntegrationContextUtils.CHANNEL_INITIALIZER_BEAN_NAME)) {
|
||||
String channelsAutoCreateExpression = IntegrationProperties.getExpressionFor(IntegrationProperties.CHANNELS_AUTOCREATE);
|
||||
String channelsAutoCreateExpression =
|
||||
IntegrationProperties.getExpressionFor(IntegrationProperties.CHANNELS_AUTOCREATE);
|
||||
BeanDefinitionBuilder channelDef = BeanDefinitionBuilder.genericBeanDefinition(ChannelInitializer.class)
|
||||
.addPropertyValue("autoCreate", channelsAutoCreateExpression);
|
||||
BeanDefinitionHolder channelCreatorHolder = new BeanDefinitionHolder(channelDef.getBeanDefinition(),
|
||||
@@ -117,16 +126,16 @@ public class IntegrationRegistrar implements ImportBeanDefinitionRegistrar, Bean
|
||||
BeanDefinitionBuilder channelRegistryBuilder = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(ChannelInitializer.AutoCreateCandidatesCollector.class);
|
||||
channelRegistryBuilder.addConstructorArgValue(new ManagedSet<String>());
|
||||
BeanDefinitionHolder channelRegistryHolder = new BeanDefinitionHolder(channelRegistryBuilder.getBeanDefinition(),
|
||||
IntegrationContextUtils.AUTO_CREATE_CHANNEL_CANDIDATES_BEAN_NAME);
|
||||
BeanDefinitionHolder channelRegistryHolder =
|
||||
new BeanDefinitionHolder(channelRegistryBuilder.getBeanDefinition(),
|
||||
IntegrationContextUtils.AUTO_CREATE_CHANNEL_CANDIDATES_BEAN_NAME);
|
||||
BeanDefinitionReaderUtils.registerBeanDefinition(channelRegistryHolder, registry);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register {@code integrationGlobalProperties} bean if necessary.
|
||||
*
|
||||
* @param registry The {@link BeanDefinitionRegistry} to register additional {@link org.springframework.beans.factory.config.BeanDefinition}s.
|
||||
* @param registry The {@link BeanDefinitionRegistry} to register additional {@link BeanDefinition}s.
|
||||
*/
|
||||
private void registerIntegrationProperties(BeanDefinitionRegistry registry) {
|
||||
boolean alreadyRegistered = false;
|
||||
@@ -135,13 +144,16 @@ public class IntegrationRegistrar implements ImportBeanDefinitionRegistrar, Bean
|
||||
.containsBean(IntegrationContextUtils.INTEGRATION_GLOBAL_PROPERTIES_BEAN_NAME);
|
||||
}
|
||||
else {
|
||||
alreadyRegistered = registry.isBeanNameInUse(IntegrationContextUtils.INTEGRATION_GLOBAL_PROPERTIES_BEAN_NAME);
|
||||
alreadyRegistered =
|
||||
registry.isBeanNameInUse(IntegrationContextUtils.INTEGRATION_GLOBAL_PROPERTIES_BEAN_NAME);
|
||||
}
|
||||
if (!alreadyRegistered) {
|
||||
ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver(this.classLoader);
|
||||
try {
|
||||
Resource[] defaultResources = resourceResolver.getResources("classpath*:META-INF/spring.integration.default.properties");
|
||||
Resource[] userResources = resourceResolver.getResources("classpath*:META-INF/spring.integration.properties");
|
||||
Resource[] defaultResources =
|
||||
resourceResolver.getResources("classpath*:META-INF/spring.integration.default.properties");
|
||||
Resource[] userResources =
|
||||
resourceResolver.getResources("classpath*:META-INF/spring.integration.properties");
|
||||
|
||||
List<Resource> resources = new LinkedList<Resource>(Arrays.asList(defaultResources));
|
||||
resources.addAll(Arrays.asList(userResources));
|
||||
@@ -162,8 +174,7 @@ public class IntegrationRegistrar implements ImportBeanDefinitionRegistrar, Bean
|
||||
/**
|
||||
* Register {@link IntegrationEvaluationContextFactoryBean} bean
|
||||
* and {@link IntegrationEvaluationContextAwareBeanPostProcessor}, if necessary.
|
||||
*
|
||||
* @param registry The {@link BeanDefinitionRegistry} to register additional {@link org.springframework.beans.factory.config.BeanDefinition}s.
|
||||
* @param registry The {@link BeanDefinitionRegistry} to register additional {@link BeanDefinition}s.
|
||||
*/
|
||||
private void registerIntegrationEvaluationContext(BeanDefinitionRegistry registry) {
|
||||
if (!registry.containsBeanDefinition(IntegrationContextUtils.INTEGRATION_EVALUATION_CONTEXT_BEAN_NAME)) {
|
||||
@@ -178,15 +189,15 @@ public class IntegrationRegistrar implements ImportBeanDefinitionRegistrar, Bean
|
||||
BeanDefinitionReaderUtils.registerBeanDefinition(integrationEvaluationContextHolder,
|
||||
registry);
|
||||
|
||||
RootBeanDefinition integrationEvalContextBPP = new RootBeanDefinition(IntegrationEvaluationContextAwareBeanPostProcessor.class);
|
||||
RootBeanDefinition integrationEvalContextBPP =
|
||||
new RootBeanDefinition(IntegrationEvaluationContextAwareBeanPostProcessor.class);
|
||||
BeanDefinitionReaderUtils.registerWithGeneratedName(integrationEvalContextBPP, registry);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register {@code jsonPath} and {@code xpath} SpEL-function beans, if necessary.
|
||||
*
|
||||
* @param registry The {@link BeanDefinitionRegistry} to register additional {@link org.springframework.beans.factory.config.BeanDefinition}s.
|
||||
* @param registry The {@link BeanDefinitionRegistry} to register additional {@link BeanDefinition}s.
|
||||
*/
|
||||
private void registerBuiltInBeans(BeanDefinitionRegistry registry) {
|
||||
int registryId = System.identityHashCode(registry);
|
||||
@@ -205,7 +216,8 @@ public class IntegrationRegistrar implements ImportBeanDefinitionRegistrar, Bean
|
||||
jsonPathClass = ClassUtils.forName("com.jayway.jsonpath.JsonPath", this.classLoader);
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
logger.debug("SpEL function '#jsonPath' isn't registered: there is no jayway json-path.jar on the classpath.");
|
||||
logger.debug("SpEL function '#jsonPath' isn't registered: " +
|
||||
"there is no jayway json-path.jar on the classpath.");
|
||||
}
|
||||
|
||||
if (jsonPathClass != null) {
|
||||
@@ -225,10 +237,12 @@ public class IntegrationRegistrar implements ImportBeanDefinitionRegistrar, Bean
|
||||
if (!alreadyRegistered && !registriesProcessed.contains(registryId)) {
|
||||
Class<?> xpathClass = null;
|
||||
try {
|
||||
xpathClass = ClassUtils.forName(IntegrationConfigUtils.BASE_PACKAGE + ".xml.xpath.XPathUtils", this.classLoader);
|
||||
xpathClass = ClassUtils.forName(IntegrationConfigUtils.BASE_PACKAGE + ".xml.xpath.XPathUtils",
|
||||
this.classLoader);
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
logger.debug("SpEL function '#xpath' isn't registered: there is no spring-integration-xml.jar on the classpath.");
|
||||
logger.debug("SpEL function '#xpath' isn't registered: " +
|
||||
"there is no spring-integration-xml.jar on the classpath.");
|
||||
}
|
||||
|
||||
if (xpathClass != null) {
|
||||
@@ -237,49 +251,73 @@ public class IntegrationRegistrar implements ImportBeanDefinitionRegistrar, Bean
|
||||
}
|
||||
}
|
||||
|
||||
alreadyRegistered = false;
|
||||
if (registry instanceof ListableBeanFactory) {
|
||||
alreadyRegistered = ((ListableBeanFactory) registry)
|
||||
.containsBean(IntegrationContextUtils.TO_STRING_FRIENDLY_JSON_NODE_TO_STRING_CONVERTER_BEAN_NAME);
|
||||
}
|
||||
else {
|
||||
alreadyRegistered = registry
|
||||
.isBeanNameInUse(IntegrationContextUtils.TO_STRING_FRIENDLY_JSON_NODE_TO_STRING_CONVERTER_BEAN_NAME);
|
||||
}
|
||||
|
||||
if (!alreadyRegistered && !registriesProcessed.contains(registryId) && this.jackson2Present) {
|
||||
registry.registerBeanDefinition(IntegrationContextUtils.TO_STRING_FRIENDLY_JSON_NODE_TO_STRING_CONVERTER_BEAN_NAME,
|
||||
BeanDefinitionBuilder.genericBeanDefinition(IntegrationConfigUtils.BASE_PACKAGE +
|
||||
".json.ToStringFriendlyJsonNodeToStringConverter")
|
||||
.getBeanDefinition());
|
||||
INTEGRATION_CONVERTER_INITIALIZER.registerConverter(registry,
|
||||
new RuntimeBeanReference(IntegrationContextUtils.TO_STRING_FRIENDLY_JSON_NODE_TO_STRING_CONVERTER_BEAN_NAME));
|
||||
}
|
||||
|
||||
registriesProcessed.add(registryId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register {@code DefaultConfiguringBeanFactoryPostProcessor}, if necessary.
|
||||
*
|
||||
* @param registry The {@link BeanDefinitionRegistry} to register additional {@link org.springframework.beans.factory.config.BeanDefinition}s.
|
||||
* @param registry The {@link BeanDefinitionRegistry} to register additional {@link BeanDefinition}s.
|
||||
*/
|
||||
private void registerDefaultConfiguringBeanFactoryPostProcessor(BeanDefinitionRegistry registry) {
|
||||
boolean alreadyRegistered = false;
|
||||
if (registry instanceof ListableBeanFactory) {
|
||||
alreadyRegistered = ((ListableBeanFactory) registry).containsBean(IntegrationContextUtils.DEFAULT_CONFIGURING_POSTPROCESSOR_BEAN_NAME);
|
||||
alreadyRegistered = ((ListableBeanFactory) registry)
|
||||
.containsBean(IntegrationContextUtils.DEFAULT_CONFIGURING_POSTPROCESSOR_BEAN_NAME);
|
||||
}
|
||||
else {
|
||||
alreadyRegistered = registry.isBeanNameInUse(IntegrationContextUtils.DEFAULT_CONFIGURING_POSTPROCESSOR_BEAN_NAME);
|
||||
}
|
||||
if (!alreadyRegistered) {
|
||||
BeanDefinitionBuilder postProcessorBuilder = BeanDefinitionBuilder.genericBeanDefinition(DefaultConfiguringBeanFactoryPostProcessor.class);
|
||||
BeanDefinitionBuilder postProcessorBuilder =
|
||||
BeanDefinitionBuilder.genericBeanDefinition(DefaultConfiguringBeanFactoryPostProcessor.class);
|
||||
BeanDefinitionHolder postProcessorHolder = new BeanDefinitionHolder(
|
||||
postProcessorBuilder.getBeanDefinition(), IntegrationContextUtils.DEFAULT_CONFIGURING_POSTPROCESSOR_BEAN_NAME);
|
||||
postProcessorBuilder.getBeanDefinition(),
|
||||
IntegrationContextUtils.DEFAULT_CONFIGURING_POSTPROCESSOR_BEAN_NAME);
|
||||
BeanDefinitionReaderUtils.registerBeanDefinition(postProcessorHolder, registry);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a {@link DefaultHeaderChannelRegistry} in the given {@link BeanDefinitionRegistry}, if necessary.
|
||||
*
|
||||
* @param registry The {@link BeanDefinitionRegistry} to register additional {@link org.springframework.beans.factory.config.BeanDefinition}s.
|
||||
* @param registry The {@link BeanDefinitionRegistry} to register additional {@link BeanDefinition}s.
|
||||
*/
|
||||
private void registerHeaderChannelRegistry(BeanDefinitionRegistry registry) {
|
||||
boolean alreadyRegistered = false;
|
||||
if (registry instanceof ListableBeanFactory) {
|
||||
alreadyRegistered = ((ListableBeanFactory) registry).containsBean(IntegrationContextUtils.INTEGRATION_HEADER_CHANNEL_REGISTRY_BEAN_NAME);
|
||||
alreadyRegistered = ((ListableBeanFactory) registry)
|
||||
.containsBean(IntegrationContextUtils.INTEGRATION_HEADER_CHANNEL_REGISTRY_BEAN_NAME);
|
||||
}
|
||||
else {
|
||||
alreadyRegistered = registry.isBeanNameInUse(IntegrationContextUtils.INTEGRATION_HEADER_CHANNEL_REGISTRY_BEAN_NAME);
|
||||
alreadyRegistered =
|
||||
registry.isBeanNameInUse(IntegrationContextUtils.INTEGRATION_HEADER_CHANNEL_REGISTRY_BEAN_NAME);
|
||||
}
|
||||
if (!alreadyRegistered) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("No bean named '" + IntegrationContextUtils.INTEGRATION_HEADER_CHANNEL_REGISTRY_BEAN_NAME +
|
||||
"' has been explicitly defined. Therefore, a default DefaultHeaderChannelRegistry will be created.");
|
||||
"' has been explicitly defined. " +
|
||||
"Therefore, a default DefaultHeaderChannelRegistry will be created.");
|
||||
}
|
||||
BeanDefinitionBuilder schedulerBuilder = BeanDefinitionBuilder.genericBeanDefinition(DefaultHeaderChannelRegistry.class);
|
||||
BeanDefinitionBuilder schedulerBuilder =
|
||||
BeanDefinitionBuilder.genericBeanDefinition(DefaultHeaderChannelRegistry.class);
|
||||
BeanDefinitionHolder replyChannelRegistryComponent = new BeanDefinitionHolder(
|
||||
schedulerBuilder.getBeanDefinition(),
|
||||
IntegrationContextUtils.INTEGRATION_HEADER_CHANNEL_REGISTRY_BEAN_NAME);
|
||||
@@ -289,51 +327,54 @@ public class IntegrationRegistrar implements ImportBeanDefinitionRegistrar, Bean
|
||||
|
||||
/**
|
||||
* Register a {@link GlobalChannelInterceptorProcessor} in the given {@link BeanDefinitionRegistry}, if necessary.
|
||||
*
|
||||
* @param registry The {@link BeanDefinitionRegistry} to register additional {@link org.springframework.beans.factory.config.BeanDefinition}s.
|
||||
* @param registry The {@link BeanDefinitionRegistry} to register additional {@link BeanDefinition}s.
|
||||
*/
|
||||
private void registerGlobalChannelInterceptorProcessor(BeanDefinitionRegistry registry) {
|
||||
if (!registry.containsBeanDefinition(IntegrationContextUtils.GLOBAL_CHANNEL_INTERCEPTOR_PROCESSOR_BEAN_NAME)) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(GlobalChannelInterceptorProcessor.class)
|
||||
.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
BeanDefinitionBuilder builder =
|
||||
BeanDefinitionBuilder.genericBeanDefinition(GlobalChannelInterceptorProcessor.class)
|
||||
.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
|
||||
registry.registerBeanDefinition(IntegrationContextUtils.GLOBAL_CHANNEL_INTERCEPTOR_PROCESSOR_BEAN_NAME, builder.getBeanDefinition());
|
||||
registry.registerBeanDefinition(IntegrationContextUtils.GLOBAL_CHANNEL_INTERCEPTOR_PROCESSOR_BEAN_NAME,
|
||||
builder.getBeanDefinition());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register {@link MessagingAnnotationPostProcessor} and {@link PublisherAnnotationBeanPostProcessor}, if necessary.
|
||||
* Inject {@code defaultPublishedChannel} from provided {@link AnnotationMetadata}, if any.
|
||||
*
|
||||
* @param meta The {@link AnnotationMetadata} to get additional properties for {@link org.springframework.beans.factory.config.BeanDefinition}s.
|
||||
* @param registry The {@link BeanDefinitionRegistry} to register additional {@link org.springframework.beans.factory.config.BeanDefinition}s.
|
||||
* @param meta The {@link AnnotationMetadata} to get additional properties for {@link BeanDefinition}s.
|
||||
* @param registry The {@link BeanDefinitionRegistry} to register additional {@link BeanDefinition}s.
|
||||
*/
|
||||
private void registerMessagingAnnotationPostProcessors(AnnotationMetadata meta, BeanDefinitionRegistry registry) {
|
||||
if (!registry.containsBeanDefinition(IntegrationContextUtils.MESSAGING_ANNOTATION_POSTPROCESSOR_NAME)) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(MessagingAnnotationPostProcessor.class)
|
||||
.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
BeanDefinitionBuilder builder =
|
||||
BeanDefinitionBuilder.genericBeanDefinition(MessagingAnnotationPostProcessor.class)
|
||||
.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
|
||||
registry.registerBeanDefinition(IntegrationContextUtils.MESSAGING_ANNOTATION_POSTPROCESSOR_NAME, builder.getBeanDefinition());
|
||||
registry.registerBeanDefinition(IntegrationContextUtils.MESSAGING_ANNOTATION_POSTPROCESSOR_NAME,
|
||||
builder.getBeanDefinition());
|
||||
}
|
||||
|
||||
new PublisherRegistrar().registerBeanDefinitions(meta, registry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register {@link IntegrationConfigurationBeanFactoryPostProcessor} to process the external Integration infrastructure.
|
||||
* Register {@link IntegrationConfigurationBeanFactoryPostProcessor}
|
||||
* to process the external Integration infrastructure.
|
||||
*/
|
||||
private void registerIntegrationConfigurationBeanFactoryPostProcessor(BeanDefinitionRegistry registry) {
|
||||
if (!registry.containsBeanDefinition(IntegrationContextUtils.INTEGRATION_CONFIGURATION_POST_PROCESSOR_BEAN_NAME)) {
|
||||
BeanDefinitionBuilder postProcessorBuilder = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(IntegrationConfigurationBeanFactoryPostProcessor.class)
|
||||
.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
registry.registerBeanDefinition(IntegrationContextUtils.INTEGRATION_CONFIGURATION_POST_PROCESSOR_BEAN_NAME, postProcessorBuilder.getBeanDefinition());
|
||||
registry.registerBeanDefinition(IntegrationContextUtils.INTEGRATION_CONFIGURATION_POST_PROCESSOR_BEAN_NAME,
|
||||
postProcessorBuilder.getBeanDefinition());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the default datatype channel MessageConverter.
|
||||
*
|
||||
* @param registry the registry.
|
||||
*/
|
||||
private void registerDefaultDatatypeChannelMessageConverter(BeanDefinitionRegistry registry) {
|
||||
|
||||
@@ -52,7 +52,9 @@ public abstract class AbstractIntegrationNamespaceHandler implements NamespaceHa
|
||||
@Override
|
||||
public final BeanDefinition parse(Element element, ParserContext parserContext) {
|
||||
this.verifySchemaVersion(element, parserContext);
|
||||
new IntegrationRegistrar().registerBeanDefinitions(null, parserContext.getRegistry());
|
||||
IntegrationRegistrar integrationRegistrar = new IntegrationRegistrar();
|
||||
integrationRegistrar.setBeanClassLoader(parserContext.getReaderContext().getBeanClassLoader());
|
||||
integrationRegistrar.registerBeanDefinitions(null, parserContext.getRegistry());
|
||||
return this.delegate.parse(element, parserContext);
|
||||
}
|
||||
|
||||
|
||||
@@ -74,6 +74,9 @@ public abstract class IntegrationContextUtils {
|
||||
|
||||
public static final String GLOBAL_CHANNEL_INTERCEPTOR_PROCESSOR_BEAN_NAME = "globalChannelInterceptorProcessor";
|
||||
|
||||
public static final String TO_STRING_FRIENDLY_JSON_NODE_TO_STRING_CONVERTER_BEAN_NAME =
|
||||
"toStringFriendlyJsonNodeToStringConverter";
|
||||
|
||||
/**
|
||||
* @param beanFactory BeanFactory for lookup, must not be null.
|
||||
* @return The {@link MetadataStore} bean whose name is "metadataStore".
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.json;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
|
||||
/**
|
||||
* The {@link Converter} implementation for the conversion of
|
||||
* {@link JsonPropertyAccessor.ToStringFriendlyJsonNode} to {@link String},
|
||||
* when the {@link JsonPropertyAccessor.ToStringFriendlyJsonNode} can be a result of the
|
||||
* expression for JSON in case of the {@link JsonPropertyAccessor} usage.
|
||||
*
|
||||
* @author Artem Bilan
|
||||
* @since 4.1
|
||||
*/
|
||||
class ToStringFriendlyJsonNodeToStringConverter
|
||||
implements Converter<JsonPropertyAccessor.ToStringFriendlyJsonNode, String> {
|
||||
|
||||
@Override
|
||||
public String convert(JsonPropertyAccessor.ToStringFriendlyJsonNode source) {
|
||||
return source.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -34,4 +34,17 @@
|
||||
|
||||
<bean id="parentJsonPropertyAccessor" class="org.springframework.integration.json.JsonPropertyAccessor"/>
|
||||
|
||||
<bean id="barService" class="org.springframework.integration.expression.ParentContextTests$Bar" />
|
||||
|
||||
<int:chain input-channel="testJsonNodeToStringConverterInputChannel"
|
||||
output-channel="testJsonNodeToStringConverterOutputChannel">
|
||||
<int:object-to-json-transformer result-type="NODE"/>
|
||||
<int:transformer expression="payload.firstName"/>
|
||||
<int:service-activator ref="barService" method="testJsonNodeToStringConverter"/>
|
||||
</int:chain>
|
||||
|
||||
<int:channel id="testJsonNodeToStringConverterOutputChannel">
|
||||
<int:queue/>
|
||||
</int:channel>
|
||||
|
||||
</beans>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.expression;
|
||||
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
@@ -30,6 +31,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Test;
|
||||
@@ -42,10 +44,12 @@ import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.config.IntegrationEvaluationContextFactoryBean;
|
||||
import org.springframework.integration.context.IntegrationContextUtils;
|
||||
import org.springframework.integration.json.JsonPathUtils;
|
||||
import org.springframework.integration.json.TestPerson;
|
||||
import org.springframework.integration.support.MutableMessageBuilder;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.PollableChannel;
|
||||
import org.springframework.messaging.support.GenericMessage;
|
||||
|
||||
/**
|
||||
@@ -66,14 +70,19 @@ public class ParentContextTests {
|
||||
* and the parent's ones are last in the propertyAccessors list of EvaluationContext.
|
||||
* Verifies that SpEL functions are inherited from parent context and overridden with the same 'id'.
|
||||
* Verifies that child and parent contexts can have different message builders.
|
||||
* <p>
|
||||
* Only single test method is allowed for 'ParentContext-context.xml',
|
||||
* since it relies on static 'evalContexts' variable.
|
||||
*/
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testSpelBeanReferencesInChildAndParent() throws Exception {
|
||||
AbstractApplicationContext parent = new ClassPathXmlApplicationContext("ParentContext-context.xml", this.getClass());
|
||||
AbstractApplicationContext parent = new ClassPathXmlApplicationContext("ParentContext-context.xml",
|
||||
this.getClass());
|
||||
|
||||
Object parentEvaluationContextFactoryBean = parent.getBean(IntegrationEvaluationContextFactoryBean.class);
|
||||
Map<?, ?> parentFunctions = TestUtils.getPropertyValue(parentEvaluationContextFactoryBean, "functions", Map.class);
|
||||
Map<?, ?> parentFunctions = TestUtils.getPropertyValue(parentEvaluationContextFactoryBean, "functions",
|
||||
Map.class);
|
||||
assertEquals(3, parentFunctions.size());
|
||||
Object jsonPath = parentFunctions.get("jsonPath");
|
||||
assertNotNull(jsonPath);
|
||||
@@ -84,7 +93,8 @@ public class ParentContextTests {
|
||||
child.refresh();
|
||||
|
||||
Object childEvaluationContextFactoryBean = child.getBean(IntegrationEvaluationContextFactoryBean.class);
|
||||
Map<?, ?> childFunctions = TestUtils.getPropertyValue(childEvaluationContextFactoryBean, "functions", Map.class);
|
||||
Map<?, ?> childFunctions = TestUtils.getPropertyValue(childEvaluationContextFactoryBean, "functions",
|
||||
Map.class);
|
||||
assertEquals(4, childFunctions.size());
|
||||
assertTrue(childFunctions.containsKey("barParent"));
|
||||
jsonPath = childFunctions.get("jsonPath");
|
||||
@@ -101,7 +111,8 @@ public class ParentContextTests {
|
||||
assertTrue(propertyAccessors.contains(parentPropertyAccessor));
|
||||
assertTrue(propertyAccessors.indexOf(parentPropertyAccessorOverride) > propertyAccessors.indexOf(parentPropertyAccessor));
|
||||
|
||||
Map<String, Object> variables = (Map<String, Object>) TestUtils.getPropertyValue(evalContexts.get(0), "variables");
|
||||
Map<String, Object> variables = (Map<String, Object>) TestUtils.getPropertyValue(evalContexts.get(0),
|
||||
"variables");
|
||||
assertEquals(3, variables.size());
|
||||
assertTrue(variables.containsKey("bar"));
|
||||
assertTrue(variables.containsKey("barParent"));
|
||||
@@ -161,6 +172,37 @@ public class ParentContextTests {
|
||||
assertEquals("org.springframework.integration.support.MutableMessage", out.getClass().getName());
|
||||
assertEquals("FOO", out.getPayload());
|
||||
|
||||
assertTrue(parent
|
||||
.containsBean(IntegrationContextUtils.TO_STRING_FRIENDLY_JSON_NODE_TO_STRING_CONVERTER_BEAN_NAME));
|
||||
|
||||
assertTrue(child
|
||||
.containsBean(IntegrationContextUtils.TO_STRING_FRIENDLY_JSON_NODE_TO_STRING_CONVERTER_BEAN_NAME));
|
||||
|
||||
Object converterRegistrar = parent.getBean(IntegrationContextUtils.CONVERTER_REGISTRAR_BEAN_NAME);
|
||||
assertNotNull(converterRegistrar);
|
||||
Set<?> converters = TestUtils.getPropertyValue(converterRegistrar, "converters", Set.class);
|
||||
boolean toStringFriendlyJsonNodeToStringConverterPresent = false;
|
||||
for (Object converter : converters) {
|
||||
if ("ToStringFriendlyJsonNodeToStringConverter".equals(converter.getClass().getSimpleName())) {
|
||||
toStringFriendlyJsonNodeToStringConverterPresent = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assertTrue(toStringFriendlyJsonNodeToStringConverterPresent);
|
||||
|
||||
MessageChannel input = parent.getBean("testJsonNodeToStringConverterInputChannel", MessageChannel.class);
|
||||
PollableChannel output = parent.getBean("testJsonNodeToStringConverterOutputChannel", PollableChannel.class);
|
||||
|
||||
TestPerson person = new TestPerson();
|
||||
person.setFirstName("John");
|
||||
|
||||
input.send(new GenericMessage<Object>(person));
|
||||
|
||||
Message<?> result = output.receive(1000);
|
||||
assertNotNull(result);
|
||||
assertEquals("JOHN", result.getPayload());
|
||||
|
||||
child.close();
|
||||
parent.close();
|
||||
}
|
||||
@@ -180,5 +222,10 @@ public class ParentContextTests {
|
||||
return o;
|
||||
}
|
||||
|
||||
public String testJsonNodeToStringConverter(String payload) {
|
||||
return payload.toUpperCase();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,7 +20,7 @@ package org.springframework.integration.json;
|
||||
* @author Mark Fisher
|
||||
* @since 2.0
|
||||
*/
|
||||
class TestPerson {
|
||||
public class TestPerson {
|
||||
|
||||
private volatile String firstName;
|
||||
|
||||
@@ -30,7 +30,7 @@ class TestPerson {
|
||||
|
||||
private volatile TestAddress address;
|
||||
|
||||
TestPerson() {
|
||||
public TestPerson() {
|
||||
}
|
||||
|
||||
public TestPerson(String firstName, String lastName, int age) {
|
||||
|
||||
@@ -798,7 +798,10 @@ public abstract class AbstractRemoteFileOutboundGateway<F> extends AbstractReply
|
||||
private File generateLocalDirectory(Message<?> message, String remoteDirectory) {
|
||||
EvaluationContext evaluationContext = ExpressionUtils.createStandardEvaluationContext(this.getBeanFactory());
|
||||
evaluationContext.setVariable("remoteDirectory", remoteDirectory);
|
||||
File localDir = this.localDirectoryExpression.getValue(evaluationContext, message, File.class);
|
||||
//TODO see org.springframework.integration.context.CustomConversionServiceFactoryBean
|
||||
// File localDir = this.localDirectoryExpression.getValue(evaluationContext, message, File.class);
|
||||
String localDirPath = this.localDirectoryExpression.getValue(evaluationContext, message, String.class);
|
||||
File localDir = new File(localDirPath);
|
||||
if (!localDir.exists()) {
|
||||
Assert.isTrue(localDir.mkdirs(), "Failed to make local directory: " + localDir);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user