Browse Source

Restored proper handling of varargs in case of unresolvable type variable

Fixed through falling back to the raw parameter type in the TypeDescriptor(MethodParameter) constructor, properly detecting the vararg array even in case of an unresolvable type variable, and through restoring getElementTypeDescriptor's original behavior for arrays, i.e. always returning a non-null descriptor.

Issue: SPR-11494
pull/484/merge
Juergen Hoeller 12 years ago
parent
commit
2a2816dfc3
  1. 4
      spring-core/src/main/java/org/springframework/core/ResolvableType.java
  2. 184
      spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java
  3. 12
      spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectionHelper.java
  4. 218
      spring-expression/src/test/java/org/springframework/expression/spel/SpelReproTests.java

4
spring-core/src/main/java/org/springframework/core/ResolvableType.java

@ -631,8 +631,8 @@ public final class ResolvableType implements Serializable { @@ -631,8 +631,8 @@ public final class ResolvableType implements Serializable {
/**
* Resolve this type to a {@link java.lang.Class}, returning {@code null} if the type
* cannot be resolved. This method will consider bounds of {@link TypeVariable}s and
* {@link WildcardType}s if direct resolution fails; however, bounds of Object.class
* will be ignored.
* {@link WildcardType}s if direct resolution fails; however, bounds of
* {@code Object.class} will be ignored.
* @return the resolved {@link Class} or {@code null}
* @see #resolve(Class)
* @see #resolveGeneric(int...)

184
spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java

@ -78,7 +78,7 @@ public class TypeDescriptor implements Serializable { @@ -78,7 +78,7 @@ public class TypeDescriptor implements Serializable {
throw new IllegalArgumentException("MethodParameter argument must have its nestingLevel set to 1");
}
this.resolvableType = ResolvableType.forMethodParameter(methodParameter);
this.type = this.resolvableType.resolve(Object.class);
this.type = this.resolvableType.resolve(methodParameter.getParameterType());
this.annotations = (methodParameter.getParameterIndex() == -1 ?
nullSafeAnnotations(methodParameter.getMethodAnnotations()) :
nullSafeAnnotations(methodParameter.getParameterAnnotations()));
@ -92,7 +92,7 @@ public class TypeDescriptor implements Serializable { @@ -92,7 +92,7 @@ public class TypeDescriptor implements Serializable {
public TypeDescriptor(Field field) {
Assert.notNull(field, "Field must not be null");
this.resolvableType = ResolvableType.forField(field);
this.type = this.resolvableType.resolve(Object.class);
this.type = this.resolvableType.resolve(field.getType());
this.annotations = nullSafeAnnotations(field.getAnnotations());
}
@ -167,15 +167,20 @@ public class TypeDescriptor implements Serializable { @@ -167,15 +167,20 @@ public class TypeDescriptor implements Serializable {
}
/**
* Narrows this {@link TypeDescriptor} by setting its type to the class of the provided value.
* <p>If the value is {@code null}, no narrowing is performed and this TypeDescriptor is returned unchanged.
* <p>Designed to be called by binding frameworks when they read property, field, or method return values.
* Allows such frameworks to narrow a TypeDescriptor built from a declared property, field, or method return value type.
* For example, a field declared as {@code java.lang.Object} would be narrowed to {@code java.util.HashMap}
* if it was set to a {@code java.util.HashMap} value. The narrowed TypeDescriptor can then be used to convert
* the HashMap to some other type. Annotation and nested type context is preserved by the narrowed copy.
* Narrows this {@link TypeDescriptor} by setting its type to the class of the
* provided value.
* <p>If the value is {@code null}, no narrowing is performed and this TypeDescriptor
* is returned unchanged.
* <p>Designed to be called by binding frameworks when they read property, field,
* or method return values. Allows such frameworks to narrow a TypeDescriptor built
* from a declared property, field, or method return value type. For example, a field
* declared as {@code java.lang.Object} would be narrowed to {@code java.util.HashMap}
* if it was set to a {@code java.util.HashMap} value. The narrowed TypeDescriptor
* can then be used to convert the HashMap to some other type. Annotation and nested
* type context is preserved by the narrowed copy.
* @param value the value to use for narrowing this type descriptor
* @return this TypeDescriptor narrowed (returns a copy with its type updated to the class of the provided value)
* @return this TypeDescriptor narrowed (returns a copy with its type updated to the
* class of the provided value)
*/
public TypeDescriptor narrow(Object value) {
if (value == null) {
@ -254,13 +259,17 @@ public class TypeDescriptor implements Serializable { @@ -254,13 +259,17 @@ public class TypeDescriptor implements Serializable {
}
/**
* Returns true if an object of this type descriptor can be assigned to the location described by the given type descriptor.
* <p>For example, valueOf(String.class).isAssignableTo(valueOf(CharSequence.class)) returns true because a String value can be assigned to a CharSequence variable.
* On the other hand, valueOf(Number.class).isAssignableTo(valueOf(Integer.class)) returns false because, while all Integers are Numbers, not all Numbers are Integers.
* <p>
* For arrays, collections, and maps, element and key/value types are checked if declared.
* For example, a List&lt;String&gt; field value is assignable to a Collection&lt;CharSequence&gt; field, but List&lt;Number&gt; is not assignable to List&lt;Integer&gt;.
* @return true if this type is assignable to the type represented by the provided type descriptor
* Returns true if an object of this type descriptor can be assigned to the location
* described by the given type descriptor.
* <p>For example, {@code valueOf(String.class).isAssignableTo(valueOf(CharSequence.class))}
* returns {@code true} because a String value can be assigned to a CharSequence variable.
* On the other hand, {@code valueOf(Number.class).isAssignableTo(valueOf(Integer.class))}
* returns {@code false} because, while all Integers are Numbers, not all Numbers are Integers.
* <p>For arrays, collections, and maps, element and key/value types are checked if declared.
* For example, a List&lt;String&gt; field value is assignable to a Collection&lt;CharSequence&gt;
* field, but List&lt;Number&gt; is not assignable to List&lt;Integer&gt;.
* @return {@code true} if this type is assignable to the type represented by the provided
* type descriptor
* @see #getObjectType()
*/
public boolean isAssignableTo(TypeDescriptor typeDescriptor) {
@ -307,28 +316,36 @@ public class TypeDescriptor implements Serializable { @@ -307,28 +316,36 @@ public class TypeDescriptor implements Serializable {
/**
* If this type is an array, returns the array's component type.
* If this type is a {@link Collection} and it is parameterized, returns the Collection's element type.
* If the Collection is not parameterized, returns null indicating the element type is not declared.
* @return the array component type or Collection element type, or {@code null} if this type is a Collection but its element type is not parameterized
* @throws IllegalStateException if this type is not a java.util.Collection or Array type
* If the Collection is not parameterized, returns {@code null} indicating the element type is not declared.
* @return the array component type or Collection element type, or {@code null} if this type is a
* Collection but its element type is not parameterized
* @throws IllegalStateException if this type is not a {@code java.util.Collection} or array type
*/
public TypeDescriptor getElementTypeDescriptor() {
assertCollectionOrArray();
if (this.resolvableType.isArray()) {
return getRelatedIfResolvable(this, this.resolvableType.getComponentType());
return new TypeDescriptor(this.resolvableType.getComponentType(), null, this.annotations);
}
Assert.state(isCollection(), "Not an array or java.util.Collection");
return getRelatedIfResolvable(this, this.resolvableType.asCollection().getGeneric());
}
/**
* If this type is a {@link Collection} or an Array, creates a element TypeDescriptor from the provided collection or array element.
* <p>Narrows the {@link #getElementTypeDescriptor() elementType} property to the class of the provided collection or array element.
* For example, if this describes a java.util.List&lt;java.lang.Number&lt; and the element argument is a java.lang.Integer, the returned TypeDescriptor will be java.lang.Integer.
* If this describes a java.util.List&lt;?&gt; and the element argument is a java.lang.Integer, the returned TypeDescriptor will be java.lang.Integer as well.
* <p>Annotation and nested type context will be preserved in the narrowed TypeDescriptor that is returned.
* If this type is a {@link Collection} or an array, creates a element TypeDescriptor
* from the provided collection or array element.
* <p>Narrows the {@link #getElementTypeDescriptor() elementType} property to the class
* of the provided collection or array element. For example, if this describes a
* {@code java.util.List&lt;java.lang.Number&lt;} and the element argument is an
* {@code java.lang.Integer}, the returned TypeDescriptor will be {@code java.lang.Integer}.
* If this describes a {@code java.util.List&lt;?&gt;} and the element argument is an
* {@code java.lang.Integer}, the returned TypeDescriptor will be {@code java.lang.Integer}
* as well.
* <p>Annotation and nested type context will be preserved in the narrowed
* TypeDescriptor that is returned.
* @param element the collection or array element
* @return a element type descriptor, narrowed to the type of the provided element
* @throws IllegalStateException if this type is not a java.util.Collection or Array type
* @throws IllegalStateException if this type is not a {@code java.util.Collection}
* or array type
* @see #narrow(Object)
*/
public TypeDescriptor elementTypeDescriptor(Object element) {
@ -343,25 +360,33 @@ public class TypeDescriptor implements Serializable { @@ -343,25 +360,33 @@ public class TypeDescriptor implements Serializable {
}
/**
* If this type is a {@link Map} and its key type is parameterized, returns the map's key type.
* If the Map's key type is not parameterized, returns null indicating the key type is not declared.
* @return the Map key type, or {@code null} if this type is a Map but its key type is not parameterized
* @throws IllegalStateException if this type is not a java.util.Map
* If this type is a {@link Map} and its key type is parameterized,
* returns the map's key type. If the Map's key type is not parameterized,
* returns {@code null} indicating the key type is not declared.
* @return the Map key type, or {@code null} if this type is a Map
* but its key type is not parameterized
* @throws IllegalStateException if this type is not a {@code java.util.Map}
*/
public TypeDescriptor getMapKeyTypeDescriptor() {
assertMap();
Assert.state(isMap(), "Not a java.util.Map");
return getRelatedIfResolvable(this, this.resolvableType.asMap().getGeneric(0));
}
/**
* If this type is a {@link Map}, creates a mapKey {@link TypeDescriptor} from the provided map key.
* <p>Narrows the {@link #getMapKeyTypeDescriptor() mapKeyType} property to the class of the provided map key.
* For example, if this describes a java.util.Map&lt;java.lang.Number, java.lang.String&lt; and the key argument is a java.lang.Integer, the returned TypeDescriptor will be java.lang.Integer.
* <p>If this describes a java.util.Map&lt;?, ?&gt; and the key argument is a java.lang.Integer, the returned TypeDescriptor will be java.lang.Integer as well.
* <p>Annotation and nested type context will be preserved in the narrowed TypeDescriptor that is returned.
* If this type is a {@link Map}, creates a mapKey {@link TypeDescriptor}
* from the provided map key.
* <p>Narrows the {@link #getMapKeyTypeDescriptor() mapKeyType} property
* to the class of the provided map key. For example, if this describes a
* {@code java.util.Map&lt;java.lang.Number, java.lang.String&lt;} and the key
* argument is a {@code java.lang.Integer}, the returned TypeDescriptor will be
* {@code java.lang.Integer}. If this describes a {@code java.util.Map&lt;?, ?&gt;}
* and the key argument is a {@code java.lang.Integer}, the returned
* TypeDescriptor will be {@code java.lang.Integer} as well.
* <p>Annotation and nested type context will be preserved in the narrowed
* TypeDescriptor that is returned.
* @param mapKey the map key
* @return the map key type descriptor
* @throws IllegalStateException if this type is not a java.util.Map
* @throws IllegalStateException if this type is not a {@code java.util.Map}
* @see #narrow(Object)
*/
public TypeDescriptor getMapKeyTypeDescriptor(Object mapKey) {
@ -369,34 +394,45 @@ public class TypeDescriptor implements Serializable { @@ -369,34 +394,45 @@ public class TypeDescriptor implements Serializable {
}
/**
* If this type is a {@link Map} and its value type is parameterized, returns the map's value type.
* <p>If the Map's value type is not parameterized, returns null indicating the value type is not declared.
* @return the Map value type, or {@code null} if this type is a Map but its value type is not parameterized
* @throws IllegalStateException if this type is not a java.util.Map
* If this type is a {@link Map} and its value type is parameterized,
* returns the map's value type.
* <p>If the Map's value type is not parameterized, returns {@code null}
* indicating the value type is not declared.
* @return the Map value type, or {@code null} if this type is a Map
* but its value type is not parameterized
* @throws IllegalStateException if this type is not a {@code java.util.Map}
*/
public TypeDescriptor getMapValueTypeDescriptor() {
assertMap();
Assert.state(isMap(), "Not a java.util.Map");
return getRelatedIfResolvable(this, this.resolvableType.asMap().getGeneric(1));
}
/**
* If this type is a {@link Map}, creates a mapValue {@link TypeDescriptor} from the provided map value.
* <p>Narrows the {@link #getMapValueTypeDescriptor() mapValueType} property to the class of the provided map value.
* For example, if this describes a java.util.Map&lt;java.lang.String, java.lang.Number&lt; and the value argument is a java.lang.Integer, the returned TypeDescriptor will be java.lang.Integer.
* If this describes a java.util.Map&lt;?, ?&gt; and the value argument is a java.lang.Integer, the returned TypeDescriptor will be java.lang.Integer as well.
* <p>Annotation and nested type context will be preserved in the narrowed TypeDescriptor that is returned.
* If this type is a {@link Map}, creates a mapValue {@link TypeDescriptor}
* from the provided map value.
* <p>Narrows the {@link #getMapValueTypeDescriptor() mapValueType} property
* to the class of the provided map value. For example, if this describes a
* {@code java.util.Map&lt;java.lang.String, java.lang.Number&lt;} and the value
* argument is a {@code java.lang.Integer}, the returned TypeDescriptor will be
* {@code java.lang.Integer}. If this describes a {@code java.util.Map&lt;?, ?&gt;}
* and the value argument is a {@code java.lang.Integer}, the returned
* TypeDescriptor will be {@code java.lang.Integer} as well.
* <p>Annotation and nested type context will be preserved in the narrowed
* TypeDescriptor that is returned.
* @param mapValue the map value
* @return the map value type descriptor
* @throws IllegalStateException if this type is not a java.util.Map
* @throws IllegalStateException if this type is not a {@code java.util.Map}
* @see #narrow(Object)
*/
public TypeDescriptor getMapValueTypeDescriptor(Object mapValue) {
return narrow(mapValue, getMapValueTypeDescriptor());
}
/**
* Returns the value of {@link TypeDescriptor#getType() getType()} for the {@link #getElementTypeDescriptor() elementTypeDescriptor}.
* Returns the value of {@link TypeDescriptor#getType() getType()} for the
* {@link #getElementTypeDescriptor() elementTypeDescriptor}.
* @deprecated in Spring 3.1 in favor of {@link #getElementTypeDescriptor()}
* @throws IllegalStateException if this type is not a java.util.Collection or Array type
* @throws IllegalStateException if this type is not a {@code java.util.Collection} or array type
*/
@Deprecated
public Class<?> getElementType() {
@ -404,9 +440,10 @@ public class TypeDescriptor implements Serializable { @@ -404,9 +440,10 @@ public class TypeDescriptor implements Serializable {
}
/**
* Returns the value of {@link TypeDescriptor#getType() getType()} for the {@link #getMapKeyTypeDescriptor() getMapKeyTypeDescriptor}.
* Returns the value of {@link TypeDescriptor#getType() getType()} for the
* {@link #getMapKeyTypeDescriptor() getMapKeyTypeDescriptor}.
* @deprecated in Spring 3.1 in favor of {@link #getMapKeyTypeDescriptor()}
* @throws IllegalStateException if this type is not a java.util.Map
* @throws IllegalStateException if this type is not a {@code java.util.Map}
*/
@Deprecated
public Class<?> getMapKeyType() {
@ -414,9 +451,10 @@ public class TypeDescriptor implements Serializable { @@ -414,9 +451,10 @@ public class TypeDescriptor implements Serializable {
}
/**
* Returns the value of {@link TypeDescriptor#getType() getType()} for the {@link #getMapValueTypeDescriptor() getMapValueTypeDescriptor}.
* Returns the value of {@link TypeDescriptor#getType() getType()} for the
* {@link #getMapValueTypeDescriptor() getMapValueTypeDescriptor}.
* @deprecated in Spring 3.1 in favor of {@link #getMapValueTypeDescriptor()}
* @throws IllegalStateException if this type is not a java.util.Map
* @throws IllegalStateException if this type is not a {@code java.util.Map}
*/
@Deprecated
public Class<?> getMapValueType() {
@ -424,19 +462,7 @@ public class TypeDescriptor implements Serializable { @@ -424,19 +462,7 @@ public class TypeDescriptor implements Serializable {
}
private Class<?> getType(TypeDescriptor typeDescriptor) {
return (typeDescriptor == null ? null : typeDescriptor.getType());
}
private void assertCollectionOrArray() {
if (!isCollection() && !isArray()) {
throw new IllegalStateException("Not a java.util.Collection or Array");
}
}
private void assertMap() {
if (!isMap()) {
throw new IllegalStateException("Not a java.util.Map");
}
return (typeDescriptor != null ? typeDescriptor.getType() : null);
}
private TypeDescriptor narrow(Object value, TypeDescriptor typeDescriptor) {
@ -589,15 +615,15 @@ public class TypeDescriptor implements Serializable { @@ -589,15 +615,15 @@ public class TypeDescriptor implements Serializable {
* @param methodParameter the method parameter with a nestingLevel of 1
* @param nestingLevel the nesting level of the collection/array element or
* map key/value declaration within the method parameter
* @return the nested type descriptor at the specified nesting level, or null
* if it could not be obtained
* @return the nested type descriptor at the specified nesting level,
* or {@code null} if it could not be obtained
* @throws IllegalArgumentException if the nesting level of the input
* {@link MethodParameter} argument is not 1, or if the types up to the
* specified nesting level are not of collection, array, or map types
*/
public static TypeDescriptor nested(MethodParameter methodParameter, int nestingLevel) {
if (methodParameter.getNestingLevel() != 1) {
throw new IllegalArgumentException("methodParameter nesting level must be 1: " +
throw new IllegalArgumentException("MethodParameter nesting level must be 1: " +
"use the nestingLevel parameter to specify the desired nestingLevel for nested type traversal");
}
return nested(new TypeDescriptor(methodParameter), nestingLevel);
@ -618,8 +644,8 @@ public class TypeDescriptor implements Serializable { @@ -618,8 +644,8 @@ public class TypeDescriptor implements Serializable {
* @param field the field
* @param nestingLevel the nesting level of the collection/array element or
* map key/value declaration within the field
* @return the nested type descriptor at the specified nesting level, or null
* if it could not be obtained
* @return the nested type descriptor at the specified nesting level,
* or {@code null} if it could not be obtained
* @throws IllegalArgumentException if the types up to the specified nesting
* level are not of collection, array, or map types
*/
@ -669,15 +695,17 @@ public class TypeDescriptor implements Serializable { @@ -669,15 +695,17 @@ public class TypeDescriptor implements Serializable {
ResolvableType nested = typeDescriptor.resolvableType;
for (int i = 0; i < nestingLevel; i++) {
if (Object.class.equals(nested.getType())) {
// could be a collection type but we don't know about its element type,
// so let's just assume there is an element type of type Object
// Could be a collection type but we don't know about its element type,
// so let's just assume there is an element type of type Object...
}
else {
nested = nested.getNested(2);
}
}
Assert.state(nested != ResolvableType.NONE, "Unable to obtain nested generic from "
+ typeDescriptor + " at level " + nestingLevel);
if (nested == ResolvableType.NONE) {
throw new IllegalStateException(
"Unable to obtain nested generic from " + typeDescriptor + " at level " + nestingLevel);
}
return getRelatedIfResolvable(typeDescriptor, nested);
}

12
spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectionHelper.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-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.
@ -189,7 +189,8 @@ public class ReflectionHelper { @@ -189,7 +189,8 @@ public class ReflectionHelper {
else {
// Now... we have the final argument in the method we are checking as a match and we have 0
// or more other arguments left to pass to it.
Class<?> varargsParamType = expectedArgTypes.get(expectedArgTypes.size() - 1).getElementTypeDescriptor().getType();
TypeDescriptor varargsDesc = expectedArgTypes.get(expectedArgTypes.size() - 1);
Class<?> varargsParamType = varargsDesc.getElementTypeDescriptor().getType();
// All remaining parameters must be of this type or convertable to this type
for (int i = expectedArgTypes.size() - 1; i < suppliedArgTypes.size(); i++) {
@ -221,9 +222,8 @@ public class ReflectionHelper { @@ -221,9 +222,8 @@ public class ReflectionHelper {
}
/**
* Takes an input set of argument values and, following the positions specified in the int array,
* it converts them to the types specified as the required parameter types. The arguments are
* converted 'in-place' in the input array.
* Takes an input set of argument values and converts them to the types specified as the
* required parameter types. The arguments are converted 'in-place' in the input array.
* @param converter the type converter to use for attempting conversions
* @param arguments the actual arguments that need conversion
* @param methodOrCtor the target Method or Constructor
@ -253,7 +253,7 @@ public class ReflectionHelper { @@ -253,7 +253,7 @@ public class ReflectionHelper {
arguments[varargsPosition] = converter.convertValue(argument, TypeDescriptor.forObject(argument), targetType);
}
else {
TypeDescriptor targetType = TypeDescriptor.nested(methodParam, 1);
TypeDescriptor targetType = new TypeDescriptor(methodParam).getElementTypeDescriptor();
for (int i = varargsPosition; i < arguments.length; i++) {
Object argument = arguments[i];
arguments[i] = converter.convertValue(argument, TypeDescriptor.forObject(argument), targetType);

218
spring-expression/src/test/java/org/springframework/expression/spel/SpelReproTests.java

@ -19,7 +19,6 @@ package org.springframework.expression.spel; @@ -19,7 +19,6 @@ package org.springframework.expression.spel;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@ -151,6 +150,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -151,6 +150,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
}
static class Spr5899Class {
public Spr5899Class() {
@ -276,7 +276,6 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -276,7 +276,6 @@ public class SpelReproTests extends AbstractExpressionTests {
public Properties jdbcProperties = new Properties();
public Properties foo = new Properties();
TestProperties() {
jdbcProperties.put("username", "Dave");
jdbcProperties.put("alias", "Dave2");
@ -285,6 +284,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -285,6 +284,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
}
static class MapAccessor implements PropertyAccessor {
@Override
@ -304,8 +304,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -304,8 +304,7 @@ public class SpelReproTests extends AbstractExpressionTests {
@Override
@SuppressWarnings("unchecked")
public void write(EvaluationContext context, Object target, String name, Object newValue)
throws AccessException {
public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException {
((Map<String, Object>) target).put(name, newValue);
}
@ -326,15 +325,13 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -326,15 +325,13 @@ public class SpelReproTests extends AbstractExpressionTests {
checkTemplateParsingError("abc${ {}( 'abc'", "Missing closing ')' for '(' at position 8");
checkTemplateParsingError("abc${ {}[ 'abc'", "Missing closing ']' for '[' at position 8");
checkTemplateParsingError("abc${ {}{ 'abc'", "Missing closing '}' for '{' at position 8");
checkTemplateParsingError("abc${ ( 'abc' }",
"Found closing '}' at position 14 but most recent opening is '(' at position 6");
checkTemplateParsingError("abc${ ( 'abc' }", "Found closing '}' at position 14 but most recent opening is '(' at position 6");
checkTemplateParsingError("abc${ '... }", "Found non terminating string literal starting at position 6");
checkTemplateParsingError("abc${ \"... }", "Found non terminating string literal starting at position 6");
checkTemplateParsingError("abc${ ) }", "Found closing ')' at position 6 without an opening '('");
checkTemplateParsingError("abc${ ] }", "Found closing ']' at position 6 without an opening '['");
checkTemplateParsingError("abc${ } }", "No expression defined within delimiter '${}' at character 3");
checkTemplateParsingError("abc$[ } ]", DOLLARSQUARE_TEMPLATE_PARSER_CONTEXT,
"Found closing '}' at position 6 without an opening '{'");
checkTemplateParsingError("abc$[ } ]", DOLLARSQUARE_TEMPLATE_PARSER_CONTEXT, "Found closing '}' at position 6 without an opening '{'");
checkTemplateParsing("abc ${\"def''g}hi\"} jkl", "abc def'g}hi jkl");
checkTemplateParsing("abc ${'def''g}hi'} jkl", "abc def'g}hi jkl");
@ -343,19 +340,13 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -343,19 +340,13 @@ public class SpelReproTests extends AbstractExpressionTests {
checkTemplateParsing("Hello ${'}'}]", "Hello }]");
checkTemplateParsing("Hello ${'}'}", "Hello }");
checkTemplateParsingError("Hello ${ ( ", "No ending suffix '}' for expression starting at character 6: ${ ( ");
checkTemplateParsingError("Hello ${ ( }",
"Found closing '}' at position 11 but most recent opening is '(' at position 9");
checkTemplateParsing("#{'Unable to render embedded object: File ({#this == 2}'}", hashes,
"Unable to render embedded object: File ({#this == 2}");
checkTemplateParsing("This is the last odd number in the list: ${listOfNumbersUpToTen.$[#this%2==1]}", dollars,
"This is the last odd number in the list: 9");
checkTemplateParsingError("Hello ${ ( }", "Found closing '}' at position 11 but most recent opening is '(' at position 9");
checkTemplateParsing("#{'Unable to render embedded object: File ({#this == 2}'}", hashes, "Unable to render embedded object: File ({#this == 2}");
checkTemplateParsing("This is the last odd number in the list: ${listOfNumbersUpToTen.$[#this%2==1]}", dollars, "This is the last odd number in the list: 9");
checkTemplateParsing("Hello ${'here is a curly bracket }'}", dollars, "Hello here is a curly bracket }");
checkTemplateParsing("He${'${'}llo ${'here is a curly bracket }'}}", dollars,
"He${llo here is a curly bracket }}");
checkTemplateParsing("Hello ${'()()()}{}{}{][]{}{][}[][][}{()()'} World", dollars,
"Hello ()()()}{}{}{][]{}{][}[][][}{()() World");
checkTemplateParsing("Hello ${'inner literal that''s got {[(])]}an escaped quote in it'} World",
"Hello inner literal that's got {[(])]}an escaped quote in it World");
checkTemplateParsing("He${'${'}llo ${'here is a curly bracket }'}}", dollars, "He${llo here is a curly bracket }}");
checkTemplateParsing("Hello ${'()()()}{}{}{][]{}{][}[][][}{()()'} World", dollars, "Hello ()()()}{}{}{][]{}{][}[][][}{()() World");
checkTemplateParsing("Hello ${'inner literal that''s got {[(])]}an escaped quote in it'} World", "Hello inner literal that's got {[(])]}an escaped quote in it World");
checkTemplateParsingError("Hello ${", "No ending suffix '}' for expression starting at character 6: ${");
}
@ -384,11 +375,8 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -384,11 +375,8 @@ public class SpelReproTests extends AbstractExpressionTests {
@Test
public void nestedProperties_SPR6923() {
StandardEvaluationContext eContext = new StandardEvaluationContext(new Foo());
String name = null;
Expression expr = null;
expr = new SpelExpressionParser().parseRaw("resource.resource.server");
name = expr.getValue(eContext, String.class);
Expression expr = new SpelExpressionParser().parseRaw("resource.resource.server");
String name = expr.getValue(eContext, String.class);
assertEquals("abc", name);
}
@ -398,11 +386,11 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -398,11 +386,11 @@ public class SpelReproTests extends AbstractExpressionTests {
public ResourceSummary resource = new ResourceSummary();
}
static class ResourceSummary {
private final Resource resource;
ResourceSummary() {
this.resource = new Resource();
}
@ -412,6 +400,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -412,6 +400,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
}
static class Resource {
public String getServer() {
@ -500,8 +489,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -500,8 +489,7 @@ public class SpelReproTests extends AbstractExpressionTests {
// will access the field 'wibble' and not use a getter
name = expr.getValue(eContext, String.class);
assertEquals("wobble", name);
name = expr.getValue(eContext, String.class); // will be using the cached accessor
// this time
name = expr.getValue(eContext, String.class); // will be using the cached accessor this time
assertEquals("wobble", name);
}
@ -519,8 +507,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -519,8 +507,7 @@ public class SpelReproTests extends AbstractExpressionTests {
// will access the field 'wibble' and not use a getter
expr.getValue(eContext, String.class);
assertEquals("world", g.wibble);
expr.getValue(eContext, String.class); // will be using the cached accessor this
// time
expr.getValue(eContext, String.class); // will be using the cached accessor this time
assertEquals("world", g.wibble);
}
@ -533,8 +520,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -533,8 +520,7 @@ public class SpelReproTests extends AbstractExpressionTests {
expr = new SpelExpressionParser().parseRaw("instance[bar]='world'");
expr.getValue(eContext, String.class);
assertEquals("world", g.value);
expr.getValue(eContext, String.class); // will be using the cached accessor this
// time
expr.getValue(eContext, String.class); // will be using the cached accessor this time
assertEquals("world", g.value);
}
@ -563,7 +549,6 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -563,7 +549,6 @@ public class SpelReproTests extends AbstractExpressionTests {
public String floo = "bar";
public XX() {
m = new HashMap<String, String>();
m.put("$foo", "wibble");
@ -571,6 +556,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -571,6 +556,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
}
static class Goo {
public static Goo instance = new Goo();
@ -581,7 +567,6 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -581,7 +567,6 @@ public class SpelReproTests extends AbstractExpressionTests {
public String wibble = "wobble";
public String getKey() {
return "hello";
}
@ -591,6 +576,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -591,6 +576,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
}
static class Holder {
public Map<String, String> map = new HashMap<String, String>();
@ -610,12 +596,10 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -610,12 +596,10 @@ public class SpelReproTests extends AbstractExpressionTests {
}
private void checkTemplateParsingError(String expression, String expectedMessage) throws Exception {
checkTemplateParsingError(expression, TemplateExpressionParsingTests.DEFAULT_TEMPLATE_PARSER_CONTEXT,
expectedMessage);
checkTemplateParsingError(expression, TemplateExpressionParsingTests.DEFAULT_TEMPLATE_PARSER_CONTEXT, expectedMessage);
}
private void checkTemplateParsingError(String expression, ParserContext context, String expectedMessage)
throws Exception {
private void checkTemplateParsingError(String expression, ParserContext context, String expectedMessage) throws Exception {
SpelExpressionParser parser = new SpelExpressionParser();
try {
parser.parseExpression(expression, context);
@ -635,17 +619,14 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -635,17 +619,14 @@ public class SpelReproTests extends AbstractExpressionTests {
private static final ParserContext DOLLARSQUARE_TEMPLATE_PARSER_CONTEXT = new ParserContext() {
@Override
public String getExpressionPrefix() {
return "$[";
}
@Override
public String getExpressionSuffix() {
return "]";
}
@Override
public boolean isTemplate() {
return true;
@ -660,11 +641,11 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -660,11 +641,11 @@ public class SpelReproTests extends AbstractExpressionTests {
}
}
static class Message {
private String payload;
public String getPayload() {
return payload;
}
@ -711,7 +692,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -711,7 +692,7 @@ public class SpelReproTests extends AbstractExpressionTests {
assertEquals(SpelMessage.EXCEPTION_DURING_BEAN_RESOLUTION, see.getMessageCode());
assertEquals("goo", see.getInserts()[0]);
assertTrue(see.getCause() instanceof AccessException);
assertTrue(((AccessException) see.getCause()).getMessage().startsWith("DONT"));
assertTrue(see.getCause().getMessage().startsWith("DONT"));
}
// bean exists
@ -864,7 +845,6 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -864,7 +845,6 @@ public class SpelReproTests extends AbstractExpressionTests {
public String[] as;
public Map<String, String> ms;
C() {
ls = new ArrayList<String>();
ls.add("abc");
@ -876,11 +856,11 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -876,11 +856,11 @@ public class SpelReproTests extends AbstractExpressionTests {
}
}
static class D {
public String a;
private D(String s) {
a = s;
}
@ -932,11 +912,9 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -932,11 +912,9 @@ public class SpelReproTests extends AbstractExpressionTests {
@SuppressWarnings("unused")
class ConversionPriority1 {
public int getX(Number i) {
return 20;
}
public int getX(int i) {
return 10;
}
@ -944,11 +922,9 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -944,11 +922,9 @@ public class SpelReproTests extends AbstractExpressionTests {
@SuppressWarnings("unused")
class ConversionPriority2 {
public int getX(int i) {
return 10;
}
public int getX(Number i) {
return 20;
}
@ -989,27 +965,22 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -989,27 +965,22 @@ public class SpelReproTests extends AbstractExpressionTests {
public void wideningPrimitiveConversion_8224() throws Exception {
class WideningPrimitiveConversion {
public int getX(long i) {
return 10;
}
}
final Integer INTEGER_VALUE = Integer.valueOf(7);
WideningPrimitiveConversion target = new WideningPrimitiveConversion();
EvaluationContext emptyEvalContext = new StandardEvaluationContext();
List<TypeDescriptor> args = new ArrayList<TypeDescriptor>();
args.add(TypeDescriptor.forObject(INTEGER_VALUE));
MethodExecutor me = new ReflectiveMethodResolver(true).resolve(emptyEvalContext, target, "getX", args);
final int actual = (Integer) me.execute(emptyEvalContext, target, INTEGER_VALUE).getValue();
final int compiler = target.getX(INTEGER_VALUE);
assertEquals(compiler, actual);
}
@ -1130,12 +1101,9 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1130,12 +1101,9 @@ public class SpelReproTests extends AbstractExpressionTests {
// "DIV","EQ","GE","GT","LE","LT","MOD","NE","NOT"
@SuppressWarnings("unused")
class Reserver {
public Reserver getReserver() {
return this;
}
public String NE = "abc";
public String ne = "def";
@ -1144,7 +1112,6 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1144,7 +1112,6 @@ public class SpelReproTests extends AbstractExpressionTests {
public Map<String, String> m = new HashMap<String, String>();
Reserver() {
m.put("NE", "xyz");
}
@ -1215,7 +1182,6 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1215,7 +1182,6 @@ public class SpelReproTests extends AbstractExpressionTests {
private String mapName;
public TestPropertyAccessor(String mapName) {
this.mapName = mapName;
}
@ -1252,12 +1218,12 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1252,12 +1218,12 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Override
public void write(EvaluationContext context, Object target, String name, Object newValue)
throws AccessException {
public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException {
getMap(target).put(name, (String) newValue);
}
}
class ContextObject {
public Map<String, String> firstContext = new HashMap<String, String>();
@ -1265,7 +1231,6 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1265,7 +1231,6 @@ public class SpelReproTests extends AbstractExpressionTests {
public Map<String, String> thirdContext = new HashMap<String, String>();
public Map<String, String> fourthContext = new HashMap<String, String>();
public ContextObject() {
firstContext.put("shouldBeFirst", "first");
secondContext.put("shouldBeFirst", "second");
@ -1310,7 +1275,6 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1310,7 +1275,6 @@ public class SpelReproTests extends AbstractExpressionTests {
StandardEvaluationContext context = new StandardEvaluationContext();
List<MethodResolver> methodResolvers = new ArrayList<MethodResolver>();
methodResolvers.add(new ReflectiveMethodResolver() {
@Override
protected Method[] getMethods(Class<?> type) {
try {
@ -1360,10 +1324,10 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1360,10 +1324,10 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_9486_floatFunctionResolver() throws Exception {
public void SPR9486_floatFunctionResolver() throws Exception {
Number expectedResult = Math.abs(-10.2f);
ExpressionParser parser = new SpelExpressionParser();
SPR_9486_FunctionsClass testObject = new SPR_9486_FunctionsClass();
SPR9486_FunctionsClass testObject = new SPR9486_FunctionsClass();
StandardEvaluationContext context = new StandardEvaluationContext();
Expression expression = parser.parseExpression("abs(-10.2f)");
@ -1372,7 +1336,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1372,7 +1336,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
class SPR_9486_FunctionsClass {
class SPR9486_FunctionsClass {
public int abs(int value) {
return Math.abs(value);
@ -1385,7 +1349,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1385,7 +1349,7 @@ public class SpelReproTests extends AbstractExpressionTests {
@Test
public void SPR_9486_addFloatWithDouble() {
public void SPR9486_addFloatWithDouble() {
Number expectedNumber = 10.21f + 10.2;
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
@ -1395,7 +1359,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1395,7 +1359,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_9486_addFloatWithFloat() {
public void SPR9486_addFloatWithFloat() {
Number expectedNumber = 10.21f + 10.2f;
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
@ -1405,7 +1369,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1405,7 +1369,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_9486_subtractFloatWithDouble() {
public void SPR9486_subtractFloatWithDouble() {
Number expectedNumber = 10.21f - 10.2;
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
@ -1415,7 +1379,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1415,7 +1379,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_9486_subtractFloatWithFloat() {
public void SPR9486_subtractFloatWithFloat() {
Number expectedNumber = 10.21f - 10.2f;
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
@ -1425,7 +1389,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1425,7 +1389,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_9486_multiplyFloatWithDouble() {
public void SPR9486_multiplyFloatWithDouble() {
Number expectedNumber = 10.21f * 10.2;
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
@ -1435,7 +1399,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1435,7 +1399,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_9486_multiplyFloatWithFloat() {
public void SPR9486_multiplyFloatWithFloat() {
Number expectedNumber = 10.21f * 10.2f;
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
@ -1445,7 +1409,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1445,7 +1409,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_9486_floatDivideByFloat() {
public void SPR9486_floatDivideByFloat() {
Number expectedNumber = -10.21f / -10.2f;
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
@ -1455,7 +1419,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1455,7 +1419,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_9486_floatDivideByDouble() {
public void SPR9486_floatDivideByDouble() {
Number expectedNumber = -10.21f / -10.2;
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
@ -1465,7 +1429,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1465,7 +1429,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_9486_floatEqFloatUnaryMinus() {
public void SPR9486_floatEqFloatUnaryMinus() {
Boolean expectedResult = -10.21f == -10.2f;
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
@ -1475,7 +1439,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1475,7 +1439,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_9486_floatEqDoubleUnaryMinus() {
public void SPR9486_floatEqDoubleUnaryMinus() {
Boolean expectedResult = -10.21f == -10.2;
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
@ -1485,7 +1449,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1485,7 +1449,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_9486_floatEqFloat() {
public void SPR9486_floatEqFloat() {
Boolean expectedResult = 10.215f == 10.2109f;
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
@ -1495,7 +1459,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1495,7 +1459,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_9486_floatEqDouble() {
public void SPR9486_floatEqDouble() {
Boolean expectedResult = 10.215f == 10.2109;
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
@ -1505,7 +1469,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1505,7 +1469,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_9486_floatNotEqFloat() {
public void SPR9486_floatNotEqFloat() {
Boolean expectedResult = 10.215f != 10.2109f;
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
@ -1515,7 +1479,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1515,7 +1479,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_9486_floatNotEqDouble() {
public void SPR9486_floatNotEqDouble() {
Boolean expectedResult = 10.215f != 10.2109;
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
@ -1525,7 +1489,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1525,7 +1489,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_9486_floatLessThanFloat() {
public void SPR9486_floatLessThanFloat() {
Boolean expectedNumber = -10.21f < -10.2f;
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
@ -1535,7 +1499,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1535,7 +1499,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_9486_floatLessThanDouble() {
public void SPR9486_floatLessThanDouble() {
Boolean expectedNumber = -10.21f < -10.2;
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
@ -1545,7 +1509,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1545,7 +1509,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_9486_floatLessThanOrEqualFloat() {
public void SPR9486_floatLessThanOrEqualFloat() {
Boolean expectedNumber = -10.21f <= -10.22f;
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
@ -1555,7 +1519,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1555,7 +1519,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_9486_floatLessThanOrEqualDouble() {
public void SPR9486_floatLessThanOrEqualDouble() {
Boolean expectedNumber = -10.21f <= -10.2;
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
@ -1565,7 +1529,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1565,7 +1529,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_9486_floatGreaterThanFloat() {
public void SPR9486_floatGreaterThanFloat() {
Boolean expectedNumber = -10.21f > -10.2f;
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
@ -1575,7 +1539,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1575,7 +1539,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_9486_floatGreaterThanDouble() {
public void SPR9486_floatGreaterThanDouble() {
Boolean expectedResult = -10.21f > -10.2;
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
@ -1585,7 +1549,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1585,7 +1549,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_9486_floatGreaterThanOrEqualFloat() {
public void SPR9486_floatGreaterThanOrEqualFloat() {
Boolean expectedNumber = -10.21f >= -10.2f;
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
@ -1595,7 +1559,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1595,7 +1559,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_9486_floatGreaterThanEqualDouble() {
public void SPR9486_floatGreaterThanEqualDouble() {
Boolean expectedResult = -10.21f >= -10.2;
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
@ -1605,7 +1569,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1605,7 +1569,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_9486_floatModulusFloat() {
public void SPR9486_floatModulusFloat() {
Number expectedResult = 10.21f % 10.2f;
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
@ -1615,7 +1579,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1615,7 +1579,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_9486_floatModulusDouble() {
public void SPR9486_floatModulusDouble() {
Number expectedResult = 10.21f % 10.2;
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
@ -1625,7 +1589,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1625,7 +1589,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_9486_floatPowerFloat() {
public void SPR9486_floatPowerFloat() {
Number expectedResult = Math.pow(10.21f, -10.2f);
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
@ -1635,7 +1599,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1635,7 +1599,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_9486_floatPowerDouble() {
public void SPR9486_floatPowerDouble() {
Number expectedResult = Math.pow(10.21f, 10.2);
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
@ -1645,7 +1609,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1645,7 +1609,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_9994_bridgeMethods() throws Exception {
public void SPR9994_bridgeMethods() throws Exception {
ReflectivePropertyAccessor accessor = new ReflectivePropertyAccessor();
StandardEvaluationContext context = new StandardEvaluationContext();
Object target = new GenericImplementation();
@ -1654,7 +1618,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1654,7 +1618,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_10162_onlyBridgeMethod() throws Exception {
public void SPR10162_onlyBridgeMethod() throws Exception {
ReflectivePropertyAccessor accessor = new ReflectivePropertyAccessor();
StandardEvaluationContext context = new StandardEvaluationContext();
Object target = new OnlyBridgeMethod();
@ -1663,7 +1627,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1663,7 +1627,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_10091_simpleTestValueType() {
public void SPR10091_simpleTestValueType() {
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext evaluationContext = new StandardEvaluationContext(new BooleanHolder());
Class<?> valueType = parser.parseExpression("simpleProperty").getValueType(evaluationContext);
@ -1671,7 +1635,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1671,7 +1635,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_10091_simpleTestValue() {
public void SPR10091_simpleTestValue() {
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext evaluationContext = new StandardEvaluationContext(new BooleanHolder());
Object value = parser.parseExpression("simpleProperty").getValue(evaluationContext);
@ -1679,7 +1643,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1679,7 +1643,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_10091_primitiveTestValueType() {
public void SPR10091_primitiveTestValueType() {
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext evaluationContext = new StandardEvaluationContext(new BooleanHolder());
Class<?> valueType = parser.parseExpression("primitiveProperty").getValueType(evaluationContext);
@ -1687,7 +1651,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1687,7 +1651,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_10091_primitiveTestValue() {
public void SPR10091_primitiveTestValue() {
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext evaluationContext = new StandardEvaluationContext(new BooleanHolder());
Object value = parser.parseExpression("primitiveProperty").getValue(evaluationContext);
@ -1695,7 +1659,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1695,7 +1659,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_10146_malformedExpressions() throws Exception {
public void SPR10146_malformedExpressions() throws Exception {
doTestSpr10146("/foo", "EL1070E:(pos 0): Problem parsing left operand");
doTestSpr10146("*foo", "EL1070E:(pos 0): Problem parsing left operand");
doTestSpr10146("%foo", "EL1070E:(pos 0): Problem parsing left operand");
@ -1714,18 +1678,18 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1714,18 +1678,18 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_10125() throws Exception {
public void SPR10125() throws Exception {
StandardEvaluationContext context = new StandardEvaluationContext();
String fromInterface = parser.parseExpression("T(" + StaticFinalImpl1.class.getName() + ").VALUE").getValue(
context, String.class);
context, String.class);
assertThat(fromInterface, is("interfaceValue"));
String fromClass = parser.parseExpression("T(" + StaticFinalImpl2.class.getName() + ").VALUE").getValue(
context, String.class);
context, String.class);
assertThat(fromClass, is("interfaceValue"));
}
@Test
public void SPR_10210() throws Exception {
public void SPR10210() throws Exception {
StandardEvaluationContext context = new StandardEvaluationContext();
context.setVariable("bridgeExample", new org.springframework.expression.spel.spr10210.D());
Expression parseExpression = parser.parseExpression("#bridgeExample.bridgeMethod()");
@ -1733,7 +1697,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1733,7 +1697,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_10328() throws Exception {
public void SPR10328() throws Exception {
thrown.expect(SpelParseException.class);
thrown.expectMessage("EL1071E:(pos 2): A required selection expression has not been specified");
Expression exp = parser.parseExpression("$[]");
@ -1741,7 +1705,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1741,7 +1705,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_10452() throws Exception {
public void SPR10452() throws Exception {
SpelParserConfiguration configuration = new SpelParserConfiguration(false, false);
ExpressionParser parser = new SpelExpressionParser(configuration);
@ -1766,7 +1730,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1766,7 +1730,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_9495() throws Exception {
public void SPR9495() throws Exception {
SpelParserConfiguration configuration = new SpelParserConfiguration(false, false);
ExpressionParser parser = new SpelExpressionParser(configuration);
@ -1782,20 +1746,17 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1782,20 +1746,17 @@ public class SpelReproTests extends AbstractExpressionTests {
assertEquals(ABC.C, Array.get(result, 2));
context.addMethodResolver(new MethodResolver() {
@Override
public MethodExecutor resolve(EvaluationContext context, Object targetObject, String name,
List<TypeDescriptor> argumentTypes) throws AccessException {
return new MethodExecutor() {
@Override
public TypedValue execute(EvaluationContext context, Object target, Object... arguments)
throws AccessException {
try {
Method method = XYZ.class.getMethod("values");
Object value = method.invoke(target, arguments);
return new TypedValue(value,
new TypeDescriptor(new MethodParameter(method, -1)).narrow(value));
return new TypedValue(value, new TypeDescriptor(new MethodParameter(method, -1)).narrow(value));
}
catch (Exception ex) {
throw new AccessException(ex.getMessage(), ex);
@ -1813,7 +1774,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1813,7 +1774,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_10486() throws Exception {
public void SPR10486() throws Exception {
SpelExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
SPR10486 rootObject = new SPR10486();
@ -1824,7 +1785,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1824,7 +1785,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_11142() throws Exception {
public void SPR11142() throws Exception {
SpelExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
SPR11142 rootObject = new SPR11142();
@ -1835,7 +1796,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1835,7 +1796,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_9194() {
public void SPR9194() {
TestClass2 one = new TestClass2("abc");
TestClass2 two = new TestClass2("abc");
Map<String, TestClass2> map = new HashMap<String, TestClass2>();
@ -1848,7 +1809,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1848,7 +1809,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
@Test
public void SPR_11348() {
public void SPR11348() {
Collection<String> coll = new HashSet<String>();
coll.add("one");
coll.add("two");
@ -1864,14 +1825,18 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1864,14 +1825,18 @@ public class SpelReproTests extends AbstractExpressionTests {
assertEquals("two", list.get(1));
}
private static enum ABC {
A, B, C
@Test
public void SPR11494() {
Expression exp = new SpelExpressionParser().parseExpression("T(java.util.Arrays).asList('a','b')");
List<String> list = (List<String>) exp.getValue();
assertThat(list.size(), is(2));
}
private static enum XYZ {
X, Y, Z
}
private static enum ABC { A, B, C }
private static enum XYZ { X, Y, Z }
public static class BooleanHolder {
@ -1879,7 +1844,6 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1879,7 +1844,6 @@ public class SpelReproTests extends AbstractExpressionTests {
private boolean primitiveProperty = true;
public Boolean isSimpleProperty() {
return simpleProperty;
}
@ -1897,11 +1861,13 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1897,11 +1861,13 @@ public class SpelReproTests extends AbstractExpressionTests {
}
}
private static interface GenericInterface<T extends Number> {
public T getProperty();
}
private static class GenericImplementation implements GenericInterface<Integer> {
@Override
@ -1910,6 +1876,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1910,6 +1876,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
}
static class PackagePrivateClassWithGetter {
public Integer getProperty() {
@ -1917,28 +1884,33 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1917,28 +1884,33 @@ public class SpelReproTests extends AbstractExpressionTests {
}
}
public static class OnlyBridgeMethod extends PackagePrivateClassWithGetter {
}
public static interface StaticFinal {
public static final String VALUE = "interfaceValue";
}
public abstract static class AbstractStaticFinal implements StaticFinal {
}
public static class StaticFinalImpl1 extends AbstractStaticFinal implements StaticFinal {
}
public static class StaticFinalImpl2 extends AbstractStaticFinal {
}
public static class SPR10486 {
private String name = "name";
public String getName() {
return name;
}
@ -1948,6 +1920,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1948,6 +1920,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
}
static class SPR11142 {
public String isSomething() {
@ -1955,6 +1928,7 @@ public class SpelReproTests extends AbstractExpressionTests { @@ -1955,6 +1928,7 @@ public class SpelReproTests extends AbstractExpressionTests {
}
}
static class TestClass2 { // SPR-9194
String string;

Loading…
Cancel
Save