From 86fc2dd5563d4e9ee4fda2fbd5e513eec19c3a70 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 23 Jan 2014 20:52:21 +0100 Subject: [PATCH] Fixed regression in SpEL's constructor resolution Issue: SPR-11348 --- .../ReflectiveConstructorResolver.java | 16 +++++++-- .../expression/spel/SpelReproTests.java | 36 ++++++++++++++----- 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectiveConstructorResolver.java b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectiveConstructorResolver.java index e2482fc7e61..e82d64bc3d5 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectiveConstructorResolver.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectiveConstructorResolver.java @@ -68,6 +68,7 @@ public class ReflectiveConstructorResolver implements ConstructorResolver { }); Constructor closeMatch = null; + Constructor matchRequiringConversion = null; for (Constructor ctor : ctors) { Class[] paramTypes = ctor.getParameterTypes(); @@ -93,13 +94,24 @@ public class ReflectiveConstructorResolver implements ConstructorResolver { if (matchInfo.isExactMatch()) { return new ReflectiveConstructorExecutor(ctor); } - else if (matchInfo.isCloseMatch() || matchInfo.isMatchRequiringConversion()) { + else if (matchInfo.isCloseMatch()) { closeMatch = ctor; } + else if (matchInfo.isMatchRequiringConversion()) { + matchRequiringConversion = ctor; + } } } - return (closeMatch != null ? new ReflectiveConstructorExecutor(closeMatch) : null); + if (closeMatch != null) { + return new ReflectiveConstructorExecutor(closeMatch); + } + else if (matchRequiringConversion != null) { + return new ReflectiveConstructorExecutor(matchRequiringConversion); + } + else { + return null; + } } catch (EvaluationException ex) { throw new AccessException("Failed to resolve constructor", ex); 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 babc55e5dd9..5de7887c4c3 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 @@ -21,7 +21,10 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -1571,7 +1574,7 @@ public class SpelReproTests extends ExpressionTestCase { ReflectivePropertyAccessor accessor = new ReflectivePropertyAccessor(); StandardEvaluationContext context = new StandardEvaluationContext(); Object target = new GenericImplementation(); - TypedValue value = accessor.read(context, target , "property"); + TypedValue value = accessor.read(context, target, "property"); assertEquals(Integer.class, value.getTypeDescriptor().getType()); } @@ -1711,8 +1714,7 @@ public class SpelReproTests extends ExpressionTestCase { Method method = XYZ.class.getMethod("values"); Object value = method.invoke(target, arguments); return new TypedValue(value, new TypeDescriptor(new MethodParameter(method, -1)).narrow(value)); - } - catch (Exception ex) { + } catch (Exception ex) { throw new AccessException(ex.getMessage(), ex); } } @@ -1752,16 +1754,32 @@ public class SpelReproTests extends ExpressionTestCase { } @Test - public void testOperatorEq_SPR9194() { + public void SPR_9194() { TestClass2 one = new TestClass2("abc"); TestClass2 two = new TestClass2("abc"); - Map map = new HashMap(); - map.put("one",one); - map.put("two",two); + Map map = new HashMap(); + map.put("one", one); + map.put("two", two); SpelExpressionParser parser = new SpelExpressionParser(); - Expression classNameExpression = parser.parseExpression("['one'] == ['two']"); - assertTrue(classNameExpression.getValue(map,Boolean.class)); + Expression expr = parser.parseExpression("['one'] == ['two']"); + assertTrue(expr.getValue(map, Boolean.class)); + } + + @Test + public void SPR_11348() { + Collection coll = new HashSet(); + coll.add("one"); + coll.add("two"); + coll = Collections.unmodifiableCollection(coll); + + SpelExpressionParser parser = new SpelExpressionParser(); + Expression expr = parser.parseExpression("new java.util.ArrayList(#root)"); + Object value = expr.getValue(coll); + assertTrue(value instanceof ArrayList); + ArrayList list = (ArrayList) value; + assertEquals("one", list.get(0)); + assertEquals("two", list.get(1)); }