From c2cc55eacc544f0f1f6591f5c54b865f2a6cc348 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 14 Jun 2023 09:31:35 +0200 Subject: [PATCH] Consider UUID as simple value type with concise toString output Closes gh-30661 (cherry picked from commit 927d27b1212e3b278c619f72003e6281329d6914) --- .../org/springframework/util/ObjectUtils.java | 22 ++++++------- .../util/ObjectUtilsTests.java | 33 +++++++++++-------- 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/util/ObjectUtils.java b/spring-core/src/main/java/org/springframework/util/ObjectUtils.java index e83adf2b1a..c2443857c3 100644 --- a/spring-core/src/main/java/org/springframework/util/ObjectUtils.java +++ b/spring-core/src/main/java/org/springframework/util/ObjectUtils.java @@ -27,6 +27,7 @@ import java.util.Locale; import java.util.Map; import java.util.Optional; import java.util.StringJoiner; +import java.util.UUID; import org.springframework.lang.Nullable; @@ -926,14 +927,15 @@ public abstract class ObjectUtils { *
  • Potentially {@linkplain StringUtils#truncate(CharSequence) truncated string} * if {@code obj} is a {@link String} or {@link CharSequence}
  • *
  • Potentially {@linkplain StringUtils#truncate(CharSequence) truncated string} - * if {@code obj} is a simple type whose {@code toString()} method returns - * a non-null value.
  • + * if {@code obj} is a simple value type whose {@code toString()} method + * returns a non-null value. *
  • Otherwise, a string representation of the object's type name concatenated * with {@code @} and a hex string form of the object's identity hash code
  • * - *

    In the context of this method, a simple type is any of the following: - * a primitive wrapper (excluding {@link Void}), an {@link Enum}, a {@link Number}, - * a {@link Date}, a {@link Temporal}, a {@link URI}, a {@link URL}, or a {@link Locale}. + *

    In the context of this method, a simple value type is any of the following: + * a primitive wrapper (excluding {@code Void}), an {@code Enum}, a {@code Number}, + * a {@code Date}, a {@code Temporal}, a {@code UUID}, a {@code URI}, a {@code URL}, + * or a {@code Locale}. * @param obj the object to build a string representation for * @return a concise string representation of the supplied object * @since 5.3.27 @@ -961,13 +963,8 @@ public abstract class ObjectUtils { } /** - * Copy of {@link org.springframework.beans.BeanUtils#isSimpleValueType(Class)}. - *

    Check if the given type represents a "simple" value type: a primitive or - * primitive wrapper, an enum, a String or other CharSequence, a Number, a - * Date, a Temporal, a URI, a URL, a Locale, or a Class. - *

    {@code Void} and {@code void} are not considered simple value types. - * @param type the type to check - * @return whether the given type represents a "simple" value type + * Derived from {@link org.springframework.beans.BeanUtils#isSimpleValueType}. + * As of 5.3.28, considering {@code UUID} in addition to the bean-level check. */ private static boolean isSimpleValueType(Class type) { return (Void.class != type && void.class != type && @@ -977,6 +974,7 @@ public abstract class ObjectUtils { Number.class.isAssignableFrom(type) || Date.class.isAssignableFrom(type) || Temporal.class.isAssignableFrom(type) || + UUID.class == type || URI.class == type || URL.class == type || Locale.class == type || diff --git a/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java b/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java index f6722c44eb..00f0a392b4 100644 --- a/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java +++ b/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java @@ -30,6 +30,7 @@ import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Set; +import java.util.UUID; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -826,6 +827,17 @@ class ObjectUtilsTests { .withMessage("Constant [bogus] does not exist in enum type org.springframework.util.ObjectUtilsTests$Tropes"); } + + private static void assertEqualHashCodes(int expected, Object array) { + int actual = ObjectUtils.nullSafeHashCode(array); + assertThat(actual).isEqualTo(expected); + assertThat(array.hashCode()).isNotEqualTo(actual); + } + + + enum Tropes {FOO, BAR, baz} + + @Nested class NullSafeConciseToStringTests { @@ -887,7 +899,13 @@ class ObjectUtilsTests { } @Test - void nullSafeConciseToStringForUri() { + void nullSafeConciseToStringForUUID() { + UUID id = UUID.randomUUID(); + assertThat(ObjectUtils.nullSafeConciseToString(id)).isEqualTo(id.toString()); + } + + @Test + void nullSafeConciseToStringForURI() { String uri = "https://www.example.com/?foo=1&bar=2&baz=3"; assertThat(ObjectUtils.nullSafeConciseToString(URI.create(uri))).isEqualTo(uri); @@ -899,7 +917,7 @@ class ObjectUtilsTests { } @Test - void nullSafeConciseToStringForUrl() throws Exception { + void nullSafeConciseToStringForURL() throws Exception { String url = "https://www.example.com/?foo=1&bar=2&baz=3"; assertThat(ObjectUtils.nullSafeConciseToString(new URL(url))).isEqualTo(url); @@ -959,17 +977,6 @@ class ObjectUtilsTests { private String prefix(Class clazz) { return clazz.getTypeName() + "@"; } - } - - private static void assertEqualHashCodes(int expected, Object array) { - int actual = ObjectUtils.nullSafeHashCode(array); - assertThat(actual).isEqualTo(expected); - assertThat(array.hashCode() != actual).isTrue(); - } - - - enum Tropes {FOO, BAR, baz} - }