1 package com.fasterxml.jackson.databind.deser;
2
3 import java.io.Serializable;
4 import java.util.*;
5 import java.util.concurrent.*;
6 import java.util.concurrent.atomic.AtomicReference;
7
8 import com.fasterxml.jackson.annotation.JacksonInject;
9 import com.fasterxml.jackson.annotation.JsonCreator;
10 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
11 import com.fasterxml.jackson.annotation.JsonSetter;
12 import com.fasterxml.jackson.annotation.Nulls;
13 import com.fasterxml.jackson.annotation.JsonCreator.Mode;
14
15 import com.fasterxml.jackson.core.JsonParser;
16
17 import com.fasterxml.jackson.databind.*;
18 import com.fasterxml.jackson.databind.cfg.ConfigOverride;
19 import com.fasterxml.jackson.databind.cfg.DeserializerFactoryConfig;
20 import com.fasterxml.jackson.databind.cfg.HandlerInstantiator;
21 import com.fasterxml.jackson.databind.deser.impl.CreatorCandidate;
22 import com.fasterxml.jackson.databind.deser.impl.CreatorCollector;
23 import com.fasterxml.jackson.databind.deser.impl.JDKValueInstantiators;
24 import com.fasterxml.jackson.databind.deser.impl.JavaUtilCollectionsDeserializers;
25 import com.fasterxml.jackson.databind.deser.std.*;
26 import com.fasterxml.jackson.databind.exc.InvalidDefinitionException;
27 import com.fasterxml.jackson.databind.ext.OptionalHandlerFactory;
28 import com.fasterxml.jackson.databind.introspect.*;
29 import com.fasterxml.jackson.databind.jsontype.NamedType;
30 import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
31 import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder;
32 import com.fasterxml.jackson.databind.type.*;
33 import com.fasterxml.jackson.databind.util.*;
34
35
45 @SuppressWarnings("serial")
46 public abstract class BasicDeserializerFactory
47 extends DeserializerFactory
48 implements java.io.Serializable
49 {
50 private final static Class<?> CLASS_OBJECT = Object.class;
51 private final static Class<?> CLASS_STRING = String.class;
52 private final static Class<?> CLASS_CHAR_SEQUENCE = CharSequence.class;
53 private final static Class<?> CLASS_ITERABLE = Iterable.class;
54 private final static Class<?> CLASS_MAP_ENTRY = Map.Entry.class;
55 private final static Class<?> CLASS_SERIALIZABLE = Serializable.class;
56
57
61 protected final static PropertyName UNWRAPPED_CREATOR_PARAM_NAME = new PropertyName("@JsonUnwrapped");
62
63
68
69
73 protected final DeserializerFactoryConfig _factoryConfig;
74
75
80
81 protected BasicDeserializerFactory(DeserializerFactoryConfig config) {
82 _factoryConfig = config;
83 }
84
85
92 public DeserializerFactoryConfig getFactoryConfig() {
93 return _factoryConfig;
94 }
95
96 protected abstract DeserializerFactory withConfig(DeserializerFactoryConfig config);
97
98
103
104
108 @Override
109 public final DeserializerFactory withAdditionalDeserializers(Deserializers additional) {
110 return withConfig(_factoryConfig.withAdditionalDeserializers(additional));
111 }
112
113
117 @Override
118 public final DeserializerFactory withAdditionalKeyDeserializers(KeyDeserializers additional) {
119 return withConfig(_factoryConfig.withAdditionalKeyDeserializers(additional));
120 }
121
122
126 @Override
127 public final DeserializerFactory withDeserializerModifier(BeanDeserializerModifier modifier) {
128 return withConfig(_factoryConfig.withDeserializerModifier(modifier));
129 }
130
131
135 @Override
136 public final DeserializerFactory withAbstractTypeResolver(AbstractTypeResolver resolver) {
137 return withConfig(_factoryConfig.withAbstractTypeResolver(resolver));
138 }
139
140
144 @Override
145 public final DeserializerFactory withValueInstantiators(ValueInstantiators instantiators) {
146 return withConfig(_factoryConfig.withValueInstantiators(instantiators));
147 }
148
149
154
155 @Override
156 public JavaType mapAbstractType(DeserializationConfig config, JavaType type) throws JsonMappingException
157 {
158
159 while (true) {
160 JavaType next = _mapAbstractType2(config, type);
161 if (next == null) {
162 return type;
163 }
164
165
166 Class<?> prevCls = type.getRawClass();
167 Class<?> nextCls = next.getRawClass();
168 if ((prevCls == nextCls) || !prevCls.isAssignableFrom(nextCls)) {
169 throw new IllegalArgumentException("Invalid abstract type resolution from "+type+" to "+next+": latter is not a subtype of former");
170 }
171 type = next;
172 }
173 }
174
175
179 private JavaType _mapAbstractType2(DeserializationConfig config, JavaType type)
180 throws JsonMappingException
181 {
182 Class<?> currClass = type.getRawClass();
183 if (_factoryConfig.hasAbstractTypeResolvers()) {
184 for (AbstractTypeResolver resolver : _factoryConfig.abstractTypeResolvers()) {
185 JavaType concrete = resolver.findTypeMapping(config, type);
186 if ((concrete != null) && !concrete.hasRawClass(currClass)) {
187 return concrete;
188 }
189 }
190 }
191 return null;
192 }
193
194
199
200
205 @Override
206 public ValueInstantiator findValueInstantiator(DeserializationContext ctxt,
207 BeanDescription beanDesc)
208 throws JsonMappingException
209 {
210 final DeserializationConfig config = ctxt.getConfig();
211
212 ValueInstantiator instantiator = null;
213
214 AnnotatedClass ac = beanDesc.getClassInfo();
215 Object instDef = ctxt.getAnnotationIntrospector().findValueInstantiator(ac);
216 if (instDef != null) {
217 instantiator = _valueInstantiatorInstance(config, ac, instDef);
218 }
219 if (instantiator == null) {
220
221
222 instantiator = JDKValueInstantiators.findStdValueInstantiator(config, beanDesc.getBeanClass());
223 if (instantiator == null) {
224 instantiator = _constructDefaultValueInstantiator(ctxt, beanDesc);
225 }
226 }
227
228
229 if (_factoryConfig.hasValueInstantiators()) {
230 for (ValueInstantiators insts : _factoryConfig.valueInstantiators()) {
231 instantiator = insts.findValueInstantiator(config, beanDesc, instantiator);
232
233 if (instantiator == null) {
234 ctxt.reportBadTypeDefinition(beanDesc,
235 "Broken registered ValueInstantiators (of type %s): returned null ValueInstantiator",
236 insts.getClass().getName());
237 }
238 }
239 }
240
241
242 if (instantiator.getIncompleteParameter() != null) {
243 final AnnotatedParameter nonAnnotatedParam = instantiator.getIncompleteParameter();
244 final AnnotatedWithParams ctor = nonAnnotatedParam.getOwner();
245 throw new IllegalArgumentException("Argument #"+nonAnnotatedParam.getIndex()
246 +" of constructor "+ctor+" has no property name annotation; must have name when multiple-parameter constructor annotated as Creator");
247 }
248
249 return instantiator;
250 }
251
252
256 protected ValueInstantiator _constructDefaultValueInstantiator(DeserializationContext ctxt,
257 BeanDescription beanDesc)
258 throws JsonMappingException
259 {
260 CreatorCollector creators = new CreatorCollector(beanDesc, ctxt.getConfig());
261 AnnotationIntrospector intr = ctxt.getAnnotationIntrospector();
262
263
264 final DeserializationConfig config = ctxt.getConfig();
265 VisibilityChecker<?> vchecker = config.getDefaultVisibilityChecker(beanDesc.getBeanClass(),
266 beanDesc.getClassInfo());
267
268
273
276 Map<AnnotatedWithParams,BeanPropertyDefinition[]> creatorDefs = _findCreatorsFromProperties(ctxt,
277 beanDesc);
278
279
280 _addDeserializerFactoryMethods(ctxt, beanDesc, vchecker, intr, creators, creatorDefs);
281
282 if (beanDesc.getType().isConcrete()) {
283 _addDeserializerConstructors(ctxt, beanDesc, vchecker, intr, creators, creatorDefs);
284 }
285 return creators.constructValueInstantiator(ctxt);
286 }
287
288 protected Map<AnnotatedWithParams,BeanPropertyDefinition[]> _findCreatorsFromProperties(DeserializationContext ctxt,
289 BeanDescription beanDesc) throws JsonMappingException
290 {
291 Map<AnnotatedWithParams,BeanPropertyDefinition[]> result = Collections.emptyMap();
292 for (BeanPropertyDefinition propDef : beanDesc.findProperties()) {
293 Iterator<AnnotatedParameter> it = propDef.getConstructorParameters();
294 while (it.hasNext()) {
295 AnnotatedParameter param = it.next();
296 AnnotatedWithParams owner = param.getOwner();
297 BeanPropertyDefinition[] defs = result.get(owner);
298 final int index = param.getIndex();
299
300 if (defs == null) {
301 if (result.isEmpty()) {
302 result = new LinkedHashMap<AnnotatedWithParams,BeanPropertyDefinition[]>();
303 }
304 defs = new BeanPropertyDefinition[owner.getParameterCount()];
305 result.put(owner, defs);
306 } else {
307 if (defs[index] != null) {
308 ctxt.reportBadTypeDefinition(beanDesc,
309 "Conflict: parameter #%d of %s bound to more than one property; %s vs %s",
310 index, owner, defs[index], propDef);
311 }
312 }
313 defs[index] = propDef;
314 }
315 }
316 return result;
317 }
318
319 public ValueInstantiator _valueInstantiatorInstance(DeserializationConfig config,
320 Annotated annotated, Object instDef)
321 throws JsonMappingException
322 {
323 if (instDef == null) {
324 return null;
325 }
326
327 ValueInstantiator inst;
328
329 if (instDef instanceof ValueInstantiator) {
330 return (ValueInstantiator) instDef;
331 }
332 if (!(instDef instanceof Class)) {
333 throw new IllegalStateException("AnnotationIntrospector returned key deserializer definition of type "
334 +instDef.getClass().getName()
335 +"; expected type KeyDeserializer or Class<KeyDeserializer> instead");
336 }
337 Class<?> instClass = (Class<?>)instDef;
338 if (ClassUtil.isBogusClass(instClass)) {
339 return null;
340 }
341 if (!ValueInstantiator.class.isAssignableFrom(instClass)) {
342 throw new IllegalStateException("AnnotationIntrospector returned Class "+instClass.getName()
343 +"; expected Class<ValueInstantiator>");
344 }
345 HandlerInstantiator hi = config.getHandlerInstantiator();
346 if (hi != null) {
347 inst = hi.valueInstantiatorInstance(config, annotated, instClass);
348 if (inst != null) {
349 return inst;
350 }
351 }
352 return (ValueInstantiator) ClassUtil.createInstance(instClass,
353 config.canOverrideAccessModifiers());
354 }
355
356
361
362 protected void _addDeserializerConstructors(DeserializationContext ctxt,
363 BeanDescription beanDesc, VisibilityChecker<?> vchecker,
364 AnnotationIntrospector intr, CreatorCollector creators,
365 Map<AnnotatedWithParams,BeanPropertyDefinition[]> creatorParams)
366 throws JsonMappingException
367 {
368
369
370
371 final boolean isNonStaticInnerClass = beanDesc.isNonStaticInnerClass();
372 if (isNonStaticInnerClass) {
373
374 return;
375 }
376
377
378
379
380 AnnotatedConstructor defaultCtor = beanDesc.findDefaultConstructor();
381 if (defaultCtor != null) {
382 if (!creators.hasDefaultCreator() || _hasCreatorAnnotation(ctxt, defaultCtor)) {
383 creators.setDefaultCreator(defaultCtor);
384 }
385 }
386
387 List<CreatorCandidate> nonAnnotated = new LinkedList<>();
388 int explCount = 0;
389 for (AnnotatedConstructor ctor : beanDesc.getConstructors()) {
390 JsonCreator.Mode creatorMode = intr.findCreatorAnnotation(ctxt.getConfig(), ctor);
391 if (Mode.DISABLED == creatorMode) {
392 continue;
393 }
394 if (creatorMode == null) {
395
396 if (vchecker.isCreatorVisible(ctor)) {
397 nonAnnotated.add(CreatorCandidate.construct(intr, ctor, creatorParams.get(ctor)));
398 }
399 continue;
400 }
401 switch (creatorMode) {
402 case DELEGATING:
403 _addExplicitDelegatingCreator(ctxt, beanDesc, creators,
404 CreatorCandidate.construct(intr, ctor, null));
405 break;
406 case PROPERTIES:
407 _addExplicitPropertyCreator(ctxt, beanDesc, creators,
408 CreatorCandidate.construct(intr, ctor, creatorParams.get(ctor)));
409 break;
410 default:
411 _addExplicitAnyCreator(ctxt, beanDesc, creators,
412 CreatorCandidate.construct(intr, ctor, creatorParams.get(ctor)));
413 break;
414 }
415 ++explCount;
416 }
417
418 if (explCount > 0) {
419 return;
420 }
421 List<AnnotatedWithParams> implicitCtors = null;
422 for (CreatorCandidate candidate : nonAnnotated) {
423 final int argCount = candidate.paramCount();
424 final AnnotatedWithParams ctor = candidate.creator();
425
426
427 if (argCount == 1) {
428 BeanPropertyDefinition propDef = candidate.propertyDef(0);
429 boolean useProps = _checkIfCreatorPropertyBased(intr, ctor, propDef);
430
431 if (useProps) {
432 SettableBeanProperty[] properties = new SettableBeanProperty[1];
433 PropertyName name = candidate.paramName(0);
434 properties[0] = constructCreatorProperty(ctxt, beanDesc, name, 0,
435 candidate.parameter(0), candidate.injection(0));
436 creators.addPropertyCreator(ctor, false, properties);
437 } else {
438 _handleSingleArgumentCreator(creators,
439 ctor, false,
440 vchecker.isCreatorVisible(ctor));
441
442
443 if (propDef != null) {
444 ((POJOPropertyBuilder) propDef).removeConstructors();
445 }
446 }
447
448 continue;
449 }
450
451
452
453
454
455 int nonAnnotatedParamIndex = -1;
456 SettableBeanProperty[] properties = new SettableBeanProperty[argCount];
457 int explicitNameCount = 0;
458 int implicitWithCreatorCount = 0;
459 int injectCount = 0;
460
461 for (int i = 0; i < argCount; ++i) {
462 final AnnotatedParameter param = ctor.getParameter(i);
463 BeanPropertyDefinition propDef = candidate.propertyDef(i);
464 JacksonInject.Value injectable = intr.findInjectableValue(param);
465 final PropertyName name = (propDef == null) ? null : propDef.getFullName();
466
467 if (propDef != null && propDef.isExplicitlyNamed()) {
468 ++explicitNameCount;
469 properties[i] = constructCreatorProperty(ctxt, beanDesc, name, i, param, injectable);
470 continue;
471 }
472 if (injectable != null) {
473 ++injectCount;
474 properties[i] = constructCreatorProperty(ctxt, beanDesc, name, i, param, injectable);
475 continue;
476 }
477 NameTransformer unwrapper = intr.findUnwrappingNameTransformer(param);
478 if (unwrapper != null) {
479 _reportUnwrappedCreatorProperty(ctxt, beanDesc, param);
480
484 continue;
485 }
486
487
494 if (nonAnnotatedParamIndex < 0) {
495 nonAnnotatedParamIndex = i;
496 }
497 }
498
499 final int namedCount = explicitNameCount + implicitWithCreatorCount;
500
501 if ((explicitNameCount > 0) || (injectCount > 0)) {
502
503 if ((namedCount + injectCount) == argCount) {
504 creators.addPropertyCreator(ctor, false, properties);
505 continue;
506 }
507 if ((explicitNameCount == 0) && ((injectCount + 1) == argCount)) {
508
509 creators.addDelegatingCreator(ctor, false, properties, 0);
510 continue;
511 }
512
513
514
515 PropertyName impl = candidate.findImplicitParamName(nonAnnotatedParamIndex);
516 if (impl == null || impl.isEmpty()) {
517
518
519
525 ctxt.reportBadTypeDefinition(beanDesc,
526 "Argument #%d of constructor %s has no property name annotation; must have name when multiple-parameter constructor annotated as Creator",
527 nonAnnotatedParamIndex, ctor);
528 }
529 }
530
531 if (!creators.hasDefaultCreator()) {
532 if (implicitCtors == null) {
533 implicitCtors = new LinkedList<>();
534 }
535 implicitCtors.add(ctor);
536 }
537 }
538
539
540 if ((implicitCtors != null) && !creators.hasDelegatingCreator()
541 && !creators.hasPropertyBasedCreator()) {
542 _checkImplicitlyNamedConstructors(ctxt, beanDesc, vchecker, intr,
543 creators, implicitCtors);
544 }
545 }
546
547
552 protected void _addExplicitDelegatingCreator(DeserializationContext ctxt,
553 BeanDescription beanDesc, CreatorCollector creators,
554 CreatorCandidate candidate)
555 throws JsonMappingException
556 {
557
558
559
560 int ix = -1;
561 final int argCount = candidate.paramCount();
562 SettableBeanProperty[] properties = new SettableBeanProperty[argCount];
563 for (int i = 0; i < argCount; ++i) {
564 AnnotatedParameter param = candidate.parameter(i);
565 JacksonInject.Value injectId = candidate.injection(i);
566 if (injectId != null) {
567 properties[i] = constructCreatorProperty(ctxt, beanDesc, null, i, param, injectId);
568 continue;
569 }
570 if (ix < 0) {
571 ix = i;
572 continue;
573 }
574
575 ctxt.reportBadTypeDefinition(beanDesc,
576 "More than one argument (#%d and #%d) left as delegating for Creator %s: only one allowed",
577 ix, i, candidate);
578 }
579
580 if (ix < 0) {
581 ctxt.reportBadTypeDefinition(beanDesc,
582 "No argument left as delegating for Creator %s: exactly one required", candidate);
583 }
584
585
586 if (argCount == 1) {
587 _handleSingleArgumentCreator(creators, candidate.creator(), true, true);
588
589
590 BeanPropertyDefinition paramDef = candidate.propertyDef(0);
591 if (paramDef != null) {
592 ((POJOPropertyBuilder) paramDef).removeConstructors();
593 }
594 return;
595 }
596 creators.addDelegatingCreator(candidate.creator(), true, properties, ix);
597 }
598
599
604 protected void _addExplicitPropertyCreator(DeserializationContext ctxt,
605 BeanDescription beanDesc, CreatorCollector creators,
606 CreatorCandidate candidate)
607 throws JsonMappingException
608 {
609 final int paramCount = candidate.paramCount();
610 SettableBeanProperty[] properties = new SettableBeanProperty[paramCount];
611
612 for (int i = 0; i < paramCount; ++i) {
613 JacksonInject.Value injectId = candidate.injection(i);
614 AnnotatedParameter param = candidate.parameter(i);
615 PropertyName name = candidate.paramName(i);
616 if (name == null) {
617
618
619 NameTransformer unwrapper = ctxt.getAnnotationIntrospector().findUnwrappingNameTransformer(param);
620 if (unwrapper != null) {
621 _reportUnwrappedCreatorProperty(ctxt, beanDesc, param);
622
626 }
627 name = candidate.findImplicitParamName(i);
628
629 if ((name == null) && (injectId == null)) {
630 ctxt.reportBadTypeDefinition(beanDesc,
631 "Argument #%d has no property name, is not Injectable: can not use as Creator %s", i, candidate);
632 }
633 }
634 properties[i] = constructCreatorProperty(ctxt, beanDesc, name, i, param, injectId);
635 }
636 creators.addPropertyCreator(candidate.creator(), true, properties);
637 }
638
639
644 protected void _addExplicitAnyCreator(DeserializationContext ctxt,
645 BeanDescription beanDesc, CreatorCollector creators,
646 CreatorCandidate candidate)
647 throws JsonMappingException
648 {
649
650 if (1 != candidate.paramCount()) {
651
652
653 int oneNotInjected = candidate.findOnlyParamWithoutInjection();
654 if (oneNotInjected >= 0) {
655
656 if (candidate.paramName(oneNotInjected) == null) {
657 _addExplicitDelegatingCreator(ctxt, beanDesc, creators, candidate);
658 return;
659 }
660 }
661 _addExplicitPropertyCreator(ctxt, beanDesc, creators, candidate);
662 return;
663 }
664 AnnotatedParameter param = candidate.parameter(0);
665 JacksonInject.Value injectId = candidate.injection(0);
666 PropertyName paramName = candidate.explicitParamName(0);
667 BeanPropertyDefinition paramDef = candidate.propertyDef(0);
668
669
670 boolean useProps = (paramName != null) || (injectId != null);
671 if (!useProps && (paramDef != null)) {
672
673
674
675
676
677
678 paramName = candidate.paramName(0);
679 useProps = (paramName != null) && paramDef.couldSerialize();
680 }
681 if (useProps) {
682 SettableBeanProperty[] properties = new SettableBeanProperty[] {
683 constructCreatorProperty(ctxt, beanDesc, paramName, 0, param, injectId)
684 };
685 creators.addPropertyCreator(candidate.creator(), true, properties);
686 return;
687 }
688 _handleSingleArgumentCreator(creators, candidate.creator(), true, true);
689
690
691
692 if (paramDef != null) {
693 ((POJOPropertyBuilder) paramDef).removeConstructors();
694 }
695 }
696
697 private boolean _checkIfCreatorPropertyBased(AnnotationIntrospector intr,
698 AnnotatedWithParams creator, BeanPropertyDefinition propDef)
699 {
700
701 if (((propDef != null) && propDef.isExplicitlyNamed())
702 || (intr.findInjectableValue(creator.getParameter(0)) != null)) {
703 return true;
704 }
705 if (propDef != null) {
706
707
708 String implName = propDef.getName();
709 if (implName != null && !implName.isEmpty()) {
710 if (propDef.couldSerialize()) {
711 return true;
712 }
713 }
714 }
715
716 return false;
717 }
718
719 private void _checkImplicitlyNamedConstructors(DeserializationContext ctxt,
720 BeanDescription beanDesc, VisibilityChecker<?> vchecker,
721 AnnotationIntrospector intr, CreatorCollector creators,
722 List<AnnotatedWithParams> implicitCtors) throws JsonMappingException
723 {
724 AnnotatedWithParams found = null;
725 SettableBeanProperty[] foundProps = null;
726
727
728
729
730
731 main_loop:
732 for (AnnotatedWithParams ctor : implicitCtors) {
733 if (!vchecker.isCreatorVisible(ctor)) {
734 continue;
735 }
736
737 final int argCount = ctor.getParameterCount();
738 SettableBeanProperty[] properties = new SettableBeanProperty[argCount];
739 for (int i = 0; i < argCount; ++i) {
740 final AnnotatedParameter param = ctor.getParameter(i);
741 final PropertyName name = _findParamName(param, intr);
742
743
744 if (name == null || name.isEmpty()) {
745 continue main_loop;
746 }
747 properties[i] = constructCreatorProperty(ctxt, beanDesc, name, param.getIndex(),
748 param, null);
749 }
750 if (found != null) {
751 found = null;
752 break;
753 }
754 found = ctor;
755 foundProps = properties;
756 }
757
758 if (found != null) {
759 creators.addPropertyCreator(found, false, foundProps);
760 BasicBeanDescription bbd = (BasicBeanDescription) beanDesc;
761
762 for (SettableBeanProperty prop : foundProps) {
763 PropertyName pn = prop.getFullName();
764 if (!bbd.hasProperty(pn)) {
765 BeanPropertyDefinition newDef = SimpleBeanPropertyDefinition.construct(
766 ctxt.getConfig(), prop.getMember(), pn);
767 bbd.addProperty(newDef);
768 }
769 }
770 }
771 }
772
773 protected void _addDeserializerFactoryMethods
774 (DeserializationContext ctxt, BeanDescription beanDesc, VisibilityChecker<?> vchecker,
775 AnnotationIntrospector intr, CreatorCollector creators,
776 Map<AnnotatedWithParams,BeanPropertyDefinition[]> creatorParams)
777 throws JsonMappingException
778 {
779 List<CreatorCandidate> nonAnnotated = new LinkedList<>();
780 int explCount = 0;
781
782
783 for (AnnotatedMethod factory : beanDesc.getFactoryMethods()) {
784 JsonCreator.Mode creatorMode = intr.findCreatorAnnotation(ctxt.getConfig(), factory);
785 final int argCount = factory.getParameterCount();
786 if (creatorMode == null) {
787
788 if ((argCount == 1) && vchecker.isCreatorVisible(factory)) {
789 nonAnnotated.add(CreatorCandidate.construct(intr, factory, null));
790 }
791 continue;
792 }
793 if (creatorMode == Mode.DISABLED) {
794 continue;
795 }
796
797
798 if (argCount == 0) {
799 creators.setDefaultCreator(factory);
800 continue;
801 }
802
803 switch (creatorMode) {
804 case DELEGATING:
805 _addExplicitDelegatingCreator(ctxt, beanDesc, creators,
806 CreatorCandidate.construct(intr, factory, null));
807 break;
808 case PROPERTIES:
809 _addExplicitPropertyCreator(ctxt, beanDesc, creators,
810 CreatorCandidate.construct(intr, factory, creatorParams.get(factory)));
811 break;
812 case DEFAULT:
813 default:
814 _addExplicitAnyCreator(ctxt, beanDesc, creators,
815 CreatorCandidate.construct(intr, factory, creatorParams.get(factory)));
816 break;
817 }
818 ++explCount;
819 }
820
821 if (explCount > 0) {
822 return;
823 }
824
825 for (CreatorCandidate candidate : nonAnnotated) {
826 final int argCount = candidate.paramCount();
827 AnnotatedWithParams factory = candidate.creator();
828 final BeanPropertyDefinition[] propDefs = creatorParams.get(factory);
829
830 if (argCount != 1) {
831 continue;
832 }
833 BeanPropertyDefinition argDef = candidate.propertyDef(0);
834 boolean useProps = _checkIfCreatorPropertyBased(intr, factory, argDef);
835 if (!useProps) {
836 _handleSingleArgumentCreator(creators,
837 factory, false, vchecker.isCreatorVisible(factory));
838
839
840 if (argDef != null) {
841 ((POJOPropertyBuilder) argDef).removeConstructors();
842 }
843 continue;
844 }
845 AnnotatedParameter nonAnnotatedParam = null;
846 SettableBeanProperty[] properties = new SettableBeanProperty[argCount];
847 int implicitNameCount = 0;
848 int explicitNameCount = 0;
849 int injectCount = 0;
850
851 for (int i = 0; i < argCount; ++i) {
852 final AnnotatedParameter param = factory.getParameter(i);
853 BeanPropertyDefinition propDef = (propDefs == null) ? null : propDefs[i];
854 JacksonInject.Value injectable = intr.findInjectableValue(param);
855 final PropertyName name = (propDef == null) ? null : propDef.getFullName();
856
857 if (propDef != null && propDef.isExplicitlyNamed()) {
858 ++explicitNameCount;
859 properties[i] = constructCreatorProperty(ctxt, beanDesc, name, i, param, injectable);
860 continue;
861 }
862 if (injectable != null) {
863 ++injectCount;
864 properties[i] = constructCreatorProperty(ctxt, beanDesc, name, i, param, injectable);
865 continue;
866 }
867 NameTransformer unwrapper = intr.findUnwrappingNameTransformer(param);
868 if (unwrapper != null) {
869 _reportUnwrappedCreatorProperty(ctxt, beanDesc, param);
870
874 continue;
875 }
876
877
886
890
898 if (nonAnnotatedParam == null) {
899 nonAnnotatedParam = param;
900 }
901 }
902 final int namedCount = explicitNameCount + implicitNameCount;
903
904
905 if (explicitNameCount > 0 || injectCount > 0) {
906
907 if ((namedCount + injectCount) == argCount) {
908 creators.addPropertyCreator(factory, false, properties);
909 } else if ((explicitNameCount == 0) && ((injectCount + 1) == argCount)) {
910
911 creators.addDelegatingCreator(factory, false, properties, 0);
912 } else {
913 ctxt.reportBadTypeDefinition(beanDesc,
914 "Argument #%d of factory method %s has no property name annotation; must have name when multiple-parameter constructor annotated as Creator",
915 nonAnnotatedParam.getIndex(), factory);
916 }
917 }
918 }
919 }
920
921 protected boolean _handleSingleArgumentCreator(CreatorCollector creators,
922 AnnotatedWithParams ctor, boolean isCreator, boolean isVisible)
923 {
924
925 Class<?> type = ctor.getRawParameterType(0);
926 if (type == String.class || type == CLASS_CHAR_SEQUENCE) {
927 if (isCreator || isVisible) {
928 creators.addStringCreator(ctor, isCreator);
929 }
930 return true;
931 }
932 if (type == int.class || type == Integer.class) {
933 if (isCreator || isVisible) {
934 creators.addIntCreator(ctor, isCreator);
935 }
936 return true;
937 }
938 if (type == long.class || type == Long.class) {
939 if (isCreator || isVisible) {
940 creators.addLongCreator(ctor, isCreator);
941 }
942 return true;
943 }
944 if (type == double.class || type == Double.class) {
945 if (isCreator || isVisible) {
946 creators.addDoubleCreator(ctor, isCreator);
947 }
948 return true;
949 }
950 if (type == boolean.class || type == Boolean.class) {
951 if (isCreator || isVisible) {
952 creators.addBooleanCreator(ctor, isCreator);
953 }
954 return true;
955 }
956
957 if (isCreator) {
958 creators.addDelegatingCreator(ctor, isCreator, null, 0);
959 return true;
960 }
961 return false;
962 }
963
964
965
966 protected void _reportUnwrappedCreatorProperty(DeserializationContext ctxt,
967 BeanDescription beanDesc, AnnotatedParameter param)
968 throws JsonMappingException
969 {
970 ctxt.reportBadDefinition(beanDesc.getType(), String.format(
971 "Cannot define Creator parameter %d as `@JsonUnwrapped`: combination not yet supported",
972 param.getIndex()));
973 }
974
975
980 protected SettableBeanProperty constructCreatorProperty(DeserializationContext ctxt,
981 BeanDescription beanDesc, PropertyName name, int index,
982 AnnotatedParameter param,
983 JacksonInject.Value injectable)
984 throws JsonMappingException
985 {
986 final DeserializationConfig config = ctxt.getConfig();
987 final AnnotationIntrospector intr = ctxt.getAnnotationIntrospector();
988 PropertyMetadata metadata;
989 {
990 if (intr == null) {
991 metadata = PropertyMetadata.STD_REQUIRED_OR_OPTIONAL;
992 } else {
993 Boolean b = intr.hasRequiredMarker(param);
994 String desc = intr.findPropertyDescription(param);
995 Integer idx = intr.findPropertyIndex(param);
996 String def = intr.findPropertyDefaultValue(param);
997 metadata = PropertyMetadata.construct(b, desc, idx, def);
998 }
999 }
1000 JavaType type = resolveMemberAndTypeAnnotations(ctxt, param, param.getType());
1001 BeanProperty.Std property = new BeanProperty.Std(name, type,
1002 intr.findWrapperName(param), param, metadata);
1003
1004 TypeDeserializer typeDeser = (TypeDeserializer) type.getTypeHandler();
1005
1006 if (typeDeser == null) {
1007 typeDeser = findTypeDeserializer(config, type);
1008 }
1009
1010
1011
1012 metadata = _getSetterInfo(ctxt, property, metadata);
1013
1014
1015
1016 SettableBeanProperty prop = CreatorProperty.construct(name, type, property.getWrapperName(),
1017 typeDeser, beanDesc.getClassAnnotations(), param, index, injectable,
1018 metadata);
1019 JsonDeserializer<?> deser = findDeserializerFromAnnotation(ctxt, param);
1020 if (deser == null) {
1021 deser = type.getValueHandler();
1022 }
1023 if (deser != null) {
1024
1025 deser = ctxt.handlePrimaryContextualization(deser, prop, type);
1026 prop = prop.withValueDeserializer(deser);
1027 }
1028 return prop;
1029 }
1030
1031 private PropertyName _findParamName(AnnotatedParameter param, AnnotationIntrospector intr)
1032 {
1033 if (param != null && intr != null) {
1034 PropertyName name = intr.findNameForDeserialization(param);
1035 if (name != null) {
1036 return name;
1037 }
1038
1039
1040
1041 String str = intr.findImplicitPropertyName(param);
1042 if (str != null && !str.isEmpty()) {
1043 return PropertyName.construct(str);
1044 }
1045 }
1046 return null;
1047 }
1048
1049
1055 protected PropertyMetadata _getSetterInfo(DeserializationContext ctxt,
1056 BeanProperty prop, PropertyMetadata metadata)
1057 {
1058 final AnnotationIntrospector intr = ctxt.getAnnotationIntrospector();
1059 final DeserializationConfig config = ctxt.getConfig();
1060
1061 boolean needMerge = true;
1062 Nulls valueNulls = null;
1063 Nulls contentNulls = null;
1064
1065
1066
1067 AnnotatedMember prim = prop.getMember();
1068
1069 if (prim != null) {
1070
1071 if (intr != null) {
1072 JsonSetter.Value setterInfo = intr.findSetterInfo(prim);
1073 if (setterInfo != null) {
1074 valueNulls = setterInfo.nonDefaultValueNulls();
1075 contentNulls = setterInfo.nonDefaultContentNulls();
1076 }
1077 }
1078
1079
1080 if (needMerge || (valueNulls == null) || (contentNulls == null)) {
1081 ConfigOverride co = config.getConfigOverride(prop.getType().getRawClass());
1082 JsonSetter.Value setterInfo = co.getSetterInfo();
1083 if (setterInfo != null) {
1084 if (valueNulls == null) {
1085 valueNulls = setterInfo.nonDefaultValueNulls();
1086 }
1087 if (contentNulls == null) {
1088 contentNulls = setterInfo.nonDefaultContentNulls();
1089 }
1090 }
1091 }
1092 }
1093 if (needMerge || (valueNulls == null) || (contentNulls == null)) {
1094 JsonSetter.Value setterInfo = config.getDefaultSetterInfo();
1095 if (valueNulls == null) {
1096 valueNulls = setterInfo.nonDefaultValueNulls();
1097 }
1098 if (contentNulls == null) {
1099 contentNulls = setterInfo.nonDefaultContentNulls();
1100 }
1101 }
1102 if ((valueNulls != null) || (contentNulls != null)) {
1103 metadata = metadata.withNulls(valueNulls, contentNulls);
1104 }
1105 return metadata;
1106 }
1107
1108
1113
1114 @Override
1115 public JsonDeserializer<?> createArrayDeserializer(DeserializationContext ctxt,
1116 ArrayType type, final BeanDescription beanDesc)
1117 throws JsonMappingException
1118 {
1119 final DeserializationConfig config = ctxt.getConfig();
1120 JavaType elemType = type.getContentType();
1121
1122
1123 JsonDeserializer<Object> contentDeser = elemType.getValueHandler();
1124
1125 TypeDeserializer elemTypeDeser = elemType.getTypeHandler();
1126
1127 if (elemTypeDeser == null) {
1128 elemTypeDeser = findTypeDeserializer(config, elemType);
1129 }
1130
1131 JsonDeserializer<?> deser = _findCustomArrayDeserializer(type,
1132 config, beanDesc, elemTypeDeser, contentDeser);
1133 if (deser == null) {
1134 if (contentDeser == null) {
1135 Class<?> raw = elemType.getRawClass();
1136 if (elemType.isPrimitive()) {
1137 return PrimitiveArrayDeserializers.forType(raw);
1138 }
1139 if (raw == String.class) {
1140 return StringArrayDeserializer.instance;
1141 }
1142 }
1143 deser = new ObjectArrayDeserializer(type, contentDeser, elemTypeDeser);
1144 }
1145
1146 if (_factoryConfig.hasDeserializerModifiers()) {
1147 for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
1148 deser = mod.modifyArrayDeserializer(config, type, beanDesc, deser);
1149 }
1150 }
1151 return deser;
1152 }
1153
1154
1159
1160 @Override
1161 public JsonDeserializer<?> createCollectionDeserializer(DeserializationContext ctxt,
1162 CollectionType type, BeanDescription beanDesc)
1163 throws JsonMappingException
1164 {
1165 JavaType contentType = type.getContentType();
1166
1167 JsonDeserializer<Object> contentDeser = contentType.getValueHandler();
1168 final DeserializationConfig config = ctxt.getConfig();
1169
1170
1171 TypeDeserializer contentTypeDeser = contentType.getTypeHandler();
1172
1173 if (contentTypeDeser == null) {
1174 contentTypeDeser = findTypeDeserializer(config, contentType);
1175 }
1176
1177 JsonDeserializer<?> deser = _findCustomCollectionDeserializer(type,
1178 config, beanDesc, contentTypeDeser, contentDeser);
1179 if (deser == null) {
1180 Class<?> collectionClass = type.getRawClass();
1181 if (contentDeser == null) {
1182
1183 if (EnumSet.class.isAssignableFrom(collectionClass)) {
1184 deser = new EnumSetDeserializer(contentType, null);
1185 }
1186 }
1187 }
1188
1189
1198 if (deser == null) {
1199 if (type.isInterface() || type.isAbstract()) {
1200 CollectionType implType = _mapAbstractCollectionType(type, config);
1201 if (implType == null) {
1202
1203 if (type.getTypeHandler() == null) {
1204 throw new IllegalArgumentException("Cannot find a deserializer for non-concrete Collection type "+type);
1205 }
1206 deser = AbstractDeserializer.constructForNonPOJO(beanDesc);
1207 } else {
1208 type = implType;
1209
1210 beanDesc = config.introspectForCreation(type);
1211 }
1212 }
1213 if (deser == null) {
1214 ValueInstantiator inst = findValueInstantiator(ctxt, beanDesc);
1215 if (!inst.canCreateUsingDefault()) {
1216
1217 if (type.hasRawClass(ArrayBlockingQueue.class)) {
1218 return new ArrayBlockingQueueDeserializer(type, contentDeser, contentTypeDeser, inst);
1219 }
1220
1221 deser = JavaUtilCollectionsDeserializers.findForCollection(ctxt, type);
1222 if (deser != null) {
1223 return deser;
1224 }
1225 }
1226
1227 if (contentType.hasRawClass(String.class)) {
1228
1229 deser = new StringCollectionDeserializer(type, contentDeser, inst);
1230 } else {
1231 deser = new CollectionDeserializer(type, contentDeser, contentTypeDeser, inst);
1232 }
1233 }
1234 }
1235
1236 if (_factoryConfig.hasDeserializerModifiers()) {
1237 for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
1238 deser = mod.modifyCollectionDeserializer(config, type, beanDesc, deser);
1239 }
1240 }
1241 return deser;
1242 }
1243
1244 protected CollectionType _mapAbstractCollectionType(JavaType type, DeserializationConfig config)
1245 {
1246 final Class<?> collectionClass = ContainerDefaultMappings.findCollectionFallback(type);
1247 if (collectionClass != null) {
1248 return (CollectionType) config.getTypeFactory()
1249 .constructSpecializedType(type, collectionClass, true);
1250 }
1251 return null;
1252 }
1253
1254
1255 @Override
1256 public JsonDeserializer<?> createCollectionLikeDeserializer(DeserializationContext ctxt,
1257 CollectionLikeType type, final BeanDescription beanDesc)
1258 throws JsonMappingException
1259 {
1260 JavaType contentType = type.getContentType();
1261
1262 JsonDeserializer<Object> contentDeser = contentType.getValueHandler();
1263 final DeserializationConfig config = ctxt.getConfig();
1264
1265
1266 TypeDeserializer contentTypeDeser = contentType.getTypeHandler();
1267
1268 if (contentTypeDeser == null) {
1269 contentTypeDeser = findTypeDeserializer(config, contentType);
1270 }
1271 JsonDeserializer<?> deser = _findCustomCollectionLikeDeserializer(type, config, beanDesc,
1272 contentTypeDeser, contentDeser);
1273 if (deser != null) {
1274
1275 if (_factoryConfig.hasDeserializerModifiers()) {
1276 for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
1277 deser = mod.modifyCollectionLikeDeserializer(config, type, beanDesc, deser);
1278 }
1279 }
1280 }
1281 return deser;
1282 }
1283
1284
1289
1290 @Override
1291 public JsonDeserializer<?> createMapDeserializer(DeserializationContext ctxt,
1292 MapType type, BeanDescription beanDesc)
1293 throws JsonMappingException
1294 {
1295 final DeserializationConfig config = ctxt.getConfig();
1296 JavaType keyType = type.getKeyType();
1297 JavaType contentType = type.getContentType();
1298
1299
1300 @SuppressWarnings("unchecked")
1301 JsonDeserializer<Object> contentDeser = (JsonDeserializer<Object>) contentType.getValueHandler();
1302
1303
1304 KeyDeserializer keyDes = (KeyDeserializer) keyType.getValueHandler();
1305
1306 TypeDeserializer contentTypeDeser = contentType.getTypeHandler();
1307
1308 if (contentTypeDeser == null) {
1309 contentTypeDeser = findTypeDeserializer(config, contentType);
1310 }
1311
1312
1313 JsonDeserializer<?> deser = _findCustomMapDeserializer(type, config, beanDesc,
1314 keyDes, contentTypeDeser, contentDeser);
1315
1316 if (deser == null) {
1317
1318 Class<?> mapClass = type.getRawClass();
1319 if (EnumMap.class.isAssignableFrom(mapClass)) {
1320 ValueInstantiator inst;
1321
1322
1323
1324 if (mapClass == EnumMap.class) {
1325 inst = null;
1326 } else {
1327 inst = findValueInstantiator(ctxt, beanDesc);
1328 }
1329 if (!keyType.isEnumImplType()) {
1330 throw new IllegalArgumentException("Cannot construct EnumMap; generic (key) type not available");
1331 }
1332 deser = new EnumMapDeserializer(type, inst, null,
1333 contentDeser, contentTypeDeser, null);
1334 }
1335
1336
1337
1338
1347 if (deser == null) {
1348 if (type.isInterface() || type.isAbstract()) {
1349 MapType fallback = _mapAbstractMapType(type, config);
1350 if (fallback != null) {
1351 type = (MapType) fallback;
1352 mapClass = type.getRawClass();
1353
1354 beanDesc = config.introspectForCreation(type);
1355 } else {
1356
1357 if (type.getTypeHandler() == null) {
1358 throw new IllegalArgumentException("Cannot find a deserializer for non-concrete Map type "+type);
1359 }
1360 deser = AbstractDeserializer.constructForNonPOJO(beanDesc);
1361 }
1362 } else {
1363
1364 deser = JavaUtilCollectionsDeserializers.findForMap(ctxt, type);
1365 if (deser != null) {
1366 return deser;
1367 }
1368 }
1369 if (deser == null) {
1370 ValueInstantiator inst = findValueInstantiator(ctxt, beanDesc);
1371
1372
1373
1374
1375 MapDeserializer md = new MapDeserializer(type, inst, keyDes, contentDeser, contentTypeDeser);
1376 JsonIgnoreProperties.Value ignorals = config.getDefaultPropertyIgnorals(Map.class,
1377 beanDesc.getClassInfo());
1378 Set<String> ignored = (ignorals == null) ? null
1379 : ignorals.findIgnoredForDeserialization();
1380 md.setIgnorableProperties(ignored);
1381 deser = md;
1382 }
1383 }
1384 }
1385 if (_factoryConfig.hasDeserializerModifiers()) {
1386 for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
1387 deser = mod.modifyMapDeserializer(config, type, beanDesc, deser);
1388 }
1389 }
1390 return deser;
1391 }
1392
1393 protected MapType _mapAbstractMapType(JavaType type, DeserializationConfig config)
1394 {
1395 final Class<?> mapClass = ContainerDefaultMappings.findMapFallback(type);
1396 if (mapClass != null) {
1397 return (MapType) config.getTypeFactory()
1398 .constructSpecializedType(type, mapClass, true);
1399 }
1400 return null;
1401 }
1402
1403
1404 @Override
1405 public JsonDeserializer<?> createMapLikeDeserializer(DeserializationContext ctxt,
1406 MapLikeType type, final BeanDescription beanDesc)
1407 throws JsonMappingException
1408 {
1409 JavaType keyType = type.getKeyType();
1410 JavaType contentType = type.getContentType();
1411 final DeserializationConfig config = ctxt.getConfig();
1412
1413
1414 @SuppressWarnings("unchecked")
1415 JsonDeserializer<Object> contentDeser = (JsonDeserializer<Object>) contentType.getValueHandler();
1416
1417
1418 KeyDeserializer keyDes = (KeyDeserializer) keyType.getValueHandler();
1419
1424
1425 TypeDeserializer contentTypeDeser = contentType.getTypeHandler();
1426
1427 if (contentTypeDeser == null) {
1428 contentTypeDeser = findTypeDeserializer(config, contentType);
1429 }
1430 JsonDeserializer<?> deser = _findCustomMapLikeDeserializer(type, config,
1431 beanDesc, keyDes, contentTypeDeser, contentDeser);
1432 if (deser != null) {
1433
1434 if (_factoryConfig.hasDeserializerModifiers()) {
1435 for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
1436 deser = mod.modifyMapLikeDeserializer(config, type, beanDesc, deser);
1437 }
1438 }
1439 }
1440 return deser;
1441 }
1442
1443
1448
1449
1452 @Override
1453 public JsonDeserializer<?> createEnumDeserializer(DeserializationContext ctxt,
1454 JavaType type, BeanDescription beanDesc)
1455 throws JsonMappingException
1456 {
1457 final DeserializationConfig config = ctxt.getConfig();
1458 final Class<?> enumClass = type.getRawClass();
1459
1460 JsonDeserializer<?> deser = _findCustomEnumDeserializer(enumClass, config, beanDesc);
1461
1462 if (deser == null) {
1463
1464
1465
1466
1467
1468 if (enumClass == Enum.class) {
1469 return AbstractDeserializer.constructForNonPOJO(beanDesc);
1470 }
1471
1472 ValueInstantiator valueInstantiator = _constructDefaultValueInstantiator(ctxt, beanDesc);
1473 SettableBeanProperty[] creatorProps = (valueInstantiator == null) ? null
1474 : valueInstantiator.getFromObjectArguments(ctxt.getConfig());
1475
1476 for (AnnotatedMethod factory : beanDesc.getFactoryMethods()) {
1477 if (_hasCreatorAnnotation(ctxt, factory)) {
1478 if (factory.getParameterCount() == 0) {
1479 deser = EnumDeserializer.deserializerForNoArgsCreator(config, enumClass, factory);
1480 break;
1481 }
1482 Class<?> returnType = factory.getRawReturnType();
1483
1484 if (!returnType.isAssignableFrom(enumClass)) {
1485 ctxt.reportBadDefinition(type, String.format(
1486 "Invalid `@JsonCreator` annotated Enum factory method [%s]: needs to return compatible type",
1487 factory.toString()));
1488 }
1489 deser = EnumDeserializer.deserializerForCreator(config, enumClass, factory, valueInstantiator, creatorProps);
1490 break;
1491 }
1492 }
1493
1494
1495 if (deser == null) {
1496 deser = new EnumDeserializer(constructEnumResolver(enumClass,
1497 config, beanDesc.findJsonValueAccessor()),
1498 config.isEnabled(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS));
1499 }
1500 }
1501
1502
1503 if (_factoryConfig.hasDeserializerModifiers()) {
1504 for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
1505 deser = mod.modifyEnumDeserializer(config, type, beanDesc, deser);
1506 }
1507 }
1508 return deser;
1509 }
1510
1511 @Override
1512 public JsonDeserializer<?> createTreeDeserializer(DeserializationConfig config,
1513 JavaType nodeType, BeanDescription beanDesc)
1514 throws JsonMappingException
1515 {
1516 @SuppressWarnings("unchecked")
1517 Class<? extends JsonNode> nodeClass = (Class<? extends JsonNode>) nodeType.getRawClass();
1518
1519 JsonDeserializer<?> custom = _findCustomTreeNodeDeserializer(nodeClass, config,
1520 beanDesc);
1521 if (custom != null) {
1522 return custom;
1523 }
1524 return JsonNodeDeserializer.getDeserializer(nodeClass);
1525 }
1526
1527 @Override
1528 public JsonDeserializer<?> createReferenceDeserializer(DeserializationContext ctxt,
1529 ReferenceType type, BeanDescription beanDesc)
1530 throws JsonMappingException
1531 {
1532 JavaType contentType = type.getContentType();
1533
1534 JsonDeserializer<Object> contentDeser = contentType.getValueHandler();
1535 final DeserializationConfig config = ctxt.getConfig();
1536
1537 TypeDeserializer contentTypeDeser = contentType.getTypeHandler();
1538 if (contentTypeDeser == null) {
1539 contentTypeDeser = findTypeDeserializer(config, contentType);
1540 }
1541 JsonDeserializer<?> deser = _findCustomReferenceDeserializer(type, config, beanDesc,
1542 contentTypeDeser, contentDeser);
1543
1544 if (deser == null) {
1545
1546 if (type.isTypeOrSubTypeOf(AtomicReference.class)) {
1547 Class<?> rawType = type.getRawClass();
1548 ValueInstantiator inst;
1549 if (rawType == AtomicReference.class) {
1550 inst = null;
1551 } else {
1552
1556 inst = findValueInstantiator(ctxt, beanDesc);
1557 }
1558 return new AtomicReferenceDeserializer(type, inst, contentTypeDeser, contentDeser);
1559 }
1560 }
1561 if (deser != null) {
1562
1563 if (_factoryConfig.hasDeserializerModifiers()) {
1564 for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
1565 deser = mod.modifyReferenceDeserializer(config, type, beanDesc, deser);
1566 }
1567 }
1568 }
1569 return deser;
1570 }
1571
1572
1577
1578 @Override
1579 public TypeDeserializer findTypeDeserializer(DeserializationConfig config,
1580 JavaType baseType)
1581 throws JsonMappingException
1582 {
1583 BeanDescription bean = config.introspectClassAnnotations(baseType.getRawClass());
1584 AnnotatedClass ac = bean.getClassInfo();
1585 AnnotationIntrospector ai = config.getAnnotationIntrospector();
1586 TypeResolverBuilder<?> b = ai.findTypeResolver(config, ac, baseType);
1587
1588
1589
1590 Collection<NamedType> subtypes = null;
1591 if (b == null) {
1592 b = config.getDefaultTyper(baseType);
1593 if (b == null) {
1594 return null;
1595 }
1596 } else {
1597 subtypes = config.getSubtypeResolver().collectAndResolveSubtypesByTypeId(config, ac);
1598 }
1599
1600
1601 if ((b.getDefaultImpl() == null) && baseType.isAbstract()) {
1602 JavaType defaultType = mapAbstractType(config, baseType);
1603 if ((defaultType != null) && !defaultType.hasRawClass(baseType.getRawClass())) {
1604 b = b.defaultImpl(defaultType.getRawClass());
1605 }
1606 }
1607
1608
1609 try {
1610 return b.buildTypeDeserializer(config, baseType, subtypes);
1611 } catch (IllegalArgumentException e0) {
1612 InvalidDefinitionException e = InvalidDefinitionException.from((JsonParser) null,
1613 ClassUtil.exceptionMessage(e0), baseType);
1614 e.initCause(e0);
1615 throw e;
1616 }
1617 }
1618
1619
1624 protected JsonDeserializer<?> findOptionalStdDeserializer(DeserializationContext ctxt,
1625 JavaType type, BeanDescription beanDesc)
1626 throws JsonMappingException
1627 {
1628 return OptionalHandlerFactory.instance.findDeserializer(type, ctxt.getConfig(), beanDesc);
1629 }
1630
1631
1636
1637 @Override
1638 public KeyDeserializer createKeyDeserializer(DeserializationContext ctxt,
1639 JavaType type)
1640 throws JsonMappingException
1641 {
1642 final DeserializationConfig config = ctxt.getConfig();
1643 BeanDescription beanDesc = null;
1644 KeyDeserializer deser = null;
1645 if (_factoryConfig.hasKeyDeserializers()) {
1646 beanDesc = config.introspectClassAnnotations(type);
1647 for (KeyDeserializers d : _factoryConfig.keyDeserializers()) {
1648 deser = d.findKeyDeserializer(type, config, beanDesc);
1649 if (deser != null) {
1650 break;
1651 }
1652 }
1653 }
1654
1655
1656 if (deser == null) {
1657
1658 if (beanDesc == null) {
1659 beanDesc = config.introspectClassAnnotations(type.getRawClass());
1660 }
1661 deser = findKeyDeserializerFromAnnotation(ctxt, beanDesc.getClassInfo());
1662 if (deser == null) {
1663 if (type.isEnumType()) {
1664 deser = _createEnumKeyDeserializer(ctxt, type);
1665 } else {
1666 deser = StdKeyDeserializers.findStringBasedKeyDeserializer(config, type);
1667 }
1668 }
1669 }
1670
1671 if (deser != null) {
1672 if (_factoryConfig.hasDeserializerModifiers()) {
1673 for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
1674 deser = mod.modifyKeyDeserializer(config, type, deser);
1675 }
1676 }
1677 }
1678 return deser;
1679 }
1680
1681 private KeyDeserializer _createEnumKeyDeserializer(DeserializationContext ctxt,
1682 JavaType type)
1683 throws JsonMappingException
1684 {
1685 final DeserializationConfig config = ctxt.getConfig();
1686 Class<?> enumClass = type.getRawClass();
1687
1688 BeanDescription beanDesc = config.introspect(type);
1689
1690 KeyDeserializer des = findKeyDeserializerFromAnnotation(ctxt, beanDesc.getClassInfo());
1691 if (des != null) {
1692 return des;
1693 } else {
1694
1695 JsonDeserializer<?> custom = _findCustomEnumDeserializer(enumClass, config, beanDesc);
1696 if (custom != null) {
1697 return StdKeyDeserializers.constructDelegatingKeyDeserializer(config, type, custom);
1698 }
1699 JsonDeserializer<?> valueDesForKey = findDeserializerFromAnnotation(ctxt, beanDesc.getClassInfo());
1700 if (valueDesForKey != null) {
1701 return StdKeyDeserializers.constructDelegatingKeyDeserializer(config, type, valueDesForKey);
1702 }
1703 }
1704 EnumResolver enumRes = constructEnumResolver(enumClass, config, beanDesc.findJsonValueAccessor());
1705
1706
1707 for (AnnotatedMethod factory : beanDesc.getFactoryMethods()) {
1708 if (_hasCreatorAnnotation(ctxt, factory)) {
1709 int argCount = factory.getParameterCount();
1710 if (argCount == 1) {
1711 Class<?> returnType = factory.getRawReturnType();
1712
1713 if (returnType.isAssignableFrom(enumClass)) {
1714
1715 if (factory.getRawParameterType(0) != String.class) {
1716
1717
1718
1719
1720 continue;
1721 }
1722 if (config.canOverrideAccessModifiers()) {
1723 ClassUtil.checkAndFixAccess(factory.getMember(),
1724 ctxt.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS));
1725 }
1726 return StdKeyDeserializers.constructEnumKeyDeserializer(enumRes, factory);
1727 }
1728 }
1729 throw new IllegalArgumentException("Unsuitable method ("+factory+") decorated with @JsonCreator (for Enum type "
1730 +enumClass.getName()+")");
1731 }
1732 }
1733
1734 return StdKeyDeserializers.constructEnumKeyDeserializer(enumRes);
1735 }
1736
1737
1742
1743 @Override
1744 public boolean hasExplicitDeserializerFor(DeserializationConfig config,
1745 Class<?> valueType)
1746 {
1747
1748
1749
1750
1751 while (valueType.isArray()) {
1752 valueType = valueType.getComponentType();
1753 }
1754
1755
1756 if (Enum.class.isAssignableFrom(valueType)) {
1757 return true;
1758 }
1759
1760 final String clsName = valueType.getName();
1761 if (clsName.startsWith("java.")) {
1762 if (Collection.class.isAssignableFrom(valueType)) {
1763 return true;
1764 }
1765 if (Map.class.isAssignableFrom(valueType)) {
1766 return true;
1767 }
1768 if (Number.class.isAssignableFrom(valueType)) {
1769 return NumberDeserializers.find(valueType, clsName) != null;
1770 }
1771 if (JdkDeserializers.hasDeserializerFor(valueType)
1772 || (valueType == CLASS_STRING)
1773 || (valueType == Boolean.class)
1774 || (valueType == EnumMap.class)
1775 || (valueType == AtomicReference.class)
1776 ) {
1777 return true;
1778 }
1779 if (DateDeserializers.hasDeserializerFor(valueType)) {
1780 return true;
1781 }
1782 } else if (clsName.startsWith("com.fasterxml.")) {
1783 return JsonNode.class.isAssignableFrom(valueType)
1784 || (valueType == TokenBuffer.class);
1785 } else {
1786 return OptionalHandlerFactory.instance.hasDeserializerFor(valueType);
1787 }
1788 return false;
1789 }
1790
1791
1796
1797
1810 public TypeDeserializer findPropertyTypeDeserializer(DeserializationConfig config,
1811 JavaType baseType, AnnotatedMember annotated)
1812 throws JsonMappingException
1813 {
1814 AnnotationIntrospector ai = config.getAnnotationIntrospector();
1815 TypeResolverBuilder<?> b = ai.findPropertyTypeResolver(config, annotated, baseType);
1816
1817 if (b == null) {
1818 return findTypeDeserializer(config, baseType);
1819 }
1820
1821 Collection<NamedType> subtypes = config.getSubtypeResolver().collectAndResolveSubtypesByTypeId(
1822 config, annotated, baseType);
1823 try {
1824 return b.buildTypeDeserializer(config, baseType, subtypes);
1825 } catch (IllegalArgumentException e0) {
1826 InvalidDefinitionException e = InvalidDefinitionException.from((JsonParser) null,
1827 ClassUtil.exceptionMessage(e0), baseType);
1828 e.initCause(e0);
1829 throw e;
1830 }
1831 }
1832
1833
1844 public TypeDeserializer findPropertyContentTypeDeserializer(DeserializationConfig config,
1845 JavaType containerType, AnnotatedMember propertyEntity)
1846 throws JsonMappingException
1847 {
1848 AnnotationIntrospector ai = config.getAnnotationIntrospector();
1849 TypeResolverBuilder<?> b = ai.findPropertyContentTypeResolver(config, propertyEntity, containerType);
1850 JavaType contentType = containerType.getContentType();
1851
1852 if (b == null) {
1853 return findTypeDeserializer(config, contentType);
1854 }
1855
1856 Collection<NamedType> subtypes = config.getSubtypeResolver().collectAndResolveSubtypesByTypeId(
1857 config, propertyEntity, contentType);
1858 return b.buildTypeDeserializer(config, contentType, subtypes);
1859 }
1860
1861
1868 public JsonDeserializer<?> findDefaultDeserializer(DeserializationContext ctxt,
1869 JavaType type, BeanDescription beanDesc)
1870 throws JsonMappingException
1871 {
1872 Class<?> rawType = type.getRawClass();
1873
1874 if ((rawType == CLASS_OBJECT) || (rawType == CLASS_SERIALIZABLE)) {
1875
1876 DeserializationConfig config = ctxt.getConfig();
1877 JavaType lt, mt;
1878
1879 if (_factoryConfig.hasAbstractTypeResolvers()) {
1880 lt = _findRemappedType(config, List.class);
1881 mt = _findRemappedType(config, Map.class);
1882 } else {
1883 lt = mt = null;
1884 }
1885 return new UntypedObjectDeserializer(lt, mt);
1886 }
1887
1888 if (rawType == CLASS_STRING || rawType == CLASS_CHAR_SEQUENCE) {
1889 return StringDeserializer.instance;
1890 }
1891 if (rawType == CLASS_ITERABLE) {
1892
1893 TypeFactory tf = ctxt.getTypeFactory();
1894 JavaType[] tps = tf.findTypeParameters(type, CLASS_ITERABLE);
1895 JavaType elemType = (tps == null || tps.length != 1) ? TypeFactory.unknownType() : tps[0];
1896 CollectionType ct = tf.constructCollectionType(Collection.class, elemType);
1897
1898 return createCollectionDeserializer(ctxt, ct, beanDesc);
1899 }
1900 if (rawType == CLASS_MAP_ENTRY) {
1901
1902 JavaType kt = type.containedTypeOrUnknown(0);
1903 JavaType vt = type.containedTypeOrUnknown(1);
1904 TypeDeserializer vts = (TypeDeserializer) vt.getTypeHandler();
1905 if (vts == null) {
1906 vts = findTypeDeserializer(ctxt.getConfig(), vt);
1907 }
1908 JsonDeserializer<Object> valueDeser = vt.getValueHandler();
1909 KeyDeserializer keyDes = (KeyDeserializer) kt.getValueHandler();
1910 return new MapEntryDeserializer(type, keyDes, valueDeser, vts);
1911 }
1912 String clsName = rawType.getName();
1913 if (rawType.isPrimitive() || clsName.startsWith("java.")) {
1914
1915 JsonDeserializer<?> deser = NumberDeserializers.find(rawType, clsName);
1916 if (deser == null) {
1917 deser = DateDeserializers.find(rawType, clsName);
1918 }
1919 if (deser != null) {
1920 return deser;
1921 }
1922 }
1923
1924 if (rawType == TokenBuffer.class) {
1925 return new TokenBufferDeserializer();
1926 }
1927 JsonDeserializer<?> deser = findOptionalStdDeserializer(ctxt, type, beanDesc);
1928 if (deser != null) {
1929 return deser;
1930 }
1931 return JdkDeserializers.find(rawType, clsName);
1932 }
1933
1934 protected JavaType _findRemappedType(DeserializationConfig config, Class<?> rawType) throws JsonMappingException {
1935 JavaType type = mapAbstractType(config, config.constructType(rawType));
1936 return (type == null || type.hasRawClass(rawType)) ? null : type;
1937 }
1938
1939
1944
1945 protected JsonDeserializer<?> _findCustomTreeNodeDeserializer(Class<? extends JsonNode> type,
1946 DeserializationConfig config, BeanDescription beanDesc)
1947 throws JsonMappingException
1948 {
1949 for (Deserializers d : _factoryConfig.deserializers()) {
1950 JsonDeserializer<?> deser = d.findTreeNodeDeserializer(type, config, beanDesc);
1951 if (deser != null) {
1952 return deser;
1953 }
1954 }
1955 return null;
1956 }
1957
1958 protected JsonDeserializer<?> _findCustomReferenceDeserializer(ReferenceType type,
1959 DeserializationConfig config, BeanDescription beanDesc,
1960 TypeDeserializer contentTypeDeserializer, JsonDeserializer<?> contentDeserializer)
1961 throws JsonMappingException
1962 {
1963 for (Deserializers d : _factoryConfig.deserializers()) {
1964 JsonDeserializer<?> deser = d.findReferenceDeserializer(type, config, beanDesc,
1965 contentTypeDeserializer, contentDeserializer);
1966 if (deser != null) {
1967 return deser;
1968 }
1969 }
1970 return null;
1971 }
1972
1973 @SuppressWarnings("unchecked")
1974 protected JsonDeserializer<Object> _findCustomBeanDeserializer(JavaType type,
1975 DeserializationConfig config, BeanDescription beanDesc)
1976 throws JsonMappingException
1977 {
1978 for (Deserializers d : _factoryConfig.deserializers()) {
1979 JsonDeserializer<?> deser = d.findBeanDeserializer(type, config, beanDesc);
1980 if (deser != null) {
1981 return (JsonDeserializer<Object>) deser;
1982 }
1983 }
1984 return null;
1985 }
1986
1987 protected JsonDeserializer<?> _findCustomArrayDeserializer(ArrayType type,
1988 DeserializationConfig config, BeanDescription beanDesc,
1989 TypeDeserializer elementTypeDeserializer, JsonDeserializer<?> elementDeserializer)
1990 throws JsonMappingException
1991 {
1992 for (Deserializers d : _factoryConfig.deserializers()) {
1993 JsonDeserializer<?> deser = d.findArrayDeserializer(type, config,
1994 beanDesc, elementTypeDeserializer, elementDeserializer);
1995 if (deser != null) {
1996 return deser;
1997 }
1998 }
1999 return null;
2000 }
2001
2002 protected JsonDeserializer<?> _findCustomCollectionDeserializer(CollectionType type,
2003 DeserializationConfig config, BeanDescription beanDesc,
2004 TypeDeserializer elementTypeDeserializer, JsonDeserializer<?> elementDeserializer)
2005 throws JsonMappingException
2006 {
2007 for (Deserializers d : _factoryConfig.deserializers()) {
2008 JsonDeserializer<?> deser = d.findCollectionDeserializer(type, config, beanDesc,
2009 elementTypeDeserializer, elementDeserializer);
2010 if (deser != null) {
2011 return deser;
2012 }
2013 }
2014 return null;
2015 }
2016
2017 protected JsonDeserializer<?> _findCustomCollectionLikeDeserializer(CollectionLikeType type,
2018 DeserializationConfig config, BeanDescription beanDesc,
2019 TypeDeserializer elementTypeDeserializer, JsonDeserializer<?> elementDeserializer)
2020 throws JsonMappingException
2021 {
2022 for (Deserializers d : _factoryConfig.deserializers()) {
2023 JsonDeserializer<?> deser = d.findCollectionLikeDeserializer(type, config, beanDesc,
2024 elementTypeDeserializer, elementDeserializer);
2025 if (deser != null) {
2026 return deser;
2027 }
2028 }
2029 return null;
2030 }
2031
2032 protected JsonDeserializer<?> _findCustomEnumDeserializer(Class<?> type,
2033 DeserializationConfig config, BeanDescription beanDesc)
2034 throws JsonMappingException
2035 {
2036 for (Deserializers d : _factoryConfig.deserializers()) {
2037 JsonDeserializer<?> deser = d.findEnumDeserializer(type, config, beanDesc);
2038 if (deser != null) {
2039 return deser;
2040 }
2041 }
2042 return null;
2043 }
2044
2045 protected JsonDeserializer<?> _findCustomMapDeserializer(MapType type,
2046 DeserializationConfig config, BeanDescription beanDesc,
2047 KeyDeserializer keyDeserializer,
2048 TypeDeserializer elementTypeDeserializer, JsonDeserializer<?> elementDeserializer)
2049 throws JsonMappingException
2050 {
2051 for (Deserializers d : _factoryConfig.deserializers()) {
2052 JsonDeserializer<?> deser = d.findMapDeserializer(type, config, beanDesc,
2053 keyDeserializer, elementTypeDeserializer, elementDeserializer);
2054 if (deser != null) {
2055 return deser;
2056 }
2057 }
2058 return null;
2059 }
2060
2061 protected JsonDeserializer<?> _findCustomMapLikeDeserializer(MapLikeType type,
2062 DeserializationConfig config, BeanDescription beanDesc,
2063 KeyDeserializer keyDeserializer,
2064 TypeDeserializer elementTypeDeserializer, JsonDeserializer<?> elementDeserializer)
2065 throws JsonMappingException
2066 {
2067 for (Deserializers d : _factoryConfig.deserializers()) {
2068 JsonDeserializer<?> deser = d.findMapLikeDeserializer(type, config, beanDesc,
2069 keyDeserializer, elementTypeDeserializer, elementDeserializer);
2070 if (deser != null) {
2071 return deser;
2072 }
2073 }
2074 return null;
2075 }
2076
2077
2082
2083
2091 protected JsonDeserializer<Object> findDeserializerFromAnnotation(DeserializationContext ctxt,
2092 Annotated ann)
2093 throws JsonMappingException
2094 {
2095 AnnotationIntrospector intr = ctxt.getAnnotationIntrospector();
2096 if (intr != null) {
2097 Object deserDef = intr.findDeserializer(ann);
2098 if (deserDef != null) {
2099 return ctxt.deserializerInstance(ann, deserDef);
2100 }
2101 }
2102 return null;
2103 }
2104
2105
2110 protected KeyDeserializer findKeyDeserializerFromAnnotation(DeserializationContext ctxt,
2111 Annotated ann)
2112 throws JsonMappingException
2113 {
2114 AnnotationIntrospector intr = ctxt.getAnnotationIntrospector();
2115 if (intr != null) {
2116 Object deserDef = intr.findKeyDeserializer(ann);
2117 if (deserDef != null) {
2118 return ctxt.keyDeserializerInstance(ann, deserDef);
2119 }
2120 }
2121 return null;
2122 }
2123
2124
2127 protected JsonDeserializer<Object> findContentDeserializerFromAnnotation(DeserializationContext ctxt,
2128 Annotated ann)
2129 throws JsonMappingException
2130 {
2131 AnnotationIntrospector intr = ctxt.getAnnotationIntrospector();
2132 if (intr != null) {
2133 Object deserDef = intr.findContentDeserializer(ann);
2134 if (deserDef != null) {
2135 return ctxt.deserializerInstance(ann, deserDef);
2136 }
2137 }
2138 return null;
2139 }
2140
2141
2150 protected JavaType resolveMemberAndTypeAnnotations(DeserializationContext ctxt,
2151 AnnotatedMember member, JavaType type)
2152 throws JsonMappingException
2153 {
2154 AnnotationIntrospector intr = ctxt.getAnnotationIntrospector();
2155 if (intr == null) {
2156 return type;
2157 }
2158
2159
2160
2161
2162 if (type.isMapLikeType()) {
2163 JavaType keyType = type.getKeyType();
2164 if (keyType != null) {
2165 Object kdDef = intr.findKeyDeserializer(member);
2166 KeyDeserializer kd = ctxt.keyDeserializerInstance(member, kdDef);
2167 if (kd != null) {
2168 type = ((MapLikeType) type).withKeyValueHandler(kd);
2169 keyType = type.getKeyType();
2170 }
2171 }
2172 }
2173
2174 if (type.hasContentType()) {
2175 Object cdDef = intr.findContentDeserializer(member);
2176 JsonDeserializer<?> cd = ctxt.deserializerInstance(member, cdDef);
2177 if (cd != null) {
2178 type = type.withContentValueHandler(cd);
2179 }
2180 TypeDeserializer contentTypeDeser = findPropertyContentTypeDeserializer(
2181 ctxt.getConfig(), type, (AnnotatedMember) member);
2182 if (contentTypeDeser != null) {
2183 type = type.withContentTypeHandler(contentTypeDeser);
2184 }
2185 }
2186 TypeDeserializer valueTypeDeser = findPropertyTypeDeserializer(ctxt.getConfig(),
2187 type, (AnnotatedMember) member);
2188 if (valueTypeDeser != null) {
2189 type = type.withTypeHandler(valueTypeDeser);
2190 }
2191
2192
2193
2194
2195
2196
2197 type = intr.refineDeserializationType(ctxt.getConfig(), member, type);
2198 return type;
2199 }
2200
2201 protected EnumResolver constructEnumResolver(Class<?> enumClass,
2202 DeserializationConfig config, AnnotatedMember jsonValueAccessor)
2203 {
2204 if (jsonValueAccessor != null) {
2205 if (config.canOverrideAccessModifiers()) {
2206 ClassUtil.checkAndFixAccess(jsonValueAccessor.getMember(),
2207 config.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS));
2208 }
2209 return EnumResolver.constructUnsafeUsingMethod(enumClass,
2210 jsonValueAccessor, config.getAnnotationIntrospector());
2211 }
2212
2213
2214 return EnumResolver.constructUnsafe(enumClass, config.getAnnotationIntrospector());
2215 }
2216
2217
2220 protected boolean _hasCreatorAnnotation(DeserializationContext ctxt,
2221 Annotated ann) {
2222 AnnotationIntrospector intr = ctxt.getAnnotationIntrospector();
2223 if (intr != null) {
2224 JsonCreator.Mode mode = intr.findCreatorAnnotation(ctxt.getConfig(), ann);
2225 return (mode != null) && (mode != JsonCreator.Mode.DISABLED);
2226 }
2227 return false;
2228 }
2229
2230
2235
2236
2242 @Deprecated
2243 protected JavaType modifyTypeByAnnotation(DeserializationContext ctxt,
2244 Annotated a, JavaType type)
2245 throws JsonMappingException
2246 {
2247 AnnotationIntrospector intr = ctxt.getAnnotationIntrospector();
2248 if (intr == null) {
2249 return type;
2250 }
2251 return intr.refineDeserializationType(ctxt.getConfig(), a, type);
2252 }
2253
2254
2257 @Deprecated
2258 protected JavaType resolveType(DeserializationContext ctxt,
2259 BeanDescription beanDesc, JavaType type, AnnotatedMember member)
2260 throws JsonMappingException
2261 {
2262 return resolveMemberAndTypeAnnotations(ctxt, member, type);
2263 }
2264
2265
2268 @Deprecated
2269 protected AnnotatedMethod _findJsonValueFor(DeserializationConfig config, JavaType enumType)
2270 {
2271 if (enumType == null) {
2272 return null;
2273 }
2274 BeanDescription beanDesc = config.introspect(enumType);
2275 return beanDesc.findJsonValueMethod();
2276 }
2277
2278
2285 @SuppressWarnings("rawtypes")
2286 protected static class ContainerDefaultMappings {
2287
2288
2289
2290 final static HashMap<String, Class<? extends Collection>> _collectionFallbacks;
2291 static {
2292 HashMap<String, Class<? extends Collection>> fallbacks = new HashMap<>();
2293
2294 final Class<? extends Collection> DEFAULT_LIST = ArrayList.class;
2295 final Class<? extends Collection> DEFAULT_SET = HashSet.class;
2296
2297 fallbacks.put(Collection.class.getName(), DEFAULT_LIST);
2298 fallbacks.put(List.class.getName(), DEFAULT_LIST);
2299 fallbacks.put(Set.class.getName(), DEFAULT_SET);
2300 fallbacks.put(SortedSet.class.getName(), TreeSet.class);
2301 fallbacks.put(Queue.class.getName(), LinkedList.class);
2302
2303
2304 fallbacks.put(AbstractList.class.getName(), DEFAULT_LIST);
2305 fallbacks.put(AbstractSet.class.getName(), DEFAULT_SET);
2306
2307
2308 fallbacks.put(Deque.class.getName(), LinkedList.class);
2309 fallbacks.put(NavigableSet.class.getName(), TreeSet.class);
2310
2311 _collectionFallbacks = fallbacks;
2312 }
2313
2314
2315
2316
2317 final static HashMap<String, Class<? extends Map>> _mapFallbacks;
2318 static {
2319 HashMap<String, Class<? extends Map>> fallbacks = new HashMap<>();
2320
2321 final Class<? extends Map> DEFAULT_MAP = LinkedHashMap.class;
2322 fallbacks.put(Map.class.getName(), DEFAULT_MAP);
2323 fallbacks.put(AbstractMap.class.getName(), DEFAULT_MAP);
2324 fallbacks.put(ConcurrentMap.class.getName(), ConcurrentHashMap.class);
2325 fallbacks.put(SortedMap.class.getName(), TreeMap.class);
2326
2327 fallbacks.put(java.util.NavigableMap.class.getName(), TreeMap.class);
2328 fallbacks.put(java.util.concurrent.ConcurrentNavigableMap.class.getName(),
2329 java.util.concurrent.ConcurrentSkipListMap.class);
2330
2331 _mapFallbacks = fallbacks;
2332 }
2333
2334 public static Class<?> findCollectionFallback(JavaType type) {
2335 return _collectionFallbacks.get(type.getRawClass().getName());
2336 }
2337
2338 public static Class<?> findMapFallback(JavaType type) {
2339 return _mapFallbacks.get(type.getRawClass().getName());
2340 }
2341 }
2342 }
2343