package org.springframework.data.mapping.model;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.WeakHashMap;
import org.springframework.util.Assert;
public class SimpleTypeHolder {
private static final Set<Class<?>> DEFAULTS = new HashSet<Class<?>>() {
private static final long serialVersionUID = -1738594126505221500L;
{
add(boolean.class);
add(boolean[].class);
add(long.class);
add(long[].class);
add(short.class);
add(short[].class);
add(int.class);
add(int[].class);
add(byte.class);
add(byte[].class);
add(float.class);
add(float[].class);
add(double.class);
add(double[].class);
add(char.class);
add(char[].class);
add(Boolean.class);
add(Long.class);
add(Short.class);
add(Integer.class);
add(Byte.class);
add(Float.class);
add(Double.class);
add(Character.class);
add(String.class);
add(Date.class);
add(Locale.class);
add(Class.class);
add(Enum.class);
}
};
public static final SimpleTypeHolder DEFAULT = new SimpleTypeHolder();
private volatile Map<Class<?>, Boolean> simpleTypes;
protected SimpleTypeHolder() {
this(Collections.emptySet(), true);
}
public SimpleTypeHolder(Set<? extends Class<?>> customSimpleTypes, boolean registerDefaults) {
Assert.notNull(customSimpleTypes, "CustomSimpleTypes must not be null!");
this.simpleTypes = new WeakHashMap<>(customSimpleTypes.size() + DEFAULTS.size());
register(customSimpleTypes);
if (registerDefaults) {
register(DEFAULTS);
}
}
public SimpleTypeHolder(Set<? extends Class<?>> customSimpleTypes, SimpleTypeHolder source) {
Assert.notNull(customSimpleTypes, "CustomSimpleTypes must not be null!");
Assert.notNull(source, "SourceTypeHolder must not be null!");
this.simpleTypes = new WeakHashMap<>(customSimpleTypes.size() + source.simpleTypes.size());
register(customSimpleTypes);
registerCachePositives(source.simpleTypes);
}
private void registerCachePositives(Map<Class<?>, Boolean> source) {
for (Entry<Class<?>, Boolean> entry : source.entrySet()) {
if (!entry.getValue()) {
continue;
}
this.simpleTypes.put(entry.getKey(), true);
}
}
public boolean isSimpleType(Class<?> type) {
Assert.notNull(type, "Type must not be null!");
Map<Class<?>, Boolean> localSimpleTypes = this.simpleTypes;
Boolean isSimpleType = localSimpleTypes.get(type);
if (Object.class.equals(type) || Enum.class.isAssignableFrom(type)) {
return true;
}
if (isSimpleType != null) {
return isSimpleType;
}
String typeName = type.getName();
if (typeName.startsWith("java.lang") || type.getName().startsWith("java.time")) {
return true;
}
for (Class<?> simpleType : localSimpleTypes.keySet()) {
if (simpleType.isAssignableFrom(type)) {
isSimpleType = localSimpleTypes.get(simpleType);
this.simpleTypes = put(localSimpleTypes, type, isSimpleType);
return isSimpleType;
}
}
this.simpleTypes = put(localSimpleTypes, type, false);
return false;
}
private void register(Collection<? extends Class<?>> types) {
types.forEach(customSimpleType -> this.simpleTypes.put(customSimpleType, true));
}
private static Map<Class<?>, Boolean> put(Map<Class<?>, Boolean> simpleTypes, Class<?> type, boolean isSimpleType) {
Map<Class<?>, Boolean> copy = new WeakHashMap<>(simpleTypes);
copy.put(type, isSimpleType);
return copy;
}
}