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 ffa0da8694..1c7c6d44ef 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 @@ -522,7 +522,7 @@ public class TypeDescriptor implements Serializable { /** * Create a new type descriptor for an object. *

Use this factory method to introspect a source object before asking the - * conversion system to convert it to some another type. + * conversion system to convert it to some other type. *

If the provided object is {@code null}, returns {@code null}, else calls * {@link #valueOf(Class)} to build a TypeDescriptor from the object's class. * @param source the source object 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 74fad1177a..4c82d36e64 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2023 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. @@ -21,6 +21,7 @@ import java.io.PrintStream; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import org.junit.jupiter.api.Test; @@ -44,11 +45,12 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; * Tests for reflection helper code. * * @author Andy Clement + * @author Sam Brannen */ -public class ReflectionHelperTests extends AbstractExpressionTests { +class ReflectionHelperTests extends AbstractExpressionTests { @Test - public void testUtilities() throws ParseException { + void utilities() throws ParseException { SpelExpression expr = (SpelExpression)parser.parseExpression("3+4+5+6+7-2"); ByteArrayOutputStream baos = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(baos); @@ -74,12 +76,12 @@ public class ReflectionHelperTests extends AbstractExpressionTests { // CompoundExpression value:2 // IntLiteral value:2 // ===> Expression '3+4+5+6+7-2' - AST end - assertThat(s.contains("===> Expression '3+4+5+6+7-2' - AST start")).isTrue(); - assertThat(s.contains(" OpPlus value:((((3 + 4) + 5) + 6) + 7) #children:2")).isTrue(); + assertThat(s).contains("===> Expression '3+4+5+6+7-2' - AST start"); + assertThat(s).contains(" OpPlus value:((((3 + 4) + 5) + 6) + 7) #children:2"); } @Test - public void testTypedValue() { + void typedValue() { TypedValue tv1 = new TypedValue("hello"); TypedValue tv2 = new TypedValue("hello"); TypedValue tv3 = new TypedValue("bye"); @@ -91,13 +93,13 @@ public class ReflectionHelperTests extends AbstractExpressionTests { assertThat(tv3).isNotEqualTo(tv2); assertThat(tv1).isNotEqualTo(tv3); assertThat(tv2).isNotEqualTo(tv3); - assertThat(tv2.hashCode()).isEqualTo(tv1.hashCode()); - assertThat(tv3.hashCode()).isNotEqualTo(tv1.hashCode()); - assertThat(tv3.hashCode()).isNotEqualTo(tv2.hashCode()); + assertThat(tv2).hasSameHashCodeAs(tv1); + assertThat(tv3).doesNotHaveSameHashCodeAs(tv1); + assertThat(tv3).doesNotHaveSameHashCodeAs(tv2); } @Test - public void testReflectionHelperCompareArguments_ExactMatching() { + void reflectionHelperCompareArguments_ExactMatching() { StandardTypeConverter tc = new StandardTypeConverter(); // Calling foo(String) with (String) is exact match @@ -108,7 +110,7 @@ public class ReflectionHelperTests extends AbstractExpressionTests { } @Test - public void testReflectionHelperCompareArguments_CloseMatching() { + void reflectionHelperCompareArguments_CloseMatching() { StandardTypeConverter tc = new StandardTypeConverter(); // Calling foo(List) with (ArrayList) is close match (no conversion required) @@ -122,7 +124,7 @@ public class ReflectionHelperTests extends AbstractExpressionTests { } @Test - public void testReflectionHelperCompareArguments_RequiresConversionMatching() { + void reflectionHelperCompareArguments_RequiresConversionMatching() { StandardTypeConverter tc = new StandardTypeConverter(); // Calling foo(String,int) with (String,Integer) requires boxing conversion of argument one @@ -139,7 +141,7 @@ public class ReflectionHelperTests extends AbstractExpressionTests { } @Test - public void testReflectionHelperCompareArguments_NotAMatch() { + void reflectionHelperCompareArguments_NotAMatch() { StandardTypeConverter typeConverter = new StandardTypeConverter(); // Passing (Super,String) on call to foo(Sub,String) is not a match @@ -147,7 +149,7 @@ public class ReflectionHelperTests extends AbstractExpressionTests { } @Test - public void testReflectionHelperCompareArguments_Varargs_ExactMatching() { + void reflectionHelperCompareArguments_Varargs_ExactMatching() { StandardTypeConverter tc = new StandardTypeConverter(); // Passing (String[]) on call to (String[]) is exact match @@ -198,7 +200,7 @@ public class ReflectionHelperTests extends AbstractExpressionTests { } @Test - public void testConvertArguments() throws Exception { + void convertArguments() throws Exception { StandardTypeConverter tc = new StandardTypeConverter(); Method oneArg = TestInterface.class.getMethod("oneArg", String.class); Method twoArg = TestInterface.class.getMethod("twoArg", String.class, String[].class); @@ -225,7 +227,7 @@ public class ReflectionHelperTests extends AbstractExpressionTests { } @Test - public void testConvertArguments2() throws Exception { + void convertArguments2() throws Exception { StandardTypeConverter tc = new StandardTypeConverter(); Method oneArg = TestInterface.class.getMethod("oneArg", String.class); Method twoArg = TestInterface.class.getMethod("twoArg", String.class, String[].class); @@ -252,7 +254,7 @@ public class ReflectionHelperTests extends AbstractExpressionTests { } @Test - public void testSetupArguments() { + void setupArguments() { Object[] newArray = ReflectionHelper.setupArgumentsForVarargsInvocation( new Class[] {String[].class}, "a", "b", "c"); @@ -260,14 +262,11 @@ public class ReflectionHelperTests extends AbstractExpressionTests { Object firstParam = newArray[0]; assertThat(firstParam.getClass().getComponentType()).isEqualTo(String.class); Object[] firstParamArray = (Object[]) firstParam; - assertThat(firstParamArray).hasSize(3); - assertThat(firstParamArray[0]).isEqualTo("a"); - assertThat(firstParamArray[1]).isEqualTo("b"); - assertThat(firstParamArray[2]).isEqualTo("c"); + assertThat(firstParamArray).containsExactly("a", "b", "c"); } @Test - public void testReflectivePropertyAccessor() throws Exception { + void reflectivePropertyAccessor() throws Exception { ReflectivePropertyAccessor rpa = new ReflectivePropertyAccessor(); Tester t = new Tester(); t.setProperty("hello"); @@ -328,7 +327,7 @@ public class ReflectionHelperTests extends AbstractExpressionTests { } @Test - public void testOptimalReflectivePropertyAccessor() throws Exception { + void optimalReflectivePropertyAccessor() throws Exception { ReflectivePropertyAccessor reflective = new ReflectivePropertyAccessor(); Tester tester = new Tester(); tester.setProperty("hello"); @@ -374,19 +373,28 @@ public class ReflectionHelperTests extends AbstractExpressionTests { MethodResolver resolver = new ReflectiveMethodResolver(); StandardEvaluationContext evaluationContext = new StandardEvaluationContext(); + // Nonexistent method MethodExecutor bogus = resolver.resolve(evaluationContext, proxy, "bogus", List.of()); assertThat(bogus).as("MethodExecutor for bogus()").isNull(); + + // Method in interface + MethodExecutor run = resolver.resolve(evaluationContext, proxy, "run", List.of()); + assertThat(run).as("MethodExecutor for run()").isNotNull(); + + // Methods in Object MethodExecutor toString = resolver.resolve(evaluationContext, proxy, "toString", List.of()); assertThat(toString).as("MethodExecutor for toString()").isNotNull(); MethodExecutor hashCode = resolver.resolve(evaluationContext, proxy, "hashCode", List.of()); assertThat(hashCode).as("MethodExecutor for hashCode()").isNotNull(); + MethodExecutor equals = resolver.resolve(evaluationContext, proxy, "equals", typeDescriptors(Object.class)); + assertThat(equals).as("MethodExecutor for equals()").isNotNull(); } /** * Used to validate the match returned from a compareArguments call. */ private void checkMatch(Class[] inputTypes, Class[] expectedTypes, StandardTypeConverter typeConverter, ArgumentsMatchKind expectedMatchKind) { - ReflectionHelper.ArgumentsMatchInfo matchInfo = ReflectionHelper.compareArguments(getTypeDescriptors(expectedTypes), getTypeDescriptors(inputTypes), typeConverter); + ReflectionHelper.ArgumentsMatchInfo matchInfo = ReflectionHelper.compareArguments(typeDescriptors(expectedTypes), typeDescriptors(inputTypes), typeConverter); if (expectedMatchKind == null) { assertThat(matchInfo).as("Did not expect them to match in any way").isNull(); } @@ -408,47 +416,42 @@ public class ReflectionHelperTests extends AbstractExpressionTests { /** * Used to validate the match returned from a compareArguments call. */ - private void checkMatch2(Class[] inputTypes, Class[] expectedTypes, StandardTypeConverter typeConverter, ArgumentsMatchKind expectedMatchKind) { - ReflectionHelper.ArgumentsMatchInfo matchInfo = ReflectionHelper.compareArgumentsVarargs(getTypeDescriptors(expectedTypes), getTypeDescriptors(inputTypes), typeConverter); + private static void checkMatch2(Class[] inputTypes, Class[] expectedTypes, + StandardTypeConverter typeConverter, ArgumentsMatchKind expectedMatchKind) { + + ReflectionHelper.ArgumentsMatchInfo matchInfo = + ReflectionHelper.compareArgumentsVarargs(typeDescriptors(expectedTypes), typeDescriptors(inputTypes), typeConverter); if (expectedMatchKind == null) { assertThat(matchInfo).as("Did not expect them to match in any way: " + matchInfo).isNull(); } else { assertThat(matchInfo).as("Should not be a null match").isNotNull(); - } - - if (expectedMatchKind == ArgumentsMatchKind.EXACT) { - assertThat(matchInfo.isExactMatch()).isTrue(); - } - else if (expectedMatchKind == ArgumentsMatchKind.CLOSE) { - assertThat(matchInfo.isCloseMatch()).isTrue(); - } - else if (expectedMatchKind == ArgumentsMatchKind.REQUIRES_CONVERSION) { - assertThat(matchInfo.isMatchRequiringConversion()).as("expected to be a match requiring conversion, but was " + matchInfo).isTrue(); + switch (expectedMatchKind) { + case EXACT -> assertThat(matchInfo.isExactMatch()).isTrue(); + case CLOSE -> assertThat(matchInfo.isCloseMatch()).isTrue(); + case REQUIRES_CONVERSION -> assertThat(matchInfo.isMatchRequiringConversion()) + .as("expected to be a match requiring conversion, but was " + matchInfo).isTrue(); + } } } - private void checkArguments(Object[] args, Object... expected) { + private static void checkArguments(Object[] args, Object... expected) { assertThat(args).hasSize(expected.length); for (int i = 0; i < expected.length; i++) { - checkArgument(expected[i],args[i]); + checkArgument(expected[i], args[i]); } } - private void checkArgument(Object expected, Object actual) { + private static void checkArgument(Object expected, Object actual) { assertThat(actual).isEqualTo(expected); } - private List getTypeDescriptors(Class... types) { - List typeDescriptors = new ArrayList<>(types.length); - for (Class type : types) { - typeDescriptors.add(TypeDescriptor.valueOf(type)); - } - return typeDescriptors; + private static List typeDescriptors(Class... types) { + return Arrays.stream(types).map(TypeDescriptor::valueOf).toList(); } - public interface TestInterface { + interface TestInterface { void oneArg(String arg1); diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/accept/RequestedContentTypeResolverBuilder.java b/spring-webflux/src/main/java/org/springframework/web/reactive/accept/RequestedContentTypeResolverBuilder.java index c85a021351..c004882caf 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/accept/RequestedContentTypeResolverBuilder.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/accept/RequestedContentTypeResolverBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2023 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.