• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.fasterxml.jackson.databind.jsontype;
2 
3 import java.io.IOException;
4 
5 import com.fasterxml.jackson.core.*;
6 import com.fasterxml.jackson.databind.BeanProperty;
7 import com.fasterxml.jackson.databind.DeserializationContext;
8 import com.fasterxml.jackson.databind.JavaType;
9 import com.fasterxml.jackson.databind.JsonDeserializer;
10 import com.fasterxml.jackson.annotation.JsonTypeInfo.As;
11 
12 
13 /**
14  * Interface for deserializing type information from JSON content, to
15  * type-safely deserialize data into correct polymorphic instance
16  * (when type inclusion has been enabled for type handled).
17  *<p>
18  * Separate deserialization methods are needed because serialized
19  * form for inclusion mechanism {@link As#PROPERTY}
20  * is slighty different if value is not expressed as JSON Object:
21  * and as such both type deserializer and serializer need to
22  * JSON Object form (array, object or other (== scalar)) being used.
23  */
24 public abstract class TypeDeserializer
25 {
26     /*
27     /**********************************************************
28     /* Initialization
29     /**********************************************************
30      */
31 
32     /**
33      * Method called to create contextual version, to be used for
34      * values of given property. This may be the type itself
35      * (as is the case for bean properties), or values contained
36      * (for {@link java.util.Collection} or {@link java.util.Map}
37      * valued properties).
38      */
forProperty(BeanProperty prop)39     public abstract TypeDeserializer forProperty(BeanProperty prop);
40 
41     /*
42     /**********************************************************
43     /* Introspection
44     /**********************************************************
45      */
46 
47     /**
48      * Accessor for type information inclusion method
49      * that deserializer uses; indicates how type information
50      * is (expected to be) embedded in JSON input.
51      */
getTypeInclusion()52     public abstract As getTypeInclusion();
53 
54     /**
55      * Name of property that contains type information, if
56      * property-based inclusion is used.
57      */
getPropertyName()58     public abstract String getPropertyName();
59 
60     /**
61      * Accessor for object that handles conversions between
62      * types and matching type ids.
63      */
getTypeIdResolver()64     public abstract TypeIdResolver getTypeIdResolver();
65 
66     /**
67      * Accessor for "default implementation" type; optionally defined
68      * class to use in cases where type id is not
69      * accessible for some reason (either missing, or cannot be
70      * resolved)
71      */
getDefaultImpl()72     public abstract Class<?> getDefaultImpl();
73 
74     /*
75     /**********************************************************
76     /* Type deserialization methods
77     /**********************************************************
78      */
79 
80     /**
81      * Method called to let this type deserializer handle
82      * deserialization of "typed" object, when value itself
83      * is serialized as JSON Object (regardless of Java type).
84      * Method needs to figure out intended
85      * polymorphic type, locate {@link JsonDeserializer} to use, and
86      * call it with JSON data to deserializer (which does not contain
87      * type information).
88      */
deserializeTypedFromObject(JsonParser p, DeserializationContext ctxt)89     public abstract Object deserializeTypedFromObject(JsonParser p, DeserializationContext ctxt) throws IOException;
90 
91     /**
92      * Method called to let this type deserializer handle
93      * deserialization of "typed" object, when value itself
94      * is serialized as JSON Array (regardless of Java type).
95      * Method needs to figure out intended
96      * polymorphic type, locate {@link JsonDeserializer} to use, and
97      * call it with JSON data to deserializer (which does not contain
98      * type information).
99      */
deserializeTypedFromArray(JsonParser p, DeserializationContext ctxt)100     public abstract Object deserializeTypedFromArray(JsonParser p, DeserializationContext ctxt) throws IOException;
101 
102     /**
103      * Method called to let this type deserializer handle
104      * deserialization of "typed" object, when value itself
105      * is serialized as a scalar JSON value (something other
106      * than Array or Object), regardless of Java type.
107      * Method needs to figure out intended
108      * polymorphic type, locate {@link JsonDeserializer} to use, and
109      * call it with JSON data to deserializer (which does not contain
110      * type information).
111      */
deserializeTypedFromScalar(JsonParser p, DeserializationContext ctxt)112     public abstract Object deserializeTypedFromScalar(JsonParser p, DeserializationContext ctxt) throws IOException;
113 
114     /**
115      * Method called to let this type deserializer handle
116      * deserialization of "typed" object, when value itself
117      * may have been serialized using any kind of JSON value
118      * (Array, Object, scalar). Should only be called if JSON
119      * serialization is polymorphic (not Java type); for example when
120      * using JSON node representation, or "untyped" Java object
121      * (which may be Map, Collection, wrapper/primitive etc).
122      */
deserializeTypedFromAny(JsonParser p, DeserializationContext ctxt)123     public abstract Object deserializeTypedFromAny(JsonParser p, DeserializationContext ctxt) throws IOException;
124 
125     /*
126     /**********************************************************
127     /* Shared helper methods
128     /**********************************************************
129      */
130 
131     /**
132      * Helper method used to check if given parser might be pointing to
133      * a "natural" value, and one that would be acceptable as the
134      * result value (compatible with declared base type)
135      */
deserializeIfNatural(JsonParser p, DeserializationContext ctxt, JavaType baseType)136     public static Object deserializeIfNatural(JsonParser p, DeserializationContext ctxt, JavaType baseType) throws IOException {
137         return deserializeIfNatural(p, ctxt, baseType.getRawClass());
138     }
139 
140     @SuppressWarnings("incomplete-switch")
deserializeIfNatural(JsonParser p, DeserializationContext ctxt, Class<?> base)141     public static Object deserializeIfNatural(JsonParser p, DeserializationContext ctxt,
142             Class<?> base) throws IOException
143     {
144         final JsonToken t = p.currentToken();
145         if (t == null) {
146             return null;
147         }
148         switch (t) {
149         case VALUE_STRING:
150             if (base.isAssignableFrom(String.class)) {
151                 return p.getText();
152             }
153             break;
154         case VALUE_NUMBER_INT:
155             if (base.isAssignableFrom(Integer.class)) {
156                 return p.getIntValue();
157             }
158             break;
159 
160         case VALUE_NUMBER_FLOAT:
161             if (base.isAssignableFrom(Double.class)) {
162                 return Double.valueOf(p.getDoubleValue());
163             }
164             break;
165         case VALUE_TRUE:
166             if (base.isAssignableFrom(Boolean.class)) {
167                 return Boolean.TRUE;
168             }
169             break;
170         case VALUE_FALSE:
171             if (base.isAssignableFrom(Boolean.class)) {
172                 return Boolean.FALSE;
173             }
174             break;
175         }
176         return null;
177     }
178 }
179