• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.fasterxml.jackson.databind.module;
2 
3 import java.lang.reflect.Modifier;
4 import java.util.*;
5 
6 import com.fasterxml.jackson.databind.AbstractTypeResolver;
7 import com.fasterxml.jackson.databind.BeanDescription;
8 import com.fasterxml.jackson.databind.DeserializationConfig;
9 import com.fasterxml.jackson.databind.JavaType;
10 import com.fasterxml.jackson.databind.type.ClassKey;
11 
12 /**
13  * Simple {@link AbstractTypeResolver} implementation, which is
14  * based on static mapping from abstract super types into
15  * sub types (concrete or abstract), but retaining generic
16  * parameterization.
17  * Can be used for things like specifying which implementation of
18  * {@link java.util.Collection} to use:
19  *<pre>
20  *  SimpleAbstractTypeResolver resolver = new SimpleAbstractTypeResolver();
21  *  // To make all properties declared as Collection, List, to LinkedList
22  *  resolver.addMapping(Collection.class, LinkedList.class);
23  *  resolver.addMapping(List.class, LinkedList.class);
24  *</pre>
25  * Can also be used as an alternative to per-class annotations when defining
26  * concrete implementations; however, only works with abstract types (since
27  * this is only called for abstract types)
28  */
29 public class SimpleAbstractTypeResolver
30     extends AbstractTypeResolver
31     implements java.io.Serializable
32 {
33     private static final long serialVersionUID = 1L;
34 
35     /**
36      * Mappings from super types to subtypes
37      */
38     protected final HashMap<ClassKey,Class<?>> _mappings = new HashMap<ClassKey,Class<?>>();
39 
40     /**
41      * Method for adding a mapping from super type to specific subtype.
42      * Arguments will be checked by method, to ensure that <code>superType</code>
43      * is abstract (since resolver is never called for concrete classes);
44      * as well as to ensure that there is supertype/subtype relationship
45      * (to ensure there won't be cycles during resolution).
46      *
47      * @param superType Abstract type to resolve
48      * @param subType Sub-class of superType, to map superTo to
49      *
50      * @return This resolver, to allow chaining of initializations
51      */
addMapping(Class<T> superType, Class<? extends T> subType)52     public <T> SimpleAbstractTypeResolver addMapping(Class<T> superType, Class<? extends T> subType)
53     {
54         // Sanity checks, just in case someone tries to force typing...
55         if (superType == subType) {
56             throw new IllegalArgumentException("Cannot add mapping from class to itself");
57         }
58         if (!superType.isAssignableFrom(subType)) {
59             throw new IllegalArgumentException("Cannot add mapping from class "+superType.getName()
60                     +" to "+subType.getName()+", as latter is not a subtype of former");
61         }
62         if (!Modifier.isAbstract(superType.getModifiers())) {
63             throw new IllegalArgumentException("Cannot add mapping from class "+superType.getName()
64                     +" since it is not abstract");
65         }
66         _mappings.put(new ClassKey(superType), subType);
67         return this;
68     }
69 
70     @Override
findTypeMapping(DeserializationConfig config, JavaType type)71     public JavaType findTypeMapping(DeserializationConfig config, JavaType type)
72     {
73         // this is the main mapping base, so let's
74         Class<?> src = type.getRawClass();
75         Class<?> dst = _mappings.get(new ClassKey(src));
76         if (dst == null) {
77             return null;
78         }
79         // 09-Aug-2015, tatu: Instead of direct call via JavaType, better use TypeFactory
80         return config.getTypeFactory().constructSpecializedType(type, dst);
81     }
82 
83     @Override
84     @Deprecated
resolveAbstractType(DeserializationConfig config, JavaType type)85     public JavaType resolveAbstractType(DeserializationConfig config, JavaType type){
86         // never materialize anything, so:
87         return null;
88     }
89 
90     @Override
resolveAbstractType(DeserializationConfig config, BeanDescription typeDesc)91     public JavaType resolveAbstractType(DeserializationConfig config,
92             BeanDescription typeDesc) {
93         // never materialize anything, so:
94         return null;
95     }
96 }
97