blob: 996d36b44b0aa68662ffb14c7221655ec954fcb3 [file] [log] [blame]
Tatu Salorantae4f23bb2011-12-23 00:31:35 -08001package com.fasterxml.jackson.databind.deser;
2
3import java.io.IOException;
4
5import com.fasterxml.jackson.core.*;
Tatu Salorantae4f23bb2011-12-23 00:31:35 -08006import com.fasterxml.jackson.databind.*;
Tatu Salorantadf6302f2011-12-23 20:05:35 -08007import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
Tatu Salorantae4f23bb2011-12-23 00:31:35 -08008
Tatu Salorantae4f23bb2011-12-23 00:31:35 -08009/**
10 * Deserializer only used for abstract types used as placeholders during polymorphic
11 * type handling deserialization. If so, there is no real deserializer associated
12 * with nominal type, just {@link TypeDeserializer}; and any calls that do not
13 * pass such resolver will result in an error.
14 *
15 * @author tatu
Tatu Salorantae4f23bb2011-12-23 00:31:35 -080016 */
17public class AbstractDeserializer
18 extends JsonDeserializer<Object>
19{
20 protected final JavaType _baseType;
Tatu Salorantaba0470f2011-12-29 22:14:05 -080021
22 // support for "native" types, which require special care:
23
24 protected final boolean _acceptString;
25 protected final boolean _acceptBoolean;
26 protected final boolean _acceptInt;
27 protected final boolean _acceptDouble;
Tatu Salorantae4f23bb2011-12-23 00:31:35 -080028
29 public AbstractDeserializer(JavaType bt)
30 {
31 _baseType = bt;
Tatu Salorantaba0470f2011-12-29 22:14:05 -080032 Class<?> cls = bt.getRawClass();
33 _acceptString = cls.isAssignableFrom(String.class);
34 _acceptBoolean = (cls == Boolean.TYPE) || cls.isAssignableFrom(Boolean.class);
35 _acceptInt = (cls == Integer.TYPE) || cls.isAssignableFrom(Integer.class);
36 _acceptDouble = (cls == Double.TYPE) || cls.isAssignableFrom(Double.class);
Tatu Salorantae4f23bb2011-12-23 00:31:35 -080037 }
38
39 @Override
40 public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt,
41 TypeDeserializer typeDeserializer)
42 throws IOException, JsonProcessingException
43 {
Tatu Salorantaba0470f2011-12-29 22:14:05 -080044 // First: support "natural" values (which are always serialized without type info!)
45 Object result = _deserializeIfNatural(jp, ctxt);
46 if (result != null) {
47 return result;
Tatu Salorantae4f23bb2011-12-23 00:31:35 -080048 }
Tatu Salorantae4f23bb2011-12-23 00:31:35 -080049 return typeDeserializer.deserializeTypedFromObject(jp, ctxt);
50 }
51
52 @Override
53 public Object deserialize(JsonParser jp, DeserializationContext ctxt)
54 throws IOException, JsonProcessingException
55 {
Tatu Salorantaba0470f2011-12-29 22:14:05 -080056 // This method should never be called...
57 throw ctxt.instantiationException(_baseType.getRawClass(), "abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information");
58 }
59
60 protected Object _deserializeIfNatural(JsonParser jp, DeserializationContext ctxt)
61 throws IOException, JsonProcessingException
62 {
63 /* As per [JACKSON-417], there is a chance we might be "natular" types
64 * (String, Boolean, Integer, Double), which do not include any type information...
65 * Care must be taken to only return this if return type matches, however.
66 * Finally, we may have to consider possibility of custom handlers for
67 * these values: but for now this should work ok.
68 */
69 switch (jp.getCurrentToken()) {
70 case VALUE_STRING:
71 if (_acceptString) {
72 return jp.getText();
73 }
74 break;
75 case VALUE_NUMBER_INT:
76 if (_acceptInt) {
77 return jp.getIntValue();
78 }
79 break;
80
81 case VALUE_NUMBER_FLOAT:
82 if (_acceptDouble) {
83 return Double.valueOf(jp.getDoubleValue());
84 }
85 break;
86 case VALUE_TRUE:
87 if (_acceptBoolean) {
88 return Boolean.TRUE;
89 }
90 break;
91 case VALUE_FALSE:
92 if (_acceptBoolean) {
93 return Boolean.FALSE;
94 }
95 break;
96 }
97 return null;
Tatu Salorantae4f23bb2011-12-23 00:31:35 -080098 }
99}
Tatu Salorantaba0470f2011-12-29 22:14:05 -0800100