Polish ReflectiveMethodResolver and unit tests

- Update Javadoc
 - Fix whitespace errors (tabs v. spaces, trailing spaces)
 - Break at 90 chars where sensible
 - Remove dead test code
 - Fix generics warnings, remove @SuppressWarnings
This commit is contained in:
Chris Beams 2012-02-01 17:19:42 +01:00
parent 8980ce712d
commit c7fd03be69
2 changed files with 275 additions and 327 deletions

View File

@ -38,27 +38,30 @@ import org.springframework.expression.spel.SpelMessage;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
/** /**
* A method resolver that uses reflection to locate the method that should be invoked. * Reflection-based {@link MethodResolver} used by default in
* {@link StandardEvaluationContext} unless explicit method resolvers have been specified.
* *
* @author Andy Clement * @author Andy Clement
* @author Juergen Hoeller * @author Juergen Hoeller
* @author Chris Beams
* @since 3.0 * @since 3.0
* @see StandardEvaluationContext#addMethodResolver(MethodResolver)
*/ */
public class ReflectiveMethodResolver implements MethodResolver { public class ReflectiveMethodResolver implements MethodResolver {
private static Method[] NO_METHODS = new Method[0]; private static Method[] NO_METHODS = new Method[0];
private Map<Class<?>, MethodFilter> filters = null; private Map<Class<?>, MethodFilter> filters = null;
// Using distance will ensure a more accurate match is discovered, // Using distance will ensure a more accurate match is discovered,
// more closely following the Java rules. // more closely following the Java rules.
private boolean useDistance = false; private boolean useDistance = false;
public ReflectiveMethodResolver() { public ReflectiveMethodResolver() {
} }
/** /**
* This constructors allows the ReflectiveMethodResolver to be configured such that it will * This constructors allows the ReflectiveMethodResolver to be configured such that it will
* use a distance computation to check which is the better of two close matches (when there * use a distance computation to check which is the better of two close matches (when there
@ -71,7 +74,7 @@ public class ReflectiveMethodResolver implements MethodResolver {
public ReflectiveMethodResolver(boolean useDistance) { public ReflectiveMethodResolver(boolean useDistance) {
this.useDistance = useDistance; this.useDistance = useDistance;
} }
/** /**
* Locate a method on a type. There are three kinds of match that might occur: * Locate a method on a type. There are three kinds of match that might occur:
* <ol> * <ol>
@ -88,14 +91,14 @@ public class ReflectiveMethodResolver implements MethodResolver {
TypeConverter typeConverter = context.getTypeConverter(); TypeConverter typeConverter = context.getTypeConverter();
Class<?> type = (targetObject instanceof Class ? (Class<?>) targetObject : targetObject.getClass()); Class<?> type = (targetObject instanceof Class ? (Class<?>) targetObject : targetObject.getClass());
Method[] methods = type.getMethods(); Method[] methods = type.getMethods();
// If a filter is registered for this type, call it // If a filter is registered for this type, call it
MethodFilter filter = (this.filters != null ? this.filters.get(type) : null); MethodFilter filter = (this.filters != null ? this.filters.get(type) : null);
if (filter != null) { if (filter != null) {
List<Method> methodsForFiltering = new ArrayList<Method>(); List<Method> methodsForFiltering = new ArrayList<Method>();
for (Method method: methods) { for (Method method: methods) {
methodsForFiltering.add(method); methodsForFiltering.add(method);
} }
List<Method> methodsFiltered = filter.filter(methodsForFiltering); List<Method> methodsFiltered = filter.filter(methodsForFiltering);
if (CollectionUtils.isEmpty(methodsFiltered)) { if (CollectionUtils.isEmpty(methodsFiltered)) {
methods = NO_METHODS; methods = NO_METHODS;
@ -124,7 +127,7 @@ public class ReflectiveMethodResolver implements MethodResolver {
continue; continue;
} }
if (method.getName().equals(name)) { if (method.getName().equals(name)) {
Class[] paramTypes = method.getParameterTypes(); Class<?>[] paramTypes = method.getParameterTypes();
List<TypeDescriptor> paramDescriptors = new ArrayList<TypeDescriptor>(paramTypes.length); List<TypeDescriptor> paramDescriptors = new ArrayList<TypeDescriptor>(paramTypes.length);
for (int i = 0; i < paramTypes.length; i++) { for (int i = 0; i < paramTypes.length; i++) {
paramDescriptors.add(new TypeDescriptor(new MethodParameter(method, i))); paramDescriptors.add(new TypeDescriptor(new MethodParameter(method, i)));

View File

@ -50,12 +50,12 @@ import org.springframework.expression.spel.support.StandardTypeLocator;
/** /**
* Tests based on Jiras up to the release of Spring 3.0.0 * Tests based on Jiras up to the release of Spring 3.0.0
* *
* @author Andy Clement * @author Andy Clement
* @author Clark Duplichien * @author Clark Duplichien
*/ */
public class SpringEL300Tests extends ExpressionTestCase { public class SpringEL300Tests extends ExpressionTestCase {
@Test @Test
public void testNPE_SPR5661() { public void testNPE_SPR5661() {
evaluate("joinThreeStrings('a',null,'c')", "anullc", String.class); evaluate("joinThreeStrings('a',null,'c')", "anullc", String.class);
@ -66,7 +66,7 @@ public class SpringEL300Tests extends ExpressionTestCase {
public void testSWF1086() { public void testSWF1086() {
evaluate("printDouble(T(java.math.BigDecimal).valueOf(14.35))", "anullc", String.class); evaluate("printDouble(T(java.math.BigDecimal).valueOf(14.35))", "anullc", String.class);
} }
@Test @Test
public void testDoubleCoercion() { public void testDoubleCoercion() {
evaluate("printDouble(14.35)", "14.35", String.class); evaluate("printDouble(14.35)", "14.35", String.class);
@ -92,15 +92,15 @@ public class SpringEL300Tests extends ExpressionTestCase {
// success // success
} }
eContext.setTypeLocator(new MyTypeLocator()); eContext.setTypeLocator(new MyTypeLocator());
// varargs // varargs
expr = new SpelExpressionParser().parseRaw("tryToInvokeWithNull3(null,'a','b')"); expr = new SpelExpressionParser().parseRaw("tryToInvokeWithNull3(null,'a','b')");
Assert.assertEquals("ab",expr.getValue(eContext)); Assert.assertEquals("ab",expr.getValue(eContext));
// varargs 2 - null is packed into the varargs // varargs 2 - null is packed into the varargs
expr = new SpelExpressionParser().parseRaw("tryToInvokeWithNull3(12,'a',null,'c')"); expr = new SpelExpressionParser().parseRaw("tryToInvokeWithNull3(12,'a',null,'c')");
Assert.assertEquals("anullc",expr.getValue(eContext)); Assert.assertEquals("anullc",expr.getValue(eContext));
// check we can find the ctor ok // check we can find the ctor ok
expr = new SpelExpressionParser().parseRaw("new Spr5899Class().toString()"); expr = new SpelExpressionParser().parseRaw("new Spr5899Class().toString()");
Assert.assertEquals("instance",expr.getValue(eContext)); Assert.assertEquals("instance",expr.getValue(eContext));
@ -116,7 +116,7 @@ public class SpringEL300Tests extends ExpressionTestCase {
expr = new SpelExpressionParser().parseRaw("new Spr5899Class(null,'a', null, 'b').toString()"); expr = new SpelExpressionParser().parseRaw("new Spr5899Class(null,'a', null, 'b').toString()");
Assert.assertEquals("instance",expr.getValue(eContext)); Assert.assertEquals("instance",expr.getValue(eContext));
} }
static class MyTypeLocator extends StandardTypeLocator { static class MyTypeLocator extends StandardTypeLocator {
public Class<?> findType(String typename) throws EvaluationException { public Class<?> findType(String typename) throws EvaluationException {
@ -132,12 +132,12 @@ public class SpringEL300Tests extends ExpressionTestCase {
static class Spr5899Class { static class Spr5899Class {
public Spr5899Class() {} public Spr5899Class() {}
public Spr5899Class(Integer i) { } public Spr5899Class(Integer i) { }
public Spr5899Class(Integer i, String... s) { } public Spr5899Class(Integer i, String... s) { }
public Integer tryToInvokeWithNull(Integer value) { return value; } public Integer tryToInvokeWithNull(Integer value) { return value; }
public Integer tryToInvokeWithNull2(int i) { return new Integer(i); } public Integer tryToInvokeWithNull2(int i) { return new Integer(i); }
public String tryToInvokeWithNull3(Integer value,String... strings) { public String tryToInvokeWithNull3(Integer value,String... strings) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (int i=0;i<strings.length;i++) { for (int i=0;i<strings.length;i++) {
if (strings[i]==null) { if (strings[i]==null) {
@ -148,12 +148,12 @@ public class SpringEL300Tests extends ExpressionTestCase {
} }
return sb.toString(); return sb.toString();
} }
public String toString() { public String toString() {
return "instance"; return "instance";
} }
} }
@Test @Test
public void testSPR5905_InnerTypeReferences() throws Exception { public void testSPR5905_InnerTypeReferences() throws Exception {
StandardEvaluationContext eContext = new StandardEvaluationContext(new Spr5899Class()); StandardEvaluationContext eContext = new StandardEvaluationContext(new Spr5899Class());
@ -166,7 +166,7 @@ public class SpringEL300Tests extends ExpressionTestCase {
expr = new SpelExpressionParser().parseRaw("new org.springframework.expression.spel.SpringEL300Tests$Outer$Inner().run2()"); expr = new SpelExpressionParser().parseRaw("new org.springframework.expression.spel.SpringEL300Tests$Outer$Inner().run2()");
Assert.assertEquals(13,expr.getValue(eContext)); Assert.assertEquals(13,expr.getValue(eContext));
} }
static class Outer { static class Outer {
static class Inner { static class Inner {
public Inner() {} public Inner() {}
@ -179,27 +179,26 @@ public class SpringEL300Tests extends ExpressionTestCase {
} }
} }
@SuppressWarnings("unchecked")
@Test @Test
public void testSPR5804() throws Exception { public void testSPR5804() throws Exception {
Map m = new HashMap(); Map<String,String> m = new HashMap<String,String>();
m.put("foo", "bar"); m.put("foo", "bar");
StandardEvaluationContext eContext = new StandardEvaluationContext(m); // root is a map instance StandardEvaluationContext eContext = new StandardEvaluationContext(m); // root is a map instance
eContext.addPropertyAccessor(new MapAccessor()); eContext.addPropertyAccessor(new MapAccessor());
Expression expr = new SpelExpressionParser().parseRaw("['foo']"); Expression expr = new SpelExpressionParser().parseRaw("['foo']");
Assert.assertEquals("bar", expr.getValue(eContext)); Assert.assertEquals("bar", expr.getValue(eContext));
} }
@Test @Test
public void testSPR5847() throws Exception { public void testSPR5847() throws Exception {
StandardEvaluationContext eContext = new StandardEvaluationContext(new TestProperties()); StandardEvaluationContext eContext = new StandardEvaluationContext(new TestProperties());
String name = null; String name = null;
Expression expr = null; Expression expr = null;
expr = new SpelExpressionParser().parseRaw("jdbcProperties['username']"); expr = new SpelExpressionParser().parseRaw("jdbcProperties['username']");
name = expr.getValue(eContext,String.class); name = expr.getValue(eContext,String.class);
Assert.assertEquals("Dave",name); Assert.assertEquals("Dave",name);
expr = new SpelExpressionParser().parseRaw("jdbcProperties[username]"); expr = new SpelExpressionParser().parseRaw("jdbcProperties[username]");
name = expr.getValue(eContext,String.class); name = expr.getValue(eContext,String.class);
Assert.assertEquals("Dave",name); Assert.assertEquals("Dave",name);
@ -209,7 +208,7 @@ public class SpringEL300Tests extends ExpressionTestCase {
eContext.addPropertyAccessor(new MapAccessor()); eContext.addPropertyAccessor(new MapAccessor());
name = expr.getValue(eContext,String.class); name = expr.getValue(eContext,String.class);
Assert.assertEquals("Dave",name); Assert.assertEquals("Dave",name);
// --- dotted property names // --- dotted property names
// lookup foo on the root, then bar on that, then use that as the key into jdbcProperties // lookup foo on the root, then bar on that, then use that as the key into jdbcProperties
@ -222,9 +221,9 @@ public class SpringEL300Tests extends ExpressionTestCase {
expr = new SpelExpressionParser().parseRaw("jdbcProperties['foo.bar']"); expr = new SpelExpressionParser().parseRaw("jdbcProperties['foo.bar']");
eContext.addPropertyAccessor(new MapAccessor()); eContext.addPropertyAccessor(new MapAccessor());
name = expr.getValue(eContext,String.class); name = expr.getValue(eContext,String.class);
Assert.assertEquals("Elephant",name); Assert.assertEquals("Elephant",name);
} }
static class TestProperties { static class TestProperties {
public Properties jdbcProperties = new Properties(); public Properties jdbcProperties = new Properties();
public Properties foo = new Properties(); public Properties foo = new Properties();
@ -239,11 +238,11 @@ public class SpringEL300Tests extends ExpressionTestCase {
static class MapAccessor implements PropertyAccessor { static class MapAccessor implements PropertyAccessor {
public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException { public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
return (((Map) target).containsKey(name)); return (((Map<?,?>) target).containsKey(name));
} }
public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException { public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
return new TypedValue(((Map) target).get(name)); return new TypedValue(((Map<?,?>) target).get(name));
} }
public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException { public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
@ -252,22 +251,22 @@ public class SpringEL300Tests extends ExpressionTestCase {
@SuppressWarnings("unchecked") @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); ((Map<String, Object>) target).put(name, newValue);
} }
public Class[] getSpecificTargetClasses() { public Class<?>[] getSpecificTargetClasses() {
return new Class[] {Map.class}; return new Class[] {Map.class};
} }
} }
@Test @Test
public void testNPE_SPR5673() throws Exception { public void testNPE_SPR5673() throws Exception {
ParserContext hashes = TemplateExpressionParsingTests.HASH_DELIMITED_PARSER_CONTEXT; ParserContext hashes = TemplateExpressionParsingTests.HASH_DELIMITED_PARSER_CONTEXT;
ParserContext dollars = TemplateExpressionParsingTests.DEFAULT_TEMPLATE_PARSER_CONTEXT; ParserContext dollars = TemplateExpressionParsingTests.DEFAULT_TEMPLATE_PARSER_CONTEXT;
checkTemplateParsing("abc${'def'} ghi","abcdef ghi"); checkTemplateParsing("abc${'def'} ghi","abcdef ghi");
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'","Missing closing ']' for '[' at position 8");
checkTemplateParsingError("abc${ {}{ 'abc'","Missing closing '}' for '{' at position 8"); checkTemplateParsingError("abc${ {}{ 'abc'","Missing closing '}' for '{' at position 8");
@ -278,7 +277,7 @@ public class SpringEL300Tests extends ExpressionTestCase {
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${ } }","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");
checkTemplateParsing("abc ${'def''g}hi'} jkl","abc def'g}hi jkl"); checkTemplateParsing("abc ${'def''g}hi'} jkl","abc def'g}hi jkl");
checkTemplateParsing("}","}"); checkTemplateParsing("}","}");
@ -295,7 +294,7 @@ public class SpringEL300Tests extends ExpressionTestCase {
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("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: ${"); checkTemplateParsingError("Hello ${","No ending suffix '}' for expression starting at character 6: ${");
} }
@Test @Test
public void testAccessingNullPropertyViaReflection_SPR5663() throws AccessException { public void testAccessingNullPropertyViaReflection_SPR5663() throws AccessException {
PropertyAccessor propertyAccessor = new ReflectivePropertyAccessor(); PropertyAccessor propertyAccessor = new ReflectivePropertyAccessor();
@ -315,33 +314,33 @@ public class SpringEL300Tests extends ExpressionTestCase {
// success // success
} }
} }
@Test @Test
public void testNestedProperties_SPR6923() { public void testNestedProperties_SPR6923() {
StandardEvaluationContext eContext = new StandardEvaluationContext(new Foo()); StandardEvaluationContext eContext = new StandardEvaluationContext(new Foo());
String name = null; String name = null;
Expression expr = null; Expression expr = null;
expr = new SpelExpressionParser().parseRaw("resource.resource.server"); expr = new SpelExpressionParser().parseRaw("resource.resource.server");
name = expr.getValue(eContext,String.class); name = expr.getValue(eContext,String.class);
Assert.assertEquals("abc",name); Assert.assertEquals("abc",name);
} }
static class Foo { static class Foo {
public ResourceSummary resource = new ResourceSummary(); public ResourceSummary resource = new ResourceSummary();
} }
static class ResourceSummary { static class ResourceSummary {
ResourceSummary() { ResourceSummary() {
this.resource = new Resource(); this.resource = new Resource();
} }
private final Resource resource; private final Resource resource;
public Resource getResource() { public Resource getResource() {
return resource; return resource;
} }
} }
static class Resource { static class Resource {
public String getServer() { public String getServer() {
return "abc"; return "abc";
@ -374,9 +373,8 @@ public class SpringEL300Tests extends ExpressionTestCase {
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
Assert.assertEquals("hello",name); Assert.assertEquals("hello",name);
} }
/** $ related identifiers */ /** $ related identifiers */
@SuppressWarnings("unchecked")
@Test @Test
public void testDollarPrefixedIdentifier_SPR7100() { public void testDollarPrefixedIdentifier_SPR7100() {
Holder h = new Holder(); Holder h = new Holder();
@ -390,7 +388,7 @@ public class SpringEL300Tests extends ExpressionTestCase {
h.map.put("$_$","tribble"); h.map.put("$_$","tribble");
String name = null; String name = null;
Expression expr = null; Expression expr = null;
expr = new SpelExpressionParser().parseRaw("map.$foo"); expr = new SpelExpressionParser().parseRaw("map.$foo");
name = expr.getValue(eContext,String.class); name = expr.getValue(eContext,String.class);
Assert.assertEquals("wibble",name); Assert.assertEquals("wibble",name);
@ -430,8 +428,11 @@ public class SpringEL300Tests extends ExpressionTestCase {
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
Assert.assertEquals("wobble",name); Assert.assertEquals("wobble",name);
} }
/** Should be accessing (setting) Goo.wibble field because 'bar' variable evaluates to "wibble" */ /**
* Should be accessing (setting) Goo.wibble field because 'bar' variable evaluates to
* "wibble"
*/
@Test @Test
public void testIndexingAsAPropertyAccess_SPR6968_4() { public void testIndexingAsAPropertyAccess_SPR6968_4() {
Goo g = Goo.instance; Goo g = Goo.instance;
@ -458,7 +459,7 @@ public class SpringEL300Tests extends ExpressionTestCase {
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
Assert.assertEquals("world",g.value); Assert.assertEquals("world",g.value);
} }
@Test @Test
public void testDollars() { public void testDollars() {
StandardEvaluationContext eContext = new StandardEvaluationContext(new XX()); StandardEvaluationContext eContext = new StandardEvaluationContext(new XX());
@ -467,7 +468,7 @@ public class SpringEL300Tests extends ExpressionTestCase {
eContext.setVariable("file_name","$foo"); eContext.setVariable("file_name","$foo");
Assert.assertEquals("wibble",expr.getValue(eContext,String.class)); Assert.assertEquals("wibble",expr.getValue(eContext,String.class));
} }
@Test @Test
public void testDollars2() { public void testDollars2() {
StandardEvaluationContext eContext = new StandardEvaluationContext(new XX()); StandardEvaluationContext eContext = new StandardEvaluationContext(new XX());
@ -476,12 +477,12 @@ public class SpringEL300Tests extends ExpressionTestCase {
eContext.setVariable("file_name","$foo"); eContext.setVariable("file_name","$foo");
Assert.assertEquals("wibble",expr.getValue(eContext,String.class)); Assert.assertEquals("wibble",expr.getValue(eContext,String.class));
} }
static class XX { static class XX {
public Map<String,String> m; public Map<String,String> m;
public String floo ="bar"; public String floo ="bar";
public XX() { public XX() {
m = new HashMap<String,String>(); m = new HashMap<String,String>();
m.put("$foo","wibble"); m.put("$foo","wibble");
@ -490,34 +491,34 @@ public class SpringEL300Tests extends ExpressionTestCase {
} }
static class Goo { static class Goo {
public static Goo instance = new Goo(); public static Goo instance = new Goo();
public String bar = "key"; public String bar = "key";
public String value = null; public String value = null;
public String wibble = "wobble"; public String wibble = "wobble";
public String getKey() { public String getKey() {
return "hello"; return "hello";
} }
public void setKey(String s) { public void setKey(String s) {
value = s; value = s;
} }
} }
static class Holder { static class Holder {
public Map map = new HashMap(); public Map<String,String> map = new HashMap<String,String>();
} }
// --- // ---
private void checkTemplateParsing(String expression, String expectedValue) throws Exception { private void checkTemplateParsing(String expression, String expectedValue) throws Exception {
checkTemplateParsing(expression,TemplateExpressionParsingTests.DEFAULT_TEMPLATE_PARSER_CONTEXT, expectedValue); checkTemplateParsing(expression,TemplateExpressionParsingTests.DEFAULT_TEMPLATE_PARSER_CONTEXT, expectedValue);
} }
private void checkTemplateParsing(String expression, ParserContext context, String expectedValue) throws Exception { private void checkTemplateParsing(String expression, ParserContext context, String expectedValue) throws Exception {
SpelExpressionParser parser = new SpelExpressionParser(); SpelExpressionParser parser = new SpelExpressionParser();
Expression expr = parser.parseExpression(expression,context); Expression expr = parser.parseExpression(expression,context);
@ -527,7 +528,7 @@ public class SpringEL300Tests extends ExpressionTestCase {
private void checkTemplateParsingError(String expression,String expectedMessage) throws Exception { 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(); SpelExpressionParser parser = new SpelExpressionParser();
try { try {
@ -540,7 +541,7 @@ public class SpringEL300Tests extends ExpressionTestCase {
Assert.assertEquals(expectedMessage,e.getMessage()); Assert.assertEquals(expectedMessage,e.getMessage());
} }
} }
private static final ParserContext DOLLARSQUARE_TEMPLATE_PARSER_CONTEXT = new ParserContext() { private static final ParserContext DOLLARSQUARE_TEMPLATE_PARSER_CONTEXT = new ParserContext() {
public String getExpressionPrefix() { public String getExpressionPrefix() {
return "$["; return "$[";
@ -552,28 +553,13 @@ public class SpringEL300Tests extends ExpressionTestCase {
return true; return true;
} }
}; };
// @Test
// public void testFails() {
//
// StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
// evaluationContext.setVariable("target", new Foo2());
// for (int i = 0; i < 300000; i++) {
// evaluationContext.addPropertyAccessor(new MapAccessor());
// ExpressionParser parser = new SpelExpressionParser();
// Expression expression = parser.parseExpression("#target.execute(payload)");
// Message message = new Message();
// message.setPayload(i+"");
// expression.getValue(evaluationContext, message);
// }
// }
static class Foo2 { static class Foo2 {
public void execute(String str){ public void execute(String str){
System.out.println("Value: " + str); System.out.println("Value: " + str);
} }
} }
static class Message{ static class Message{
private String payload; private String payload;
@ -587,7 +573,7 @@ public class SpringEL300Tests extends ExpressionTestCase {
} }
// bean resolver tests // bean resolver tests
@Test @Test
public void beanResolution() { public void beanResolution() {
StandardEvaluationContext eContext = new StandardEvaluationContext(new XX()); StandardEvaluationContext eContext = new StandardEvaluationContext(new XX());
@ -601,7 +587,7 @@ public class SpringEL300Tests extends ExpressionTestCase {
Assert.assertEquals(SpelMessage.NO_BEAN_RESOLVER_REGISTERED,see.getMessageCode()); Assert.assertEquals(SpelMessage.NO_BEAN_RESOLVER_REGISTERED,see.getMessageCode());
Assert.assertEquals("foo",see.getInserts()[0]); Assert.assertEquals("foo",see.getInserts()[0]);
} }
eContext.setBeanResolver(new MyBeanResolver()); eContext.setBeanResolver(new MyBeanResolver());
// bean exists // bean exists
@ -622,11 +608,11 @@ public class SpringEL300Tests extends ExpressionTestCase {
Assert.assertTrue(see.getCause() instanceof AccessException); Assert.assertTrue(see.getCause() instanceof AccessException);
Assert.assertTrue(((AccessException)see.getCause()).getMessage().startsWith("DONT")); Assert.assertTrue(((AccessException)see.getCause()).getMessage().startsWith("DONT"));
} }
// bean exists // bean exists
expr = new SpelExpressionParser().parseRaw("@'foo.bar'"); expr = new SpelExpressionParser().parseRaw("@'foo.bar'");
Assert.assertEquals("trouble",expr.getValue(eContext,String.class)); Assert.assertEquals("trouble",expr.getValue(eContext,String.class));
// bean exists // bean exists
try { try {
expr = new SpelExpressionParser().parseRaw("@378"); expr = new SpelExpressionParser().parseRaw("@378");
@ -635,7 +621,7 @@ public class SpringEL300Tests extends ExpressionTestCase {
Assert.assertEquals(SpelMessage.INVALID_BEAN_REFERENCE,spe.getMessageCode()); Assert.assertEquals(SpelMessage.INVALID_BEAN_REFERENCE,spe.getMessageCode());
} }
} }
static class MyBeanResolver implements BeanResolver { static class MyBeanResolver implements BeanResolver {
public Object resolve(EvaluationContext context, String beanname) throws AccessException { public Object resolve(EvaluationContext context, String beanname) throws AccessException {
if (beanname.equals("foo")) { if (beanname.equals("foo")) {
@ -648,14 +634,14 @@ public class SpringEL300Tests extends ExpressionTestCase {
return null; return null;
} }
} }
// end bean resolver tests // end bean resolver tests
@Test @Test
public void elvis_SPR7209_1() { public void elvis_SPR7209_1() {
StandardEvaluationContext eContext = new StandardEvaluationContext(new XX()); StandardEvaluationContext eContext = new StandardEvaluationContext(new XX());
Expression expr = null; Expression expr = null;
// Different parts of elvis expression are null // Different parts of elvis expression are null
expr = new SpelExpressionParser().parseRaw("(?:'default')"); expr = new SpelExpressionParser().parseRaw("(?:'default')");
Assert.assertEquals("default", expr.getValue()); Assert.assertEquals("default", expr.getValue());
@ -696,68 +682,67 @@ public class SpringEL300Tests extends ExpressionTestCase {
expr = new SpelExpressionParser().parseRaw("''?:'default'"); expr = new SpelExpressionParser().parseRaw("''?:'default'");
Assert.assertEquals("default", expr.getValue()); Assert.assertEquals("default", expr.getValue());
} }
@Test
@SuppressWarnings("unchecked")
public void testMapOfMap_SPR7244() throws Exception {
Map<String,Object> map = new LinkedHashMap();
map.put("uri", "http:");
Map nameMap = new LinkedHashMap();
nameMap.put("givenName", "Arthur");
map.put("value", nameMap);
StandardEvaluationContext ctx = new StandardEvaluationContext(map);
ExpressionParser parser = new SpelExpressionParser();
String el1 = "#root['value'].get('givenName')";
Expression exp = parser.parseExpression(el1);
Object evaluated = exp.getValue(ctx);
Assert.assertEquals("Arthur", evaluated);
String el2 = "#root['value']['givenName']"; @Test
exp = parser.parseExpression(el2); public void testMapOfMap_SPR7244() throws Exception {
evaluated = exp.getValue(ctx); Map<String,Object> map = new LinkedHashMap<String,Object>();
Assert.assertEquals("Arthur",evaluated); map.put("uri", "http:");
} Map<String,String> nameMap = new LinkedHashMap<String,String>();
nameMap.put("givenName", "Arthur");
map.put("value", nameMap);
StandardEvaluationContext ctx = new StandardEvaluationContext(map);
ExpressionParser parser = new SpelExpressionParser();
String el1 = "#root['value'].get('givenName')";
Expression exp = parser.parseExpression(el1);
Object evaluated = exp.getValue(ctx);
Assert.assertEquals("Arthur", evaluated);
String el2 = "#root['value']['givenName']";
exp = parser.parseExpression(el2);
evaluated = exp.getValue(ctx);
Assert.assertEquals("Arthur",evaluated);
}
@Test @Test
public void testProjectionTypeDescriptors_1() throws Exception { public void testProjectionTypeDescriptors_1() throws Exception {
StandardEvaluationContext ctx = new StandardEvaluationContext(new C()); StandardEvaluationContext ctx = new StandardEvaluationContext(new C());
SpelExpressionParser parser = new SpelExpressionParser(); SpelExpressionParser parser = new SpelExpressionParser();
String el1 = "ls.![#this.equals('abc')]"; String el1 = "ls.![#this.equals('abc')]";
SpelExpression exp = parser.parseRaw(el1); SpelExpression exp = parser.parseRaw(el1);
List value = (List)exp.getValue(ctx); List<?> value = (List<?>)exp.getValue(ctx);
// value is list containing [true,false] // value is list containing [true,false]
Assert.assertEquals(Boolean.class,value.get(0).getClass()); Assert.assertEquals(Boolean.class,value.get(0).getClass());
TypeDescriptor evaluated = exp.getValueTypeDescriptor(ctx); TypeDescriptor evaluated = exp.getValueTypeDescriptor(ctx);
Assert.assertEquals(null, evaluated.getElementTypeDescriptor()); Assert.assertEquals(null, evaluated.getElementTypeDescriptor());
} }
@Test @Test
public void testProjectionTypeDescriptors_2() throws Exception { public void testProjectionTypeDescriptors_2() throws Exception {
StandardEvaluationContext ctx = new StandardEvaluationContext(new C()); StandardEvaluationContext ctx = new StandardEvaluationContext(new C());
SpelExpressionParser parser = new SpelExpressionParser(); SpelExpressionParser parser = new SpelExpressionParser();
String el1 = "as.![#this.equals('abc')]"; String el1 = "as.![#this.equals('abc')]";
SpelExpression exp = parser.parseRaw(el1); SpelExpression exp = parser.parseRaw(el1);
Object[] value = (Object[])exp.getValue(ctx); Object[] value = (Object[])exp.getValue(ctx);
// value is array containing [true,false] // value is array containing [true,false]
Assert.assertEquals(Boolean.class,value[0].getClass()); Assert.assertEquals(Boolean.class,value[0].getClass());
TypeDescriptor evaluated = exp.getValueTypeDescriptor(ctx); TypeDescriptor evaluated = exp.getValueTypeDescriptor(ctx);
Assert.assertEquals(Boolean.class, evaluated.getElementTypeDescriptor().getType()); Assert.assertEquals(Boolean.class, evaluated.getElementTypeDescriptor().getType());
} }
@Test @Test
public void testProjectionTypeDescriptors_3() throws Exception { public void testProjectionTypeDescriptors_3() throws Exception {
StandardEvaluationContext ctx = new StandardEvaluationContext(new C()); StandardEvaluationContext ctx = new StandardEvaluationContext(new C());
SpelExpressionParser parser = new SpelExpressionParser(); SpelExpressionParser parser = new SpelExpressionParser();
String el1 = "ms.![key.equals('abc')]"; String el1 = "ms.![key.equals('abc')]";
SpelExpression exp = parser.parseRaw(el1); SpelExpression exp = parser.parseRaw(el1);
List value = (List)exp.getValue(ctx); List<?> value = (List<?>)exp.getValue(ctx);
// value is list containing [true,false] // value is list containing [true,false]
Assert.assertEquals(Boolean.class,value.get(0).getClass()); Assert.assertEquals(Boolean.class,value.get(0).getClass());
TypeDescriptor evaluated = exp.getValueTypeDescriptor(ctx); TypeDescriptor evaluated = exp.getValueTypeDescriptor(ctx);
Assert.assertEquals(null, evaluated.getElementTypeDescriptor()); Assert.assertEquals(null, evaluated.getElementTypeDescriptor());
} }
static class C { static class C {
public List<String> ls; public List<String> ls;
public String[] as; public String[] as;
@ -772,19 +757,19 @@ public class SpringEL300Tests extends ExpressionTestCase {
ms.put("def","pqr"); ms.put("def","pqr");
} }
} }
static class D { static class D {
public String a; public String a;
private D(String s) { private D(String s) {
a=s; a=s;
} }
public String toString() { public String toString() {
return "D("+a+")"; return "D("+a+")";
} }
} }
@Test @Test
public void testGreaterThanWithNulls_SPR7840() throws Exception { public void testGreaterThanWithNulls_SPR7840() throws Exception {
List<D> list = new ArrayList<D>(); List<D> list = new ArrayList<D>();
@ -794,30 +779,31 @@ public class SpringEL300Tests extends ExpressionTestCase {
list.add(new D("ccc")); list.add(new D("ccc"));
list.add(new D(null)); list.add(new D(null));
list.add(new D("zzz")); list.add(new D("zzz"));
StandardEvaluationContext ctx = new StandardEvaluationContext(list);
SpelExpressionParser parser = new SpelExpressionParser();
String el1 = "#root.?[a < 'hhh']"; StandardEvaluationContext ctx = new StandardEvaluationContext(list);
SpelExpression exp = parser.parseRaw(el1); SpelExpressionParser parser = new SpelExpressionParser();
Object value = exp.getValue(ctx);
assertEquals("[D(aaa), D(bbb), D(null), D(ccc), D(null)]",value.toString());
String el2 = "#root.?[a > 'hhh']"; String el1 = "#root.?[a < 'hhh']";
SpelExpression exp2 = parser.parseRaw(el2); SpelExpression exp = parser.parseRaw(el1);
Object value2 = exp2.getValue(ctx); Object value = exp.getValue(ctx);
assertEquals("[D(zzz)]",value2.toString()); assertEquals("[D(aaa), D(bbb), D(null), D(ccc), D(null)]",value.toString());
// trim out the nulls first String el2 = "#root.?[a > 'hhh']";
String el3 = "#root.?[a!=null].?[a < 'hhh']"; SpelExpression exp2 = parser.parseRaw(el2);
SpelExpression exp3 = parser.parseRaw(el3); Object value2 = exp2.getValue(ctx);
Object value3 = exp3.getValue(ctx); assertEquals("[D(zzz)]",value2.toString());
assertEquals("[D(aaa), D(bbb), D(ccc)]",value3.toString());
// trim out the nulls first
String el3 = "#root.?[a!=null].?[a < 'hhh']";
SpelExpression exp3 = parser.parseRaw(el3);
Object value3 = exp3.getValue(ctx);
assertEquals("[D(aaa), D(bbb), D(ccc)]",value3.toString());
} }
/** /**
* Test whether {@link ReflectiveMethodResolver} follows Java Method Invocation Conversion order. And more precisely * Test whether {@link ReflectiveMethodResolver} follows Java Method Invocation
* that widening reference conversion is 'higher' than a unboxing conversion. * Conversion order. And more precisely that widening reference conversion is 'higher'
* than a unboxing conversion.
*/ */
@Test @Test
public void testConversionPriority_8224() throws Exception { public void testConversionPriority_8224() throws Exception {
@ -904,16 +890,16 @@ public class SpringEL300Tests extends ExpressionTestCase {
} }
@Test @Test
public void varargsAndPrimitives_SPR8174() throws Exception { public void varargsAndPrimitives_SPR8174() throws Exception {
EvaluationContext emptyEvalContext = new StandardEvaluationContext(); EvaluationContext emptyEvalContext = new StandardEvaluationContext();
List<TypeDescriptor> args = new ArrayList<TypeDescriptor>(); List<TypeDescriptor> args = new ArrayList<TypeDescriptor>();
args.add(TypeDescriptor.forObject(34L)); args.add(TypeDescriptor.forObject(34L));
ReflectionUtil<Integer> ru = new ReflectionUtil<Integer>(); ReflectionUtil<Integer> ru = new ReflectionUtil<Integer>();
MethodExecutor me = new ReflectiveMethodResolver().resolve(emptyEvalContext,ru,"methodToCall",args); MethodExecutor me = new ReflectiveMethodResolver().resolve(emptyEvalContext,ru,"methodToCall",args);
args.set(0,TypeDescriptor.forObject(23)); args.set(0,TypeDescriptor.forObject(23));
me = new ReflectiveMethodResolver().resolve(emptyEvalContext,ru,"foo",args); me = new ReflectiveMethodResolver().resolve(emptyEvalContext,ru,"foo",args);
me.execute(emptyEvalContext, ru, 45); me.execute(emptyEvalContext, ru, 45);
@ -941,127 +927,126 @@ public class SpringEL300Tests extends ExpressionTestCase {
args.set(0,TypeDescriptor.forObject((byte)23)); args.set(0,TypeDescriptor.forObject((byte)23));
me = new ReflectiveMethodResolver().resolve(emptyEvalContext,ru,"foo",args); me = new ReflectiveMethodResolver().resolve(emptyEvalContext,ru,"foo",args);
me.execute(emptyEvalContext, ru, (byte)23); me.execute(emptyEvalContext, ru, (byte)23);
args.set(0,TypeDescriptor.forObject(true)); args.set(0,TypeDescriptor.forObject(true));
me = new ReflectiveMethodResolver().resolve(emptyEvalContext,ru,"foo",args); me = new ReflectiveMethodResolver().resolve(emptyEvalContext,ru,"foo",args);
me.execute(emptyEvalContext, ru, true); me.execute(emptyEvalContext, ru, true);
// trickier: // trickier:
args.set(0,TypeDescriptor.forObject(12)); args.set(0,TypeDescriptor.forObject(12));
args.add(TypeDescriptor.forObject(23f)); args.add(TypeDescriptor.forObject(23f));
me = new ReflectiveMethodResolver().resolve(emptyEvalContext,ru,"bar",args); me = new ReflectiveMethodResolver().resolve(emptyEvalContext,ru,"bar",args);
me.execute(emptyEvalContext, ru, 12,23f); me.execute(emptyEvalContext, ru, 12,23f);
} }
public class ReflectionUtil<T extends Number> { public class ReflectionUtil<T extends Number> {
public Object methodToCall(T param) { public Object methodToCall(T param) {
System.out.println(param+" "+param.getClass()); System.out.println(param+" "+param.getClass());
return "Object methodToCall(T param)"; return "Object methodToCall(T param)";
} }
public void foo(int... array) { public void foo(int... array) {
if (array.length==0) { if (array.length==0) {
throw new RuntimeException(); throw new RuntimeException();
} }
} }
public void foo(float...array) { public void foo(float...array) {
if (array.length==0) { if (array.length==0) {
throw new RuntimeException(); throw new RuntimeException();
} }
} }
public void foo(double...array) { public void foo(double...array) {
if (array.length==0) { if (array.length==0) {
throw new RuntimeException(); throw new RuntimeException();
} }
} }
public void foo(short...array) { public void foo(short...array) {
if (array.length==0) { if (array.length==0) {
throw new RuntimeException(); throw new RuntimeException();
} }
} }
public void foo(long...array) { public void foo(long...array) {
if (array.length==0) { if (array.length==0) {
throw new RuntimeException(); throw new RuntimeException();
} }
} }
public void foo(boolean...array) { public void foo(boolean...array) {
if (array.length==0) { if (array.length==0) {
throw new RuntimeException(); throw new RuntimeException();
} }
} }
public void foo(char...array) { public void foo(char...array) {
if (array.length==0) { if (array.length==0) {
throw new RuntimeException(); throw new RuntimeException();
} }
} }
public void foo(byte...array) { public void foo(byte...array) {
if (array.length==0) { if (array.length==0) {
throw new RuntimeException(); throw new RuntimeException();
} }
} }
public void bar(int... array) { public void bar(int... array) {
if (array.length==0) { if (array.length==0) {
throw new RuntimeException(); throw new RuntimeException();
} }
} }
} }
@Test @Test
public void testReservedWords_8228() throws Exception { public void testReservedWords_8228() throws Exception {
// "DIV","EQ","GE","GT","LE","LT","MOD","NE","NOT" // "DIV","EQ","GE","GT","LE","LT","MOD","NE","NOT"
@SuppressWarnings("unused") @SuppressWarnings("unused")
class Reserver { class Reserver {
public Reserver getReserver() { public Reserver getReserver() {
return this; return this;
} }
public String NE = "abc"; public String NE = "abc";
public String ne = "def"; public String ne = "def";
public int DIV = 1; public int DIV = 1;
public int div = 3; public int div = 3;
public Map m = new HashMap(); public Map<String,String> m = new HashMap<String,String>();
@SuppressWarnings("unchecked")
Reserver() { Reserver() {
m.put("NE","xyz"); m.put("NE","xyz");
} }
} }
StandardEvaluationContext ctx = new StandardEvaluationContext(new Reserver()); StandardEvaluationContext ctx = new StandardEvaluationContext(new Reserver());
SpelExpressionParser parser = new SpelExpressionParser(); SpelExpressionParser parser = new SpelExpressionParser();
String ex = "getReserver().NE"; String ex = "getReserver().NE";
SpelExpression exp = null; SpelExpression exp = null;
exp = parser.parseRaw(ex); exp = parser.parseRaw(ex);
String value = (String)exp.getValue(ctx); String value = (String)exp.getValue(ctx);
Assert.assertEquals("abc",value); Assert.assertEquals("abc",value);
ex = "getReserver().ne"; ex = "getReserver().ne";
exp = parser.parseRaw(ex); exp = parser.parseRaw(ex);
value = (String)exp.getValue(ctx); value = (String)exp.getValue(ctx);
Assert.assertEquals("def",value); Assert.assertEquals("def",value);
ex = "getReserver().m[NE]"; ex = "getReserver().m[NE]";
exp = parser.parseRaw(ex); exp = parser.parseRaw(ex);
value = (String)exp.getValue(ctx); value = (String)exp.getValue(ctx);
Assert.assertEquals("xyz",value); Assert.assertEquals("xyz",value);
ex = "getReserver().DIV";
exp = parser.parseRaw(ex);
Assert.assertEquals(1,exp.getValue(ctx));
ex = "getReserver().div"; ex = "getReserver().DIV";
exp = parser.parseRaw(ex); exp = parser.parseRaw(ex);
Assert.assertEquals(3,exp.getValue(ctx)); Assert.assertEquals(1,exp.getValue(ctx));
exp = parser.parseRaw("NE"); ex = "getReserver().div";
Assert.assertEquals("abc",exp.getValue(ctx)); exp = parser.parseRaw(ex);
Assert.assertEquals(3,exp.getValue(ctx));
exp = parser.parseRaw("NE");
Assert.assertEquals("abc",exp.getValue(ctx));
} }
/** /**
* We add property accessors in the order: * We add property accessors in the order:
* First, Second, Third, Fourth. * First, Second, Third, Fourth.
@ -1071,39 +1056,24 @@ public class SpringEL300Tests extends ExpressionTestCase {
@Test @Test
public void testPropertyAccessorOrder_8211() { public void testPropertyAccessorOrder_8211() {
ExpressionParser expressionParser = new SpelExpressionParser(); ExpressionParser expressionParser = new SpelExpressionParser();
StandardEvaluationContext evaluationContext = StandardEvaluationContext evaluationContext =
new StandardEvaluationContext(new ContextObject()); new StandardEvaluationContext(new ContextObject());
evaluationContext.addPropertyAccessor(new TestPropertyAccessor("firstContext")); evaluationContext.addPropertyAccessor(new TestPropertyAccessor("firstContext"));
evaluationContext.addPropertyAccessor(new TestPropertyAccessor("secondContext")); evaluationContext.addPropertyAccessor(new TestPropertyAccessor("secondContext"));
evaluationContext.addPropertyAccessor(new TestPropertyAccessor("thirdContext")); evaluationContext.addPropertyAccessor(new TestPropertyAccessor("thirdContext"));
evaluationContext.addPropertyAccessor(new TestPropertyAccessor("fourthContext")); evaluationContext.addPropertyAccessor(new TestPropertyAccessor("fourthContext"));
assertEquals("first", assertEquals("first",
expressionParser.parseExpression("shouldBeFirst").getValue(evaluationContext)); expressionParser.parseExpression("shouldBeFirst").getValue(evaluationContext));
assertEquals("second", assertEquals("second",
expressionParser.parseExpression("shouldBeSecond").getValue(evaluationContext)); expressionParser.parseExpression("shouldBeSecond").getValue(evaluationContext));
assertEquals("third", assertEquals("third",
expressionParser.parseExpression("shouldBeThird").getValue(evaluationContext)); expressionParser.parseExpression("shouldBeThird").getValue(evaluationContext));
assertEquals("fourth", assertEquals("fourth",
expressionParser.parseExpression("shouldBeFourth").getValue(evaluationContext)); expressionParser.parseExpression("shouldBeFourth").getValue(evaluationContext));
} }
// test not quite complete, it doesn't check that the list of resolvers at the end of
// PropertyOrFieldReference.getPropertyAccessorsToTry() doesn't contain duplicates, which
// is what it is trying to test by having a property accessor that returns specific
// classes Integer and Number
// @Test
// public void testPropertyAccessorOrder_8211_2() {
// ExpressionParser expressionParser = new SpelExpressionParser();
// StandardEvaluationContext evaluationContext =
// new StandardEvaluationContext(new Integer(42));
//
// evaluationContext.addPropertyAccessor(new TestPropertyAccessor2());
//
// assertEquals("42", expressionParser.parseExpression("x").getValue(evaluationContext));
// }
class TestPropertyAccessor implements PropertyAccessor { class TestPropertyAccessor implements PropertyAccessor {
private String mapName; private String mapName;
public TestPropertyAccessor(String mapName) { public TestPropertyAccessor(String mapName) {
@ -1139,38 +1109,13 @@ public class SpringEL300Tests extends ExpressionTestCase {
} }
} }
// class TestPropertyAccessor2 implements PropertyAccessor {
//
// public Class[] getSpecificTargetClasses() {
// return new Class[]{Integer.class,Number.class};
// }
//
// public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
// return true;
// }
//
// public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
// return new TypedValue(target.toString(),TypeDescriptor.valueOf(String.class));
// }
//
// public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
// return false;
// }
//
// public void write(EvaluationContext context, Object target, String name, Object newValue)
// throws AccessException {
// throw new UnsupportedOperationException();
// }
//
// }
class ContextObject { class ContextObject {
public Map<String, String> firstContext = new HashMap<String, String>(); public Map<String, String> firstContext = new HashMap<String, String>();
public Map<String, String> secondContext = new HashMap<String, String>(); public Map<String, String> secondContext = new HashMap<String, String>();
public Map<String, String> thirdContext = new HashMap<String, String>(); public Map<String, String> thirdContext = new HashMap<String, String>();
public Map<String, String> fourthContext = new HashMap<String, String>(); public Map<String, String> fourthContext = new HashMap<String, String>();
public ContextObject() { public ContextObject() {
firstContext.put("shouldBeFirst", "first"); firstContext.put("shouldBeFirst", "first");
secondContext.put("shouldBeFirst", "second"); secondContext.put("shouldBeFirst", "second");
@ -1180,10 +1125,10 @@ public class SpringEL300Tests extends ExpressionTestCase {
secondContext.put("shouldBeSecond", "second"); secondContext.put("shouldBeSecond", "second");
thirdContext.put("shouldBeSecond", "third"); thirdContext.put("shouldBeSecond", "third");
fourthContext.put("shouldBeSecond", "fourth"); fourthContext.put("shouldBeSecond", "fourth");
thirdContext.put("shouldBeThird", "third"); thirdContext.put("shouldBeThird", "third");
fourthContext.put("shouldBeThird", "fourth"); fourthContext.put("shouldBeThird", "fourth");
fourthContext.put("shouldBeFourth", "fourth"); fourthContext.put("shouldBeFourth", "fourth");
} }
public Map<String, String> getFirstContext() {return firstContext;} public Map<String, String> getFirstContext() {return firstContext;}