1 package com.fasterxml.jackson.databind.deser.impl;
2
3 import java.io.IOException;
4 import java.util.*;
5
6 import com.fasterxml.jackson.core.JsonParser;
7
8 import com.fasterxml.jackson.databind.*;
9 import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
10 import com.fasterxml.jackson.databind.deser.ValueInstantiator;
11
12
20 public final class PropertyBasedCreator
21 {
22
26 protected final int _propertyCount;
27
28
32 protected final ValueInstantiator _valueInstantiator;
33
34
39 protected final HashMap<String, SettableBeanProperty> _propertyLookup;
40
41
45 protected final SettableBeanProperty[] _allProperties;
46
47
52
53 protected PropertyBasedCreator(DeserializationContext ctxt,
54 ValueInstantiator valueInstantiator,
55 SettableBeanProperty[] creatorProps,
56 boolean caseInsensitive,
57 boolean addAliases)
58 {
59 _valueInstantiator = valueInstantiator;
60 if (caseInsensitive) {
61 _propertyLookup = CaseInsensitiveMap.construct(ctxt.getConfig().getLocale());
62 } else {
63 _propertyLookup = new HashMap<String, SettableBeanProperty>();
64 }
65 final int len = creatorProps.length;
66 _propertyCount = len;
67 _allProperties = new SettableBeanProperty[len];
68
69
70
71 if (addAliases) {
72 final DeserializationConfig config = ctxt.getConfig();
73 for (SettableBeanProperty prop : creatorProps) {
74
75 if (!prop.isIgnorable()) {
76 List<PropertyName> aliases = prop.findAliases(config);
77 if (!aliases.isEmpty()) {
78 for (PropertyName pn : aliases) {
79 _propertyLookup.put(pn.getSimpleName(), prop);
80 }
81 }
82 }
83 }
84 }
85 for (int i = 0; i < len; ++i) {
86 SettableBeanProperty prop = creatorProps[i];
87 _allProperties[i] = prop;
88
89 if (!prop.isIgnorable()) {
90 _propertyLookup.put(prop.getName(), prop);
91 }
92 }
93 }
94
95
101 public static PropertyBasedCreator construct(DeserializationContext ctxt,
102 ValueInstantiator valueInstantiator, SettableBeanProperty[] srcCreatorProps,
103 BeanPropertyMap allProperties)
104 throws JsonMappingException
105 {
106 final int len = srcCreatorProps.length;
107 SettableBeanProperty[] creatorProps = new SettableBeanProperty[len];
108 for (int i = 0; i < len; ++i) {
109 SettableBeanProperty prop = srcCreatorProps[i];
110 if (!prop.hasValueDeserializer()) {
111
112
113 if (!prop.isInjectionOnly()) {
114 prop = prop.withValueDeserializer(ctxt.findContextualValueDeserializer(prop.getType(), prop));
115 }
116 }
117 creatorProps[i] = prop;
118 }
119 return new PropertyBasedCreator(ctxt, valueInstantiator, creatorProps,
120 allProperties.isCaseInsensitive(),
121
122
123
124 true);
125 }
126
127
134 public static PropertyBasedCreator construct(DeserializationContext ctxt,
135 ValueInstantiator valueInstantiator, SettableBeanProperty[] srcCreatorProps,
136 boolean caseInsensitive)
137 throws JsonMappingException
138 {
139 final int len = srcCreatorProps.length;
140 SettableBeanProperty[] creatorProps = new SettableBeanProperty[len];
141 for (int i = 0; i < len; ++i) {
142 SettableBeanProperty prop = srcCreatorProps[i];
143 if (!prop.hasValueDeserializer()) {
144 prop = prop.withValueDeserializer(ctxt.findContextualValueDeserializer(prop.getType(), prop));
145 }
146 creatorProps[i] = prop;
147 }
148 return new PropertyBasedCreator(ctxt, valueInstantiator, creatorProps,
149 caseInsensitive, false);
150 }
151
152 @Deprecated
153 public static PropertyBasedCreator construct(DeserializationContext ctxt,
154 ValueInstantiator valueInstantiator, SettableBeanProperty[] srcCreatorProps)
155 throws JsonMappingException
156 {
157 return construct(ctxt, valueInstantiator, srcCreatorProps,
158 ctxt.isEnabled(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES));
159 }
160
161
166
167 public Collection<SettableBeanProperty> properties() {
168 return _propertyLookup.values();
169 }
170
171 public SettableBeanProperty findCreatorProperty(String name) {
172 return _propertyLookup.get(name);
173 }
174
175 public SettableBeanProperty findCreatorProperty(int propertyIndex) {
176 for (SettableBeanProperty prop : _propertyLookup.values()) {
177 if (prop.getPropertyIndex() == propertyIndex) {
178 return prop;
179 }
180 }
181 return null;
182 }
183
184
189
190
195 public PropertyValueBuffer startBuilding(JsonParser p, DeserializationContext ctxt,
196 ObjectIdReader oir) {
197 return new PropertyValueBuffer(p, ctxt, _propertyCount, oir);
198 }
199
200 public Object build(DeserializationContext ctxt, PropertyValueBuffer buffer) throws IOException
201 {
202 Object bean = _valueInstantiator.createFromObjectWith(ctxt,
203 _allProperties, buffer);
204
205 if (bean != null) {
206
207 bean = buffer.handleIdValue(ctxt, bean);
208
209
210 for (PropertyValue pv = buffer.buffered(); pv != null; pv = pv.next) {
211 pv.assign(bean);
212 }
213 }
214 return bean;
215 }
216
217
222
223
229 static class CaseInsensitiveMap extends HashMap<String, SettableBeanProperty>
230 {
231 private static final long serialVersionUID = 1L;
232
233
238 protected final Locale _locale;
239
240 @Deprecated
241 public CaseInsensitiveMap() {
242 this(Locale.getDefault());
243 }
244
245
246 public CaseInsensitiveMap(Locale l) {
247 _locale = l;
248 }
249
250
251 public static CaseInsensitiveMap construct(Locale l) {
252 return new CaseInsensitiveMap(l);
253 }
254
255 @Override
256 public SettableBeanProperty get(Object key0) {
257 return super.get(((String) key0).toLowerCase(_locale));
258 }
259
260 @Override
261 public SettableBeanProperty put(String key, SettableBeanProperty value) {
262 key = key.toLowerCase(_locale);
263 return super.put(key, value);
264 }
265 }
266 }
267