@@ -774,12 +774,7 @@ protected JsonSerializer<?> buildMapSerializer(SerializerProvider prov,
774
774
MapSerializer mapSer = MapSerializer .construct (ignored ,
775
775
type , staticTyping , elementTypeSerializer ,
776
776
keySerializer , elementValueSerializer , filterId );
777
- Object suppressableValue = findSuppressableContentValue (config ,
778
- type .getContentType (), beanDesc );
779
- if (suppressableValue != null ) {
780
- mapSer = mapSer .withContentInclusion (suppressableValue );
781
- }
782
- ser = mapSer ;
777
+ ser = _checkMapContentInclusion (prov , beanDesc , mapSer );
783
778
}
784
779
}
785
780
// [databind#120]: Allow post-processing
@@ -792,42 +787,95 @@ protected JsonSerializer<?> buildMapSerializer(SerializerProvider prov,
792
787
}
793
788
794
789
/**
795
- *<p>
796
- * NOTE: although return type is left opaque, it really needs to be
797
- * <code>JsonInclude.Include</code> for things to work as expected.
790
+ * Helper method that does figures out content inclusion value to use, if any,
791
+ * and construct re-configured {@link MapSerializer} appropriately.
798
792
*
799
- * @since 2.5
793
+ * @since 2.9
800
794
*/
801
- protected Object findSuppressableContentValue ( SerializationConfig config ,
802
- JavaType contentType , BeanDescription beanDesc )
795
+ protected MapSerializer _checkMapContentInclusion ( SerializerProvider prov ,
796
+ BeanDescription beanDesc , MapSerializer mapSer )
803
797
throws JsonMappingException
804
798
{
805
- /* 16-Apr-2016, tatu: Should this consider possible property-config overrides?
806
- * Quite possibly yes, but would need to carefully check that content type being
807
- * used is appropriate.
808
- */
809
- JsonInclude .Value inclV = beanDesc .findPropertyInclusion (config .getDefaultPropertyInclusion ());
799
+ final SerializationConfig config = prov .getConfig ();
810
800
811
- if (inclV == null ) {
812
- return null ;
801
+ // 30-Sep-2016, tatu: Defaulting gets complicated because we might have two distinct
802
+ // axis to consider: Map itself, and then value type.
803
+ // Start with Map-defaults, then use more-specific value override, if any
804
+
805
+ // Start by getting global setting, overridden by Map-type-override
806
+ JsonInclude .Value inclV = config .getDefaultPropertyInclusion (Map .class ,
807
+ config .getDefaultPropertyInclusion ());
808
+ // and then merge content-type overrides, if any. But note that there's
809
+ // content-to-value inclusion shift we have to do
810
+ final JavaType contentType = mapSer .getContentType ();
811
+ JsonInclude .Value valueIncl = config .getDefaultPropertyInclusion (contentType .getRawClass (), null );
812
+
813
+ if (valueIncl != null ) {
814
+ switch (valueIncl .getValueInclusion ()) {
815
+ case USE_DEFAULTS :
816
+ break ;
817
+ case CUSTOM :
818
+ inclV = inclV .withContentFilter (valueIncl .getContentFilter ());
819
+ break ;
820
+ default :
821
+ inclV = inclV .withContentInclusion (valueIncl .getValueInclusion ());
822
+ }
813
823
}
814
- JsonInclude .Include incl = inclV .getContentInclusion ();
815
- switch (incl ) {
816
- case USE_DEFAULTS : // means "dunno"
817
- return null ;
824
+ JsonInclude .Include incl = (inclV == null ) ? JsonInclude .Include .USE_DEFAULTS : inclV .getContentInclusion ();
825
+ if (incl == JsonInclude .Include .USE_DEFAULTS ) {
826
+ if (!config .isEnabled (SerializationFeature .WRITE_NULL_MAP_VALUES )) {
827
+ return mapSer .withContentInclusion (null , true );
828
+ }
829
+ return mapSer ;
830
+ }
831
+ // NOTE: mostly copied from `PropertyBuilder`; would be nice to refactor
832
+ // but code is not identical nor are these types related
833
+ Object valueToSuppress ;
834
+ boolean suppressNulls ;
835
+
836
+ switch (inclV .getContentInclusion ()) {
818
837
case NON_DEFAULT :
819
- // 19-Oct-2014, tatu: Not sure what this'd mean; so take it to mean "NON_EMPTY"...
820
- // 11-Nov-2015, tatu: With 2.6, we did indeed revert to "NON_EMPTY", but that did
821
- // not go well, so with 2.7, we'll do this instead...
822
- // But not 100% sure if we ought to call new `JsonSerializer.findDefaultValue()`;
823
- // to do that, would need to locate said serializer
824
- // incl = JsonInclude.Include.NON_EMPTY;
838
+ valueToSuppress = BeanUtil .getDefaultValue (contentType );
839
+ suppressNulls = true ;
840
+ if (valueToSuppress != null ) {
841
+ if (valueToSuppress .getClass ().isArray ()) {
842
+ valueToSuppress = ArrayBuilders .getArrayComparator (valueToSuppress );
843
+ }
844
+ }
825
845
break ;
846
+ case NON_ABSENT : // new with 2.6, to support Guava/JDK8 Optionals
847
+ // always suppress nulls
848
+ suppressNulls = true ;
849
+ // and for referential types, also "empty", which in their case means "absent"
850
+ valueToSuppress = contentType .isReferenceType ()
851
+ ? MapSerializer .MARKER_FOR_EMPTY : null ;
852
+ break ;
853
+ case NON_EMPTY :
854
+ // always suppress nulls
855
+ suppressNulls = true ;
856
+ // but possibly also 'empty' values:
857
+ valueToSuppress = MapSerializer .MARKER_FOR_EMPTY ;
858
+ break ;
859
+ case CUSTOM : // new with 2.9
860
+ valueToSuppress = prov .includeFilterInstance (null , inclV .getContentFilter ());
861
+ if (valueToSuppress == null ) { // is this legal?
862
+ suppressNulls = true ;
863
+ } else {
864
+ suppressNulls = prov .includeFilterSuppressNulls (valueToSuppress );
865
+ }
866
+ break ;
867
+ case NON_NULL :
868
+ valueToSuppress = null ;
869
+ suppressNulls = true ;
870
+ // fall through
871
+ case ALWAYS : // default
826
872
default :
827
- // all other modes actually good as is, unless we'll find better ways
873
+ valueToSuppress = null ;
874
+ suppressNulls = !prov .isEnabled (SerializationFeature .WRITE_NULL_MAP_VALUES );
828
875
break ;
829
876
}
830
- return incl ;
877
+
878
+ return mapSer .withContentInclusion (valueToSuppress , suppressNulls );
831
879
}
832
880
833
881
/*
0 commit comments