package com.fasterxml.jackson.databind.module;
import java.lang.reflect.Modifier;
import java.util.*;
import com.fasterxml.jackson.databind.AbstractTypeResolver;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.DeserializationConfig;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.type.ClassKey;
Simple AbstractTypeResolver
implementation, which is based on static mapping from abstract super types into sub types (concrete or abstract), but retaining generic parameterization. Can be used for things like specifying which implementation of Collection
to use: SimpleAbstractTypeResolver resolver = new SimpleAbstractTypeResolver();
// To make all properties declared as Collection, List, to LinkedList
resolver.addMapping(Collection.class, LinkedList.class);
resolver.addMapping(List.class, LinkedList.class);
Can also be used as an alternative to per-class annotations when defining
concrete implementations; however, only works with abstract types (since
this is only called for abstract types)
/**
* Simple {@link AbstractTypeResolver} implementation, which is
* based on static mapping from abstract super types into
* sub types (concrete or abstract), but retaining generic
* parameterization.
* Can be used for things like specifying which implementation of
* {@link java.util.Collection} to use:
*<pre>
* SimpleAbstractTypeResolver resolver = new SimpleAbstractTypeResolver();
* // To make all properties declared as Collection, List, to LinkedList
* resolver.addMapping(Collection.class, LinkedList.class);
* resolver.addMapping(List.class, LinkedList.class);
*</pre>
* Can also be used as an alternative to per-class annotations when defining
* concrete implementations; however, only works with abstract types (since
* this is only called for abstract types)
*/
public class SimpleAbstractTypeResolver
extends AbstractTypeResolver
implements java.io.Serializable
{
private static final long serialVersionUID = 8635483102371490919L;
Mappings from super types to subtypes
/**
* Mappings from super types to subtypes
*/
protected final HashMap<ClassKey,Class<?>> _mappings = new HashMap<ClassKey,Class<?>>();
Method for adding a mapping from super type to specific subtype.
Arguments will be checked by method, to ensure that superType
is abstract (since resolver is never called for concrete classes);
as well as to ensure that there is supertype/subtype relationship
(to ensure there won't be cycles during resolution).
Params: - superType – Abstract type to resolve
- subType – Sub-class of superType, to map superTo to
Returns: This resolver, to allow chaining of initializations
/**
* Method for adding a mapping from super type to specific subtype.
* Arguments will be checked by method, to ensure that <code>superType</code>
* is abstract (since resolver is never called for concrete classes);
* as well as to ensure that there is supertype/subtype relationship
* (to ensure there won't be cycles during resolution).
*
* @param superType Abstract type to resolve
* @param subType Sub-class of superType, to map superTo to
*
* @return This resolver, to allow chaining of initializations
*/
public <T> SimpleAbstractTypeResolver addMapping(Class<T> superType, Class<? extends T> subType)
{
// Sanity checks, just in case someone tries to force typing...
if (superType == subType) {
throw new IllegalArgumentException("Cannot add mapping from class to itself");
}
if (!superType.isAssignableFrom(subType)) {
throw new IllegalArgumentException("Cannot add mapping from class "+superType.getName()
+" to "+subType.getName()+", as latter is not a subtype of former");
}
if (!Modifier.isAbstract(superType.getModifiers())) {
throw new IllegalArgumentException("Cannot add mapping from class "+superType.getName()
+" since it is not abstract");
}
_mappings.put(new ClassKey(superType), subType);
return this;
}
@Override
public JavaType findTypeMapping(DeserializationConfig config, JavaType type)
{
// this is the main mapping base, so let's
Class<?> src = type.getRawClass();
Class<?> dst = _mappings.get(new ClassKey(src));
if (dst == null) {
return null;
}
// 09-Aug-2015, tatu: Instead of direct call via JavaType, better use TypeFactory
return config.getTypeFactory().constructSpecializedType(type, dst);
}
@Override
@Deprecated
public JavaType resolveAbstractType(DeserializationConfig config, JavaType type){
// never materialize anything, so:
return null;
}
@Override
public JavaType resolveAbstractType(DeserializationConfig config,
BeanDescription typeDesc) {
// never materialize anything, so:
return null;
}
}