Browse Source

Do not invoke [Map|Collection].isEmpty() in nullSafeConciseToString()

gh-30811 introduced explicit support for collections and maps in
ObjectUtils.nullSafeConciseToString() by invoking isEmpty() on a Map or
Collection to determine which concise string representation should be
used. However, this caused a regression in which an exception was
thrown if the Map or Collection was a proxy generated by
AbstractFactoryBean to support <util:set />, <util:list />, and
<util:map /> in XML configuration.

This commit addresses this set of regressions by always returning
"[...]" or "{...}" for a Collection or Map, respectively, disregarding
whether the map is empty or not.

Closes gh-31156
pull/31598/head
Sam Brannen 2 years ago
parent
commit
ddcae04ad5
  1. 20
      spring-core/src/main/java/org/springframework/util/ObjectUtils.java
  2. 6
      spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java

20
spring-core/src/main/java/org/springframework/util/ObjectUtils.java

@ -70,8 +70,8 @@ public abstract class ObjectUtils { @@ -70,8 +70,8 @@ public abstract class ObjectUtils {
private static final String ARRAY_ELEMENT_SEPARATOR = ", ";
private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
private static final String NON_EMPTY_ARRAY = ARRAY_START + "..." + ARRAY_END;
private static final String EMPTY_COLLECTION = "[]";
private static final String NON_EMPTY_COLLECTION = "[...]";
private static final String COLLECTION = "[...]";
private static final String MAP = NON_EMPTY_ARRAY;
/**
@ -938,10 +938,9 @@ public abstract class ObjectUtils { @@ -938,10 +938,9 @@ public abstract class ObjectUtils {
* <li>{@code"Optional[<concise-string>]"} if {@code obj} is a non-empty {@code Optional},
* where {@code <concise-string>} is the result of invoking {@link #nullSafeConciseToString}
* on the object contained in the {@code Optional}</li>
* <li>{@code "{}"} if {@code obj} is an empty array or {@link Map}</li>
* <li>{@code "{...}"} if {@code obj} is a non-empty array or {@link Map}</li>
* <li>{@code "[]"} if {@code obj} is an empty {@link Collection}</li>
* <li>{@code "[...]"} if {@code obj} is a non-empty {@link Collection}</li>
* <li>{@code "{}"} if {@code obj} is an empty array</li>
* <li>{@code "{...}"} if {@code obj} is a {@link Map} or a non-empty array</li>
* <li>{@code "[...]"} if {@code obj} is a {@link Collection}</li>
* <li>{@linkplain Class#getName() Class name} if {@code obj} is a {@link Class}</li>
* <li>{@linkplain Charset#name() Charset name} if {@code obj} is a {@link Charset}</li>
* <li>{@linkplain TimeZone#getID() TimeZone ID} if {@code obj} is a {@link TimeZone}</li>
@ -977,12 +976,11 @@ public abstract class ObjectUtils { @@ -977,12 +976,11 @@ public abstract class ObjectUtils {
if (obj.getClass().isArray()) {
return (Array.getLength(obj) == 0 ? EMPTY_ARRAY : NON_EMPTY_ARRAY);
}
if (obj instanceof Collection<?>) {
return (((Collection<?>) obj).isEmpty() ? EMPTY_COLLECTION : NON_EMPTY_COLLECTION);
if (obj instanceof Collection) {
return COLLECTION;
}
if (obj instanceof Map<?, ?>) {
// EMPTY_ARRAY and NON_EMPTY_ARRAY are also used for maps.
return (((Map<?, ?>) obj).isEmpty() ? EMPTY_ARRAY : NON_EMPTY_ARRAY);
if (obj instanceof Map) {
return MAP;
}
if (obj instanceof Class<?>) {
return ((Class<?>) obj).getName();

6
spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java

@ -1078,8 +1078,8 @@ class ObjectUtilsTests { @@ -1078,8 +1078,8 @@ class ObjectUtilsTests {
void nullSafeConciseToStringForEmptyCollections() {
List<String> list = Collections.emptyList();
Set<Integer> set = Collections.emptySet();
assertThat(ObjectUtils.nullSafeConciseToString(list)).isEqualTo("[]");
assertThat(ObjectUtils.nullSafeConciseToString(set)).isEqualTo("[]");
assertThat(ObjectUtils.nullSafeConciseToString(list)).isEqualTo("[...]");
assertThat(ObjectUtils.nullSafeConciseToString(set)).isEqualTo("[...]");
}
@Test
@ -1094,7 +1094,7 @@ class ObjectUtilsTests { @@ -1094,7 +1094,7 @@ class ObjectUtilsTests {
@Test
void nullSafeConciseToStringForEmptyMaps() {
Map<String, Object> map = Collections.emptyMap();
assertThat(ObjectUtils.nullSafeConciseToString(map)).isEqualTo("{}");
assertThat(ObjectUtils.nullSafeConciseToString(map)).isEqualTo("{...}");
}
@Test

Loading…
Cancel
Save