1 package com.fasterxml.jackson.databind.introspect;
2
3 import java.lang.annotation.Annotation;
4 import java.util.ArrayList;
5 import java.util.Collection;
6 import java.util.List;
7
8 import com.fasterxml.jackson.annotation.JacksonInject;
9 import com.fasterxml.jackson.annotation.JsonCreator;
10 import com.fasterxml.jackson.annotation.JsonFormat;
11 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
12 import com.fasterxml.jackson.annotation.JsonInclude;
13 import com.fasterxml.jackson.annotation.JsonProperty;
14 import com.fasterxml.jackson.annotation.JsonSetter;
15 import com.fasterxml.jackson.core.Version;
16 import com.fasterxml.jackson.databind.*;
17 import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
18 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
19 import com.fasterxml.jackson.databind.cfg.MapperConfig;
20 import com.fasterxml.jackson.databind.jsontype.NamedType;
21 import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder;
22 import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
23 import com.fasterxml.jackson.databind.util.ClassUtil;
24 import com.fasterxml.jackson.databind.util.NameTransformer;
25
26 /**
27  * Helper class that allows using 2 introspectors such that one
28  * introspector acts as the primary one to use; and second one
29  * as a fallback used if the primary does not provide conclusive
30  * or useful result for a method.
31  *<p>
32  * An obvious consequence of priority is that it is easy to construct
33  * longer chains of introspectors by linking multiple pairs.
34  * Currently most likely combination is that of using the default
35  * Jackson provider, along with JAXB annotation introspector.
36  *<p>
37  * Note: up until 2.0, this class was an inner class of
38  * {@link AnnotationIntrospector}; moved here for convenience.
39  * 
40  * @since 2.1
41  */

