Merge branch '5.3.x'
# Conflicts: # spring-core/src/main/java/org/springframework/core/annotation/SynthesizedMergedAnnotationInvocationHandler.java # src/eclipse/org.eclipse.jdt.ui.prefs
This commit is contained in:
commit
5ae9217271
|
|
@ -177,7 +177,7 @@ final class SynthesizedMergedAnnotationInvocationHandler<A extends Annotation> i
|
||||||
private String annotationToString() {
|
private String annotationToString() {
|
||||||
String string = this.string;
|
String string = this.string;
|
||||||
if (string == null) {
|
if (string == null) {
|
||||||
StringBuilder builder = new StringBuilder("@").append(this.type.getName()).append('(');
|
StringBuilder builder = new StringBuilder("@").append(getName(this.type)).append('(');
|
||||||
for (int i = 0; i < this.attributes.size(); i++) {
|
for (int i = 0; i < this.attributes.size(); i++) {
|
||||||
Method attribute = this.attributes.get(i);
|
Method attribute = this.attributes.get(i);
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
|
|
@ -194,15 +194,43 @@ final class SynthesizedMergedAnnotationInvocationHandler<A extends Annotation> i
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method currently does not address the following issues which we may
|
||||||
|
* choose to address at a later point in time.
|
||||||
|
*
|
||||||
|
* <ul>
|
||||||
|
* <li>non-ASCII, non-visible, and non-printable characters within a character
|
||||||
|
* or String literal are not escaped.</li>
|
||||||
|
* <li>formatting for float and double values does not take into account whether
|
||||||
|
* a value is not a number (NaN) or infinite.</li>
|
||||||
|
* </ul>
|
||||||
|
* @param value the attribute value to format
|
||||||
|
* @return the formatted string representation
|
||||||
|
*/
|
||||||
private String toString(Object value) {
|
private String toString(Object value) {
|
||||||
if (value instanceof String str) {
|
if (value instanceof String str) {
|
||||||
return '"' + str + '"';
|
return '"' + str + '"';
|
||||||
}
|
}
|
||||||
|
if (value instanceof Character) {
|
||||||
|
return '\'' + value.toString() + '\'';
|
||||||
|
}
|
||||||
|
if (value instanceof Byte) {
|
||||||
|
return String.format("(byte) 0x%02X", value);
|
||||||
|
}
|
||||||
|
if (value instanceof Long longValue) {
|
||||||
|
return Long.toString(longValue) + 'L';
|
||||||
|
}
|
||||||
|
if (value instanceof Float floatValue) {
|
||||||
|
return Float.toString(floatValue) + 'f';
|
||||||
|
}
|
||||||
|
if (value instanceof Double doubleValue) {
|
||||||
|
return Double.toString(doubleValue) + 'd';
|
||||||
|
}
|
||||||
if (value instanceof Enum<?> e) {
|
if (value instanceof Enum<?> e) {
|
||||||
return e.name();
|
return e.name();
|
||||||
}
|
}
|
||||||
if (value instanceof Class<?> clazz) {
|
if (value instanceof Class<?> clazz) {
|
||||||
return clazz.getName() + ".class";
|
return getName(clazz) + ".class";
|
||||||
}
|
}
|
||||||
if (value.getClass().isArray()) {
|
if (value.getClass().isArray()) {
|
||||||
StringBuilder builder = new StringBuilder("{");
|
StringBuilder builder = new StringBuilder("{");
|
||||||
|
|
@ -277,6 +305,11 @@ final class SynthesizedMergedAnnotationInvocationHandler<A extends Annotation> i
|
||||||
return (A) Proxy.newProxyInstance(classLoader, interfaces, handler);
|
return (A) Proxy.newProxyInstance(classLoader, interfaces, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String getName(Class<?> clazz) {
|
||||||
|
String canonicalName = clazz.getCanonicalName();
|
||||||
|
return (canonicalName != null ? canonicalName : clazz.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private static boolean isVisible(ClassLoader classLoader, Class<?> interfaceClass) {
|
private static boolean isVisible(ClassLoader classLoader, Class<?> interfaceClass) {
|
||||||
if (classLoader == interfaceClass.getClassLoader()) {
|
if (classLoader == interfaceClass.getClassLoader()) {
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ import java.util.stream.Stream;
|
||||||
|
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.condition.JRE;
|
||||||
|
|
||||||
import org.springframework.core.Ordered;
|
import org.springframework.core.Ordered;
|
||||||
import org.springframework.core.annotation.MergedAnnotation.Adapt;
|
import org.springframework.core.annotation.MergedAnnotation.Adapt;
|
||||||
|
|
@ -1883,15 +1884,44 @@ class MergedAnnotationsTests {
|
||||||
|
|
||||||
// Formatting common to Spring and JDK 9+
|
// Formatting common to Spring and JDK 9+
|
||||||
assertThat(string)
|
assertThat(string)
|
||||||
.startsWith("@" + RequestMapping.class.getName() + "(")
|
.contains("value={\"/test\"}", "path={\"/test\"}", "name=\"bar\"", "ch='X'", "chars={'X'}")
|
||||||
.contains("value={\"/test\"}", "path={\"/test\"}", "name=\"bar\"", "clazz=java.lang.Object.class")
|
|
||||||
.endsWith(")");
|
.endsWith(")");
|
||||||
|
|
||||||
if (webMapping instanceof SynthesizedAnnotation) {
|
if (webMapping instanceof SynthesizedAnnotation) {
|
||||||
assertThat(string).as("Spring uses Enum#name()").contains("method={GET, POST}");
|
assertThat(string).as("Spring formatting")
|
||||||
|
.startsWith("@org.springframework.core.annotation.MergedAnnotationsTests.RequestMapping(")
|
||||||
|
.contains("method={GET, POST}",
|
||||||
|
"clazz=org.springframework.core.annotation.MergedAnnotationsTests.RequestMethod.class",
|
||||||
|
"classes={int[][].class, org.springframework.core.annotation.MergedAnnotationsTests.RequestMethod[].class}",
|
||||||
|
"byteValue=(byte) 0xFF", "bytes={(byte) 0xFF}",
|
||||||
|
"shortValue=9876", "shorts={9876}",
|
||||||
|
"longValue=42L", "longs={42L}",
|
||||||
|
"floatValue=3.14f", "floats={3.14f}",
|
||||||
|
"doubleValue=99.999d", "doubles={99.999d}"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assertThat(string).as("JDK uses Enum#toString()").contains("method={method: get, method: post}");
|
assertThat(string).as("JDK 9-18 formatting")
|
||||||
|
.startsWith("@org.springframework.core.annotation.MergedAnnotationsTests$RequestMapping(")
|
||||||
|
.contains("method={method: get, method: post}",
|
||||||
|
"clazz=org.springframework.core.annotation.MergedAnnotationsTests$RequestMethod.class",
|
||||||
|
"classes={int[][].class, org.springframework.core.annotation.MergedAnnotationsTests$RequestMethod[].class}",
|
||||||
|
"shortValue=9876", "shorts={9876}",
|
||||||
|
"floatValue=3.14f", "floats={3.14f}",
|
||||||
|
"doubleValue=99.999", "doubles={99.999}"
|
||||||
|
);
|
||||||
|
if (JRE.currentVersion().ordinal() < JRE.JAVA_14.ordinal()) {
|
||||||
|
assertThat(string).as("JDK 9-13 formatting")
|
||||||
|
.contains("longValue=42", "longs={42}",
|
||||||
|
"byteValue=-1", "bytes={-1}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assertThat(string).as("JDK 14+ formatting")
|
||||||
|
.contains("longValue=42L", "longs={42L}",
|
||||||
|
"byteValue=(byte)0xff", "bytes={(byte)0xff}"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2985,8 +3015,29 @@ class MergedAnnotationsTests {
|
||||||
|
|
||||||
RequestMethod[] method() default {};
|
RequestMethod[] method() default {};
|
||||||
|
|
||||||
// clazz is only used for testing annotation toString() implementations
|
// ---------------------------------------------------------------------
|
||||||
Class<?> clazz() default Object.class;
|
// All remaining attributes declare default values that are used solely
|
||||||
|
// for the purpose of testing the toString() implementations for annotations.
|
||||||
|
Class<?> clazz() default RequestMethod.class;
|
||||||
|
Class<?>[] classes() default {int[][].class, RequestMethod[].class};
|
||||||
|
|
||||||
|
char ch() default 'X';
|
||||||
|
char[] chars() default {'X'};
|
||||||
|
|
||||||
|
byte byteValue() default (byte) 0xFF;
|
||||||
|
byte[] bytes() default {(byte) 0xFF};
|
||||||
|
|
||||||
|
short shortValue() default 9876;
|
||||||
|
short[] shorts() default {9876};
|
||||||
|
|
||||||
|
long longValue() default 42L;
|
||||||
|
long[] longs() default {42L};
|
||||||
|
|
||||||
|
float floatValue() default 3.14F;
|
||||||
|
float[] floats() default {3.14F};
|
||||||
|
|
||||||
|
double doubleValue() default 99.999D;
|
||||||
|
double[] doubles() default {99.999D};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2020 the original author or authors.
|
* Copyright 2002-2022 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -72,8 +72,8 @@ class BootstrapUtilsTests {
|
||||||
assertThatIllegalStateException().isThrownBy(() ->
|
assertThatIllegalStateException().isThrownBy(() ->
|
||||||
resolveTestContextBootstrapper(bootstrapContext))
|
resolveTestContextBootstrapper(bootstrapContext))
|
||||||
.withMessageContaining("Configuration error: found multiple declarations of @BootstrapWith")
|
.withMessageContaining("Configuration error: found multiple declarations of @BootstrapWith")
|
||||||
.withMessageContaining(FooBootstrapper.class.getName())
|
.withMessageContaining(FooBootstrapper.class.getCanonicalName())
|
||||||
.withMessageContaining(BarBootstrapper.class.getName());
|
.withMessageContaining(BarBootstrapper.class.getCanonicalName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue