EclipseMapDeserializers.java
package tools.jackson.datatype.eclipsecollections.deser.map;
import tools.jackson.databind.JavaType;
import tools.jackson.databind.type.TypeBindings;
import tools.jackson.databind.type.TypeFactory;
import tools.jackson.datatype.primitive_collections_base.deser.map.KeyHandler;
import tools.jackson.datatype.primitive_collections_base.deser.map.MapDeserializer;
import tools.jackson.datatype.primitive_collections_base.deser.map.TypeHandlerPair;
import tools.jackson.datatype.primitive_collections_base.deser.map.ValueHandler;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
public final class EclipseMapDeserializers
{
private static final Map<Class<?>, Entry<?, ?, ?, ?>> ENTRIES = new HashMap<>();
public static MapDeserializer<?, ?, ?, ?> createDeserializer(JavaType type) {
Class<?> rawClass = type.getRawClass();
Entry<?, ?, ?, ?> entry = ENTRIES.get(rawClass);
if (entry == null) {
return null;
}
return entry.createDeserializer(type);
}
@SuppressWarnings("unused") // Used from TypeHandlerPairs
static <T, I> void add(
boolean refKey, boolean refValue, Class<T> type,
TypeHandlerPair<I, ?, ?> handlerPair, Function<I, T> finish
) {
if (ENTRIES.putIfAbsent(type, new Entry<>(refKey, refValue, handlerPair, finish)) != null) {
throw new IllegalStateException();
}
}
private static final class Entry<T, I, K extends KeyHandler<K>, V extends ValueHandler<V>> {
private final boolean refKey;
private final boolean refValue;
final TypeHandlerPair<I, K, V> typeHandlerPair;
// null if this is the identity function
final Function<I, T> finish;
Entry(boolean refKey, boolean refValue,
TypeHandlerPair<I, K, V> typeHandlerPair, Function<I, T> finish) {
this.refKey = refKey;
this.refValue = refValue;
this.typeHandlerPair = Objects.requireNonNull(typeHandlerPair);
this.finish = finish;
}
MapDeserializer<T, I, K, V> createDeserializer(JavaType type) {
List<JavaType> typeParameters = null;
TypeBindings bindings = type.getBindings();
if (bindings != null) {
typeParameters = bindings.getTypeParameters();
}
JavaType keyType;
JavaType valueType;
if (typeParameters != null && !typeParameters.isEmpty()) {
if (refKey && refValue) {
if (typeParameters.size() != 2) {
throw new IllegalStateException(
"type parameters: " + typeParameters + ", expected exactly two");
}
} else if (refKey || refValue) {
if (typeParameters.size() != 1) {
throw new IllegalStateException(
"type parameters: " + typeParameters + ", expected exactly one");
}
}
keyType = refKey ? typeParameters.get(0) : null;
valueType = refValue ? typeParameters.get(typeParameters.size() - 1) : null;
} else {
// `type` is a raw type
keyType = TypeFactory.unknownType();
valueType = TypeFactory.unknownType();
}
return MapDeserializer.create(keyType, valueType, typeHandlerPair, finish);
}
}
static {
TypeHandlerPairs.addDeserializers();
}
private EclipseMapDeserializers() {
}
}