@@ -547,7 +547,7 @@ protected JsonSerializer<?> buildContainerSerializer(SerializerProvider prov,
547
547
{
548
548
final SerializationConfig config = prov .getConfig ();
549
549
550
- /* [Issue #23], 15-Mar-2013, tatu: must force static handling of root value type,
550
+ /* [databind #23], 15-Mar-2013, tatu: must force static handling of root value type,
551
551
* with just one important exception: if value type is "untyped", let's
552
552
* leave it as is; no clean way to make it work.
553
553
*/
@@ -568,62 +568,70 @@ protected JsonSerializer<?> buildContainerSerializer(SerializerProvider prov,
568
568
}
569
569
JsonSerializer <Object > elementValueSerializer = _findContentSerializer (prov ,
570
570
beanDesc .getClassInfo ());
571
-
572
571
if (type .isMapLikeType ()) { // implements java.util.Map
573
572
MapLikeType mlt = (MapLikeType ) type ;
574
573
/* 29-Sep-2012, tatu: This is actually too early to (try to) find
575
574
* key serializer from property annotations, and can lead to caching
576
- * issues (see [Issue #75]). Instead, must be done from 'createContextual()' call.
575
+ * issues (see [databind #75]). Instead, must be done from 'createContextual()' call.
577
576
* But we do need to check class annotations.
578
577
*/
579
578
JsonSerializer <Object > keySerializer = _findKeySerializer (prov , beanDesc .getClassInfo ());
580
579
if (mlt .isTrueMapType ()) {
581
- return buildMapSerializer (config , (MapType ) mlt , beanDesc , staticTyping ,
580
+ return buildMapSerializer (prov , (MapType ) mlt , beanDesc , staticTyping ,
582
581
keySerializer , elementTypeSerializer , elementValueSerializer );
583
582
}
584
- // Only custom serializers may be available:
585
- for (Serializers serializers : customSerializers ()) {
586
- MapLikeType mlType = (MapLikeType ) type ;
587
- JsonSerializer <?> ser = serializers .findMapLikeSerializer (config ,
583
+ // With Map-like, just 2 options: (1) Custom, (2) Annotations
584
+ JsonSerializer <?> ser = null ;
585
+ MapLikeType mlType = (MapLikeType ) type ;
586
+ for (Serializers serializers : customSerializers ()) { // (1) Custom
587
+ ser = serializers .findMapLikeSerializer (config ,
588
588
mlType , beanDesc , keySerializer , elementTypeSerializer , elementValueSerializer );
589
589
if (ser != null ) {
590
- // [Issue#120]: Allow post-processing
591
- if (_factoryConfig .hasSerializerModifiers ()) {
592
- for (BeanSerializerModifier mod : _factoryConfig .serializerModifiers ()) {
593
- ser = mod .modifyMapLikeSerializer (config , mlType , beanDesc , ser );
594
- }
590
+ break ;
591
+ }
592
+ }
593
+ if (ser == null ) { // (2) Annotations-based ones:
594
+ ser = findSerializerByAnnotations (prov , type , beanDesc );
595
+ }
596
+ if (ser != null ) {
597
+ if (_factoryConfig .hasSerializerModifiers ()) {
598
+ for (BeanSerializerModifier mod : _factoryConfig .serializerModifiers ()) {
599
+ ser = mod .modifyMapLikeSerializer (config , mlType , beanDesc , ser );
595
600
}
596
- return ser ;
597
601
}
598
602
}
599
- return null ;
603
+ return ser ;
600
604
}
601
605
if (type .isCollectionLikeType ()) {
602
606
CollectionLikeType clt = (CollectionLikeType ) type ;
603
607
if (clt .isTrueCollectionType ()) {
604
- return buildCollectionSerializer (config , (CollectionType ) clt , beanDesc , staticTyping ,
608
+ return buildCollectionSerializer (prov , (CollectionType ) clt , beanDesc , staticTyping ,
605
609
elementTypeSerializer , elementValueSerializer );
606
610
}
611
+ // With Map-like, just 2 options: (1) Custom, (2) Annotations
612
+ JsonSerializer <?> ser = null ;
607
613
CollectionLikeType clType = (CollectionLikeType ) type ;
608
- // Only custom variants for this:
609
- for (Serializers serializers : customSerializers ()) {
610
- JsonSerializer <?> ser = serializers .findCollectionLikeSerializer (config ,
614
+ for (Serializers serializers : customSerializers ()) { // (1) Custom
615
+ ser = serializers .findCollectionLikeSerializer (config ,
611
616
clType , beanDesc , elementTypeSerializer , elementValueSerializer );
612
617
if (ser != null ) {
613
- // [Issue#120]: Allow post-processing
614
- if (_factoryConfig .hasSerializerModifiers ()) {
615
- for (BeanSerializerModifier mod : _factoryConfig .serializerModifiers ()) {
616
- ser = mod .modifyCollectionLikeSerializer (config , clType , beanDesc , ser );
617
- }
618
+ break ;
619
+ }
620
+ }
621
+ if (ser == null ) { // (2) Annotations-based ones:
622
+ ser = findSerializerByAnnotations (prov , type , beanDesc );
623
+ }
624
+ if (ser != null ) {
625
+ if (_factoryConfig .hasSerializerModifiers ()) {
626
+ for (BeanSerializerModifier mod : _factoryConfig .serializerModifiers ()) {
627
+ ser = mod .modifyCollectionLikeSerializer (config , clType , beanDesc , ser );
618
628
}
619
- return ser ;
620
629
}
621
630
}
622
- // fall through either way (whether shape dictates serialization as POJO or not)
623
- return null ;
631
+ return ser ;
624
632
}
625
633
if (type .isArrayType ()) {
626
- return buildArraySerializer (config , (ArrayType ) type , beanDesc , staticTyping ,
634
+ return buildArraySerializer (prov , (ArrayType ) type , beanDesc , staticTyping ,
627
635
elementTypeSerializer , elementValueSerializer );
628
636
}
629
637
return null ;
@@ -635,14 +643,18 @@ protected JsonSerializer<?> buildContainerSerializer(SerializerProvider prov,
635
643
*
636
644
* @since 2.1
637
645
*/
638
- protected JsonSerializer <?> buildCollectionSerializer (SerializationConfig config ,
646
+ protected JsonSerializer <?> buildCollectionSerializer (SerializerProvider prov ,
639
647
CollectionType type , BeanDescription beanDesc , boolean staticTyping ,
640
648
TypeSerializer elementTypeSerializer , JsonSerializer <Object > elementValueSerializer )
641
649
throws JsonMappingException
642
650
{
651
+ SerializationConfig config = prov .getConfig ();
643
652
JsonSerializer <?> ser = null ;
644
- // Module-provided custom collection serializers?
645
- for (Serializers serializers : customSerializers ()) {
653
+ // Order of lookups:
654
+ // 1. Custom serializers
655
+ // 2. Annotations (@JsonValue, @JsonDeserialize)
656
+ // 3. Defaults
657
+ for (Serializers serializers : customSerializers ()) { // (1) Custom
646
658
ser = serializers .findCollectionSerializer (config ,
647
659
type , beanDesc , elementTypeSerializer , elementValueSerializer );
648
660
if (ser != null ) {
@@ -651,46 +663,49 @@ protected JsonSerializer<?> buildCollectionSerializer(SerializationConfig config
651
663
}
652
664
653
665
if (ser == null ) {
654
- // We may also want to use serialize Collections "as beans", if (and only if)
655
- // this is specified with `@JsonFormat(shape=Object)`
656
- JsonFormat .Value format = beanDesc .findExpectedFormat (null );
657
- if (format != null && format .getShape () == JsonFormat .Shape .OBJECT ) {
658
- return null ;
659
- }
660
- Class <?> raw = type .getRawClass ();
661
- if (EnumSet .class .isAssignableFrom (raw )) {
662
- // this may or may not be available (Class doesn't; type of field/method does)
663
- JavaType enumType = type .getContentType ();
664
- // and even if nominally there is something, only use if it really is enum
665
- if (!enumType .isEnumType ()) {
666
- enumType = null ;
666
+ ser = findSerializerByAnnotations (prov , type , beanDesc ); // (2) Annotations
667
+ if (ser == null ) {
668
+ // We may also want to use serialize Collections "as beans", if (and only if)
669
+ // this is specified with `@JsonFormat(shape=Object)`
670
+ JsonFormat .Value format = beanDesc .findExpectedFormat (null );
671
+ if (format != null && format .getShape () == JsonFormat .Shape .OBJECT ) {
672
+ return null ;
667
673
}
668
- ser = buildEnumSetSerializer (enumType );
669
- } else {
670
- Class <?> elementRaw = type .getContentType ().getRawClass ();
671
- if (isIndexedList (raw )) {
672
- if (elementRaw == String .class ) {
674
+ Class <?> raw = type .getRawClass ();
675
+ if (EnumSet .class .isAssignableFrom (raw )) {
676
+ // this may or may not be available (Class doesn't; type of field/method does)
677
+ JavaType enumType = type .getContentType ();
678
+ // and even if nominally there is something, only use if it really is enum
679
+ if (!enumType .isEnumType ()) {
680
+ enumType = null ;
681
+ }
682
+ ser = buildEnumSetSerializer (enumType );
683
+ } else {
684
+ Class <?> elementRaw = type .getContentType ().getRawClass ();
685
+ if (isIndexedList (raw )) {
686
+ if (elementRaw == String .class ) {
687
+ // [JACKSON-829] Must NOT use if we have custom serializer
688
+ if (elementValueSerializer == null || ClassUtil .isJacksonStdImpl (elementValueSerializer )) {
689
+ ser = IndexedStringListSerializer .instance ;
690
+ }
691
+ } else {
692
+ ser = buildIndexedListSerializer (type .getContentType (), staticTyping ,
693
+ elementTypeSerializer , elementValueSerializer );
694
+ }
695
+ } else if (elementRaw == String .class ) {
673
696
// [JACKSON-829] Must NOT use if we have custom serializer
674
697
if (elementValueSerializer == null || ClassUtil .isJacksonStdImpl (elementValueSerializer )) {
675
- ser = IndexedStringListSerializer .instance ;
698
+ ser = StringCollectionSerializer .instance ;
676
699
}
677
- } else {
678
- ser = buildIndexedListSerializer (type .getContentType (), staticTyping ,
679
- elementTypeSerializer , elementValueSerializer );
680
700
}
681
- } else if (elementRaw == String .class ) {
682
- // [JACKSON-829] Must NOT use if we have custom serializer
683
- if (elementValueSerializer == null || ClassUtil .isJacksonStdImpl (elementValueSerializer )) {
684
- ser = StringCollectionSerializer .instance ;
701
+ if (ser == null ) {
702
+ ser = buildCollectionSerializer (type .getContentType (), staticTyping ,
703
+ elementTypeSerializer , elementValueSerializer );
685
704
}
686
705
}
687
- if (ser == null ) {
688
- ser = buildCollectionSerializer (type .getContentType (), staticTyping ,
689
- elementTypeSerializer , elementValueSerializer );
690
- }
691
706
}
692
707
}
693
- // [Issue #120]: Allow post-processing
708
+ // [databind #120]: Allow post-processing
694
709
if (_factoryConfig .hasSerializerModifiers ()) {
695
710
for (BeanSerializerModifier mod : _factoryConfig .serializerModifiers ()) {
696
711
ser = mod .modifyCollectionSerializer (config , type , beanDesc , ser );
@@ -733,48 +748,58 @@ public JsonSerializer<?> buildEnumSetSerializer(JavaType enumType) {
733
748
* Helper method that handles configuration details when constructing serializers for
734
749
* {@link java.util.Map} types.
735
750
*/
736
- protected JsonSerializer <?> buildMapSerializer (SerializationConfig config ,
751
+ protected JsonSerializer <?> buildMapSerializer (SerializerProvider prov ,
737
752
MapType type , BeanDescription beanDesc ,
738
753
boolean staticTyping , JsonSerializer <Object > keySerializer ,
739
754
TypeSerializer elementTypeSerializer , JsonSerializer <Object > elementValueSerializer )
740
755
throws JsonMappingException
741
756
{
757
+ final SerializationConfig config = prov .getConfig ();
742
758
JsonSerializer <?> ser = null ;
743
- for (Serializers serializers : customSerializers ()) {
759
+
760
+ // Order of lookups:
761
+ // 1. Custom serializers
762
+ // 2. Annotations (@JsonValue, @JsonDeserialize)
763
+ // 3. Defaults
764
+
765
+ for (Serializers serializers : customSerializers ()) { // (1) Custom
744
766
ser = serializers .findMapSerializer (config , type , beanDesc ,
745
767
keySerializer , elementTypeSerializer , elementValueSerializer );
746
768
if (ser != null ) { break ; }
747
769
}
748
770
if (ser == null ) {
749
- // 08-Nov-2014, tatu: As per [databind#601], better just use default Map serializer
750
- /*
751
- if (EnumMap.class.isAssignableFrom(type.getRawClass())
752
- && ((keySerializer == null) || ClassUtil.isJacksonStdImpl(keySerializer))) {
753
- JavaType keyType = type.getKeyType();
754
- // Need to find key enum values...
755
- EnumValues enums = null;
756
- if (keyType.isEnumType()) { // non-enum if we got it as type erased class (from instance)
757
- @SuppressWarnings("unchecked")
758
- Class<Enum<?>> enumClass = (Class<Enum<?>>) keyType.getRawClass();
759
- enums = EnumValues.construct(config, enumClass);
771
+ ser = findSerializerByAnnotations (prov , type , beanDesc ); // (2) Annotations
772
+ if (ser == null ) {
773
+ // 08-Nov-2014, tatu: As per [databind#601], better just use default Map serializer
774
+ /*
775
+ if (EnumMap.class.isAssignableFrom(type.getRawClass())
776
+ && ((keySerializer == null) || ClassUtil.isJacksonStdImpl(keySerializer))) {
777
+ JavaType keyType = type.getKeyType();
778
+ // Need to find key enum values...
779
+ EnumValues enums = null;
780
+ if (keyType.isEnumType()) { // non-enum if we got it as type erased class (from instance)
781
+ @SuppressWarnings("unchecked")
782
+ Class<Enum<?>> enumClass = (Class<Enum<?>>) keyType.getRawClass();
783
+ enums = EnumValues.construct(config, enumClass);
784
+ }
785
+ ser = new EnumMapSerializer(type.getContentType(), staticTyping, enums,
786
+ elementTypeSerializer, elementValueSerializer);
787
+ } else {
788
+ */
789
+ Object filterId = findFilterId (config , beanDesc );
790
+ AnnotationIntrospector ai = config .getAnnotationIntrospector ();
791
+ MapSerializer mapSer = MapSerializer .construct (ai .findPropertiesToIgnore (beanDesc .getClassInfo (), true ),
792
+ type , staticTyping , elementTypeSerializer ,
793
+ keySerializer , elementValueSerializer , filterId );
794
+ Object suppressableValue = findSuppressableContentValue (config ,
795
+ type .getContentType (), beanDesc );
796
+ if (suppressableValue != null ) {
797
+ mapSer = mapSer .withContentInclusion (suppressableValue );
760
798
}
761
- ser = new EnumMapSerializer(type.getContentType(), staticTyping, enums,
762
- elementTypeSerializer, elementValueSerializer);
763
- } else {
764
- */
765
- Object filterId = findFilterId (config , beanDesc );
766
- AnnotationIntrospector ai = config .getAnnotationIntrospector ();
767
- MapSerializer mapSer = MapSerializer .construct (ai .findPropertiesToIgnore (beanDesc .getClassInfo (), true ),
768
- type , staticTyping , elementTypeSerializer ,
769
- keySerializer , elementValueSerializer , filterId );
770
- Object suppressableValue = findSuppressableContentValue (config ,
771
- type .getContentType (), beanDesc );
772
- if (suppressableValue != null ) {
773
- mapSer = mapSer .withContentInclusion (suppressableValue );
799
+ ser = mapSer ;
774
800
}
775
- ser = mapSer ;
776
801
}
777
- // [Issue #120]: Allow post-processing
802
+ // [databind #120]: Allow post-processing
778
803
if (_factoryConfig .hasSerializerModifiers ()) {
779
804
for (BeanSerializerModifier mod : _factoryConfig .serializerModifiers ()) {
780
805
ser = mod .modifyMapSerializer (config , type , beanDesc , ser );
@@ -821,22 +846,28 @@ protected Object findSuppressableContentValue(SerializationConfig config,
821
846
* Helper method that handles configuration details when constructing serializers for
822
847
* <code>Object[]</code> (and subtypes, except for String).
823
848
*/
824
- protected JsonSerializer <?> buildArraySerializer (SerializationConfig config ,
849
+ protected JsonSerializer <?> buildArraySerializer (SerializerProvider prov ,
825
850
ArrayType type , BeanDescription beanDesc ,
826
851
boolean staticTyping ,
827
852
TypeSerializer elementTypeSerializer , JsonSerializer <Object > elementValueSerializer )
828
853
throws JsonMappingException
829
854
{
830
- JsonSerializer <?> ser = null ;
831
- // Module-provided custom collection serializers?
832
- for (Serializers serializers : customSerializers ()) {
855
+ // 25-Jun-2015, tatu: Note that unlike with Collection(Like) and Map(Like) types, array
856
+ // types can not be annotated (in theory I guess we could have mix-ins but... ?)
857
+ // so we need not do primary annotation lookup here.
858
+ // So all we need is (1) Custom, (2) Default array serializers
859
+ SerializationConfig config = prov .getConfig ();
860
+ JsonSerializer <?> ser = null ;
861
+
862
+ for (Serializers serializers : customSerializers ()) { // (1) Custom
833
863
ser = serializers .findArraySerializer (config ,
834
864
type , beanDesc , elementTypeSerializer , elementValueSerializer );
835
865
if (ser != null ) {
836
866
break ;
837
867
}
838
- }
839
- if (ser == null ) {
868
+ }
869
+
870
+ if (ser == null ) {
840
871
Class <?> raw = type .getRawClass ();
841
872
// Important: do NOT use standard serializers if non-standard element value serializer specified
842
873
if (elementValueSerializer == null || ClassUtil .isJacksonStdImpl (elementValueSerializer )) {
@@ -852,7 +883,7 @@ protected JsonSerializer<?> buildArraySerializer(SerializationConfig config,
852
883
elementValueSerializer );
853
884
}
854
885
}
855
- // [Issue #120]: Allow post-processing
886
+ // [databind #120]: Allow post-processing
856
887
if (_factoryConfig .hasSerializerModifiers ()) {
857
888
for (BeanSerializerModifier mod : _factoryConfig .serializerModifiers ()) {
858
889
ser = mod .modifyArraySerializer (config , type , beanDesc , ser );
0 commit comments