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 91bae22b4c..7d5d6efcda 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 @@ -38,7 +38,7 @@ import org.springframework.expression.spel.support.ReflectionHelper.ArgumentsMat import static org.junit.Assert.*; /** - * Tests for any helper code. + * Tests for reflection helper code. * * @author Andy Clement */ @@ -46,23 +46,14 @@ public class ReflectionHelperTests extends AbstractExpressionTests { @Test public void testFormatHelperForClassName() { - assertEquals("java.lang.String",FormatHelper.formatClassNameForMessage(String.class)); - assertEquals("java.lang.String[]",FormatHelper.formatClassNameForMessage(new String[1].getClass())); - assertEquals("java.lang.String[][]",FormatHelper.formatClassNameForMessage(new String[1][1].getClass())); - assertEquals("int[]",FormatHelper.formatClassNameForMessage(new int[1].getClass())); - assertEquals("int[][]",FormatHelper.formatClassNameForMessage(new int[1][2].getClass())); - assertEquals("null",FormatHelper.formatClassNameForMessage(null)); + 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 testFormatHelperForMethod() { - assertEquals("foo(java.lang.String)",FormatHelper.formatMethodForMessage("foo", String.class)); - assertEquals("goo(java.lang.String,int[])",FormatHelper.formatMethodForMessage("goo", String.class, new int[1].getClass())); - assertEquals("boo()",FormatHelper.formatMethodForMessage("boo")); - } - */ - @Test public void testUtilities() throws ParseException { SpelExpression expr = (SpelExpression)parser.parseExpression("3+4+5+6+7-2"); @@ -159,47 +150,45 @@ public class ReflectionHelperTests extends AbstractExpressionTests { StandardTypeConverter typeConverter = new StandardTypeConverter(); // Passing (Super,String) on call to foo(Sub,String) is not a match - checkMatch(new Class>[] {Super.class,String.class}, new Class>[] {Sub.class,String.class},typeConverter,null); + checkMatch(new Class>[] {Super.class,String.class}, new Class>[] {Sub.class,String.class}, typeConverter, null); } @Test public void testReflectionHelperCompareArguments_Varargs_ExactMatching() { StandardTypeConverter tc = new StandardTypeConverter(); - Class> stringArrayClass = new String[0].getClass(); - Class> integerArrayClass = new Integer[0].getClass(); // Passing (String[]) on call to (String[]) is exact match - checkMatch2(new Class>[] {stringArrayClass}, new Class>[] {stringArrayClass}, tc, ArgumentsMatchKind.EXACT); + checkMatch2(new Class>[] {String[].class}, new Class>[] {String[].class}, tc, ArgumentsMatchKind.EXACT); // Passing (Integer, String[]) on call to (Integer, String[]) is exact match - checkMatch2(new Class>[] {Integer.class, stringArrayClass}, new Class>[] {Integer.class, stringArrayClass}, tc, ArgumentsMatchKind.EXACT); + checkMatch2(new Class>[] {Integer.class, String[].class}, new Class>[] {Integer.class, String[].class}, tc, ArgumentsMatchKind.EXACT); // Passing (String, Integer, String[]) on call to (String, String, String[]) is exact match - checkMatch2(new Class>[] {String.class, Integer.class, stringArrayClass}, new Class>[] {String.class,Integer.class, stringArrayClass}, tc, ArgumentsMatchKind.EXACT); + checkMatch2(new Class>[] {String.class, Integer.class, String[].class}, new Class>[] {String.class,Integer.class, String[].class}, tc, ArgumentsMatchKind.EXACT); // Passing (Sub, String[]) on call to (Super, String[]) is exact match - checkMatch2(new Class>[] {Sub.class, stringArrayClass}, new Class>[] {Super.class,stringArrayClass}, tc, ArgumentsMatchKind.CLOSE); + checkMatch2(new Class>[] {Sub.class, String[].class}, new Class>[] {Super.class,String[].class}, tc, ArgumentsMatchKind.CLOSE); // Passing (Integer, String[]) on call to (String, String[]) is exact match - checkMatch2(new Class>[] {Integer.class, stringArrayClass}, new Class>[] {String.class, stringArrayClass}, tc, ArgumentsMatchKind.REQUIRES_CONVERSION); + checkMatch2(new Class>[] {Integer.class, String[].class}, new Class>[] {String.class, String[].class}, tc, ArgumentsMatchKind.REQUIRES_CONVERSION); // Passing (Integer, Sub, String[]) on call to (String, Super, String[]) is exact match checkMatch2(new Class>[] {Integer.class, Sub.class, String[].class}, new Class>[] {String.class,Super .class, String[].class}, tc, ArgumentsMatchKind.REQUIRES_CONVERSION); // Passing (String) on call to (String[]) is exact match - checkMatch2(new Class>[] {String.class}, new Class>[] {stringArrayClass}, tc, ArgumentsMatchKind.EXACT); + checkMatch2(new Class>[] {String.class}, new Class>[] {String[].class}, tc, ArgumentsMatchKind.EXACT); // Passing (Integer,String) on call to (Integer,String[]) is exact match - checkMatch2(new Class>[] {Integer.class, String.class}, new Class>[] {Integer.class, stringArrayClass}, tc, ArgumentsMatchKind.EXACT); + checkMatch2(new Class>[] {Integer.class, String.class}, new Class>[] {Integer.class, String[].class}, tc, ArgumentsMatchKind.EXACT); // Passing (String) on call to (Integer[]) is conversion match (String to Integer) - checkMatch2(new Class>[] {String.class}, new Class>[] {integerArrayClass}, tc, ArgumentsMatchKind.REQUIRES_CONVERSION); + checkMatch2(new Class>[] {String.class}, new Class>[] {Integer[].class}, tc, ArgumentsMatchKind.REQUIRES_CONVERSION); // Passing (Sub) on call to (Super[]) is close match - checkMatch2(new Class>[] {Sub.class}, new Class>[] {new Super[0].getClass()}, tc, ArgumentsMatchKind.CLOSE); + checkMatch2(new Class>[] {Sub.class}, new Class>[] {Super[].class}, tc, ArgumentsMatchKind.CLOSE); // Passing (Super) on call to (Sub[]) is not a match - checkMatch2(new Class>[] {Super.class}, new Class>[] {new Sub[0].getClass()}, tc, null); + checkMatch2(new Class>[] {Super.class}, new Class>[] {Sub[].class}, tc, null); checkMatch2(new Class>[] {Unconvertable.class, String.class}, new Class>[] {Sub.class, Super[].class}, tc, null); @@ -234,12 +223,12 @@ public class ReflectionHelperTests extends AbstractExpressionTests { // varargs with nothing needing conversion args = new Object[] {3, "abc", "abc"}; ReflectionHelper.convertArguments(tc, args, twoArg, 1); - checkArguments(args, "3","abc","abc"); + checkArguments(args, "3", "abc", "abc"); // varargs with conversion required args = new Object[] {3, false ,3.0d}; ReflectionHelper.convertArguments(tc, args, twoArg, 1); - checkArguments(args, "3","false","3.0"); + checkArguments(args, "3", "false", "3.0"); } @Test @@ -251,33 +240,33 @@ public class ReflectionHelperTests extends AbstractExpressionTests { // Simple conversion: int to string Object[] args = new Object[] {3}; ReflectionHelper.convertAllArguments(tc, args, oneArg); - checkArguments(args,"3"); + checkArguments(args, "3"); // varargs conversion args = new Object[] {3, false, 3.0f}; ReflectionHelper.convertAllArguments(tc, args, twoArg); - checkArguments(args,"3","false","3.0"); + checkArguments(args, "3", "false", "3.0"); // varargs conversion but no varargs args = new Object[] {3}; ReflectionHelper.convertAllArguments(tc, args, twoArg); - checkArguments(args,"3"); + checkArguments(args, "3"); // null value args = new Object[] {3, null, 3.0f}; ReflectionHelper.convertAllArguments(tc, args, twoArg); - checkArguments(args,"3",null,"3.0"); + checkArguments(args, "3", null, "3.0"); } @Test public void testSetupArguments() { Object[] newArray = ReflectionHelper.setupArgumentsForVarargsInvocation( - new Class>[] {new String[0].getClass()},"a","b","c"); + new Class>[] {String[].class}, "a", "b", "c"); assertEquals(1, newArray.length); Object firstParam = newArray[0]; assertEquals(String.class,firstParam.getClass().getComponentType()); - Object[] firstParamArray = (Object[])firstParam; + Object[] firstParamArray = (Object[]) firstParam; assertEquals(3,firstParamArray.length); assertEquals("a",firstParamArray[0]); assertEquals("b",firstParamArray[1]); @@ -285,75 +274,75 @@ public class ReflectionHelperTests extends AbstractExpressionTests { } @Test - public void testReflectivePropertyResolver() throws Exception { - ReflectivePropertyAccessor rpr = new ReflectivePropertyAccessor(); + public void testReflectivePropertyAccessor() throws Exception { + ReflectivePropertyAccessor rpa = new ReflectivePropertyAccessor(); Tester t = new Tester(); t.setProperty("hello"); EvaluationContext ctx = new StandardEvaluationContext(t); - assertTrue(rpr.canRead(ctx, t, "property")); - assertEquals("hello",rpr.read(ctx, t, "property").getValue()); - assertEquals("hello",rpr.read(ctx, t, "property").getValue()); // cached accessor used + assertTrue(rpa.canRead(ctx, t, "property")); + assertEquals("hello",rpa.read(ctx, t, "property").getValue()); + assertEquals("hello",rpa.read(ctx, t, "property").getValue()); // cached accessor used - assertTrue(rpr.canRead(ctx, t, "field")); - assertEquals(3,rpr.read(ctx, t, "field").getValue()); - assertEquals(3,rpr.read(ctx, t, "field").getValue()); // cached accessor used + assertTrue(rpa.canRead(ctx, t, "field")); + assertEquals(3,rpa.read(ctx, t, "field").getValue()); + assertEquals(3,rpa.read(ctx, t, "field").getValue()); // cached accessor used - assertTrue(rpr.canWrite(ctx, t, "property")); - rpr.write(ctx, t, "property","goodbye"); - rpr.write(ctx, t, "property","goodbye"); // cached accessor used + assertTrue(rpa.canWrite(ctx, t, "property")); + rpa.write(ctx, t, "property", "goodbye"); + rpa.write(ctx, t, "property", "goodbye"); // cached accessor used - assertTrue(rpr.canWrite(ctx, t, "field")); - rpr.write(ctx, t, "field",12); - rpr.write(ctx, t, "field",12); + assertTrue(rpa.canWrite(ctx, t, "field")); + rpa.write(ctx, t, "field", 12); + rpa.write(ctx, t, "field", 12); // Attempted write as first activity on this field and property to drive testing // of populating type descriptor cache - rpr.write(ctx,t,"field2",3); - rpr.write(ctx, t, "property2","doodoo"); - assertEquals(3,rpr.read(ctx,t,"field2").getValue()); + rpa.write(ctx, t, "field2", 3); + rpa.write(ctx, t, "property2", "doodoo"); + assertEquals(3,rpa.read(ctx, t, "field2").getValue()); // Attempted read as first activity on this field and property (no canRead before them) - assertEquals(0,rpr.read(ctx,t,"field3").getValue()); - assertEquals("doodoo",rpr.read(ctx,t,"property3").getValue()); + assertEquals(0,rpa.read(ctx, t, "field3").getValue()); + assertEquals("doodoo",rpa.read(ctx, t, "property3").getValue()); // Access through is method -// assertEquals(0,rpr.read(ctx,t,"field3").getValue()); - assertEquals(false,rpr.read(ctx,t,"property4").getValue()); - assertTrue(rpr.canRead(ctx,t,"property4")); + assertEquals(0,rpa .read(ctx, t, "field3").getValue()); + assertEquals(false,rpa.read(ctx, t, "property4").getValue()); + assertTrue(rpa.canRead(ctx, t, "property4")); // repro SPR-9123, ReflectivePropertyAccessor JavaBean property names compliance tests - assertEquals("iD",rpr.read(ctx,t,"iD").getValue()); - assertTrue(rpr.canRead(ctx,t,"iD")); - assertEquals("id",rpr.read(ctx,t,"id").getValue()); - assertTrue(rpr.canRead(ctx,t,"id")); - assertEquals("ID",rpr.read(ctx,t,"ID").getValue()); - assertTrue(rpr.canRead(ctx,t,"ID")); + assertEquals("iD",rpa.read(ctx, t, "iD").getValue()); + assertTrue(rpa.canRead(ctx, t, "iD")); + assertEquals("id",rpa.read(ctx, t, "id").getValue()); + assertTrue(rpa.canRead(ctx, t, "id")); + assertEquals("ID",rpa.read(ctx, t, "ID").getValue()); + assertTrue(rpa.canRead(ctx, t, "ID")); // note: "Id" is not a valid JavaBean name, nevertheless it is treated as "id" - assertEquals("id",rpr.read(ctx,t,"Id").getValue()); - assertTrue(rpr.canRead(ctx,t,"Id")); + assertEquals("id",rpa.read(ctx, t, "Id").getValue()); + assertTrue(rpa.canRead(ctx, t, "Id")); // repro SPR-10994 - assertEquals("xyZ",rpr.read(ctx,t,"xyZ").getValue()); - assertTrue(rpr.canRead(ctx,t,"xyZ")); - assertEquals("xY",rpr.read(ctx,t,"xY").getValue()); - assertTrue(rpr.canRead(ctx,t,"xY")); + assertEquals("xyZ",rpa.read(ctx, t, "xyZ").getValue()); + assertTrue(rpa.canRead(ctx, t, "xyZ")); + assertEquals("xY",rpa.read(ctx, t, "xY").getValue()); + assertTrue(rpa.canRead(ctx, t, "xY")); // SPR-10122, ReflectivePropertyAccessor JavaBean property names compliance tests - setters - rpr.write(ctx, t, "pEBS","Test String"); - assertEquals("Test String",rpr.read(ctx,t,"pEBS").getValue()); + rpa.write(ctx, t, "pEBS", "Test String"); + assertEquals("Test String",rpa.read(ctx, t, "pEBS").getValue()); } @Test - public void testOptimalReflectivePropertyResolver() throws Exception { - ReflectivePropertyAccessor rpr = new ReflectivePropertyAccessor(); + public void testOptimalReflectivePropertyAccessor() throws Exception { + ReflectivePropertyAccessor rpa = new ReflectivePropertyAccessor(); Tester t = new Tester(); t.setProperty("hello"); EvaluationContext ctx = new StandardEvaluationContext(t); -// assertTrue(rpr.canRead(ctx, t, "property")); -// assertEquals("hello",rpr.read(ctx, t, "property").getValue()); -// assertEquals("hello",rpr.read(ctx, t, "property").getValue()); // cached accessor used + assertTrue(rpa.canRead(ctx, t, "property")); + assertEquals("hello", rpa.read(ctx, t, "property").getValue()); + assertEquals("hello", rpa.read(ctx, t, "property").getValue()); // cached accessor used - PropertyAccessor optA = rpr.createOptimalAccessor(ctx, t, "property"); + PropertyAccessor optA = rpa.createOptimalAccessor(ctx, t, "property"); assertTrue(optA.canRead(ctx, t, "property")); assertFalse(optA.canRead(ctx, t, "property2")); try { @@ -381,14 +370,14 @@ public class ReflectionHelperTests extends AbstractExpressionTests { // success } try { - optA.write(ctx,t,"property",null); + optA.write(ctx, t, "property", null); fail(); } catch (UnsupportedOperationException uoe) { // success } - optA = rpr.createOptimalAccessor(ctx, t, "field"); + optA = rpa.createOptimalAccessor(ctx, t, "field"); assertTrue(optA.canRead(ctx, t, "field")); assertFalse(optA.canRead(ctx, t, "field2")); try { @@ -406,7 +395,7 @@ public class ReflectionHelperTests extends AbstractExpressionTests { // success } assertEquals(3,optA.read(ctx, t, "field").getValue()); - assertEquals(3,optA.read(ctx, t, "field").getValue()); // cached accessor used + assertEquals(3,optA.read(ctx, t, "field").getValue()); // cached accessor used try { optA.getSpecificTargetClasses(); @@ -416,7 +405,7 @@ public class ReflectionHelperTests extends AbstractExpressionTests { // success } try { - optA.write(ctx,t,"field",null); + optA.write(ctx, t, "field", null); fail(); } catch (UnsupportedOperationException uoe) { diff --git a/spring-test/src/main/java/org/springframework/test/web/client/match/ContentRequestMatchers.java b/spring-test/src/main/java/org/springframework/test/web/client/match/ContentRequestMatchers.java index a6d0baa8b3..1e837e7af9 100644 --- a/spring-test/src/main/java/org/springframework/test/web/client/match/ContentRequestMatchers.java +++ b/spring-test/src/main/java/org/springframework/test/web/client/match/ContentRequestMatchers.java @@ -23,7 +23,6 @@ import javax.xml.transform.Source; import javax.xml.transform.dom.DOMSource; import org.hamcrest.Matcher; -import org.springframework.test.util.JsonExpectationsHelper; import org.w3c.dom.Node; import org.springframework.http.HttpHeaders; @@ -32,6 +31,7 @@ import org.springframework.http.MediaType; import org.springframework.http.client.ClientHttpRequest; import org.springframework.http.converter.FormHttpMessageConverter; import org.springframework.mock.http.client.MockClientHttpRequest; +import org.springframework.test.util.JsonExpectationsHelper; import org.springframework.test.util.XmlExpectationsHelper; import org.springframework.test.web.client.RequestMatcher; import org.springframework.util.MultiValueMap; @@ -218,8 +218,8 @@ public class ContentRequestMatchers { * regardless of formatting. *
Can compare in two modes, depending on {@code strict} parameter value: *
Use of this matcher requires the JSONassert library. @@ -232,8 +232,9 @@ public class ContentRequestMatchers { try { MockClientHttpRequest mockRequest = (MockClientHttpRequest) request; jsonHelper.assertJsonEqual(expectedJsonContent, mockRequest.getBodyAsString(), strict); - } catch (Exception e) { - throw new AssertionError("Failed to parse expected or actual JSON request content", e); + } + catch (Exception ex) { + throw new AssertionError("Failed to parse expected or actual JSON request content", ex); } }; } @@ -259,4 +260,3 @@ public class ContentRequestMatchers { } } - diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java index 0691dd5ce2..01de47e905 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java @@ -537,6 +537,24 @@ public class ResourceHttpRequestHandler extends WebContentGenerator return resource; } + /** + * Process the given resource path. + *
The default implementation replaces: + *
The default implementation replaces: - *