diff --git a/spring-core/src/main/java/org/springframework/core/ResolvableType.java b/spring-core/src/main/java/org/springframework/core/ResolvableType.java index 62d51fa48d0..a27513e9823 100644 --- a/spring-core/src/main/java/org/springframework/core/ResolvableType.java +++ b/spring-core/src/main/java/org/springframework/core/ResolvableType.java @@ -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...) diff --git a/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java b/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java index 3f7b8e71603..8b658eede45 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java +++ b/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java @@ -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 { 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 { } /** - * Narrows this {@link TypeDescriptor} by setting its type to the class of the provided value. - *

If the value is {@code null}, no narrowing is performed and this TypeDescriptor is returned unchanged. - *

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. + *

If the value is {@code null}, no narrowing is performed and this TypeDescriptor + * is returned unchanged. + *

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 { } /** - * Returns true if an object of this type descriptor can be assigned to the location described by the given type descriptor. - *

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. - *

- * For arrays, collections, and maps, element and key/value types are checked if declared. - * For example, a List<String> field value is assignable to a Collection<CharSequence> field, but List<Number> is not assignable to List<Integer>. - * @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. + *

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. + *

For arrays, collections, and maps, element and key/value types are checked if declared. + * For example, a List<String> field value is assignable to a Collection<CharSequence> + * field, but List<Number> is not assignable to List<Integer>. + * @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 { /** * 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. - *

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<java.lang.Number< and the element argument is a java.lang.Integer, the returned TypeDescriptor will be java.lang.Integer. - * If this describes a java.util.List<?> and the element argument is a java.lang.Integer, the returned TypeDescriptor will be java.lang.Integer as well. - *

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. + *

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<java.lang.Number<} 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<?>} and the element argument is an + * {@code java.lang.Integer}, the returned TypeDescriptor will be {@code java.lang.Integer} + * as well. + *

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 { } /** - * 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. - *

Narrows the {@link #getMapKeyTypeDescriptor() mapKeyType} property to the class of the provided map key. - * For example, if this describes a java.util.Map<java.lang.Number, java.lang.String< and the key argument is a java.lang.Integer, the returned TypeDescriptor will be java.lang.Integer. - *

If this describes a java.util.Map<?, ?> and the key argument is a java.lang.Integer, the returned TypeDescriptor will be java.lang.Integer as well. - *

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. + *

Narrows the {@link #getMapKeyTypeDescriptor() mapKeyType} property + * to the class of the provided map key. For example, if this describes a + * {@code java.util.Map<java.lang.Number, java.lang.String<} 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<?, ?>} + * and the key argument is a {@code java.lang.Integer}, the returned + * TypeDescriptor will be {@code java.lang.Integer} as well. + *

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 { } /** - * If this type is a {@link Map} and its value type is parameterized, returns the map's value type. - *

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. + *

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. - *

Narrows the {@link #getMapValueTypeDescriptor() mapValueType} property to the class of the provided map value. - * For example, if this describes a java.util.Map<java.lang.String, java.lang.Number< and the value argument is a java.lang.Integer, the returned TypeDescriptor will be java.lang.Integer. - * If this describes a java.util.Map<?, ?> and the value argument is a java.lang.Integer, the returned TypeDescriptor will be java.lang.Integer as well. - *

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. + *

Narrows the {@link #getMapValueTypeDescriptor() mapValueType} property + * to the class of the provided map value. For example, if this describes a + * {@code java.util.Map<java.lang.String, java.lang.Number<} 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<?, ?>} + * and the value argument is a {@code java.lang.Integer}, the returned + * TypeDescriptor will be {@code java.lang.Integer} as well. + *

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 { } /** - * 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 { } /** - * 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 { } 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 { * @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 { * @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 { 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); } diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectionHelper.java b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectionHelper.java index be760a29526..66fd45551f0 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectionHelper.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectionHelper.java @@ -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 { 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 { } /** - * 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 { 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); diff --git a/spring-expression/src/test/java/org/springframework/expression/spel/SpelReproTests.java b/spring-expression/src/test/java/org/springframework/expression/spel/SpelReproTests.java index 784bd190e4e..b5fa273dc9b 100644 --- a/spring-expression/src/test/java/org/springframework/expression/spel/SpelReproTests.java +++ b/spring-expression/src/test/java/org/springframework/expression/spel/SpelReproTests.java @@ -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 { } } + static class Spr5899Class { public Spr5899Class() { @@ -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 { } } + static class MapAccessor implements PropertyAccessor { @Override @@ -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) target).put(name, newValue); } @@ -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 { 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 { @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 { 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 { } } + static class Resource { public String getServer() { @@ -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 { // 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 { 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 { public String floo = "bar"; - public XX() { m = new HashMap(); m.put("$foo", "wibble"); @@ -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 { public String wibble = "wobble"; - public String getKey() { return "hello"; } @@ -591,6 +576,7 @@ public class SpelReproTests extends AbstractExpressionTests { } } + static class Holder { public Map map = new HashMap(); @@ -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 { 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 { } } + static class Message { private String payload; - public String getPayload() { return payload; } @@ -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 { public String[] as; public Map ms; - C() { ls = new ArrayList(); ls.add("abc"); @@ -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 { @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 { @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 { 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 args = new ArrayList(); 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 { // "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 { public Map m = new HashMap(); - Reserver() { m.put("NE", "xyz"); } @@ -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 { } @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 firstContext = new HashMap(); @@ -1265,7 +1231,6 @@ public class SpelReproTests extends AbstractExpressionTests { public Map thirdContext = new HashMap(); public Map fourthContext = new HashMap(); - public ContextObject() { firstContext.put("shouldBeFirst", "first"); secondContext.put("shouldBeFirst", "second"); @@ -1310,7 +1275,6 @@ public class SpelReproTests extends AbstractExpressionTests { StandardEvaluationContext context = new StandardEvaluationContext(); List methodResolvers = new ArrayList(); methodResolvers.add(new ReflectiveMethodResolver() { - @Override protected Method[] getMethods(Class type) { try { @@ -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 { } - 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 { @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 { } @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 { } @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 { } @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 { } @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 { } @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 { } @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 { } @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 { } @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 { } @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 { } @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 { } @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 { } @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 { } @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 { } @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 { } @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 { } @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 { } @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 { } @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 { } @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 { } @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 { } @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 { } @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 { } @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 { } @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 { } @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 { } @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 { } @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 { } @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 { } @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 { } @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 { } @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 { } @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 { } @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 { } @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 { } @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 { } @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 { assertEquals(ABC.C, Array.get(result, 2)); context.addMethodResolver(new MethodResolver() { - @Override public MethodExecutor resolve(EvaluationContext context, Object targetObject, String name, List 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 { } @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 { } @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 { } @Test - public void SPR_9194() { + public void SPR9194() { TestClass2 one = new TestClass2("abc"); TestClass2 two = new TestClass2("abc"); Map map = new HashMap(); @@ -1848,7 +1809,7 @@ public class SpelReproTests extends AbstractExpressionTests { } @Test - public void SPR_11348() { + public void SPR11348() { Collection coll = new HashSet(); coll.add("one"); coll.add("two"); @@ -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 list = (List) 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 { private boolean primitiveProperty = true; - public Boolean isSimpleProperty() { return simpleProperty; } @@ -1897,11 +1861,13 @@ public class SpelReproTests extends AbstractExpressionTests { } } + private static interface GenericInterface { public T getProperty(); } + private static class GenericImplementation implements GenericInterface { @Override @@ -1910,6 +1876,7 @@ public class SpelReproTests extends AbstractExpressionTests { } } + static class PackagePrivateClassWithGetter { public Integer getProperty() { @@ -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 { } } + static class SPR11142 { public String isSomething() { @@ -1955,6 +1928,7 @@ public class SpelReproTests extends AbstractExpressionTests { } } + static class TestClass2 { // SPR-9194 String string;