Tatu Saloranta | e4f23bb | 2011-12-23 00:31:35 -0800 | [diff] [blame] | 1 | package com.fasterxml.jackson.databind.deser; |
| 2 | |
| 3 | import java.io.IOException; |
| 4 | |
| 5 | import com.fasterxml.jackson.core.*; |
Tatu Saloranta | e4f23bb | 2011-12-23 00:31:35 -0800 | [diff] [blame] | 6 | import com.fasterxml.jackson.databind.*; |
Tatu Saloranta | df6302f | 2011-12-23 20:05:35 -0800 | [diff] [blame] | 7 | import com.fasterxml.jackson.databind.jsontype.TypeDeserializer; |
Tatu Saloranta | e4f23bb | 2011-12-23 00:31:35 -0800 | [diff] [blame] | 8 | |
Tatu Saloranta | e4f23bb | 2011-12-23 00:31:35 -0800 | [diff] [blame] | 9 | /** |
| 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 Saloranta | e4f23bb | 2011-12-23 00:31:35 -0800 | [diff] [blame] | 16 | */ |
| 17 | public class AbstractDeserializer |
| 18 | extends JsonDeserializer<Object> |
| 19 | { |
| 20 | protected final JavaType _baseType; |
Tatu Saloranta | ba0470f | 2011-12-29 22:14:05 -0800 | [diff] [blame^] | 21 | |
| 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 Saloranta | e4f23bb | 2011-12-23 00:31:35 -0800 | [diff] [blame] | 28 | |
| 29 | public AbstractDeserializer(JavaType bt) |
| 30 | { |
| 31 | _baseType = bt; |
Tatu Saloranta | ba0470f | 2011-12-29 22:14:05 -0800 | [diff] [blame^] | 32 | 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 Saloranta | e4f23bb | 2011-12-23 00:31:35 -0800 | [diff] [blame] | 37 | } |
| 38 | |
| 39 | @Override |
| 40 | public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt, |
| 41 | TypeDeserializer typeDeserializer) |
| 42 | throws IOException, JsonProcessingException |
| 43 | { |
Tatu Saloranta | ba0470f | 2011-12-29 22:14:05 -0800 | [diff] [blame^] | 44 | // 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 Saloranta | e4f23bb | 2011-12-23 00:31:35 -0800 | [diff] [blame] | 48 | } |
Tatu Saloranta | e4f23bb | 2011-12-23 00:31:35 -0800 | [diff] [blame] | 49 | return typeDeserializer.deserializeTypedFromObject(jp, ctxt); |
| 50 | } |
| 51 | |
| 52 | @Override |
| 53 | public Object deserialize(JsonParser jp, DeserializationContext ctxt) |
| 54 | throws IOException, JsonProcessingException |
| 55 | { |
Tatu Saloranta | ba0470f | 2011-12-29 22:14:05 -0800 | [diff] [blame^] | 56 | // 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 Saloranta | e4f23bb | 2011-12-23 00:31:35 -0800 | [diff] [blame] | 98 | } |
| 99 | } |
Tatu Saloranta | ba0470f | 2011-12-29 22:14:05 -0800 | [diff] [blame^] | 100 | |