GH-3085 Add Number and Boolean Spel converter
Refactor SpelConverter into an abstract class Resolves #3085
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2018 the original author or authors.
|
||||
* Copyright 2015-2025 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.
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package org.springframework.cloud.stream.config;
|
||||
|
||||
import java.beans.Introspector;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
@@ -44,6 +42,7 @@ import org.springframework.integration.json.JsonPropertyAccessor;
|
||||
*
|
||||
* @author Eric Bottard
|
||||
* @author Artem Bilan
|
||||
* @author Oleg Zhurakousky
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
@@ -61,19 +60,19 @@ public class SpelExpressionConverterConfiguration {
|
||||
@Bean
|
||||
public static SpelPropertyAccessorRegistrar spelPropertyAccessorRegistrar() {
|
||||
return new SpelPropertyAccessorRegistrar()
|
||||
.add(Introspector
|
||||
.decapitalize(JsonPropertyAccessor.class.getSimpleName()),
|
||||
new JsonPropertyAccessor());
|
||||
.add(new JsonPropertyAccessor());
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConfigurationPropertiesBinding
|
||||
@IntegrationConverter
|
||||
public Converter<Object, Expression> spelConverter(ConfigurableApplicationContext context) {
|
||||
public Converter<String, Expression> spelConverter(ConfigurableApplicationContext context) {
|
||||
SpelConverter converter = new SpelConverter();
|
||||
ConfigurableConversionService cs = (ConfigurableConversionService) context.getBeanFactory().getConversionService();
|
||||
if (cs != null) {
|
||||
cs.addConverter(converter);
|
||||
cs.addConverter(new NumberToStringSpelConverter());
|
||||
cs.addConverter(new BooleanToStringSpelConverter());
|
||||
}
|
||||
return converter;
|
||||
}
|
||||
@@ -83,7 +82,30 @@ public class SpelExpressionConverterConfiguration {
|
||||
*
|
||||
* @author Eric Bottard
|
||||
*/
|
||||
public static class SpelConverter implements Converter<Object, Expression> {
|
||||
public static class SpelConverter extends AbstractSpelConverter<String> {
|
||||
@Override
|
||||
public Expression convert(String source) {
|
||||
return this.doConvert(source);
|
||||
}
|
||||
}
|
||||
|
||||
public static class NumberToStringSpelConverter extends AbstractSpelConverter<Number> {
|
||||
@Override
|
||||
public Expression convert(Number source) {
|
||||
String value = source.toString();
|
||||
return this.doConvert(value);
|
||||
}
|
||||
}
|
||||
|
||||
public static class BooleanToStringSpelConverter extends AbstractSpelConverter<Boolean> {
|
||||
@Override
|
||||
public Expression convert(Boolean source) {
|
||||
String value = source.toString();
|
||||
return this.doConvert(value);
|
||||
}
|
||||
}
|
||||
|
||||
public static abstract class AbstractSpelConverter<T> implements Converter<T, Expression> {
|
||||
|
||||
private SpelExpressionParser parser = new SpelExpressionParser();
|
||||
|
||||
@@ -92,12 +114,8 @@ public class SpelExpressionConverterConfiguration {
|
||||
@Lazy
|
||||
private EvaluationContext evaluationContext;
|
||||
|
||||
@Override
|
||||
public Expression convert(Object source) {
|
||||
public Expression doConvert(String source) {
|
||||
try {
|
||||
if (!(source instanceof String)) {
|
||||
source = String.valueOf(source); // see https://github.com/spring-cloud/spring-cloud-stream/issues/2989
|
||||
}
|
||||
Expression expression = this.parser.parseExpression((String) source);
|
||||
if (expression instanceof SpelExpression) {
|
||||
((SpelExpression) expression)
|
||||
@@ -110,7 +128,5 @@ public class SpelExpressionConverterConfiguration {
|
||||
"Could not convert '%s' into a SpEL expression", source), e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.PropertyAccessor;
|
||||
@@ -47,8 +48,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Artem Bilan
|
||||
* @author Soby Chacko
|
||||
*/
|
||||
@SpringBootTest(classes = SpelExpressionConverterConfigurationTests.Config.class, properties = {
|
||||
"expression: a.b" })
|
||||
@SpringBootTest(classes = SpelExpressionConverterConfigurationTests.Config.class)
|
||||
class SpelExpressionConverterConfigurationTests {
|
||||
|
||||
@Autowired
|
||||
@@ -77,6 +77,12 @@ class SpelExpressionConverterConfigurationTests {
|
||||
|
||||
assertThat(propertyAccessors)
|
||||
.hasAtLeastOneElementOfType(JsonPropertyAccessor.class);
|
||||
|
||||
Expression numberExpression = this.pojo.getNumberExpression();
|
||||
assertThat(numberExpression.getValue()).isEqualTo(5);
|
||||
|
||||
Expression booleanExpression = this.pojo.getBooleanExpression();
|
||||
assertThat(booleanExpression.getValue()).isEqualTo(true);
|
||||
}
|
||||
|
||||
@ConfigurationProperties
|
||||
@@ -84,6 +90,10 @@ class SpelExpressionConverterConfigurationTests {
|
||||
|
||||
private Expression expression;
|
||||
|
||||
private Expression numberExpression;
|
||||
|
||||
private Expression booleanExpression;
|
||||
|
||||
public Expression getExpression() {
|
||||
return this.expression;
|
||||
}
|
||||
@@ -92,11 +102,28 @@ class SpelExpressionConverterConfigurationTests {
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
public Expression getNumberExpression() {
|
||||
return numberExpression;
|
||||
}
|
||||
|
||||
public void setNumberExpression(Expression numberExpression) {
|
||||
this.numberExpression = numberExpression;
|
||||
}
|
||||
|
||||
public Expression getBooleanExpression() {
|
||||
return booleanExpression;
|
||||
}
|
||||
|
||||
public void setBooleanExpression(Expression booleanExpression) {
|
||||
this.booleanExpression = booleanExpression;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@EnableConfigurationProperties(Pojo.class)
|
||||
@PropertySource("classpath:/application.yml")
|
||||
public static class Config implements BeanFactoryAware {
|
||||
|
||||
private BeanFactory beanFactory;
|
||||
|
||||
Reference in New Issue
Block a user