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 {
findStdValueInstantiator(DeserializationConfig config, Class<?> raw)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();
ArrayListInstantiator()65         public ArrayListInstantiator() {
66             super(ArrayList.class);
67         }
68 
69         @Override
canInstantiate()70         public boolean canInstantiate() { return true; }
71 
72         @Override
canCreateUsingDefault()73         public boolean canCreateUsingDefault() {  return true; }
74 
75         @Override
createUsingDefault(DeserializationContext ctxt)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 
HashMapInstantiator()89         public HashMapInstantiator() {
90             super(HashMap.class);
91         }
92 
93         @Override
canInstantiate()94         public boolean canInstantiate() { return true; }
95 
96         @Override
canCreateUsingDefault()97         public boolean canCreateUsingDefault() {  return true; }
98 
99         @Override
createUsingDefault(DeserializationContext ctxt)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 
LinkedHashMapInstantiator()113         public LinkedHashMapInstantiator() {
114             super(LinkedHashMap.class);
115         }
116 
117         @Override
canInstantiate()118         public boolean canInstantiate() { return true; }
119 
120         @Override
canCreateUsingDefault()121         public boolean canCreateUsingDefault() {  return true; }
122 
123         @Override
createUsingDefault(DeserializationContext ctxt)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 
ConstantValueInstantiator(Object value)137         public ConstantValueInstantiator(Object value) {
138             super(value.getClass());
139             _value = value;
140         }
141 
142         @Override // yes, since default ctor works
canInstantiate()143         public boolean canInstantiate() { return true; }
144 
145         @Override
canCreateUsingDefault()146         public boolean canCreateUsingDefault() {  return true; }
147 
148         @Override
createUsingDefault(DeserializationContext ctxt)149         public Object createUsingDefault(DeserializationContext ctxt) throws IOException {
150             return _value;
151         }
152     }
153 
154 }
155