1 package com.fasterxml.jackson.databind.deser.impl;
2
3 import java.io.IOException;
4 import java.util.ArrayList;
5 import java.util.Collection;
6 import java.util.Collections;
7 import java.util.HashMap;
8 import java.util.LinkedHashMap;
9 import java.util.Map;
10
11 import com.fasterxml.jackson.core.JsonLocation;
12 import com.fasterxml.jackson.databind.DeserializationConfig;
13 import com.fasterxml.jackson.databind.DeserializationContext;
14 import com.fasterxml.jackson.databind.deser.ValueInstantiator;
15 import com.fasterxml.jackson.databind.deser.std.JsonLocationInstantiator;
16
17 /**
18  * Container for a set of {@link ValueInstantiator}s used for certain critical
19  * JDK value types, either as performance optimization for initialization time observed
20  * by profiling, or due to difficulty in otherwise finding constructors.
21  *
22  * @since 2.10
23  */

24 public abstract class JDKValueInstantiators
25 {
26     public static ValueInstantiator findStdValueInstantiator(DeserializationConfig config,
27             Class<?> raw)
28     {
29         if (raw == JsonLocation.class) {
30             return new JsonLocationInstantiator();
31         }
32         // [databind#1868]: empty List/Set/Map
33         // [databind#2416]: optimize commonly needed default creators
34         if (Collection.class.isAssignableFrom(raw)) {
35             if (raw == ArrayList.class) {
36                 return ArrayListInstantiator.INSTANCE;
37             }
38             if (Collections.EMPTY_SET.getClass() == raw) {
39                 return new ConstantValueInstantiator(Collections.EMPTY_SET);
40             }
41             if (Collections.EMPTY_LIST.getClass() == raw) {
42                 return new ConstantValueInstantiator(Collections.EMPTY_LIST);
43             }
44         } else if (Map.class.isAssignableFrom(raw)) {
45             if (raw == LinkedHashMap.class) {
46                 return LinkedHashMapInstantiator.INSTANCE;
47             }
48             if (raw == HashMap.class) {
49                 return HashMapInstantiator.INSTANCE;
50             }
51             if (Collections.EMPTY_MAP.getClass() == raw) {
52                 return new ConstantValueInstantiator(Collections.EMPTY_MAP);
53             }
54         }
55         return null;
56     }
57
58     private static class ArrayListInstantiator
59         extends ValueInstantiator.Base
60         implements java.io.Serializable
61     {
62         private static final long serialVersionUID = 2L;
63
64         public final static ArrayListInstantiator INSTANCE = new ArrayListInstantiator();
65         public ArrayListInstantiator() {
66             super(ArrayList.class);
67         }
68
69         @Override
70         public boolean canInstantiate() { return true; }
71
72         @Override
73         public boolean canCreateUsingDefault() {  return true; }
74
75         @Override
76         public Object createUsingDefault(DeserializationContext ctxt) throws IOException {
77             return new ArrayList<>();
78         }
79     }
80
81     private static class HashMapInstantiator
82         extends ValueInstantiator.Base
83         implements java.io.Serializable
84     {
85         private static final long serialVersionUID = 2L;
86
87         public final static HashMapInstantiator INSTANCE = new HashMapInstantiator();
88
89         public HashMapInstantiator() {
90             super(HashMap.class);
91         }
92
93         @Override
94         public boolean canInstantiate() { return true; }
95
96         @Override
97         public boolean canCreateUsingDefault() {  return true; }
98
99         @Override
100         public Object createUsingDefault(DeserializationContext ctxt) throws IOException {
101             return new HashMap<>();
102         }
103     }
104
105     private static class LinkedHashMapInstantiator
106         extends ValueInstantiator.Base
107         implements java.io.Serializable
108     {
109         private static final long serialVersionUID = 2L;
110
111         public final static LinkedHashMapInstantiator INSTANCE = new LinkedHashMapInstantiator();
112
113         public LinkedHashMapInstantiator() {
114             super(LinkedHashMap.class);
115         }
116
117         @Override
118         public boolean canInstantiate() { return true; }
119
120         @Override
121         public boolean canCreateUsingDefault() {  return true; }
122
123         @Override
124         public Object createUsingDefault(DeserializationContext ctxt) throws IOException {
125             return new LinkedHashMap<>();
126         }
127     }
128
129     private static class ConstantValueInstantiator
130         extends ValueInstantiator.Base
131         implements java.io.Serializable
132     {
133         private static final long serialVersionUID = 2L;
134
135         protected final Object _value;
136
137         public ConstantValueInstantiator(Object value) {
138             super(value.getClass());
139             _value = value;
140         }
141
142         @Override // yes, since default ctor works
143         public boolean canInstantiate() { return true; }
144
145         @Override
146         public boolean canCreateUsingDefault() {  return true; }
147
148         @Override
149         public Object createUsingDefault(DeserializationContext ctxt) throws IOException {
150             return _value;
151         }
152     }
153
154 }
155