1 package com.fasterxml.jackson.databind.ser.std;
2
3 import java.io.IOException;
4 import java.lang.reflect.Type;
5 import java.util.*;
6
7 import com.fasterxml.jackson.annotation.JsonFormat;
8 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
9 import com.fasterxml.jackson.annotation.JsonInclude;
10 import com.fasterxml.jackson.core.*;
11 import com.fasterxml.jackson.core.type.WritableTypeId;
12 import com.fasterxml.jackson.databind.*;
13 import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
14 import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
15 import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
16 import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonMapFormatVisitor;
17 import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
18 import com.fasterxml.jackson.databind.ser.ContainerSerializer;
19 import com.fasterxml.jackson.databind.ser.ContextualSerializer;
20 import com.fasterxml.jackson.databind.ser.PropertyFilter;
21 import com.fasterxml.jackson.databind.ser.impl.PropertySerializerMap;
22 import com.fasterxml.jackson.databind.type.TypeFactory;
23 import com.fasterxml.jackson.databind.util.ArrayBuilders;
24 import com.fasterxml.jackson.databind.util.BeanUtil;
25 import com.fasterxml.jackson.databind.util.ClassUtil;
26
27
33 @JacksonStdImpl
34 public class MapSerializer
35 extends ContainerSerializer<Map<?,?>>
36 implements ContextualSerializer
37 {
38 private static final long serialVersionUID = 1L;
39
40 protected final static JavaType UNSPECIFIED_TYPE = TypeFactory.unknownType();
41
42
45 public final static Object MARKER_FOR_EMPTY = JsonInclude.Include.NON_EMPTY;
46
47
52
53
56 protected final BeanProperty _property;
57
58
62 protected final boolean _valueTypeIsStatic;
63
64
67 protected final JavaType _keyType;
68
69
72 protected final JavaType _valueType;
73
74
79
80
83 protected JsonSerializer<Object> _keySerializer;
84
85
88 protected JsonSerializer<Object> _valueSerializer;
89
90
93 protected final TypeSerializer _valueTypeSerializer;
94
95
99 protected PropertySerializerMap _dynamicValueSerializers;
100
101
106
107
110 protected final Set<String> _ignoredEntries;
111
112
117 protected final Object _filterId;
118
119
129 protected final Object _suppressableValue;
130
131
137 protected final boolean _suppressNulls;
138
139
144
145
151 protected final boolean _sortKeys;
152
153
158
159
162 @SuppressWarnings("unchecked")
163 protected MapSerializer(Set<String> ignoredEntries,
164 JavaType keyType, JavaType valueType, boolean valueTypeIsStatic,
165 TypeSerializer vts,
166 JsonSerializer<?> keySerializer, JsonSerializer<?> valueSerializer)
167 {
168 super(Map.class, false);
169 _ignoredEntries = ((ignoredEntries == null) || ignoredEntries.isEmpty())
170 ? null : ignoredEntries;
171 _keyType = keyType;
172 _valueType = valueType;
173 _valueTypeIsStatic = valueTypeIsStatic;
174 _valueTypeSerializer = vts;
175 _keySerializer = (JsonSerializer<Object>) keySerializer;
176 _valueSerializer = (JsonSerializer<Object>) valueSerializer;
177 _dynamicValueSerializers = PropertySerializerMap.emptyForProperties();
178 _property = null;
179 _filterId = null;
180 _sortKeys = false;
181 _suppressableValue = null;
182 _suppressNulls = false;
183 }
184
185 @SuppressWarnings("unchecked")
186 protected MapSerializer(MapSerializer src, BeanProperty property,
187 JsonSerializer<?> keySerializer, JsonSerializer<?> valueSerializer,
188 Set<String> ignoredEntries)
189 {
190 super(Map.class, false);
191 _ignoredEntries = ((ignoredEntries == null) || ignoredEntries.isEmpty())
192 ? null : ignoredEntries;
193 _keyType = src._keyType;
194 _valueType = src._valueType;
195 _valueTypeIsStatic = src._valueTypeIsStatic;
196 _valueTypeSerializer = src._valueTypeSerializer;
197 _keySerializer = (JsonSerializer<Object>) keySerializer;
198 _valueSerializer = (JsonSerializer<Object>) valueSerializer;
199
200 _dynamicValueSerializers = PropertySerializerMap.emptyForProperties();
201 _property = property;
202 _filterId = src._filterId;
203 _sortKeys = src._sortKeys;
204 _suppressableValue = src._suppressableValue;
205 _suppressNulls = src._suppressNulls;
206 }
207
208
211 protected MapSerializer(MapSerializer src, TypeSerializer vts,
212 Object suppressableValue, boolean suppressNulls)
213 {
214 super(Map.class, false);
215 _ignoredEntries = src._ignoredEntries;
216 _keyType = src._keyType;
217 _valueType = src._valueType;
218 _valueTypeIsStatic = src._valueTypeIsStatic;
219 _valueTypeSerializer = vts;
220 _keySerializer = src._keySerializer;
221 _valueSerializer = src._valueSerializer;
222
223
224 _dynamicValueSerializers = src._dynamicValueSerializers;
225 _property = src._property;
226 _filterId = src._filterId;
227 _sortKeys = src._sortKeys;
228 _suppressableValue = suppressableValue;
229 _suppressNulls = suppressNulls;
230 }
231
232 protected MapSerializer(MapSerializer src, Object filterId, boolean sortKeys)
233 {
234 super(Map.class, false);
235 _ignoredEntries = src._ignoredEntries;
236 _keyType = src._keyType;
237 _valueType = src._valueType;
238 _valueTypeIsStatic = src._valueTypeIsStatic;
239 _valueTypeSerializer = src._valueTypeSerializer;
240 _keySerializer = src._keySerializer;
241 _valueSerializer = src._valueSerializer;
242
243 _dynamicValueSerializers = PropertySerializerMap.emptyForProperties();
244 _property = src._property;
245 _filterId = filterId;
246 _sortKeys = sortKeys;
247 _suppressableValue = src._suppressableValue;
248 _suppressNulls = src._suppressNulls;
249 }
250
251 @Override
252 public MapSerializer _withValueTypeSerializer(TypeSerializer vts) {
253 if (_valueTypeSerializer == vts) {
254 return this;
255 }
256 _ensureOverride("_withValueTypeSerializer");
257 return new MapSerializer(this, vts, _suppressableValue, _suppressNulls);
258 }
259
260
263 public MapSerializer withResolved(BeanProperty property,
264 JsonSerializer<?> keySerializer, JsonSerializer<?> valueSerializer,
265 Set<String> ignored, boolean sortKeys)
266 {
267 _ensureOverride("withResolved");
268 MapSerializer ser = new MapSerializer(this, property, keySerializer, valueSerializer, ignored);
269 if (sortKeys != ser._sortKeys) {
270 ser = new MapSerializer(ser, _filterId, sortKeys);
271 }
272 return ser;
273 }
274
275 @Override
276 public MapSerializer withFilterId(Object filterId) {
277 if (_filterId == filterId) {
278 return this;
279 }
280 _ensureOverride("withFilterId");
281 return new MapSerializer(this, filterId, _sortKeys);
282 }
283
284
290 public MapSerializer withContentInclusion(Object suppressableValue, boolean suppressNulls) {
291 if ((suppressableValue == _suppressableValue) && (suppressNulls == _suppressNulls)) {
292 return this;
293 }
294 _ensureOverride("withContentInclusion");
295 return new MapSerializer(this, _valueTypeSerializer, suppressableValue, suppressNulls);
296 }
297
298
301 public static MapSerializer construct(Set<String> ignoredEntries, JavaType mapType,
302 boolean staticValueType, TypeSerializer vts,
303 JsonSerializer<Object> keySerializer, JsonSerializer<Object> valueSerializer,
304 Object filterId)
305 {
306 JavaType keyType, valueType;
307
308 if (mapType == null) {
309 keyType = valueType = UNSPECIFIED_TYPE;
310 } else {
311 keyType = mapType.getKeyType();
312 if (mapType.hasRawClass(java.util.Properties.class)) {
313
314
315 valueType = TypeFactory.unknownType();
316 } else {
317 valueType = mapType.getContentType();
318 }
319 }
320
321 if (!staticValueType) {
322 staticValueType = (valueType != null && valueType.isFinal());
323 } else {
324
325 if (valueType.getRawClass() == Object.class) {
326 staticValueType = false;
327 }
328 }
329 MapSerializer ser = new MapSerializer(ignoredEntries, keyType, valueType, staticValueType, vts,
330 keySerializer, valueSerializer);
331 if (filterId != null) {
332 ser = ser.withFilterId(filterId);
333 }
334 return ser;
335 }
336
337
340 protected void _ensureOverride(String method) {
341 ClassUtil.verifyMustOverride(MapSerializer.class, this, method);
342 }
343
344
347 @Deprecated
348 protected void _ensureOverride() {
349 _ensureOverride("N/A");
350 }
351
352
357
358
362 @Deprecated
363 protected MapSerializer(MapSerializer src, TypeSerializer vts,
364 Object suppressableValue)
365 {
366 this(src, vts, suppressableValue, false);
367 }
368
369
372 @Deprecated
373 public MapSerializer withContentInclusion(Object suppressableValue) {
374 return new MapSerializer(this, _valueTypeSerializer, suppressableValue, _suppressNulls);
375 }
376
377
382 @Deprecated
383 public static MapSerializer construct(String[] ignoredList, JavaType mapType,
384 boolean staticValueType, TypeSerializer vts,
385 JsonSerializer<Object> keySerializer, JsonSerializer<Object> valueSerializer,
386 Object filterId)
387 {
388 Set<String> ignoredEntries = ArrayBuilders.arrayToSet(ignoredList);
389 return construct(ignoredEntries, mapType, staticValueType, vts,
390 keySerializer, valueSerializer, filterId);
391 }
392
393
398
399 @Override
400 public JsonSerializer<?> createContextual(SerializerProvider provider,
401 BeanProperty property)
402 throws JsonMappingException
403 {
404 JsonSerializer<?> ser = null;
405 JsonSerializer<?> keySer = null;
406 final AnnotationIntrospector intr = provider.getAnnotationIntrospector();
407 final AnnotatedMember propertyAcc = (property == null) ? null : property.getMember();
408
409
410 if (_neitherNull(propertyAcc, intr)) {
411 Object serDef = intr.findKeySerializer(propertyAcc);
412 if (serDef != null) {
413 keySer = provider.serializerInstance(propertyAcc, serDef);
414 }
415 serDef = intr.findContentSerializer(propertyAcc);
416 if (serDef != null) {
417 ser = provider.serializerInstance(propertyAcc, serDef);
418 }
419 }
420 if (ser == null) {
421 ser = _valueSerializer;
422 }
423
424 ser = findContextualConvertingSerializer(provider, property, ser);
425 if (ser == null) {
426
427
428
429 if (_valueTypeIsStatic && !_valueType.isJavaLangObject()) {
430 ser = provider.findContentValueSerializer(_valueType, property);
431 }
432 }
433 if (keySer == null) {
434 keySer = _keySerializer;
435 }
436 if (keySer == null) {
437 keySer = provider.findKeySerializer(_keyType, property);
438 } else {
439 keySer = provider.handleSecondaryContextualization(keySer, property);
440 }
441 Set<String> ignored = _ignoredEntries;
442 boolean sortKeys = false;
443 if (_neitherNull(propertyAcc, intr)) {
444 JsonIgnoreProperties.Value ignorals = intr.findPropertyIgnorals(propertyAcc);
445 if (ignorals != null){
446 Set<String> newIgnored = ignorals.findIgnoredForSerialization();
447 if (_nonEmpty(newIgnored)) {
448 ignored = (ignored == null) ? new HashSet<String>() : new HashSet<String>(ignored);
449 for (String str : newIgnored) {
450 ignored.add(str);
451 }
452 }
453 }
454 Boolean b = intr.findSerializationSortAlphabetically(propertyAcc);
455 sortKeys = Boolean.TRUE.equals(b);
456 }
457 JsonFormat.Value format = findFormatOverrides(provider, property, Map.class);
458 if (format != null) {
459 Boolean B = format.getFeature(JsonFormat.Feature.WRITE_SORTED_MAP_ENTRIES);
460 if (B != null) {
461 sortKeys = B.booleanValue();
462 }
463 }
464 MapSerializer mser = withResolved(property, keySer, ser, ignored, sortKeys);
465
466
467 if (property != null) {
468 AnnotatedMember m = property.getMember();
469 if (m != null) {
470 Object filterId = intr.findFilterId(m);
471 if (filterId != null) {
472 mser = mser.withFilterId(filterId);
473 }
474 }
475 }
476 JsonInclude.Value inclV = findIncludeOverrides(provider, property, Map.class);
477 if (inclV != null) {
478 JsonInclude.Include incl = inclV.getContentInclusion();
479
480 if (incl != JsonInclude.Include.USE_DEFAULTS) {
481 Object valueToSuppress;
482 boolean suppressNulls;
483 switch (incl) {
484 case NON_DEFAULT:
485 valueToSuppress = BeanUtil.getDefaultValue(_valueType);
486 suppressNulls = true;
487 if (valueToSuppress != null) {
488 if (valueToSuppress.getClass().isArray()) {
489 valueToSuppress = ArrayBuilders.getArrayComparator(valueToSuppress);
490 }
491 }
492 break;
493 case NON_ABSENT:
494 suppressNulls = true;
495 valueToSuppress = _valueType.isReferenceType() ? MARKER_FOR_EMPTY : null;
496 break;
497 case NON_EMPTY:
498 suppressNulls = true;
499 valueToSuppress = MARKER_FOR_EMPTY;
500 break;
501 case CUSTOM:
502 valueToSuppress = provider.includeFilterInstance(null, inclV.getContentFilter());
503 if (valueToSuppress == null) {
504 suppressNulls = true;
505 } else {
506 suppressNulls = provider.includeFilterSuppressNulls(valueToSuppress);
507 }
508 break;
509 case NON_NULL:
510 valueToSuppress = null;
511 suppressNulls = true;
512 break;
513 case ALWAYS:
514 default:
515 valueToSuppress = null;
516
517
518 suppressNulls = false;
519 break;
520 }
521 mser = mser.withContentInclusion(valueToSuppress, suppressNulls);
522 }
523 }
524 return mser;
525 }
526
527
532
533 @Override
534 public JavaType getContentType() {
535 return _valueType;
536 }
537
538 @Override
539 public JsonSerializer<?> getContentSerializer() {
540 return _valueSerializer;
541 }
542
543 @Override
544 public boolean isEmpty(SerializerProvider prov, Map<?,?> value)
545 {
546 if (value.isEmpty()) {
547 return true;
548 }
549
550
551
552 Object supp = _suppressableValue;
553 if ((supp == null) && !_suppressNulls) {
554 return false;
555 }
556 JsonSerializer<Object> valueSer = _valueSerializer;
557 final boolean checkEmpty = (MARKER_FOR_EMPTY == supp);
558 if (valueSer != null) {
559 for (Object elemValue : value.values()) {
560 if (elemValue == null) {
561 if (_suppressNulls) {
562 continue;
563 }
564 return false;
565 }
566 if (checkEmpty) {
567 if (!valueSer.isEmpty(prov, elemValue)) {
568 return false;
569 }
570 } else if ((supp == null) || !supp.equals(value)) {
571 return false;
572 }
573 }
574 return true;
575 }
576
577 for (Object elemValue : value.values()) {
578 if (elemValue == null) {
579 if (_suppressNulls) {
580 continue;
581 }
582 return false;
583 }
584 try {
585 valueSer = _findSerializer(prov, elemValue);
586 } catch (JsonMappingException e) {
587
588 return false;
589 }
590 if (checkEmpty) {
591 if (!valueSer.isEmpty(prov, elemValue)) {
592 return false;
593 }
594 } else if ((supp == null) || !supp.equals(value)) {
595 return false;
596 }
597 }
598 return true;
599 }
600
601 @Override
602 public boolean hasSingleElement(Map<?,?> value) {
603 return (value.size() == 1);
604 }
605
606
611
612
622 public JsonSerializer<?> getKeySerializer() {
623 return _keySerializer;
624 }
625
626
631
632 @Override
633 public void serialize(Map<?,?> value, JsonGenerator gen, SerializerProvider provider)
634 throws IOException
635 {
636 gen.writeStartObject(value);
637 serializeWithoutTypeInfo(value, gen, provider);
638 gen.writeEndObject();
639 }
640
641 @Override
642 public void serializeWithType(Map<?,?> value, JsonGenerator gen, SerializerProvider provider,
643 TypeSerializer typeSer)
644 throws IOException
645 {
646
647 gen.setCurrentValue(value);
648 WritableTypeId typeIdDef = typeSer.writeTypePrefix(gen,
649 typeSer.typeId(value, JsonToken.START_OBJECT));
650 serializeWithoutTypeInfo(value, gen, provider);
651 typeSer.writeTypeSuffix(gen, typeIdDef);
652 }
653
654
659
660
668 public void serializeWithoutTypeInfo(Map<?, ?> value, JsonGenerator gen, SerializerProvider provider) throws IOException {
669 if (!value.isEmpty()) {
670 if (_sortKeys || provider.isEnabled(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS)) {
671 value = _orderEntries(value, gen, provider);
672 }
673 PropertyFilter pf;
674 if ((_filterId != null) && (pf = findPropertyFilter(provider, _filterId, value)) != null) {
675 serializeFilteredFields(value, gen, provider, pf, _suppressableValue);
676 } else if ((_suppressableValue != null) || _suppressNulls) {
677 serializeOptionalFields(value, gen, provider, _suppressableValue);
678 } else if (_valueSerializer != null) {
679 serializeFieldsUsing(value, gen, provider, _valueSerializer);
680 } else {
681 serializeFields(value, gen, provider);
682 }
683 }
684 }
685
686
691 public void serializeFields(Map<?,?> value, JsonGenerator gen, SerializerProvider provider)
692 throws IOException
693 {
694
695 if (_valueTypeSerializer != null) {
696 serializeTypedFields(value, gen, provider, null);
697 return;
698 }
699 final JsonSerializer<Object> keySerializer = _keySerializer;
700 final Set<String> ignored = _ignoredEntries;
701 Object keyElem = null;
702
703 try {
704 for (Map.Entry<?,?> entry : value.entrySet()) {
705 Object valueElem = entry.getValue();
706
707 keyElem = entry.getKey();
708 if (keyElem == null) {
709 provider.findNullKeySerializer(_keyType, _property).serialize(null, gen, provider);
710 } else {
711
712 if ((ignored != null) && ignored.contains(keyElem)) {
713 continue;
714 }
715 keySerializer.serialize(keyElem, gen, provider);
716 }
717
718 if (valueElem == null) {
719 provider.defaultSerializeNull(gen);
720 continue;
721 }
722 JsonSerializer<Object> serializer = _valueSerializer;
723 if (serializer == null) {
724 serializer = _findSerializer(provider, valueElem);
725 }
726 serializer.serialize(valueElem, gen, provider);
727 }
728 } catch (Exception e) {
729 wrapAndThrow(provider, e, value, String.valueOf(keyElem));
730 }
731 }
732
733
736 public void serializeOptionalFields(Map<?,?> value, JsonGenerator gen, SerializerProvider provider,
737 Object suppressableValue)
738 throws IOException
739 {
740
741 if (_valueTypeSerializer != null) {
742 serializeTypedFields(value, gen, provider, suppressableValue);
743 return;
744 }
745 final Set<String> ignored = _ignoredEntries;
746 final boolean checkEmpty = (MARKER_FOR_EMPTY == suppressableValue);
747
748 for (Map.Entry<?,?> entry : value.entrySet()) {
749
750 final Object keyElem = entry.getKey();
751 JsonSerializer<Object> keySerializer;
752 if (keyElem == null) {
753 keySerializer = provider.findNullKeySerializer(_keyType, _property);
754 } else {
755 if (ignored != null && ignored.contains(keyElem)) continue;
756 keySerializer = _keySerializer;
757 }
758
759
760 final Object valueElem = entry.getValue();
761 JsonSerializer<Object> valueSer;
762 if (valueElem == null) {
763 if (_suppressNulls) {
764 continue;
765 }
766 valueSer = provider.getDefaultNullValueSerializer();
767 } else {
768 valueSer = _valueSerializer;
769 if (valueSer == null) {
770 valueSer = _findSerializer(provider, valueElem);
771 }
772
773 if (checkEmpty) {
774 if (valueSer.isEmpty(provider, valueElem)) {
775 continue;
776 }
777 } else if (suppressableValue != null) {
778 if (suppressableValue.equals(valueElem)) {
779 continue;
780 }
781 }
782 }
783
784 try {
785 keySerializer.serialize(keyElem, gen, provider);
786 valueSer.serialize(valueElem, gen, provider);
787 } catch (Exception e) {
788 wrapAndThrow(provider, e, value, String.valueOf(keyElem));
789 }
790 }
791 }
792
793
798 public void serializeFieldsUsing(Map<?,?> value, JsonGenerator gen, SerializerProvider provider,
799 JsonSerializer<Object> ser)
800 throws IOException
801 {
802 final JsonSerializer<Object> keySerializer = _keySerializer;
803 final Set<String> ignored = _ignoredEntries;
804 final TypeSerializer typeSer = _valueTypeSerializer;
805
806 for (Map.Entry<?,?> entry : value.entrySet()) {
807 Object keyElem = entry.getKey();
808 if (ignored != null && ignored.contains(keyElem)) continue;
809
810 if (keyElem == null) {
811 provider.findNullKeySerializer(_keyType, _property).serialize(null, gen, provider);
812 } else {
813 keySerializer.serialize(keyElem, gen, provider);
814 }
815 final Object valueElem = entry.getValue();
816 if (valueElem == null) {
817 provider.defaultSerializeNull(gen);
818 } else {
819 try {
820 if (typeSer == null) {
821 ser.serialize(valueElem, gen, provider);
822 } else {
823 ser.serializeWithType(valueElem, gen, provider, typeSer);
824 }
825 } catch (Exception e) {
826 wrapAndThrow(provider, e, value, String.valueOf(keyElem));
827 }
828 }
829 }
830 }
831
832
838 public void serializeFilteredFields(Map<?,?> value, JsonGenerator gen, SerializerProvider provider,
839 PropertyFilter filter,
840 Object suppressableValue)
841 throws IOException
842 {
843 final Set<String> ignored = _ignoredEntries;
844 final MapProperty prop = new MapProperty(_valueTypeSerializer, _property);
845 final boolean checkEmpty = (MARKER_FOR_EMPTY == suppressableValue);
846
847 for (Map.Entry<?,?> entry : value.entrySet()) {
848
849 final Object keyElem = entry.getKey();
850 if (ignored != null && ignored.contains(keyElem)) continue;
851
852 JsonSerializer<Object> keySerializer;
853 if (keyElem == null) {
854 keySerializer = provider.findNullKeySerializer(_keyType, _property);
855 } else {
856 keySerializer = _keySerializer;
857 }
858
859 final Object valueElem = entry.getValue();
860
861 JsonSerializer<Object> valueSer;
862
863 if (valueElem == null) {
864 if (_suppressNulls) {
865 continue;
866 }
867 valueSer = provider.getDefaultNullValueSerializer();
868 } else {
869 valueSer = _valueSerializer;
870 if (valueSer == null) {
871 valueSer = _findSerializer(provider, valueElem);
872 }
873
874 if (checkEmpty) {
875 if (valueSer.isEmpty(provider, valueElem)) {
876 continue;
877 }
878 } else if (suppressableValue != null) {
879 if (suppressableValue.equals(valueElem)) {
880 continue;
881 }
882 }
883 }
884
885 prop.reset(keyElem, valueElem, keySerializer, valueSer);
886 try {
887 filter.serializeAsField(value, gen, provider, prop);
888 } catch (Exception e) {
889 wrapAndThrow(provider, e, value, String.valueOf(keyElem));
890 }
891 }
892 }
893
894
897 public void serializeTypedFields(Map<?,?> value, JsonGenerator gen, SerializerProvider provider,
898 Object suppressableValue)
899 throws IOException
900 {
901 final Set<String> ignored = _ignoredEntries;
902 final boolean checkEmpty = (MARKER_FOR_EMPTY == suppressableValue);
903
904 for (Map.Entry<?,?> entry : value.entrySet()) {
905 Object keyElem = entry.getKey();
906 JsonSerializer<Object> keySerializer;
907 if (keyElem == null) {
908 keySerializer = provider.findNullKeySerializer(_keyType, _property);
909 } else {
910
911 if (ignored != null && ignored.contains(keyElem)) continue;
912 keySerializer = _keySerializer;
913 }
914 final Object valueElem = entry.getValue();
915
916
917 JsonSerializer<Object> valueSer;
918 if (valueElem == null) {
919 if (_suppressNulls) {
920 continue;
921 }
922 valueSer = provider.getDefaultNullValueSerializer();
923 } else {
924 valueSer = _valueSerializer;
925 if (valueSer == null) {
926 valueSer = _findSerializer(provider, valueElem);
927 }
928
929 if (checkEmpty) {
930 if (valueSer.isEmpty(provider, valueElem)) {
931 continue;
932 }
933 } else if (suppressableValue != null) {
934 if (suppressableValue.equals(valueElem)) {
935 continue;
936 }
937 }
938 }
939 keySerializer.serialize(keyElem, gen, provider);
940 try {
941 valueSer.serializeWithType(valueElem, gen, provider, _valueTypeSerializer);
942 } catch (Exception e) {
943 wrapAndThrow(provider, e, value, String.valueOf(keyElem));
944 }
945 }
946 }
947
948
956 public void serializeFilteredAnyProperties(SerializerProvider provider, JsonGenerator gen,
957 Object bean, Map<?,?> value, PropertyFilter filter,
958 Object suppressableValue)
959 throws IOException
960 {
961 final Set<String> ignored = _ignoredEntries;
962 final MapProperty prop = new MapProperty(_valueTypeSerializer, _property);
963 final boolean checkEmpty = (MARKER_FOR_EMPTY == suppressableValue);
964
965 for (Map.Entry<?,?> entry : value.entrySet()) {
966
967 final Object keyElem = entry.getKey();
968 if (ignored != null && ignored.contains(keyElem)) continue;
969
970 JsonSerializer<Object> keySerializer;
971 if (keyElem == null) {
972 keySerializer = provider.findNullKeySerializer(_keyType, _property);
973 } else {
974 keySerializer = _keySerializer;
975 }
976
977 final Object valueElem = entry.getValue();
978
979 JsonSerializer<Object> valueSer;
980
981 if (valueElem == null) {
982 if (_suppressNulls) {
983 continue;
984 }
985 valueSer = provider.getDefaultNullValueSerializer();
986 } else {
987 valueSer = _valueSerializer;
988 if (valueSer == null) {
989 valueSer = _findSerializer(provider, valueElem);
990 }
991
992 if (checkEmpty) {
993 if (valueSer.isEmpty(provider, valueElem)) {
994 continue;
995 }
996 } else if (suppressableValue != null) {
997 if (suppressableValue.equals(valueElem)) {
998 continue;
999 }
1000 }
1001 }
1002
1003 prop.reset(keyElem, valueElem, keySerializer, valueSer);
1004 try {
1005 filter.serializeAsField(bean, gen, provider, prop);
1006 } catch (Exception e) {
1007 wrapAndThrow(provider, e, value, String.valueOf(keyElem));
1008 }
1009 }
1010 }
1011
1012
1017
1018 @Override
1019 public JsonNode getSchema(SerializerProvider provider, Type typeHint)
1020 {
1021
1022
1023 return createSchemaNode("object", true);
1024 }
1025
1026 @Override
1027 public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
1028 throws JsonMappingException
1029 {
1030 JsonMapFormatVisitor v2 = visitor.expectMapFormat(typeHint);
1031 if (v2 != null) {
1032 v2.keyFormat(_keySerializer, _keyType);
1033 JsonSerializer<?> valueSer = _valueSerializer;
1034 if (valueSer == null) {
1035 valueSer = _findAndAddDynamic(_dynamicValueSerializers,
1036 _valueType, visitor.getProvider());
1037 }
1038 v2.valueFormat(valueSer, _valueType);
1039 }
1040 }
1041
1042
1047
1048 protected final JsonSerializer<Object> _findAndAddDynamic(PropertySerializerMap map,
1049 Class<?> type, SerializerProvider provider) throws JsonMappingException
1050 {
1051 PropertySerializerMap.SerializerAndMapResult result = map.findAndAddSecondarySerializer(type, provider, _property);
1052
1053 if (map != result.map) {
1054 _dynamicValueSerializers = result.map;
1055 }
1056 return result.serializer;
1057 }
1058
1059 protected final JsonSerializer<Object> _findAndAddDynamic(PropertySerializerMap map,
1060 JavaType type, SerializerProvider provider) throws JsonMappingException
1061 {
1062 PropertySerializerMap.SerializerAndMapResult result = map.findAndAddSecondarySerializer(type, provider, _property);
1063 if (map != result.map) {
1064 _dynamicValueSerializers = result.map;
1065 }
1066 return result.serializer;
1067 }
1068
1069 protected Map<?,?> _orderEntries(Map<?,?> input, JsonGenerator gen,
1070 SerializerProvider provider) throws IOException
1071 {
1072
1073 if (input instanceof SortedMap<?,?>) {
1074 return input;
1075 }
1076
1077
1078
1079
1080 if (_hasNullKey(input)) {
1081 TreeMap<Object,Object> result = new TreeMap<Object,Object>();
1082 for (Map.Entry<?,?> entry : input.entrySet()) {
1083 Object key = entry.getKey();
1084 if (key == null) {
1085 _writeNullKeyedEntry(gen, provider, entry.getValue());
1086 continue;
1087 }
1088 result.put(key, entry.getValue());
1089 }
1090 return result;
1091 }
1092 return new TreeMap<Object,Object>(input);
1093 }
1094
1095
1098 protected boolean _hasNullKey(Map<?,?> input) {
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108 return (input instanceof HashMap) && input.containsKey(null);
1109 }
1110
1111 protected void _writeNullKeyedEntry(JsonGenerator gen, SerializerProvider provider,
1112 Object value) throws IOException
1113 {
1114 JsonSerializer<Object> keySerializer = provider.findNullKeySerializer(_keyType, _property);
1115 JsonSerializer<Object> valueSer;
1116 if (value == null) {
1117 if (_suppressNulls) {
1118 return;
1119 }
1120 valueSer = provider.getDefaultNullValueSerializer();
1121 } else {
1122 valueSer = _valueSerializer;
1123 if (valueSer == null) {
1124 valueSer = _findSerializer(provider, value);
1125 }
1126 if (_suppressableValue == MARKER_FOR_EMPTY) {
1127 if (valueSer.isEmpty(provider, value)) {
1128 return;
1129 }
1130 } else if ((_suppressableValue != null)
1131 && (_suppressableValue.equals(value))) {
1132 return;
1133 }
1134 }
1135
1136 try {
1137 keySerializer.serialize(null, gen, provider);
1138 valueSer.serialize(value, gen, provider);
1139 } catch (Exception e) {
1140 wrapAndThrow(provider, e, value, "");
1141 }
1142 }
1143
1144 private final JsonSerializer<Object> _findSerializer(SerializerProvider provider,
1145 Object value) throws JsonMappingException
1146 {
1147 final Class<?> cc = value.getClass();
1148 JsonSerializer<Object> valueSer = _dynamicValueSerializers.serializerFor(cc);
1149 if (valueSer != null) {
1150 return valueSer;
1151 }
1152 if (_valueType.hasGenericTypes()) {
1153 return _findAndAddDynamic(_dynamicValueSerializers,
1154 provider.constructSpecializedType(_valueType, cc), provider);
1155 }
1156 return _findAndAddDynamic(_dynamicValueSerializers, cc, provider);
1157 }
1158 }
1159