Skip to content

Commit

Permalink
Consistent simple value type check
Browse files Browse the repository at this point in the history
Includes UUID treatment for data binding and bean dependency checks.

Closes gh-30664
  • Loading branch information
jhoeller committed Jun 14, 2023
1 parent 858ea1a commit ca4de8f
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,10 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URI;
import java.net.URL;
import java.time.temporal.Temporal;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

Expand Down Expand Up @@ -663,26 +658,20 @@ public static boolean isSimpleProperty(Class<?> type) {
}

/**
* 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.
* Check if the given type represents a "simple" value type for
* bean property and data binding purposes:
* a primitive or primitive wrapper, an {@code Enum}, a {@code String}
* or other {@code CharSequence}, a {@code Number}, a {@code Date},
* a {@code Temporal}, a {@code UUID}, a {@code URI}, a {@code URL},
* a {@code Locale}, or a {@code Class}.
* <p>{@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
* @see #isSimpleProperty(Class)
* @see ClassUtils#isSimpleValueType(Class)
*/
public static boolean isSimpleValueType(Class<?> type) {
return (Void.class != type && void.class != type &&
(ClassUtils.isPrimitiveOrWrapper(type) ||
Enum.class.isAssignableFrom(type) ||
CharSequence.class.isAssignableFrom(type) ||
Number.class.isAssignableFrom(type) ||
Date.class.isAssignableFrom(type) ||
Temporal.class.isAssignableFrom(type) ||
URI.class == type ||
URL.class == type ||
Locale.class == type ||
Class.class == type));
return ClassUtils.isSimpleValueType(type);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.UUID;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
Expand Down Expand Up @@ -470,7 +471,8 @@ void spr6063() {
@ValueSource(classes = {
boolean.class, char.class, byte.class, short.class, int.class, long.class, float.class, double.class,
Boolean.class, Character.class, Byte.class, Short.class, Integer.class, Long.class, Float.class, Double.class,
DayOfWeek.class, String.class, LocalDateTime.class, Date.class, URI.class, URL.class, Locale.class, Class.class
DayOfWeek.class, String.class, LocalDateTime.class, Date.class, UUID.class, URI.class, URL.class,
Locale.class, Class.class
})
void isSimpleValueType(Class<?> type) {
assertThat(BeanUtils.isSimpleValueType(type)).as("Type [" + type.getName() + "] should be a simple value type").isTrue();
Expand All @@ -486,8 +488,8 @@ void isNotSimpleValueType(Class<?> type) {
@ValueSource(classes = {
boolean.class, char.class, byte.class, short.class, int.class, long.class, float.class, double.class,
Boolean.class, Character.class, Byte.class, Short.class, Integer.class, Long.class, Float.class, Double.class,
DayOfWeek.class, String.class, LocalDateTime.class, Date.class, URI.class, URL.class, Locale.class, Class.class,
boolean[].class, Boolean[].class, LocalDateTime[].class, Date[].class
DayOfWeek.class, String.class, LocalDateTime.class, Date.class, UUID.class, URI.class, URL.class,
Locale.class, Class.class, boolean[].class, Boolean[].class, LocalDateTime[].class, Date[].class
})
void isSimpleProperty(Class<?> type) {
assertThat(BeanUtils.isSimpleProperty(type)).as("Type [" + type.getName() + "] should be a simple property").isTrue();
Expand Down
34 changes: 34 additions & 0 deletions spring-core/src/main/java/org/springframework/util/ClassUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,26 @@
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.net.URI;
import java.net.URL;
import java.time.temporal.Temporal;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.StringJoiner;
import java.util.UUID;

import org.springframework.lang.Nullable;

Expand Down Expand Up @@ -528,6 +534,34 @@ public static Class<?> resolvePrimitiveIfNecessary(Class<?> clazz) {
return (clazz.isPrimitive() && clazz != void.class ? primitiveTypeToWrapperMap.get(clazz) : clazz);
}

/**
* Delegate for {@link org.springframework.beans.BeanUtils#isSimpleValueType}.
* Also used by {@link ObjectUtils#nullSafeConciseToString}.
* <p>Check if the given type represents a common "simple" value type:
* a primitive or primitive wrapper, an {@code Enum}, a {@code String}
* or other {@code CharSequence}, a {@code Number}, a {@code Date},
* a {@code Temporal}, a {@code UUID}, a {@code URI}, a {@code URL},
* a {@code Locale}, or a {@code Class}.
* <p>{@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
* @since 6.1
*/
public static boolean isSimpleValueType(Class<?> type) {
return (Void.class != type && void.class != type &&
(isPrimitiveOrWrapper(type) ||
Enum.class.isAssignableFrom(type) ||
CharSequence.class.isAssignableFrom(type) ||
Number.class.isAssignableFrom(type) ||
Date.class.isAssignableFrom(type) ||
Temporal.class.isAssignableFrom(type) ||
UUID.class.isAssignableFrom(type) ||
URI.class == type ||
URL.class == type ||
Locale.class == type ||
Class.class == type));
}

/**
* Check if the right-hand side type may be assigned to the left-hand side
* type, assuming setting by reflection. Considers primitive wrapper
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,11 @@
package org.springframework.util;

import java.lang.reflect.Array;
import java.net.URI;
import java.net.URL;
import java.time.temporal.Temporal;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
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;

Expand Down Expand Up @@ -918,6 +912,7 @@ public static String nullSafeToString(@Nullable short[] array) {
* @since 5.3.27
* @see #nullSafeToString(Object)
* @see StringUtils#truncate(CharSequence)
* @see ClassUtils#isSimpleValueType(Class)
*/
public static String nullSafeConciseToString(@Nullable Object obj) {
if (obj == null) {
Expand All @@ -930,7 +925,7 @@ public static String nullSafeConciseToString(@Nullable Object obj) {
return StringUtils.truncate(charSequence);
}
Class<?> type = obj.getClass();
if (isSimpleValueType(type)) {
if (ClassUtils.isSimpleValueType(type)) {
String str = obj.toString();
if (str != null) {
return StringUtils.truncate(str);
Expand All @@ -939,22 +934,4 @@ public static String nullSafeConciseToString(@Nullable Object obj) {
return type.getTypeName() + "@" + getIdentityHexString(obj);
}

/**
* Derived from {@link org.springframework.beans.BeanUtils#isSimpleValueType}.
*/
private static boolean isSimpleValueType(Class<?> type) {
return (Void.class != type && void.class != type &&
(ClassUtils.isPrimitiveOrWrapper(type) ||
Enum.class.isAssignableFrom(type) ||
CharSequence.class.isAssignableFrom(type) ||
Number.class.isAssignableFrom(type) ||
Date.class.isAssignableFrom(type) ||
Temporal.class.isAssignableFrom(type) ||
UUID.class.isAssignableFrom(type) ||
URI.class == type ||
URL.class == type ||
Locale.class == type ||
Class.class == type));
}

}

0 comments on commit ca4de8f

Please sign in to comment.