42 public class AnnotationIntrospectorPair
43     extends AnnotationIntrospector
44     implements java.io.Serializable
45 {
46     private static final long serialVersionUID = 1L;
47
48     protected final AnnotationIntrospector _primary, _secondary;
49
50     public AnnotationIntrospectorPair(AnnotationIntrospector p, AnnotationIntrospector s)
51     {
52         _primary = p;
53         _secondary = s;
54     }
55
56     @Override
57     public Version version() {
58         return _primary.version();
59     }
60
61     /**
62      * Helper method for constructing a Pair from two given introspectors (if
63      * neither is null); or returning non-null introspector if one is null
64      * (and return just null if both are null)
65      */

66     public static AnnotationIntrospector create(AnnotationIntrospector primary,
67             AnnotationIntrospector secondary)
68     {
69         if (primary == null) {
70             return secondary;
71         }
72         if (secondary == null) {
73             return primary;
74         }
75         return new AnnotationIntrospectorPair(primary, secondary);
76     }
77
78     @Override
79     public Collection<AnnotationIntrospector> allIntrospectors() {
80         return allIntrospectors(new ArrayList<AnnotationIntrospector>());
81     }
82
83     @Override
84     public Collection<AnnotationIntrospector> allIntrospectors(Collection<AnnotationIntrospector> result)
85     {
86         _primary.allIntrospectors(result);
87         _secondary.allIntrospectors(result);
88         return result;
89     }
90     
91     // // // Generic annotation properties, lookup
92     
93     @Override
94     public boolean isAnnotationBundle(Annotation ann) {
95         return _primary.isAnnotationBundle(ann) || _secondary.isAnnotationBundle(ann);
96     }
97     
98     /*
99     /******************************************************
100     /* General class annotations
101     /******************************************************
102      */

103
104     @Override
105     public PropertyName findRootName(AnnotatedClass ac)
106     {
107         PropertyName name1 = _primary.findRootName(ac);
108         if (name1 == null) {
109             return _secondary.findRootName(ac);
110         }
111         if (name1.hasSimpleName()) {
112             return name1;
113         }
114         // name1 is empty; how about secondary?
115         PropertyName name2 = _secondary.findRootName(ac);
116         return (name2 == null) ? name1 : name2;
117     }
118
119     @Override
120     public JsonIgnoreProperties.Value findPropertyIgnorals(Annotated a)
121     {
122         JsonIgnoreProperties.Value v2 = _secondary.findPropertyIgnorals(a);
123         JsonIgnoreProperties.Value v1 = _primary.findPropertyIgnorals(a);
124         return (v2 == null// shouldn't occur but
125             ? v1 : v2.withOverrides(v1);
126     }
127
128     @Override
129     public Boolean isIgnorableType(AnnotatedClass ac)
130     {
131         Boolean result = _primary.isIgnorableType(ac);
132         if (result == null) {
133             result = _secondary.isIgnorableType(ac);
134         }
135         return result;
136     }
137
138     @Override
139     public Object findFilterId(Annotated ann)
140     {
141         Object id = _primary.findFilterId(ann);
142         if (id == null) {
143             id = _secondary.findFilterId(ann);
144         }
145         return id;
146     }
147     
148     @Override
149     public Object findNamingStrategy(AnnotatedClass ac)
150     {
151         Object str = _primary.findNamingStrategy(ac);
152         if (str == null) {
153             str = _secondary.findNamingStrategy(ac);
154         }
155         return str;
156     }
157
158     @Override
159     public String findClassDescription(AnnotatedClass ac) {
160         String str = _primary.findClassDescription(ac);
161         if ((str == null) || str.isEmpty()) {
162             str = _secondary.findClassDescription(ac);
163         }
164         return str;
165     }
166
167     @Override
168     @Deprecated // since 2.6
169     public String[] findPropertiesToIgnore(Annotated ac) {
170         String[] result = _primary.findPropertiesToIgnore(ac);
171         if (result == null) {
172             result = _secondary.findPropertiesToIgnore(ac);
173         }
174         return result;            
175     }
176
177     @Override
178     @Deprecated // since 2.8
179     public String[] findPropertiesToIgnore(Annotated ac, boolean forSerialization) {
180         String[] result = _primary.findPropertiesToIgnore(ac, forSerialization);
181         if (result == null) {
182             result = _secondary.findPropertiesToIgnore(ac, forSerialization);
183         }
184         return result;            
185     }
186
187     @Override
188     @Deprecated // since 2.8
189     public Boolean findIgnoreUnknownProperties(AnnotatedClass ac)
190     {
191         Boolean result = _primary.findIgnoreUnknownProperties(ac);
192         if (result == null) {
193             result = _secondary.findIgnoreUnknownProperties(ac);
194         }
195         return result;
196     }        
197
198     /*
199     /******************************************************
200     /* Property auto-detection
201     /******************************************************
202     */

203     
204     @Override
205     public VisibilityChecker<?> findAutoDetectVisibility(AnnotatedClass ac,
206         VisibilityChecker<?> checker)
207     {
208         /* Note: to have proper priorities, we must actually call delegatees
209          * in reverse order:
210          */

211         checker = _secondary.findAutoDetectVisibility(ac, checker);
212         return _primary.findAutoDetectVisibility(ac, checker);
213     }
214
215     /*
216     /******************************************************
217     /* Type handling
218     /******************************************************
219      */

220
221     @Override
222     public TypeResolverBuilder<?> findTypeResolver(MapperConfig<?> config,
223             AnnotatedClass ac, JavaType baseType)
224     {
225         TypeResolverBuilder<?> b = _primary.findTypeResolver(config, ac, baseType);
226         if (b == null) {
227             b = _secondary.findTypeResolver(config, ac, baseType);
228         }
229         return b;
230     }
231
232     @Override
233     public TypeResolverBuilder<?> findPropertyTypeResolver(MapperConfig<?> config,
234             AnnotatedMember am, JavaType baseType)
235     {
236         TypeResolverBuilder<?> b = _primary.findPropertyTypeResolver(config, am, baseType);
237         if (b == null) {
238             b = _secondary.findPropertyTypeResolver(config, am, baseType);
239         }
240         return b;
241     }
242
243     @Override
244     public TypeResolverBuilder<?> findPropertyContentTypeResolver(MapperConfig<?> config,
245             AnnotatedMember am, JavaType baseType)
246     {
247         TypeResolverBuilder<?> b = _primary.findPropertyContentTypeResolver(config, am, baseType);
248         if (b == null) {
249             b = _secondary.findPropertyContentTypeResolver(config, am, baseType);
250         }
251         return b;
252     }
253     
254     @Override
255     public List<NamedType> findSubtypes(Annotated a)
256     {
257         List<NamedType> types1 = _primary.findSubtypes(a);
258         List<NamedType> types2 = _secondary.findSubtypes(a);
259         if (types1 == null || types1.isEmpty()) return types2;
260         if (types2 == null || types2.isEmpty()) return types1;
261         ArrayList<NamedType> result = new ArrayList<NamedType>(types1.size() + types2.size());
262         result.addAll(types1);
263         result.addAll(types2);
264         return result;
265     }
266
267     @Override
268     public String findTypeName(AnnotatedClass ac)
269     {
270         String name = _primary.findTypeName(ac);
271         if (name == null || name.length() == 0) {
272             name = _secondary.findTypeName(ac);                
273         }
274         return name;
275     }
276     /*
277     /******************************************************
278     /* General member (field, method/constructor) annotations
279     /******************************************************
280      */

281     
282     @Override        
283     public ReferenceProperty findReferenceType(AnnotatedMember member) {
284         ReferenceProperty r = _primary.findReferenceType(member);
285         return (r == null) ? _secondary.findReferenceType(member) : r;
286     }
287
288     @Override        
289     public NameTransformer findUnwrappingNameTransformer(AnnotatedMember member) {
290         NameTransformer r = _primary.findUnwrappingNameTransformer(member);
291         return (r == null) ? _secondary.findUnwrappingNameTransformer(member) : r;
292     }
293
294     @Override
295     public JacksonInject.Value findInjectableValue(AnnotatedMember m) {
296         JacksonInject.Value r = _primary.findInjectableValue(m);
297         return (r == null) ? _secondary.findInjectableValue(m) : r;
298     }
299
300     @Override
301     public boolean hasIgnoreMarker(AnnotatedMember m) {
302         return _primary.hasIgnoreMarker(m) || _secondary.hasIgnoreMarker(m);
303     }
304
305     @Override
306     public Boolean hasRequiredMarker(AnnotatedMember m) {
307         Boolean r = _primary.hasRequiredMarker(m);
308         return (r == null) ? _secondary.hasRequiredMarker(m) : r;
309     }
310
311     @Override
312     @Deprecated // since 2.9
313     public Object findInjectableValueId(AnnotatedMember m) {
314         Object r = _primary.findInjectableValueId(m);
315         return (r == null) ? _secondary.findInjectableValueId(m) : r;
316     }
317
318     // // // Serialization: general annotations
319
320     @Override
321     public Object findSerializer(Annotated am) {
322         Object r = _primary.findSerializer(am);
323         if (_isExplicitClassOrOb(r, JsonSerializer.None.class)) {
324             return r;
325         }
326         return _explicitClassOrOb(_secondary.findSerializer(am),
327                 JsonSerializer.None.class);
328     }
329     
330     @Override
331     public Object findKeySerializer(Annotated a) {
332         Object r = _primary.findKeySerializer(a);
333         if (_isExplicitClassOrOb(r, JsonSerializer.None.class)) {
334             return r;
335         }
336         return _explicitClassOrOb(_secondary.findKeySerializer(a),
337                 JsonSerializer.None.class);
338     }
339
340     @Override
341     public Object findContentSerializer(Annotated a) {
342         Object r = _primary.findContentSerializer(a);
343         if (_isExplicitClassOrOb(r, JsonSerializer.None.class)) {
344             return r;
345         }
346         return _explicitClassOrOb(_secondary.findContentSerializer(a),
347                 JsonSerializer.None.class);
348     }
349     
350     @Override
351     public Object findNullSerializer(Annotated a) {
352         Object r = _primary.findNullSerializer(a);
353         if (_isExplicitClassOrOb(r, JsonSerializer.None.class)) {
354             return r;
355         }
356         return _explicitClassOrOb(_secondary.findNullSerializer(a),
357                 JsonSerializer.None.class);
358     }
359     
360     @Deprecated
361     @Override
362     public JsonInclude.Include findSerializationInclusion(Annotated a,
363             JsonInclude.Include defValue)
364     {
365         // note: call secondary first, to give lower priority
366         defValue = _secondary.findSerializationInclusion(a, defValue);
367         defValue = _primary.findSerializationInclusion(a, defValue);
368         return defValue;
369     }
370
371     @Deprecated
372     @Override
373     public JsonInclude.Include findSerializationInclusionForContent(Annotated a, JsonInclude.Include defValue)
374     {
375         // note: call secondary first, to give lower priority
376         defValue = _secondary.findSerializationInclusionForContent(a, defValue);
377         defValue = _primary.findSerializationInclusionForContent(a, defValue);
378         return defValue;
379     }
380
381     @Override
382     public JsonInclude.Value findPropertyInclusion(Annotated a)
383     {
384         JsonInclude.Value v2 = _secondary.findPropertyInclusion(a);
385         JsonInclude.Value v1 = _primary.findPropertyInclusion(a);
386
387         if (v2 == null) { // shouldn't occur but
388             return v1;
389         }
390         return v2.withOverrides(v1);
391     }
392
393     @Override
394     public JsonSerialize.Typing findSerializationTyping(Annotated a) {
395         JsonSerialize.Typing r = _primary.findSerializationTyping(a);
396         return (r == null) ? _secondary.findSerializationTyping(a) : r;
397     }
398
399     @Override
400     public Object findSerializationConverter(Annotated a) {
401         Object r = _primary.findSerializationConverter(a);
402         return (r == null) ? _secondary.findSerializationConverter(a) : r;
403     }
404
405     @Override
406     public Object findSerializationContentConverter(AnnotatedMember a) {
407         Object r = _primary.findSerializationContentConverter(a);
408         return (r == null) ? _secondary.findSerializationContentConverter(a) : r;
409     }
410
411     @Override
412     public Class<?>[] findViews(Annotated a) {
413         /* Theoretically this could be trickier, if multiple introspectors
414          * return non-null entries. For now, though, we'll just consider
415          * first one to return non-null to win.
416          */

417         Class<?>[] result = _primary.findViews(a);
418         if (result == null) {
419             result = _secondary.findViews(a);
420         }
421         return result;
422     }
423
424     @Override
425     public Boolean isTypeId(AnnotatedMember member) {
426         Boolean b = _primary.isTypeId(member);
427         return (b == null) ? _secondary.isTypeId(member) : b;
428     }
429
430     @Override
431     public ObjectIdInfo findObjectIdInfo(Annotated ann) {
432         ObjectIdInfo r = _primary.findObjectIdInfo(ann);
433         return (r == null) ? _secondary.findObjectIdInfo(ann) : r;
434     }
435
436     @Override
437     public ObjectIdInfo findObjectReferenceInfo(Annotated ann, ObjectIdInfo objectIdInfo) {
438         // to give precedence for primary, must start with secondary:
439         objectIdInfo = _secondary.findObjectReferenceInfo(ann, objectIdInfo);
440         objectIdInfo = _primary.findObjectReferenceInfo(ann, objectIdInfo);
441         return objectIdInfo;
442     }
443
444     @Override
445     public JsonFormat.Value findFormat(Annotated ann) {
446         JsonFormat.Value v1 = _primary.findFormat(ann);
447         JsonFormat.Value v2 = _secondary.findFormat(ann);
448         if (v2 == null) { // shouldn't occur but just in case
449             return v1;
450         }
451         return v2.withOverrides(v1);
452     }
453
454     @Override
455     public PropertyName findWrapperName(Annotated ann) {
456         PropertyName name = _primary.findWrapperName(ann);
457         if (name == null) {
458             name = _secondary.findWrapperName(ann);
459         } else if (name == PropertyName.USE_DEFAULT) {
460             // does the other introspector have a better idea?
461             PropertyName name2 = _secondary.findWrapperName(ann);
462             if (name2 != null) {
463                 name = name2;
464             }
465         }
466         return name;
467     }
468
469     @Override
470     public String findPropertyDefaultValue(Annotated ann) {
471         String str = _primary.findPropertyDefaultValue(ann);
472         return (str == null || str.isEmpty()) ? _secondary.findPropertyDefaultValue(ann) : str;
473     }
474
475     @Override
476     public String findPropertyDescription(Annotated ann) {
477         String r = _primary.findPropertyDescription(ann);
478         return (r == null) ? _secondary.findPropertyDescription(ann) : r;
479     }
480
481     @Override
482     public Integer findPropertyIndex(Annotated ann) {
483         Integer r = _primary.findPropertyIndex(ann);
484         return (r == null) ? _secondary.findPropertyIndex(ann) : r;
485     }
486
487     @Override
488     public String findImplicitPropertyName(AnnotatedMember ann) {
489         String r = _primary.findImplicitPropertyName(ann);
490         return (r == null) ? _secondary.findImplicitPropertyName(ann) : r;
491     }
492
493     @Override
494     public List<PropertyName> findPropertyAliases(Annotated ann) {
495         List<PropertyName> r = _primary.findPropertyAliases(ann);
496         return (r == null) ? _secondary.findPropertyAliases(ann) : r;
497     }
498
499     @Override
500     public JsonProperty.Access findPropertyAccess(Annotated ann) {
501         JsonProperty.Access acc = _primary.findPropertyAccess(ann);
502         if ((acc != null) && (acc != JsonProperty.Access.AUTO)) {
503             return acc;
504         }
505         acc = _secondary.findPropertyAccess(ann);
506         if (acc != null) {
507             return acc;
508         }
509         return JsonProperty.Access.AUTO;
510     }
511
512     @Override // since 2.7
513     public AnnotatedMethod resolveSetterConflict(MapperConfig<?> config,
514             AnnotatedMethod setter1, AnnotatedMethod setter2)
515     {
516         AnnotatedMethod res = _primary.resolveSetterConflict(config, setter1, setter2);
517         if (res == null) {
518             res = _secondary.resolveSetterConflict(config, setter1, setter2);
519         }
520         return res;
521     }
522
523     @Override // since 2.11
524     public PropertyName findRenameByField(MapperConfig<?> config,
525             AnnotatedField f, PropertyName implName) {
526         PropertyName n = _secondary.findRenameByField(config, f, implName);
527         if (n == null) {
528             n = _primary.findRenameByField(config, f, implName);
529         }
530         return n;
531     }
532
533     // // // Serialization: type refinements
534
535     @Override // since 2.7
536     public JavaType refineSerializationType(MapperConfig<?> config,
537             Annotated a, JavaType baseType) throws JsonMappingException
538     {
539         JavaType t = _secondary.refineSerializationType(config, a, baseType);
540         return _primary.refineSerializationType(config, a, t);
541     }
542     
543     @Override
544     @Deprecated
545     public Class<?> findSerializationType(Annotated a) {
546         Class<?> r = _primary.findSerializationType(a);
547         return (r == null) ? _secondary.findSerializationType(a) : r;
548     }
549
550     @Override
551     @Deprecated
552     public Class<?> findSerializationKeyType(Annotated am, JavaType baseType) {
553         Class<?> r = _primary.findSerializationKeyType(am, baseType);
554         return (r == null) ? _secondary.findSerializationKeyType(am, baseType) : r;
555     }
556
557     @Override
558     @Deprecated
559     public Class<?> findSerializationContentType(Annotated am, JavaType baseType) {
560         Class<?> r = _primary.findSerializationContentType(am, baseType);
561         return (r == null) ? _secondary.findSerializationContentType(am, baseType) : r;
562     }
563     
564     // // // Serialization: class annotations
565
566     @Override
567     public String[] findSerializationPropertyOrder(AnnotatedClass ac) {
568         String[] r = _primary.findSerializationPropertyOrder(ac);
569         return (r == null) ? _secondary.findSerializationPropertyOrder(ac) : r;
570     }
571
572     @Override
573     public Boolean findSerializationSortAlphabetically(Annotated ann) {
574         Boolean r = _primary.findSerializationSortAlphabetically(ann);
575         return (r == null) ? _secondary.findSerializationSortAlphabetically(ann) : r;
576     }
577
578     @Override
579     public void findAndAddVirtualProperties(MapperConfig<?> config, AnnotatedClass ac,
580             List<BeanPropertyWriter> properties) {
581         // first secondary, then primary, to give proper precedence
582         _primary.findAndAddVirtualProperties(config, ac, properties);
583         _secondary.findAndAddVirtualProperties(config, ac, properties);
584     }
585
586     // // // Serialization: property annotations
587     
588     @Override
589     public PropertyName findNameForSerialization(Annotated a) {
590         PropertyName n = _primary.findNameForSerialization(a);
591         // note: "use default" should not block explicit answer, so:
592         if (n == null) {
593             n = _secondary.findNameForSerialization(a);
594         } else if (n == PropertyName.USE_DEFAULT) {
595             PropertyName n2 = _secondary.findNameForSerialization(a);
596             if (n2 != null) {
597                 n = n2;
598             }
599         }
600         return n;
601     }
602
603     @Override
604     public Boolean hasAsValue(Annotated a) {
605         Boolean b = _primary.hasAsValue(a);
606         if (b == null) {
607             b = _secondary.hasAsValue(a);
608         }
609         return b;
610     }
611
612     @Override
613     public Boolean hasAnyGetter(Annotated a) {
614         Boolean b = _primary.hasAnyGetter(a);
615         if (b == null) {
616             b = _secondary.hasAnyGetter(a);
617         }
618         return b;
619     }
620
621     @Override
622     public  String[] findEnumValues(Class<?> enumType, Enum<?>[] enumValues, String[] names) {
623         // reverse order to give _primary higher precedence
624         names = _secondary.findEnumValues(enumType, enumValues, names);
625         names = _primary.findEnumValues(enumType, enumValues, names);
626         return names;
627     }
628
629     @Override
630     public void findEnumAliases(Class<?> enumType, Enum<?>[] enumValues, String[][] aliases) {
631         // reverse order to give _primary higher precedence
632         _secondary.findEnumAliases(enumType, enumValues, aliases);
633         _primary.findEnumAliases(enumType, enumValues, aliases);
634     }
635
636     @Override
637     public Enum<?> findDefaultEnumValue(Class<Enum<?>> enumCls) {
638         Enum<?> en = _primary.findDefaultEnumValue(enumCls);
639         return (en == null) ? _secondary.findDefaultEnumValue(enumCls) : en;
640     }
641
642     @Override
643     @Deprecated // since 2.8
644     public String findEnumValue(Enum<?> value) {
645         String r = _primary.findEnumValue(value);
646         return (r == null) ? _secondary.findEnumValue(value) : r;
647     }        
648
649     @Override
650     @Deprecated // since 2.9
651     public boolean hasAsValueAnnotation(AnnotatedMethod am) {
652         return _primary.hasAsValueAnnotation(am) || _secondary.hasAsValueAnnotation(am);
653     }
654     
655     @Override
656     @Deprecated // since 2.9
657     public boolean hasAnyGetterAnnotation(AnnotatedMethod am) {
658         return _primary.hasAnyGetterAnnotation(am) || _secondary.hasAnyGetterAnnotation(am);
659     }
660
661     // // // Deserialization: general annotations
662
663     @Override
664     public Object findDeserializer(Annotated a) {
665         Object r = _primary.findDeserializer(a);
666         if (_isExplicitClassOrOb(r, JsonDeserializer.None.class)) {
667             return r;
668         }
669         return _explicitClassOrOb(_secondary.findDeserializer(a),
670                 JsonDeserializer.None.class);
671     }
672
673     @Override
674     public Object findKeyDeserializer(Annotated a) {
675         Object r = _primary.findKeyDeserializer(a);
676         if (_isExplicitClassOrOb(r, KeyDeserializer.None.class)) {
677             return r;
678         }
679         return _explicitClassOrOb(_secondary.findKeyDeserializer(a),
680                 KeyDeserializer.None.class);
681     }
682
683     @Override
684     public Object findContentDeserializer(Annotated am) {
685         Object r = _primary.findContentDeserializer(am);
686         if (_isExplicitClassOrOb(r, JsonDeserializer.None.class)) {
687             return r;
688         }
689         return _explicitClassOrOb(_secondary.findContentDeserializer(am),
690                 JsonDeserializer.None.class);
691                 
692     }
693
694     @Override
695     public Object findDeserializationConverter(Annotated a) {
696         Object ob = _primary.findDeserializationConverter(a);
697         return (ob == null) ? _secondary.findDeserializationConverter(a) : ob;
698     }
699
700     @Override
701     public Object findDeserializationContentConverter(AnnotatedMember a) {
702         Object ob = _primary.findDeserializationContentConverter(a);
703         return (ob == null) ? _secondary.findDeserializationContentConverter(a) : ob;
704     }
705
706     // // // Deserialization: type refinements
707
708     // since 2.7
709     @Override
710     public JavaType refineDeserializationType(MapperConfig<?> config,
711             Annotated a, JavaType baseType) throws JsonMappingException
712     {
713         JavaType t = _secondary.refineDeserializationType(config, a, baseType);
714         return _primary.refineDeserializationType(config, a, t);
715     }
716     
717     @Override
718     @Deprecated
719     public Class<?> findDeserializationType(Annotated am, JavaType baseType) {
720         Class<?> r = _primary.findDeserializationType(am, baseType);
721         return (r != null) ? r : _secondary.findDeserializationType(am, baseType);
722     }
723
724     @Override
725     @Deprecated
726     public Class<?> findDeserializationKeyType(Annotated am, JavaType baseKeyType) {
727         Class<?> result = _primary.findDeserializationKeyType(am, baseKeyType);
728         return (result == null) ? _secondary.findDeserializationKeyType(am, baseKeyType) : result;
729     }
730
731     @Override
732     @Deprecated
733     public Class<?> findDeserializationContentType(Annotated am, JavaType baseContentType) {
734         Class<?> result = _primary.findDeserializationContentType(am, baseContentType);
735         return (result == null) ? _secondary.findDeserializationContentType(am, baseContentType) : result;
736     }
737     
738     // // // Deserialization: class annotations
739
740     @Override
741     public Object findValueInstantiator(AnnotatedClass ac) {
742         Object result = _primary.findValueInstantiator(ac);
743         return (result == null) ? _secondary.findValueInstantiator(ac) : result;
744     }
745
746     @Override
747     public Class<?> findPOJOBuilder(AnnotatedClass ac) {
748         Class<?> result = _primary.findPOJOBuilder(ac);
749         return (result == null) ? _secondary.findPOJOBuilder(ac) : result;
750     }
751
752     @Override
753     public JsonPOJOBuilder.Value findPOJOBuilderConfig(AnnotatedClass ac) {
754         JsonPOJOBuilder.Value result = _primary.findPOJOBuilderConfig(ac);
755         return (result == null) ? _secondary.findPOJOBuilderConfig(ac) : result;
756     }
757
758     // // // Deserialization: method annotations
759
760     @Override
761     public PropertyName findNameForDeserialization(Annotated a)
762     {
763         // note: "use default" should not block explicit answer, so:
764         PropertyName n = _primary.findNameForDeserialization(a);
765         if (n == null) {
766             n = _secondary.findNameForDeserialization(a);
767         } else if (n == PropertyName.USE_DEFAULT) {
768             PropertyName n2 = _secondary.findNameForDeserialization(a);
769             if (n2 != null) {
770                 n = n2;
771             }
772         }
773         return n;
774     }
775
776     @Override
777     public Boolean hasAnySetter(Annotated a) {
778         Boolean b = _primary.hasAnySetter(a);
779         if (b == null) {
780             b = _secondary.hasAnySetter(a);
781         }
782         return b;
783     }
784
785     @Override
786     public JsonSetter.Value findSetterInfo(Annotated a) {
787         JsonSetter.Value v2 = _secondary.findSetterInfo(a);
788         JsonSetter.Value v1 = _primary.findSetterInfo(a);
789         return (v2 == null// shouldn't occur but
790             ? v1 : v2.withOverrides(v1);
791     }
792
793     @Override // since 2.9
794     public Boolean findMergeInfo(Annotated a) {
795         Boolean b = _primary.findMergeInfo(a);
796         if (b == null) {
797             b = _secondary.findMergeInfo(a);
798         }
799         return b;
800     }
801
802     @Override
803     @Deprecated // since 2.9
804     public boolean hasCreatorAnnotation(Annotated a) {
805         return _primary.hasCreatorAnnotation(a) || _secondary.hasCreatorAnnotation(a);
806     }
807
808     @Override
809     @Deprecated // since 2.9
810     public JsonCreator.Mode findCreatorBinding(Annotated a) {
811         JsonCreator.Mode mode = _primary.findCreatorBinding(a);
812         if (mode != null) {
813             return mode;
814         }
815         return _secondary.findCreatorBinding(a);
816     }
817
818     @Override
819     public JsonCreator.Mode findCreatorAnnotation(MapperConfig<?> config, Annotated a) {
820         JsonCreator.Mode mode = _primary.findCreatorAnnotation(config, a);
821         return (mode == null) ? _secondary.findCreatorAnnotation(config, a) : mode;
822     }
823
824     @Override
825     @Deprecated // since 2.9
826     public boolean hasAnySetterAnnotation(AnnotatedMethod am) {
827         return _primary.hasAnySetterAnnotation(am) || _secondary.hasAnySetterAnnotation(am);
828     }
829
830     protected boolean _isExplicitClassOrOb(Object maybeCls, Class<?> implicit) {
831         if ((maybeCls == null) || (maybeCls == implicit)) {
832             return false;
833         }
834         if (maybeCls instanceof Class<?>) {
835             return !ClassUtil.isBogusClass((Class<?>) maybeCls);
836         }
837         return true;
838     }
839
840     // @since 2.9
841     protected Object _explicitClassOrOb(Object maybeCls, Class<?> implicit) {
842         if ((maybeCls == null) || (maybeCls == implicit)) {
843             return null;
844         }
845         if ((maybeCls instanceof Class<?>) && ClassUtil.isBogusClass((Class<?>) maybeCls)) {
846             return null;
847         }
848         return maybeCls;
849     }
850 }
851