Call ConversionService for null SpEL values

Update SpEL boolean operators to always call the ConversionService
for null values. Primarily to allow null values to be treated as
false by overriding GenericConversionService.convertNullSource().

Issue: SPR-9445
This commit is contained in:
Oliver Becker
2012-11-21 22:53:29 -08:00
committed by Phillip Webb
parent d9bd2e19a2
commit 759c9b35cd
7 changed files with 79 additions and 86 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2012 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,15 @@
package org.springframework.expression.spel;
import org.junit.Test;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.expression.spel.support.StandardTypeConverter;
/**
* Tests the evaluation of real boolean expressions, these use AND, OR, NOT, TRUE, FALSE
*
*
* @author Andy Clement
* @author Oliver Becker
*/
public class BooleanExpressionTests extends ExpressionTestCase {
@@ -83,4 +87,27 @@ public class BooleanExpressionTests extends ExpressionTestCase {
evaluateAndCheckError("!35.2", SpelMessage.TYPE_CONVERSION_ERROR, 1);
evaluateAndCheckError("! 'foob'", SpelMessage.TYPE_CONVERSION_ERROR, 2);
}
@Test
public void testConvertAndHandleNull() { // SPR-9445
// without null conversion
evaluateAndCheckError("null or true", SpelMessage.TYPE_CONVERSION_ERROR, 0, "null", "boolean");
evaluateAndCheckError("null and true", SpelMessage.TYPE_CONVERSION_ERROR, 0, "null", "boolean");
evaluateAndCheckError("!null", SpelMessage.TYPE_CONVERSION_ERROR, 1, "null", "boolean");
evaluateAndCheckError("null ? 'foo' : 'bar'", SpelMessage.TYPE_CONVERSION_ERROR, 0, "null", "boolean");
// with null conversion (null -> false)
GenericConversionService conversionService = new GenericConversionService() {
@Override
protected Object convertNullSource(TypeDescriptor sourceType, TypeDescriptor targetType) {
return targetType.getType() == Boolean.class ? false : null;
}
};
eContext.setTypeConverter(new StandardTypeConverter(conversionService));
evaluate("null or true", Boolean.TRUE, Boolean.class, false);
evaluate("null and true", Boolean.FALSE, Boolean.class, false);
evaluate("!null", Boolean.TRUE, Boolean.class, false);
evaluate("null ? 'foo' : 'bar'", "bar", String.class, false);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2012 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.
@@ -40,8 +40,8 @@ public abstract class ExpressionTestCase {
protected final static boolean SHOULD_BE_WRITABLE = true;
protected final static boolean SHOULD_NOT_BE_WRITABLE = false;
protected final static ExpressionParser parser = new SpelExpressionParser();
protected final static StandardEvaluationContext eContext = TestScenarioCreator.getTestEvaluationContext();
protected final ExpressionParser parser = new SpelExpressionParser();
protected final StandardEvaluationContext eContext = TestScenarioCreator.getTestEvaluationContext();
/**
* Evaluate an expression and check that the actual result matches the expectedValue and the class of the result