diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/SpelEvaluationException.java b/spring-expression/src/main/java/org/springframework/expression/spel/SpelEvaluationException.java index 9aced9dbf59..30d5e8b7db9 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/SpelEvaluationException.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/SpelEvaluationException.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2018 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. @@ -48,7 +48,7 @@ public class SpelEvaluationException extends EvaluationException { } public SpelEvaluationException(int position, Throwable cause, SpelMessage message, Object... inserts) { - super(position, message.formatMessage(inserts),cause); + super(position, message.formatMessage(inserts), cause); this.message = message; this.inserts = inserts; } diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/SpelMessage.java b/spring-expression/src/main/java/org/springframework/expression/spel/SpelMessage.java index 03787c84a50..42292db5246 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/SpelMessage.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/SpelMessage.java @@ -45,13 +45,13 @@ public enum SpelMessage { "A problem occurred whilst attempting to construct an object of type ''{0}'' using arguments ''{1}''"), METHOD_NOT_FOUND(Kind.ERROR, 1004, - "Method call: Method {0} cannot be found on {1} type"), + "Method call: Method {0} cannot be found on type {1}"), TYPE_NOT_FOUND(Kind.ERROR, 1005, "Type cannot be found ''{0}''"), FUNCTION_NOT_DEFINED(Kind.ERROR, 1006, - "The function ''{0}'' could not be found"), + "Function ''{0}'' could not be found"), PROPERTY_OR_FIELD_NOT_READABLE_ON_NULL(Kind.ERROR, 1007, "Property or field ''{0}'' cannot be found on null"), diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/FormatHelper.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/FormatHelper.java index f271910f1b3..a5d83159def 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/FormatHelper.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/FormatHelper.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2018 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. @@ -23,11 +23,11 @@ import org.springframework.lang.Nullable; import org.springframework.util.ClassUtils; /** - * Utility methods (formatters, etc) used during parsing and evaluation. + * Utility methods (formatters etc) used during parsing and evaluation. * * @author Andy Clement */ -public class FormatHelper { +abstract class FormatHelper { /** * Produce a readable representation for a given method name with specified arguments. diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/MethodReference.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/MethodReference.java index 16ecbbaaa14..b6a7505ffc6 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/MethodReference.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/MethodReference.java @@ -131,7 +131,7 @@ public class MethodReference extends SpelNodeImpl { } // either there was no accessor or it no longer existed - executorToUse = findAccessorForMethod(this.name, argumentTypes, value, evaluationContext); + executorToUse = findAccessorForMethod(argumentTypes, value, evaluationContext); this.cachedExecutor = new CachedMethodExecutor( executorToUse, (value instanceof Class ? (Class) value : null), targetType, argumentTypes); try { @@ -196,33 +196,40 @@ public class MethodReference extends SpelNodeImpl { return null; } - private MethodExecutor findAccessorForMethod(String name, List argumentTypes, - Object targetObject, EvaluationContext evaluationContext) throws SpelEvaluationException { + private MethodExecutor findAccessorForMethod(List argumentTypes, Object targetObject, + EvaluationContext evaluationContext) throws SpelEvaluationException { + AccessException accessException = null; List methodResolvers = evaluationContext.getMethodResolvers(); for (MethodResolver methodResolver : methodResolvers) { try { MethodExecutor methodExecutor = methodResolver.resolve( - evaluationContext, targetObject, name, argumentTypes); + evaluationContext, targetObject, this.name, argumentTypes); if (methodExecutor != null) { return methodExecutor; } } catch (AccessException ex) { - throw new SpelEvaluationException(getStartPosition(), ex, - SpelMessage.PROBLEM_LOCATING_METHOD, name, targetObject.getClass()); + accessException = ex; + break; } } - throw new SpelEvaluationException(getStartPosition(), SpelMessage.METHOD_NOT_FOUND, - FormatHelper.formatMethodForMessage(name, argumentTypes), - FormatHelper.formatClassNameForMessage( - targetObject instanceof Class ? ((Class) targetObject) : targetObject.getClass())); + String method = FormatHelper.formatMethodForMessage(this.name, argumentTypes); + String className = FormatHelper.formatClassNameForMessage( + targetObject instanceof Class ? ((Class) targetObject) : targetObject.getClass()); + if (accessException != null) { + throw new SpelEvaluationException( + getStartPosition(), accessException, SpelMessage.PROBLEM_LOCATING_METHOD, method, className); + } + else { + throw new SpelEvaluationException(getStartPosition(), SpelMessage.METHOD_NOT_FOUND, method, className); + } } /** - * Decode the AccessException, throwing a lightweight evaluation exception or, if the - * cause was a RuntimeException, throw the RuntimeException directly. + * Decode the AccessException, throwing a lightweight evaluation exception or, + * if the cause was a RuntimeException, throw the RuntimeException directly. */ private void throwSimpleExceptionIfPossible(Object value, AccessException ex) { if (ex.getCause() instanceof InvocationTargetException) { 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 212d8a3af19..63c0f134ad4 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-2017 the original author or authors. + * Copyright 2002-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,7 +40,7 @@ import org.springframework.util.MethodInvoker; * @author Juergen Hoeller * @since 3.0 */ -public class ReflectionHelper { +public abstract class ReflectionHelper { /** * Compare argument arrays and return information about whether they match. diff --git a/spring-expression/src/test/java/org/springframework/expression/spel/support/ReflectionHelperTests.java b/spring-expression/src/test/java/org/springframework/expression/spel/support/ReflectionHelperTests.java index 7d5d6efcdae..e5685ef68c2 100644 --- a/spring-expression/src/test/java/org/springframework/expression/spel/support/ReflectionHelperTests.java +++ b/spring-expression/src/test/java/org/springframework/expression/spel/support/ReflectionHelperTests.java @@ -31,7 +31,6 @@ import org.springframework.expression.PropertyAccessor; import org.springframework.expression.TypedValue; import org.springframework.expression.spel.AbstractExpressionTests; import org.springframework.expression.spel.SpelUtilities; -import org.springframework.expression.spel.ast.FormatHelper; import org.springframework.expression.spel.standard.SpelExpression; import org.springframework.expression.spel.support.ReflectionHelper.ArgumentsMatchKind; @@ -44,16 +43,6 @@ import static org.junit.Assert.*; */ public class ReflectionHelperTests extends AbstractExpressionTests { - @Test - public void testFormatHelperForClassName() { - assertEquals("java.lang.String", FormatHelper.formatClassNameForMessage(String.class)); - assertEquals("java.lang.String[]", FormatHelper.formatClassNameForMessage(String[].class)); - assertEquals("java.lang.String[][]", FormatHelper.formatClassNameForMessage(String[][].class)); - assertEquals("int[]", FormatHelper.formatClassNameForMessage(int[].class)); - assertEquals("int[][]", FormatHelper.formatClassNameForMessage(int[][].class)); - assertEquals("null", FormatHelper.formatClassNameForMessage(null)); - } - @Test public void testUtilities() throws ParseException { SpelExpression expr = (SpelExpression)parser.parseExpression("3+4+5+6+7-2"); @@ -414,60 +403,6 @@ public class ReflectionHelperTests extends AbstractExpressionTests { } - // test classes - static class Tester { - String property; - public int field = 3; - public int field2; - public int field3 = 0; - String property2; - String property3 = "doodoo"; - boolean property4 = false; - String iD = "iD"; - String id = "id"; - String ID = "ID"; - String pEBS = "pEBS"; - String xY = "xY"; - String xyZ = "xyZ"; - - public String getProperty() { return property; } - public void setProperty(String value) { property = value; } - - public void setProperty2(String value) { property2 = value; } - - public String getProperty3() { return property3; } - - public boolean isProperty4() { return property4; } - - public String getiD() { return iD; } - - public String getId() { return id; } - - public String getID() { return ID; } - - public String getXY() { return xY; } - - public String getXyZ() { return xyZ; } - - public String getpEBS() { - return pEBS; - } - - public void setpEBS(String pEBS) { - this.pEBS = pEBS; - } - } - - static class Super { - } - - static class Sub extends Super { - } - - static class Unconvertable {} - - // --- - /** * Used to validate the match returned from a compareArguments call. */ @@ -541,4 +476,58 @@ public class ReflectionHelperTests extends AbstractExpressionTests { void twoArg(String arg1, String... arg2); } + + static class Super { + } + + + static class Sub extends Super { + } + + + static class Unconvertable { + } + + + static class Tester { + + String property; + public int field = 3; + public int field2; + public int field3 = 0; + String property2; + String property3 = "doodoo"; + boolean property4 = false; + String iD = "iD"; + String id = "id"; + String ID = "ID"; + String pEBS = "pEBS"; + String xY = "xY"; + String xyZ = "xyZ"; + + public String getProperty() { return property; } + + public void setProperty(String value) { property = value; } + + public void setProperty2(String value) { property2 = value; } + + public String getProperty3() { return property3; } + + public boolean isProperty4() { return property4; } + + public String getiD() { return iD; } + + public String getId() { return id; } + + public String getID() { return ID; } + + public String getXY() { return xY; } + + public String getXyZ() { return xyZ; } + + public String getpEBS() { return pEBS; } + + public void setpEBS(String pEBS) { this.pEBS = pEBS; } + } + }