Add NPE test for ExprEvalSqlParameterSourceFactory
Related to https://github.com/spring-projects/spring-integration/issues/3113 Also clean up code style in the `ExpressionEvaluatingSqlParameterSourceFactory`
This commit is contained in:
@@ -22,11 +22,10 @@ import java.util.Map;
|
|||||||
|
|
||||||
import org.springframework.expression.Expression;
|
import org.springframework.expression.Expression;
|
||||||
import org.springframework.expression.ExpressionException;
|
import org.springframework.expression.ExpressionException;
|
||||||
import org.springframework.expression.ExpressionParser;
|
|
||||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
|
||||||
import org.springframework.integration.util.AbstractExpressionEvaluator;
|
import org.springframework.integration.util.AbstractExpressionEvaluator;
|
||||||
import org.springframework.jdbc.core.namedparam.AbstractSqlParameterSource;
|
import org.springframework.jdbc.core.namedparam.AbstractSqlParameterSource;
|
||||||
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
|
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -45,8 +44,6 @@ import org.springframework.util.Assert;
|
|||||||
public class ExpressionEvaluatingSqlParameterSourceFactory extends AbstractExpressionEvaluator
|
public class ExpressionEvaluatingSqlParameterSourceFactory extends AbstractExpressionEvaluator
|
||||||
implements SqlParameterSourceFactory {
|
implements SqlParameterSourceFactory {
|
||||||
|
|
||||||
private static final ExpressionParser PARSER = new SpelExpressionParser();
|
|
||||||
|
|
||||||
private static final Object ERROR = new Object();
|
private static final Object ERROR = new Object();
|
||||||
|
|
||||||
private final Map<String, Object> staticParameters = new HashMap<>();
|
private final Map<String, Object> staticParameters = new HashMap<>();
|
||||||
@@ -117,8 +114,8 @@ public class ExpressionEvaluatingSqlParameterSourceFactory extends AbstractExpre
|
|||||||
String key = entry.getKey();
|
String key = entry.getKey();
|
||||||
String expression = entry.getValue();
|
String expression = entry.getValue();
|
||||||
Expression[] expressions = new Expression[] {
|
Expression[] expressions = new Expression[] {
|
||||||
PARSER.parseExpression(expression),
|
EXPRESSION_PARSER.parseExpression(expression),
|
||||||
PARSER.parseExpression("#root.![" + expression + "]")
|
EXPRESSION_PARSER.parseExpression("#root.![" + expression + "]")
|
||||||
};
|
};
|
||||||
paramExpressions.put(key, expressions);
|
paramExpressions.put(key, expressions);
|
||||||
}
|
}
|
||||||
@@ -172,6 +169,7 @@ public class ExpressionEvaluatingSqlParameterSourceFactory extends AbstractExpre
|
|||||||
|
|
||||||
ExpressionEvaluatingSqlParameterSource(Object input, Map<String, ?> staticParameters,
|
ExpressionEvaluatingSqlParameterSource(Object input, Map<String, ?> staticParameters,
|
||||||
Map<String, Expression[]> parameterExpressions, boolean cache) {
|
Map<String, Expression[]> parameterExpressions, boolean cache) {
|
||||||
|
|
||||||
this.input = input;
|
this.input = input;
|
||||||
this.parameterExpressions = parameterExpressions;
|
this.parameterExpressions = parameterExpressions;
|
||||||
this.values.putAll(staticParameters);
|
this.values.putAll(staticParameters);
|
||||||
@@ -182,10 +180,12 @@ public class ExpressionEvaluatingSqlParameterSourceFactory extends AbstractExpre
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public Object getValue(String paramName) throws IllegalArgumentException {
|
public Object getValue(String paramName) throws IllegalArgumentException {
|
||||||
return this.doGetValue(paramName, false);
|
return doGetValue(paramName, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public Object doGetValue(String paramName, boolean calledFromHasValue) throws IllegalArgumentException {
|
public Object doGetValue(String paramName, boolean calledFromHasValue) throws IllegalArgumentException {
|
||||||
if (this.values.containsKey(paramName)) {
|
if (this.values.containsKey(paramName)) {
|
||||||
Object cachedByHasValue = this.values.get(paramName);
|
Object cachedByHasValue = this.values.get(paramName);
|
||||||
@@ -197,14 +197,14 @@ public class ExpressionEvaluatingSqlParameterSourceFactory extends AbstractExpre
|
|||||||
|
|
||||||
if (!this.parameterExpressions.containsKey(paramName)) {
|
if (!this.parameterExpressions.containsKey(paramName)) {
|
||||||
Expression[] expressions = new Expression[] {
|
Expression[] expressions = new Expression[] {
|
||||||
PARSER.parseExpression(paramName),
|
EXPRESSION_PARSER.parseExpression(paramName),
|
||||||
PARSER.parseExpression("#root.![" + paramName + "]")
|
EXPRESSION_PARSER.parseExpression("#root.![" + paramName + "]")
|
||||||
};
|
};
|
||||||
ExpressionEvaluatingSqlParameterSourceFactory.this.parameterExpressions.put(paramName, expressions);
|
ExpressionEvaluatingSqlParameterSourceFactory.this.parameterExpressions.put(paramName, expressions);
|
||||||
this.parameterExpressions.put(paramName, expressions);
|
this.parameterExpressions.put(paramName, expressions);
|
||||||
}
|
}
|
||||||
|
|
||||||
Expression expression = null;
|
Expression expression;
|
||||||
|
|
||||||
if (this.input instanceof Collection<?>) {
|
if (this.input instanceof Collection<?>) {
|
||||||
expression = this.parameterExpressions.get(paramName)[1];
|
expression = this.parameterExpressions.get(paramName)[1];
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import java.sql.Types;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import org.springframework.beans.factory.BeanFactory;
|
import org.springframework.beans.factory.BeanFactory;
|
||||||
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
|
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
|
||||||
@@ -32,39 +32,41 @@ import org.springframework.jdbc.support.JdbcUtils;
|
|||||||
/**
|
/**
|
||||||
* @author Dave Syer
|
* @author Dave Syer
|
||||||
* @author Meherzad Lahewala
|
* @author Meherzad Lahewala
|
||||||
|
* @author Artem Bilan
|
||||||
*/
|
*/
|
||||||
public class ExpressionEvaluatingSqlParameterSourceFactoryTests {
|
class ExpressionEvaluatingSqlParameterSourceFactoryTests {
|
||||||
|
|
||||||
private final ExpressionEvaluatingSqlParameterSourceFactory factory =
|
private final ExpressionEvaluatingSqlParameterSourceFactory factory =
|
||||||
new ExpressionEvaluatingSqlParameterSourceFactory();
|
new ExpressionEvaluatingSqlParameterSourceFactory();
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSetStaticParameters() throws Exception {
|
void testSetStaticParameters() {
|
||||||
factory.setStaticParameters(Collections.singletonMap("foo", "bar"));
|
this.factory.setStaticParameters(Collections.singletonMap("foo", "bar"));
|
||||||
factory.setBeanFactory(mock(BeanFactory.class));
|
this.factory.setBeanFactory(mock(BeanFactory.class));
|
||||||
factory.afterPropertiesSet();
|
this.factory.afterPropertiesSet();
|
||||||
SqlParameterSource source = factory.createParameterSource(null);
|
SqlParameterSource source = this.factory.createParameterSource(null);
|
||||||
assertThat(source.hasValue("foo")).isTrue();
|
assertThat(source.hasValue("foo")).isTrue();
|
||||||
assertThat(source.getValue("foo")).isEqualTo("bar");
|
assertThat(source.getValue("foo")).isEqualTo("bar");
|
||||||
assertThat(source.getSqlType("foo")).isEqualTo(JdbcUtils.TYPE_UNKNOWN);
|
assertThat(source.getSqlType("foo")).isEqualTo(JdbcUtils.TYPE_UNKNOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMapInput() throws Exception {
|
void testMapInput() {
|
||||||
factory.setBeanFactory(mock(BeanFactory.class));
|
this.factory.setBeanFactory(mock(BeanFactory.class));
|
||||||
factory.afterPropertiesSet();
|
this.factory.afterPropertiesSet();
|
||||||
SqlParameterSource source = factory.createParameterSource(Collections.singletonMap("foo", "bar"));
|
SqlParameterSource source = this.factory.createParameterSource(Collections.singletonMap("foo", "bar"));
|
||||||
assertThat(source.hasValue("foo")).isTrue();
|
assertThat(source.hasValue("foo")).isTrue();
|
||||||
assertThat(source.getValue("foo")).isEqualTo("bar");
|
assertThat(source.getValue("foo")).isEqualTo("bar");
|
||||||
assertThat(source.getSqlType("foo")).isEqualTo(JdbcUtils.TYPE_UNKNOWN);
|
assertThat(source.getSqlType("foo")).isEqualTo(JdbcUtils.TYPE_UNKNOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testListOfMapsInput() throws Exception {
|
void testListOfMapsInput() {
|
||||||
factory.setBeanFactory(mock(BeanFactory.class));
|
this.factory.setBeanFactory(mock(BeanFactory.class));
|
||||||
factory.afterPropertiesSet();
|
this.factory.afterPropertiesSet();
|
||||||
SqlParameterSource source = factory.createParameterSource(Arrays.asList(Collections.singletonMap("foo", "bar"),
|
SqlParameterSource source =
|
||||||
Collections.singletonMap("foo", "bucket")));
|
this.factory.createParameterSource(Arrays.asList(Collections.singletonMap("foo", "bar"),
|
||||||
|
Collections.singletonMap("foo", "bucket")));
|
||||||
String expression = "foo";
|
String expression = "foo";
|
||||||
assertThat(source.hasValue(expression)).isTrue();
|
assertThat(source.hasValue(expression)).isTrue();
|
||||||
assertThat(source.getValue(expression).toString()).isEqualTo("[bar, bucket]");
|
assertThat(source.getValue(expression).toString()).isEqualTo("[bar, bucket]");
|
||||||
@@ -72,10 +74,10 @@ public class ExpressionEvaluatingSqlParameterSourceFactoryTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMapInputWithExpression() throws Exception {
|
void testMapInputWithExpression() {
|
||||||
factory.setBeanFactory(mock(BeanFactory.class));
|
this.factory.setBeanFactory(mock(BeanFactory.class));
|
||||||
factory.afterPropertiesSet();
|
this.factory.afterPropertiesSet();
|
||||||
SqlParameterSource source = factory.createParameterSource(Collections.singletonMap("foo", "bar"));
|
SqlParameterSource source = this.factory.createParameterSource(Collections.singletonMap("foo", "bar"));
|
||||||
// This is an illegal parameter name in Spring JDBC so we'd never get this as input
|
// This is an illegal parameter name in Spring JDBC so we'd never get this as input
|
||||||
assertThat(source.hasValue("foo.toUpperCase()")).isTrue();
|
assertThat(source.hasValue("foo.toUpperCase()")).isTrue();
|
||||||
assertThat(source.getValue("foo.toUpperCase()")).isEqualTo("BAR");
|
assertThat(source.getValue("foo.toUpperCase()")).isEqualTo("BAR");
|
||||||
@@ -83,35 +85,37 @@ public class ExpressionEvaluatingSqlParameterSourceFactoryTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMapInputWithMappedExpression() throws Exception {
|
void testMapInputWithMappedExpression() {
|
||||||
factory.setParameterExpressions(Collections.singletonMap("spam", "foo.toUpperCase()"));
|
this.factory.setParameterExpressions(Collections.singletonMap("spam", "foo.toUpperCase()"));
|
||||||
factory.setBeanFactory(mock(BeanFactory.class));
|
this.factory.setBeanFactory(mock(BeanFactory.class));
|
||||||
factory.afterPropertiesSet();
|
this.factory.afterPropertiesSet();
|
||||||
SqlParameterSource source = factory.createParameterSource(Collections.singletonMap("foo", "bar"));
|
SqlParameterSource source = this.factory.createParameterSource(Collections.singletonMap("foo", "bar"));
|
||||||
assertThat(source.hasValue("spam")).isTrue();
|
assertThat(source.hasValue("spam")).isTrue();
|
||||||
assertThat(source.getValue("spam")).isEqualTo("BAR");
|
assertThat(source.getValue("spam")).isEqualTo("BAR");
|
||||||
assertThat(source.getSqlType("spam")).isEqualTo(JdbcUtils.TYPE_UNKNOWN);
|
assertThat(source.getSqlType("spam")).isEqualTo(JdbcUtils.TYPE_UNKNOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMapInputWithMappedExpressionResolveStatic() throws Exception {
|
void testMapInputWithMappedExpressionResolveStatic() {
|
||||||
factory.setParameterExpressions(Collections.singletonMap("spam", "#staticParameters['foo'].toUpperCase()"));
|
this.factory.setParameterExpressions(
|
||||||
factory.setStaticParameters(Collections.singletonMap("foo", "bar"));
|
Collections.singletonMap("spam", "#staticParameters['foo'].toUpperCase()"));
|
||||||
factory.setBeanFactory(mock(BeanFactory.class));
|
this.factory.setStaticParameters(Collections.singletonMap("foo", "bar"));
|
||||||
factory.afterPropertiesSet();
|
this.factory.setBeanFactory(mock(BeanFactory.class));
|
||||||
SqlParameterSource source = factory.createParameterSource(Collections.singletonMap("crap", "bucket"));
|
this.factory.afterPropertiesSet();
|
||||||
|
SqlParameterSource source = this.factory.createParameterSource(Collections.singletonMap("crap", "bucket"));
|
||||||
assertThat(source.hasValue("spam")).isTrue();
|
assertThat(source.hasValue("spam")).isTrue();
|
||||||
assertThat(source.getValue("spam")).isEqualTo("BAR");
|
assertThat(source.getValue("spam")).isEqualTo("BAR");
|
||||||
assertThat(source.getSqlType("spam")).isEqualTo(JdbcUtils.TYPE_UNKNOWN);
|
assertThat(source.getSqlType("spam")).isEqualTo(JdbcUtils.TYPE_UNKNOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testListOfMapsInputWithExpression() throws Exception {
|
void testListOfMapsInputWithExpression() {
|
||||||
factory.setParameterExpressions(Collections.singletonMap("spam", "foo.toUpperCase()"));
|
this.factory.setParameterExpressions(Collections.singletonMap("spam", "foo.toUpperCase()"));
|
||||||
factory.setBeanFactory(mock(BeanFactory.class));
|
this.factory.setBeanFactory(mock(BeanFactory.class));
|
||||||
factory.afterPropertiesSet();
|
this.factory.afterPropertiesSet();
|
||||||
SqlParameterSource source = factory.createParameterSource(Arrays.asList(Collections.singletonMap("foo", "bar"),
|
SqlParameterSource source =
|
||||||
Collections.singletonMap("foo", "bucket")));
|
this.factory.createParameterSource(Arrays.asList(Collections.singletonMap("foo", "bar"),
|
||||||
|
Collections.singletonMap("foo", "bucket")));
|
||||||
String expression = "spam";
|
String expression = "spam";
|
||||||
assertThat(source.hasValue(expression)).isTrue();
|
assertThat(source.hasValue(expression)).isTrue();
|
||||||
assertThat(source.getValue(expression).toString()).isEqualTo("[BAR, BUCKET]");
|
assertThat(source.getValue(expression).toString()).isEqualTo("[BAR, BUCKET]");
|
||||||
@@ -119,13 +123,14 @@ public class ExpressionEvaluatingSqlParameterSourceFactoryTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testListOfMapsInputWithExpressionAndTypes() throws Exception {
|
void testListOfMapsInputWithExpressionAndTypes() {
|
||||||
factory.setParameterExpressions(Collections.singletonMap("spam", "foo.toUpperCase()"));
|
this.factory.setParameterExpressions(Collections.singletonMap("spam", "foo.toUpperCase()"));
|
||||||
factory.setBeanFactory(mock(BeanFactory.class));
|
this.factory.setBeanFactory(mock(BeanFactory.class));
|
||||||
factory.setSqlParameterTypes(Collections.singletonMap("spam", Types.SQLXML));
|
this.factory.setSqlParameterTypes(Collections.singletonMap("spam", Types.SQLXML));
|
||||||
factory.afterPropertiesSet();
|
this.factory.afterPropertiesSet();
|
||||||
SqlParameterSource source = factory.createParameterSource(Arrays.asList(Collections.singletonMap("foo", "bar"),
|
SqlParameterSource source =
|
||||||
Collections.singletonMap("foo", "bucket")));
|
this.factory.createParameterSource(Arrays.asList(Collections.singletonMap("foo", "bar"),
|
||||||
|
Collections.singletonMap("foo", "bucket")));
|
||||||
String expression = "spam";
|
String expression = "spam";
|
||||||
assertThat(source.hasValue(expression)).isTrue();
|
assertThat(source.hasValue(expression)).isTrue();
|
||||||
assertThat(source.getValue(expression).toString()).isEqualTo("[BAR, BUCKET]");
|
assertThat(source.getValue(expression).toString()).isEqualTo("[BAR, BUCKET]");
|
||||||
@@ -133,17 +138,29 @@ public class ExpressionEvaluatingSqlParameterSourceFactoryTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testListOfMapsInputWithExpressionAndEmptyTypes() throws Exception {
|
void testListOfMapsInputWithExpressionAndEmptyTypes() {
|
||||||
factory.setParameterExpressions(Collections.singletonMap("spam", "foo.toUpperCase()"));
|
this.factory.setParameterExpressions(Collections.singletonMap("spam", "foo.toUpperCase()"));
|
||||||
factory.setBeanFactory(mock(BeanFactory.class));
|
this.factory.setBeanFactory(mock(BeanFactory.class));
|
||||||
factory.setSqlParameterTypes(Collections.emptyMap());
|
this.factory.setSqlParameterTypes(Collections.emptyMap());
|
||||||
factory.afterPropertiesSet();
|
this.factory.afterPropertiesSet();
|
||||||
SqlParameterSource source = factory.createParameterSource(Arrays.asList(Collections.singletonMap("foo", "bar"),
|
SqlParameterSource source =
|
||||||
Collections.singletonMap("foo", "bucket")));
|
this.factory.createParameterSource(Arrays.asList(Collections.singletonMap("foo", "bar"),
|
||||||
|
Collections.singletonMap("foo", "bucket")));
|
||||||
String expression = "spam";
|
String expression = "spam";
|
||||||
assertThat(source.hasValue(expression)).isTrue();
|
assertThat(source.hasValue(expression)).isTrue();
|
||||||
assertThat(source.getValue(expression).toString()).isEqualTo("[BAR, BUCKET]");
|
assertThat(source.getValue(expression).toString()).isEqualTo("[BAR, BUCKET]");
|
||||||
assertThat(source.getSqlType("spam")).isEqualTo(JdbcUtils.TYPE_UNKNOWN);
|
assertThat(source.getSqlType("spam")).isEqualTo(JdbcUtils.TYPE_UNKNOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testNullValue() {
|
||||||
|
this.factory.setStaticParameters(Collections.singletonMap("foo", null));
|
||||||
|
this.factory.setBeanFactory(mock(BeanFactory.class));
|
||||||
|
this.factory.afterPropertiesSet();
|
||||||
|
SqlParameterSource source = this.factory.createParameterSource(null);
|
||||||
|
assertThat(source.hasValue("foo")).isTrue();
|
||||||
|
assertThat(source.getValue("foo")).isNull();
|
||||||
|
assertThat(source.getSqlType("foo")).isEqualTo(JdbcUtils.TYPE_UNKNOWN);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user