aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/com/fasterxml/jackson/databind/deser/StdDeserializers.java
blob: 4cca7f76ea69f689e8104b933a324d316687c5de (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package com.fasterxml.jackson.databind.deser;

import java.util.*;

import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.deser.std.AtomicBooleanDeserializer;
import com.fasterxml.jackson.databind.deser.std.CalendarDeserializer;
import com.fasterxml.jackson.databind.deser.std.ClassDeserializer;
import com.fasterxml.jackson.databind.deser.std.DateDeserializer;
import com.fasterxml.jackson.databind.deser.std.FromStringDeserializer;
import com.fasterxml.jackson.databind.deser.std.JavaTypeDeserializer;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.deser.std.StringDeserializer;
import com.fasterxml.jackson.databind.deser.std.TimestampDeserializer;
import com.fasterxml.jackson.databind.deser.std.TokenBufferDeserializer;
import com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer;
import com.fasterxml.jackson.databind.type.*;

/**
 * Helper class used to contain simple/well-known deserializers for core JDK types.
 *<p>
 * Note: as of Jackson 1.9, we use type-erased class for registering, since
 * some types may come either as type-erased or typed (for example,
 * <code>java.lang.Class</code>).
 */
class StdDeserializers
{
    final HashMap<ClassKey, JsonDeserializer<Object>> _deserializers
        = new HashMap<ClassKey, JsonDeserializer<Object>>();

    private StdDeserializers()
    {
        // First, add the fall-back "untyped" deserializer:
        add(new UntypedObjectDeserializer());

        // Then String and String-like converters:
        StdDeserializer<?> strDeser = new StringDeserializer();
        add(strDeser, String.class);
        add(strDeser, CharSequence.class);
        add(new ClassDeserializer());

        // Then primitive-wrappers (simple):
        add(new StdDeserializer.BooleanDeserializer(Boolean.class, null));
        add(new StdDeserializer.ByteDeserializer(Byte.class, null));
        add(new StdDeserializer.ShortDeserializer(Short.class, null));
        add(new StdDeserializer.CharacterDeserializer(Character.class, null));
        add(new StdDeserializer.IntegerDeserializer(Integer.class, null));
        add(new StdDeserializer.LongDeserializer(Long.class, null));
        add(new StdDeserializer.FloatDeserializer(Float.class, null));
        add(new StdDeserializer.DoubleDeserializer(Double.class, null));
        
        /* And actual primitives: difference is the way nulls are to be
         * handled...
         */
        add(new StdDeserializer.BooleanDeserializer(Boolean.TYPE, Boolean.FALSE));
        add(new StdDeserializer.ByteDeserializer(Byte.TYPE, Byte.valueOf((byte)(0))));
        add(new StdDeserializer.ShortDeserializer(Short.TYPE, Short.valueOf((short)0)));
        add(new StdDeserializer.CharacterDeserializer(Character.TYPE, Character.valueOf('\0')));
        add(new StdDeserializer.IntegerDeserializer(Integer.TYPE, Integer.valueOf(0)));
        add(new StdDeserializer.LongDeserializer(Long.TYPE, Long.valueOf(0L)));
        add(new StdDeserializer.FloatDeserializer(Float.TYPE, Float.valueOf(0.0f)));
        add(new StdDeserializer.DoubleDeserializer(Double.TYPE, Double.valueOf(0.0)));
        
        // and related
        add(new StdDeserializer.NumberDeserializer());
        add(new StdDeserializer.BigDecimalDeserializer());
        add(new StdDeserializer.BigIntegerDeserializer());
        
        add(new CalendarDeserializer());
        add(new DateDeserializer());
        /* 24-Jan-2010, tatu: When including type information, we may
         *    know that we specifically need GregorianCalendar...
         */
        add(new CalendarDeserializer(GregorianCalendar.class),
                GregorianCalendar.class);
        add(new StdDeserializer.SqlDateDeserializer());
        add(new TimestampDeserializer());

        // From-string deserializers:
        for (StdDeserializer<?> deser : FromStringDeserializer.all()) {
            add(deser);
        }

        // And finally some odds and ends

        // to deserialize Throwable, need stack trace elements:
        add(new StdDeserializer.StackTraceElementDeserializer());

        // [JACKSON-283] need to support atomic types, too
        // (note: AtomicInteger/Long work due to single-arg constructor)
        add(new AtomicBooleanDeserializer());

        // including some core Jackson types:
        add(new TokenBufferDeserializer());
        add(new JavaTypeDeserializer());
    }

    /**
     * Public accessor to deserializers for core types.
     */
    public static HashMap<ClassKey, JsonDeserializer<Object>> constructAll()
    {
        return new StdDeserializers()._deserializers;
    }

    private void add(StdDeserializer<?> stdDeser)
    {
        add(stdDeser, stdDeser.getValueClass());
    }

    private void add(StdDeserializer<?> stdDeser, Class<?> valueClass)
    {
        // must do some unfortunate casting here...
        @SuppressWarnings("unchecked")
        JsonDeserializer<Object> deser = (JsonDeserializer<Object>) stdDeser;
        // Not super clean, but default TypeFactory does work here:
        _deserializers.put(new ClassKey(valueClass), deser);
    }
}