1 package com.fasterxml.jackson.databind.deser;
2
3 import java.util.*;
4
5 import com.fasterxml.jackson.annotation.*;
6 import com.fasterxml.jackson.databind.*;
7 import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
8 import com.fasterxml.jackson.databind.cfg.DeserializerFactoryConfig;
9 import com.fasterxml.jackson.databind.deser.impl.*;
10 import com.fasterxml.jackson.databind.deser.std.ThrowableDeserializer;
11 import com.fasterxml.jackson.databind.exc.InvalidDefinitionException;
12 import com.fasterxml.jackson.databind.introspect.*;
13 import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
14 import com.fasterxml.jackson.databind.jsontype.impl.SubTypeValidator;
15 import com.fasterxml.jackson.databind.util.ClassUtil;
16 import com.fasterxml.jackson.databind.util.SimpleBeanPropertyDefinition;
17
18
29 public class BeanDeserializerFactory
30 extends BasicDeserializerFactory
31 implements java.io.Serializable
32 {
33 private static final long serialVersionUID = 1;
34
35
38 private final static Class<?>[] INIT_CAUSE_PARAMS = new Class<?>[] { Throwable.class };
39
40
45
46
50 public final static BeanDeserializerFactory instance = new BeanDeserializerFactory(
51 new DeserializerFactoryConfig());
52
53 public BeanDeserializerFactory(DeserializerFactoryConfig config) {
54 super(config);
55 }
56
57
62 @Override
63 public DeserializerFactory withConfig(DeserializerFactoryConfig config)
64 {
65 if (_factoryConfig == config) {
66 return this;
67 }
68
74 ClassUtil.verifyMustOverride(BeanDeserializerFactory.class, this, "withConfig");
75 return new BeanDeserializerFactory(config);
76 }
77
78
83
84
89 @SuppressWarnings("unchecked")
90 @Override
91 public JsonDeserializer<Object> createBeanDeserializer(DeserializationContext ctxt,
92 JavaType type, BeanDescription beanDesc)
93 throws JsonMappingException
94 {
95 final DeserializationConfig config = ctxt.getConfig();
96
97 JsonDeserializer<?> deser = _findCustomBeanDeserializer(type, config, beanDesc);
98 if (deser != null) {
99
100 if (_factoryConfig.hasDeserializerModifiers()) {
101 for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
102 deser = mod.modifyDeserializer(ctxt.getConfig(), beanDesc, deser);
103 }
104 }
105 return (JsonDeserializer<Object>) deser;
106 }
107
111 if (type.isThrowable()) {
112 return buildThrowableDeserializer(ctxt, type, beanDesc);
113 }
114
115
116
117
118
119 if (type.isAbstract() && !type.isPrimitive() && !type.isEnumType()) {
120
121 JavaType concreteType = materializeAbstractType(ctxt, type, beanDesc);
122 if (concreteType != null) {
123
126 beanDesc = config.introspect(concreteType);
127 return buildBeanDeserializer(ctxt, concreteType, beanDesc);
128 }
129 }
130
131 deser = findStdDeserializer(ctxt, type, beanDesc);
132 if (deser != null) {
133 return (JsonDeserializer<Object>)deser;
134 }
135
136
137 if (!isPotentialBeanType(type.getRawClass())) {
138 return null;
139 }
140
141 _validateSubType(ctxt, type, beanDesc);
142
143 return buildBeanDeserializer(ctxt, type, beanDesc);
144 }
145
146 @Override
147 public JsonDeserializer<Object> createBuilderBasedDeserializer(DeserializationContext ctxt,
148 JavaType valueType, BeanDescription beanDesc, Class<?> builderClass)
149 throws JsonMappingException
150 {
151
152 JavaType builderType = ctxt.constructType(builderClass);
153 BeanDescription builderDesc = ctxt.getConfig().introspectForBuilder(builderType);
154 return buildBuilderBasedDeserializer(ctxt, valueType, builderDesc);
155 }
156
157
161 protected JsonDeserializer<?> findStdDeserializer(DeserializationContext ctxt,
162 JavaType type, BeanDescription beanDesc)
163 throws JsonMappingException
164 {
165
166
167 JsonDeserializer<?> deser = findDefaultDeserializer(ctxt, type, beanDesc);
168
169 if (deser != null) {
170 if (_factoryConfig.hasDeserializerModifiers()) {
171 for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
172 deser = mod.modifyDeserializer(ctxt.getConfig(), beanDesc, deser);
173 }
174 }
175 }
176 return deser;
177 }
178
179 protected JavaType materializeAbstractType(DeserializationContext ctxt,
180 JavaType type, BeanDescription beanDesc)
181 throws JsonMappingException
182 {
183
184 for (AbstractTypeResolver r : _factoryConfig.abstractTypeResolvers()) {
185 JavaType concrete = r.resolveAbstractType(ctxt.getConfig(), beanDesc);
186 if (concrete != null) {
187 return concrete;
188 }
189 }
190 return null;
191 }
192
193
200
201
207 @SuppressWarnings("unchecked")
208 public JsonDeserializer<Object> buildBeanDeserializer(DeserializationContext ctxt,
209 JavaType type, BeanDescription beanDesc)
210 throws JsonMappingException
211 {
212
213 ValueInstantiator valueInstantiator;
214
219 try {
220 valueInstantiator = findValueInstantiator(ctxt, beanDesc);
221 } catch (NoClassDefFoundError error) {
222 return new ErrorThrowingDeserializer(error);
223 } catch (IllegalArgumentException e) {
224
225
226
227 throw InvalidDefinitionException.from(ctxt.getParser(),
228 ClassUtil.exceptionMessage(e),
229 beanDesc, null);
230 }
231 BeanDeserializerBuilder builder = constructBeanDeserializerBuilder(ctxt, beanDesc);
232 builder.setValueInstantiator(valueInstantiator);
233
234 addBeanProps(ctxt, beanDesc, builder);
235 addObjectIdReader(ctxt, beanDesc, builder);
236
237
238 addBackReferenceProperties(ctxt, beanDesc, builder);
239 addInjectables(ctxt, beanDesc, builder);
240
241 final DeserializationConfig config = ctxt.getConfig();
242 if (_factoryConfig.hasDeserializerModifiers()) {
243 for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
244 builder = mod.updateBuilder(config, beanDesc, builder);
245 }
246 }
247 JsonDeserializer<?> deserializer;
248
249 if (type.isAbstract() && !valueInstantiator.canInstantiate()) {
250 deserializer = builder.buildAbstract();
251 } else {
252 deserializer = builder.build();
253 }
254
255
256 if (_factoryConfig.hasDeserializerModifiers()) {
257 for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
258 deserializer = mod.modifyDeserializer(config, beanDesc, deserializer);
259 }
260 }
261 return (JsonDeserializer<Object>) deserializer;
262 }
263
264
271 @SuppressWarnings("unchecked")
272 protected JsonDeserializer<Object> buildBuilderBasedDeserializer(
273 DeserializationContext ctxt, JavaType valueType, BeanDescription builderDesc)
274 throws JsonMappingException
275 {
276
277 ValueInstantiator valueInstantiator;
278 try {
279 valueInstantiator = findValueInstantiator(ctxt, builderDesc);
280 } catch (NoClassDefFoundError error) {
281 return new ErrorThrowingDeserializer(error);
282 } catch (IllegalArgumentException e) {
283
284
285
286 throw InvalidDefinitionException.from(ctxt.getParser(),
287 ClassUtil.exceptionMessage(e),
288 builderDesc, null);
289 }
290 final DeserializationConfig config = ctxt.getConfig();
291 BeanDeserializerBuilder builder = constructBeanDeserializerBuilder(ctxt, builderDesc);
292 builder.setValueInstantiator(valueInstantiator);
293
294 addBeanProps(ctxt, builderDesc, builder);
295 addObjectIdReader(ctxt, builderDesc, builder);
296
297
298 addBackReferenceProperties(ctxt, builderDesc, builder);
299 addInjectables(ctxt, builderDesc, builder);
300
301 JsonPOJOBuilder.Value builderConfig = builderDesc.findPOJOBuilderConfig();
302 final String buildMethodName = (builderConfig == null) ?
303 JsonPOJOBuilder.DEFAULT_BUILD_METHOD : builderConfig.buildMethodName;
304
305
306 AnnotatedMethod buildMethod = builderDesc.findMethod(buildMethodName, null);
307 if (buildMethod != null) {
308 if (config.canOverrideAccessModifiers()) {
309 ClassUtil.checkAndFixAccess(buildMethod.getMember(), config.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS));
310 }
311 }
312 builder.setPOJOBuilder(buildMethod, builderConfig);
313
314 if (_factoryConfig.hasDeserializerModifiers()) {
315 for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
316 builder = mod.updateBuilder(config, builderDesc, builder);
317 }
318 }
319 JsonDeserializer<?> deserializer = builder.buildBuilderBased(
320 valueType, buildMethodName);
321
322
323 if (_factoryConfig.hasDeserializerModifiers()) {
324 for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
325 deserializer = mod.modifyDeserializer(config, builderDesc, deserializer);
326 }
327 }
328 return (JsonDeserializer<Object>) deserializer;
329 }
330
331 protected void addObjectIdReader(DeserializationContext ctxt,
332 BeanDescription beanDesc, BeanDeserializerBuilder builder)
333 throws JsonMappingException
334 {
335 ObjectIdInfo objectIdInfo = beanDesc.getObjectIdInfo();
336 if (objectIdInfo == null) {
337 return;
338 }
339 Class<?> implClass = objectIdInfo.getGeneratorType();
340 JavaType idType;
341 SettableBeanProperty idProp;
342 ObjectIdGenerator<?> gen;
343
344 ObjectIdResolver resolver = ctxt.objectIdResolverInstance(beanDesc.getClassInfo(), objectIdInfo);
345
346
347 if (implClass == ObjectIdGenerators.PropertyGenerator.class) {
348 PropertyName propName = objectIdInfo.getPropertyName();
349 idProp = builder.findProperty(propName);
350 if (idProp == null) {
351 throw new IllegalArgumentException("Invalid Object Id definition for "
352 +beanDesc.getBeanClass().getName()+": cannot find property with name '"+propName+"'");
353 }
354 idType = idProp.getType();
355 gen = new PropertyBasedObjectIdGenerator(objectIdInfo.getScope());
356 } else {
357 JavaType type = ctxt.constructType(implClass);
358 idType = ctxt.getTypeFactory().findTypeParameters(type, ObjectIdGenerator.class)[0];
359 idProp = null;
360 gen = ctxt.objectIdGeneratorInstance(beanDesc.getClassInfo(), objectIdInfo);
361 }
362
363 JsonDeserializer<?> deser = ctxt.findRootValueDeserializer(idType);
364 builder.setObjectIdReader(ObjectIdReader.construct(idType,
365 objectIdInfo.getPropertyName(), gen, deser, idProp, resolver));
366 }
367
368 @SuppressWarnings("unchecked")
369 public JsonDeserializer<Object> buildThrowableDeserializer(DeserializationContext ctxt,
370 JavaType type, BeanDescription beanDesc)
371 throws JsonMappingException
372 {
373 final DeserializationConfig config = ctxt.getConfig();
374
375 BeanDeserializerBuilder builder = constructBeanDeserializerBuilder(ctxt, beanDesc);
376 builder.setValueInstantiator(findValueInstantiator(ctxt, beanDesc));
377
378 addBeanProps(ctxt, beanDesc, builder);
379
380
381
382
383 AnnotatedMethod am = beanDesc.findMethod("initCause", INIT_CAUSE_PARAMS);
384 if (am != null) {
385 SimpleBeanPropertyDefinition propDef = SimpleBeanPropertyDefinition.construct(ctxt.getConfig(), am,
386 new PropertyName("cause"));
387 SettableBeanProperty prop = constructSettableProperty(ctxt, beanDesc, propDef,
388 am.getParameterType(0));
389 if (prop != null) {
390
391
392 builder.addOrReplaceProperty(prop, true);
393 }
394 }
395
396
397 builder.addIgnorable("localizedMessage");
398
399 builder.addIgnorable("suppressed");
400
401
402
403
404
405
406 if (_factoryConfig.hasDeserializerModifiers()) {
407 for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
408 builder = mod.updateBuilder(config, beanDesc, builder);
409 }
410 }
411 JsonDeserializer<?> deserializer = builder.build();
412
413
416 if (deserializer instanceof BeanDeserializer) {
417 deserializer = new ThrowableDeserializer((BeanDeserializer) deserializer);
418 }
419
420
421 if (_factoryConfig.hasDeserializerModifiers()) {
422 for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
423 deserializer = mod.modifyDeserializer(config, beanDesc, deserializer);
424 }
425 }
426 return (JsonDeserializer<Object>) deserializer;
427 }
428
429
435
436
441 protected BeanDeserializerBuilder constructBeanDeserializerBuilder(DeserializationContext ctxt,
442 BeanDescription beanDesc) {
443 return new BeanDeserializerBuilder(beanDesc, ctxt);
444 }
445
446
453 protected void addBeanProps(DeserializationContext ctxt,
454 BeanDescription beanDesc, BeanDeserializerBuilder builder)
455 throws JsonMappingException
456 {
457 final boolean isConcrete = !beanDesc.getType().isAbstract();
458 final SettableBeanProperty[] creatorProps = isConcrete
459 ? builder.getValueInstantiator().getFromObjectArguments(ctxt.getConfig())
460 : null;
461 final boolean hasCreatorProps = (creatorProps != null);
462
463
464
465
466
467 JsonIgnoreProperties.Value ignorals = ctxt.getConfig()
468 .getDefaultPropertyIgnorals(beanDesc.getBeanClass(),
469 beanDesc.getClassInfo());
470 Set<String> ignored;
471 if (ignorals != null) {
472 boolean ignoreAny = ignorals.getIgnoreUnknown();
473 builder.setIgnoreUnknownProperties(ignoreAny);
474
475 ignored = ignorals.findIgnoredForDeserialization();
476 for (String propName : ignored) {
477 builder.addIgnorable(propName);
478 }
479 } else {
480 ignored = Collections.emptySet();
481 }
482
483
484 AnnotatedMember anySetter = beanDesc.findAnySetterAccessor();
485 if (anySetter != null) {
486 builder.setAnySetter(constructAnySetter(ctxt, beanDesc, anySetter));
487 } else {
488
489
490 Collection<String> ignored2 = beanDesc.getIgnoredPropertyNames();
491 if (ignored2 != null) {
492 for (String propName : ignored2) {
493
494
495 builder.addIgnorable(propName);
496 }
497 }
498 }
499 final boolean useGettersAsSetters = ctxt.isEnabled(MapperFeature.USE_GETTERS_AS_SETTERS)
500 && ctxt.isEnabled(MapperFeature.AUTO_DETECT_GETTERS);
501
502
503 List<BeanPropertyDefinition> propDefs = filterBeanProps(ctxt,
504 beanDesc, builder, beanDesc.findProperties(), ignored);
505
506 if (_factoryConfig.hasDeserializerModifiers()) {
507 for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
508 propDefs = mod.updateProperties(ctxt.getConfig(), beanDesc, propDefs);
509 }
510 }
511
512
513 for (BeanPropertyDefinition propDef : propDefs) {
514 SettableBeanProperty prop = null;
515
516
517
518
519 if (propDef.hasSetter()) {
520 AnnotatedMethod setter = propDef.getSetter();
521 JavaType propertyType = setter.getParameterType(0);
522 prop = constructSettableProperty(ctxt, beanDesc, propDef, propertyType);
523 } else if (propDef.hasField()) {
524 AnnotatedField field = propDef.getField();
525 JavaType propertyType = field.getType();
526 prop = constructSettableProperty(ctxt, beanDesc, propDef, propertyType);
527 } else {
528
529 AnnotatedMethod getter = propDef.getGetter();
530 if (getter != null) {
531 if (useGettersAsSetters && _isSetterlessType(getter.getRawType())) {
532
533
534 if (builder.hasIgnorable(propDef.getName())) {
535 ;
536 } else {
537 prop = constructSetterlessProperty(ctxt, beanDesc, propDef);
538 }
539 } else if (!propDef.hasConstructorParameter()) {
540 PropertyMetadata md = propDef.getMetadata();
541
542
543
544
545 if (md.getMergeInfo() != null) {
546 prop = constructSetterlessProperty(ctxt, beanDesc, propDef);
547 }
548 }
549 }
550 }
551
552
553
554 if (hasCreatorProps && propDef.hasConstructorParameter()) {
555
559
560 final String name = propDef.getName();
561 CreatorProperty cprop = null;
562 if (creatorProps != null) {
563 for (SettableBeanProperty cp : creatorProps) {
564 if (name.equals(cp.getName()) && (cp instanceof CreatorProperty)) {
565 cprop = (CreatorProperty) cp;
566 break;
567 }
568 }
569 }
570 if (cprop == null) {
571 List<String> n = new ArrayList<>();
572 for (SettableBeanProperty cp : creatorProps) {
573 n.add(cp.getName());
574 }
575 ctxt.reportBadPropertyDefinition(beanDesc, propDef,
576 "Could not find creator property with name '%s' (known Creator properties: %s)",
577 name, n);
578 continue;
579 }
580 if (prop != null) {
581 cprop.setFallbackSetter(prop);
582 }
583 Class<?>[] views = propDef.findViews();
584 if (views == null) {
585 views = beanDesc.findDefaultViews();
586 }
587 cprop.setViews(views);
588 builder.addCreatorProperty(cprop);
589 continue;
590 }
591 if (prop != null) {
592
593 Class<?>[] views = propDef.findViews();
594 if (views == null) {
595 views = beanDesc.findDefaultViews();
596 }
597 prop.setViews(views);
598 builder.addProperty(prop);
599 }
600 }
601 }
602
603 private boolean _isSetterlessType(Class<?> rawType) {
604
605
606
607 return Collection.class.isAssignableFrom(rawType)
608 || Map.class.isAssignableFrom(rawType);
609 }
610
611
617 protected List<BeanPropertyDefinition> filterBeanProps(DeserializationContext ctxt,
618 BeanDescription beanDesc, BeanDeserializerBuilder builder,
619 List<BeanPropertyDefinition> propDefsIn,
620 Set<String> ignored)
621 throws JsonMappingException
622 {
623 ArrayList<BeanPropertyDefinition> result = new ArrayList<BeanPropertyDefinition>(
624 Math.max(4, propDefsIn.size()));
625 HashMap<Class<?>,Boolean> ignoredTypes = new HashMap<Class<?>,Boolean>();
626
627 for (BeanPropertyDefinition property : propDefsIn) {
628 String name = property.getName();
629 if (ignored.contains(name)) {
630 continue;
631 }
632 if (!property.hasConstructorParameter()) {
633 Class<?> rawPropertyType = property.getRawPrimaryType();
634
635 if ((rawPropertyType != null)
636 && isIgnorableType(ctxt.getConfig(), property, rawPropertyType, ignoredTypes)) {
637
638 builder.addIgnorable(name);
639 continue;
640 }
641 }
642 result.add(property);
643 }
644 return result;
645 }
646
647
653 protected void addBackReferenceProperties(DeserializationContext ctxt,
654 BeanDescription beanDesc, BeanDeserializerBuilder builder)
655 throws JsonMappingException
656 {
657
658 List<BeanPropertyDefinition> refProps = beanDesc.findBackReferences();
659 if (refProps != null) {
660 for (BeanPropertyDefinition refProp : refProps) {
661
677 String refName = refProp.findReferenceName();
678 builder.addBackReferenceProperty(refName, constructSettableProperty(ctxt,
679 beanDesc, refProp, refProp.getPrimaryType()));
680 }
681 }
682 }
683
684 @Deprecated
685 protected void addReferenceProperties(DeserializationContext ctxt,
686 BeanDescription beanDesc, BeanDeserializerBuilder builder)
687 throws JsonMappingException
688 {
689 addBackReferenceProperties(ctxt, beanDesc, builder);
690 }
691
692
696 protected void addInjectables(DeserializationContext ctxt,
697 BeanDescription beanDesc, BeanDeserializerBuilder builder)
698 throws JsonMappingException
699 {
700 Map<Object, AnnotatedMember> raw = beanDesc.findInjectables();
701 if (raw != null) {
702 for (Map.Entry<Object, AnnotatedMember> entry : raw.entrySet()) {
703 AnnotatedMember m = entry.getValue();
704 builder.addInjectable(PropertyName.construct(m.getName()),
705 m.getType(),
706 beanDesc.getClassAnnotations(), m, entry.getKey());
707 }
708 }
709 }
710
711
719 @SuppressWarnings("unchecked")
720 protected SettableAnyProperty constructAnySetter(DeserializationContext ctxt,
721 BeanDescription beanDesc, AnnotatedMember mutator)
722 throws JsonMappingException
723 {
724
725 BeanProperty prop;
726 JavaType keyType;
727 JavaType valueType;
728
729 if (mutator instanceof AnnotatedMethod) {
730
731 AnnotatedMethod am = (AnnotatedMethod) mutator;
732 keyType = am.getParameterType(0);
733 valueType = am.getParameterType(1);
734 valueType = resolveMemberAndTypeAnnotations(ctxt, mutator, valueType);
735 prop = new BeanProperty.Std(PropertyName.construct(mutator.getName()),
736 valueType, null, mutator,
737 PropertyMetadata.STD_OPTIONAL);
738
739 } else if (mutator instanceof AnnotatedField) {
740 AnnotatedField af = (AnnotatedField) mutator;
741
742 JavaType mapType = af.getType();
743 mapType = resolveMemberAndTypeAnnotations(ctxt, mutator, mapType);
744 keyType = mapType.getKeyType();
745 valueType = mapType.getContentType();
746 prop = new BeanProperty.Std(PropertyName.construct(mutator.getName()),
747 mapType, null, mutator, PropertyMetadata.STD_OPTIONAL);
748 } else {
749 return ctxt.reportBadDefinition(beanDesc.getType(), String.format(
750 "Unrecognized mutator type for any setter: %s", mutator.getClass()));
751 }
752
753
754 KeyDeserializer keyDeser = findKeyDeserializerFromAnnotation(ctxt, mutator);
755 if (keyDeser == null) {
756 keyDeser = keyType.getValueHandler();
757 }
758 if (keyDeser == null) {
759 keyDeser = ctxt.findKeyDeserializer(keyType, prop);
760 } else {
761 if (keyDeser instanceof ContextualKeyDeserializer) {
762 keyDeser = ((ContextualKeyDeserializer) keyDeser)
763 .createContextual(ctxt, prop);
764 }
765 }
766 JsonDeserializer<Object> deser = findContentDeserializerFromAnnotation(ctxt, mutator);
767 if (deser == null) {
768 deser = valueType.getValueHandler();
769 }
770 if (deser != null) {
771
772 deser = (JsonDeserializer<Object>) ctxt.handlePrimaryContextualization(deser, prop, valueType);
773 }
774 TypeDeserializer typeDeser = valueType.getTypeHandler();
775 return new SettableAnyProperty(prop, mutator, valueType,
776 keyDeser, deser, typeDeser);
777 }
778
779
786 protected SettableBeanProperty constructSettableProperty(DeserializationContext ctxt,
787 BeanDescription beanDesc, BeanPropertyDefinition propDef,
788 JavaType propType0)
789 throws JsonMappingException
790 {
791
792 AnnotatedMember mutator = propDef.getNonConstructorMutator();
793
794
795
796 if (mutator == null) {
797 ctxt.reportBadPropertyDefinition(beanDesc, propDef, "No non-constructor mutator available");
798 }
799 JavaType type = resolveMemberAndTypeAnnotations(ctxt, mutator, propType0);
800
801 TypeDeserializer typeDeser = type.getTypeHandler();
802 SettableBeanProperty prop;
803 if (mutator instanceof AnnotatedMethod) {
804 prop = new MethodProperty(propDef, type, typeDeser,
805 beanDesc.getClassAnnotations(), (AnnotatedMethod) mutator);
806 } else {
807
808 prop = new FieldProperty(propDef, type, typeDeser,
809 beanDesc.getClassAnnotations(), (AnnotatedField) mutator);
810 }
811 JsonDeserializer<?> deser = findDeserializerFromAnnotation(ctxt, mutator);
812 if (deser == null) {
813 deser = type.getValueHandler();
814 }
815 if (deser != null) {
816 deser = ctxt.handlePrimaryContextualization(deser, prop, type);
817 prop = prop.withValueDeserializer(deser);
818 }
819
820 AnnotationIntrospector.ReferenceProperty ref = propDef.findReferenceType();
821 if (ref != null && ref.isManagedReference()) {
822 prop.setManagedReferenceName(ref.getName());
823 }
824 ObjectIdInfo objectIdInfo = propDef.findObjectIdInfo();
825 if (objectIdInfo != null){
826 prop.setObjectIdInfo(objectIdInfo);
827 }
828 return prop;
829 }
830
831
835 protected SettableBeanProperty constructSetterlessProperty(DeserializationContext ctxt,
836 BeanDescription beanDesc, BeanPropertyDefinition propDef)
837 throws JsonMappingException
838 {
839 final AnnotatedMethod getter = propDef.getGetter();
840 JavaType type = resolveMemberAndTypeAnnotations(ctxt, getter, getter.getType());
841 TypeDeserializer typeDeser = type.getTypeHandler();
842 SettableBeanProperty prop = new SetterlessProperty(propDef, type, typeDeser,
843 beanDesc.getClassAnnotations(), getter);
844 JsonDeserializer<?> deser = findDeserializerFromAnnotation(ctxt, getter);
845 if (deser == null) {
846 deser = type.getValueHandler();
847 }
848 if (deser != null) {
849 deser = ctxt.handlePrimaryContextualization(deser, prop, type);
850 prop = prop.withValueDeserializer(deser);
851 }
852 return prop;
853 }
854
855
860
861
869 protected boolean isPotentialBeanType(Class<?> type)
870 {
871 String typeStr = ClassUtil.canBeABeanType(type);
872 if (typeStr != null) {
873 throw new IllegalArgumentException("Cannot deserialize Class "+type.getName()+" (of type "+typeStr+") as a Bean");
874 }
875 if (ClassUtil.isProxyType(type)) {
876 throw new IllegalArgumentException("Cannot deserialize Proxy class "+type.getName()+" as a Bean");
877 }
878
879
880 typeStr = ClassUtil.isLocalType(type, true);
881 if (typeStr != null) {
882 throw new IllegalArgumentException("Cannot deserialize Class "+type.getName()+" (of type "+typeStr+") as a Bean");
883 }
884 return true;
885 }
886
887
891 protected boolean isIgnorableType(DeserializationConfig config, BeanPropertyDefinition propDef,
892 Class<?> type, Map<Class<?>,Boolean> ignoredTypes)
893 {
894 Boolean status = ignoredTypes.get(type);
895 if (status != null) {
896 return status.booleanValue();
897 }
898
899 if ((type == String.class) || type.isPrimitive()) {
900 status = Boolean.FALSE;
901 } else {
902
903 status = config.getConfigOverride(type).getIsIgnoredType();
904 if (status == null) {
905 BeanDescription desc = config.introspectClassAnnotations(type);
906 status = config.getAnnotationIntrospector().isIgnorableType(desc.getClassInfo());
907
908 if (status == null) {
909 status = Boolean.FALSE;
910 }
911 }
912 }
913 ignoredTypes.put(type, status);
914 return status.booleanValue();
915 }
916
917
920 protected void _validateSubType(DeserializationContext ctxt, JavaType type,
921 BeanDescription beanDesc)
922 throws JsonMappingException
923 {
924 SubTypeValidator.instance().validateSubType(ctxt, type, beanDesc);
925 }
926 }
927