1 package com.fasterxml.jackson.databind.ser;
2
3 import java.math.BigDecimal;
4 import java.math.BigInteger;
5 import java.net.InetAddress;
6 import java.net.InetSocketAddress;
7 import java.nio.ByteBuffer;
8 import java.util.*;
9 import java.util.concurrent.atomic.AtomicReference;
10
11 import com.fasterxml.jackson.annotation.JsonFormat;
12 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
13 import com.fasterxml.jackson.annotation.JsonInclude;
14 import com.fasterxml.jackson.databind.*;
15 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
16 import com.fasterxml.jackson.databind.cfg.SerializerFactoryConfig;
17 import com.fasterxml.jackson.databind.ext.OptionalHandlerFactory;
18 import com.fasterxml.jackson.databind.introspect.*;
19 import com.fasterxml.jackson.databind.jsontype.NamedType;
20 import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder;
21 import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
22 import com.fasterxml.jackson.databind.ser.impl.*;
23 import com.fasterxml.jackson.databind.ser.std.*;
24 import com.fasterxml.jackson.databind.type.*;
25 import com.fasterxml.jackson.databind.util.*;
26
27
36 @SuppressWarnings("serial")
37 public abstract class BasicSerializerFactory
38 extends SerializerFactory
39 implements java.io.Serializable
40 {
41
46
47
52 protected final static HashMap<String, JsonSerializer<?>> _concrete;
53
54
59 protected final static HashMap<String, Class<? extends JsonSerializer<?>>> _concreteLazy;
60
61 static {
62 HashMap<String, Class<? extends JsonSerializer<?>>> concLazy
63 = new HashMap<String, Class<? extends JsonSerializer<?>>>();
64 HashMap<String, JsonSerializer<?>> concrete
65 = new HashMap<String, JsonSerializer<?>>();
66
67
68
71 concrete.put(String.class.getName(), new StringSerializer());
72 final ToStringSerializer sls = ToStringSerializer.instance;
73 concrete.put(StringBuffer.class.getName(), sls);
74 concrete.put(StringBuilder.class.getName(), sls);
75 concrete.put(Character.class.getName(), sls);
76 concrete.put(Character.TYPE.getName(), sls);
77
78
79 NumberSerializers.addAll(concrete);
80 concrete.put(Boolean.TYPE.getName(), new BooleanSerializer(true));
81 concrete.put(Boolean.class.getName(), new BooleanSerializer(false));
82
83
84 concrete.put(BigInteger.class.getName(), new NumberSerializer(BigInteger.class));
85 concrete.put(BigDecimal.class.getName(),new NumberSerializer(BigDecimal.class));
86
87
88
89 concrete.put(Calendar.class.getName(), CalendarSerializer.instance);
90 concrete.put(java.util.Date.class.getName(), DateSerializer.instance);
91
92
93 for (Map.Entry<Class<?>,Object> en : StdJdkSerializers.all()) {
94 Object value = en.getValue();
95 if (value instanceof JsonSerializer<?>) {
96 concrete.put(en.getKey().getName(), (JsonSerializer<?>) value);
97 } else {
98 @SuppressWarnings("unchecked")
99 Class<? extends JsonSerializer<?>> cls = (Class<? extends JsonSerializer<?>>) value;
100 concLazy.put(en.getKey().getName(), cls);
101 }
102 }
103
104
105
106 concLazy.put(TokenBuffer.class.getName(), TokenBufferSerializer.class);
107
108 _concrete = concrete;
109 _concreteLazy = concLazy;
110 }
111
112
117
118
122 protected final SerializerFactoryConfig _factoryConfig;
123
124
129
130
135 protected BasicSerializerFactory(SerializerFactoryConfig config) {
136 _factoryConfig = (config == null) ? new SerializerFactoryConfig() : config;
137 }
138
139
146 public SerializerFactoryConfig getFactoryConfig() {
147 return _factoryConfig;
148 }
149
150
160 public abstract SerializerFactory withConfig(SerializerFactoryConfig config);
161
162
166 @Override
167 public final SerializerFactory withAdditionalSerializers(Serializers additional) {
168 return withConfig(_factoryConfig.withAdditionalSerializers(additional));
169 }
170
171
175 @Override
176 public final SerializerFactory withAdditionalKeySerializers(Serializers additional) {
177 return withConfig(_factoryConfig.withAdditionalKeySerializers(additional));
178 }
179
180
184 @Override
185 public final SerializerFactory withSerializerModifier(BeanSerializerModifier modifier) {
186 return withConfig(_factoryConfig.withSerializerModifier(modifier));
187 }
188
189
194
195
196 @Override
197 public abstract JsonSerializer<Object> createSerializer(SerializerProvider prov,
198 JavaType type)
199 throws JsonMappingException;
200
201 @Override
202 @SuppressWarnings("unchecked")
203 public JsonSerializer<Object> createKeySerializer(SerializerProvider ctxt,
204 JavaType keyType, JsonSerializer<Object> defaultImpl) throws JsonMappingException
205 {
206
207
208 final SerializationConfig config = ctxt.getConfig();
209 BeanDescription beanDesc = config.introspect(keyType);
210 JsonSerializer<?> ser = null;
211
212 if (_factoryConfig.hasKeySerializers()) {
213
214 for (Serializers serializers : _factoryConfig.keySerializers()) {
215 ser = serializers.findSerializer(config, keyType, beanDesc);
216 if (ser != null) {
217 break;
218 }
219 }
220 }
221 if (ser == null) {
222
223 ser = _findKeySerializer(ctxt, beanDesc.getClassInfo());
224 if (ser == null) {
225 ser = defaultImpl;
226 if (ser == null) {
227 ser = StdKeySerializers.getStdKeySerializer(config, keyType.getRawClass(), false);
228
229 if (ser == null) {
230 AnnotatedMember am = beanDesc.findJsonValueAccessor();
231 if (am != null) {
232 final Class<?> rawType = am.getRawType();
233 JsonSerializer<?> delegate = StdKeySerializers.getStdKeySerializer(config,
234 rawType, true);
235 if (config.canOverrideAccessModifiers()) {
236 ClassUtil.checkAndFixAccess(am.getMember(),
237 config.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS));
238 }
239 ser = new JsonValueSerializer(am, delegate);
240 } else {
241 ser = StdKeySerializers.getFallbackKeySerializer(config, keyType.getRawClass());
242 }
243 }
244 }
245 }
246 }
247
248
249 if (_factoryConfig.hasSerializerModifiers()) {
250 for (BeanSerializerModifier mod : _factoryConfig.serializerModifiers()) {
251 ser = mod.modifyKeySerializer(config, keyType, beanDesc, ser);
252 }
253 }
254 return (JsonSerializer<Object>) ser;
255 }
256
257
258 @Override
259 @SuppressWarnings("unchecked")
260 @Deprecated
261 public JsonSerializer<Object> createKeySerializer(SerializationConfig config,
262 JavaType keyType, JsonSerializer<Object> defaultImpl)
263 {
264 BeanDescription beanDesc = config.introspect(keyType);
265 JsonSerializer<?> ser = null;
266 if (_factoryConfig.hasKeySerializers()) {
267 for (Serializers serializers : _factoryConfig.keySerializers()) {
268 ser = serializers.findSerializer(config, keyType, beanDesc);
269 if (ser != null) {
270 break;
271 }
272 }
273 }
274 if (ser == null) {
275 ser = defaultImpl;
276 if (ser == null) {
277 ser = StdKeySerializers.getStdKeySerializer(config, keyType.getRawClass(), false);
278 if (ser == null) {
279 AnnotatedMember am = beanDesc.findJsonValueAccessor();
280 if (am != null) {
281 final Class<?> rawType = am.getRawType();
282 JsonSerializer<?> delegate = StdKeySerializers.getStdKeySerializer(config,
283 rawType, true);
284 if (config.canOverrideAccessModifiers()) {
285 ClassUtil.checkAndFixAccess(am.getMember(),
286 config.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS));
287 }
288 ser = new JsonValueSerializer(am, delegate);
289 } else {
290 ser = StdKeySerializers.getFallbackKeySerializer(config, keyType.getRawClass());
291 }
292 }
293 }
294 }
295 if (_factoryConfig.hasSerializerModifiers()) {
296 for (BeanSerializerModifier mod : _factoryConfig.serializerModifiers()) {
297 ser = mod.modifyKeySerializer(config, keyType, beanDesc, ser);
298 }
299 }
300 return (JsonSerializer<Object>) ser;
301 }
302
303
308 @Override
309 public TypeSerializer createTypeSerializer(SerializationConfig config,
310 JavaType baseType)
311 {
312 BeanDescription bean = config.introspectClassAnnotations(baseType.getRawClass());
313 AnnotatedClass ac = bean.getClassInfo();
314 AnnotationIntrospector ai = config.getAnnotationIntrospector();
315 TypeResolverBuilder<?> b = ai.findTypeResolver(config, ac, baseType);
316
319 Collection<NamedType> subtypes = null;
320 if (b == null) {
321 b = config.getDefaultTyper(baseType);
322 } else {
323 subtypes = config.getSubtypeResolver().collectAndResolveSubtypesByClass(config, ac);
324 }
325 if (b == null) {
326 return null;
327 }
328
329
330 return b.buildTypeSerializer(config, baseType, subtypes);
331 }
332
333
338
339 protected abstract Iterable<Serializers> customSerializers();
340
341
346
347
351 protected final JsonSerializer<?> findSerializerByLookup(JavaType type,
352 SerializationConfig config, BeanDescription beanDesc,
353 boolean staticTyping)
354 {
355 Class<?> raw = type.getRawClass();
356 String clsName = raw.getName();
357 JsonSerializer<?> ser = _concrete.get(clsName);
358 if (ser == null) {
359 Class<? extends JsonSerializer<?>> serClass = _concreteLazy.get(clsName);
360 if (serClass != null) {
361
362
363
364 return ClassUtil.createInstance(serClass, false);
365 }
366 }
367 return ser;
368 }
369
370
386 protected final JsonSerializer<?> findSerializerByAnnotations(SerializerProvider prov,
387 JavaType type, BeanDescription beanDesc)
388 throws JsonMappingException
389 {
390 Class<?> raw = type.getRawClass();
391
392 if (JsonSerializable.class.isAssignableFrom(raw)) {
393 return SerializableSerializer.instance;
394 }
395
396 AnnotatedMember valueAccessor = beanDesc.findJsonValueAccessor();
397 if (valueAccessor != null) {
398 if (prov.canOverrideAccessModifiers()) {
399 ClassUtil.checkAndFixAccess(valueAccessor.getMember(),
400 prov.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS));
401 }
402 JsonSerializer<Object> ser = findSerializerFromAnnotation(prov, valueAccessor);
403 return new JsonValueSerializer(valueAccessor, ser);
404 }
405
406 return null;
407 }
408
409
416 protected final JsonSerializer<?> findSerializerByPrimaryType(SerializerProvider prov,
417 JavaType type, BeanDescription beanDesc,
418 boolean staticTyping)
419 throws JsonMappingException
420 {
421 if (type.isEnumType()) {
422 return buildEnumSerializer(prov.getConfig(), type, beanDesc);
423 }
424
425 final Class<?> raw = type.getRawClass();
426
427 JsonSerializer<?> ser = findOptionalStdSerializer(prov, type, beanDesc, staticTyping);
428 if (ser != null) {
429 return ser;
430 }
431
432 if (Calendar.class.isAssignableFrom(raw)) {
433 return CalendarSerializer.instance;
434 }
435 if (java.util.Date.class.isAssignableFrom(raw)) {
436 return DateSerializer.instance;
437 }
438 if (Map.Entry.class.isAssignableFrom(raw)) {
439
440 JavaType mapEntryType = type.findSuperType(Map.Entry.class);
441
442
443 JavaType kt = mapEntryType.containedTypeOrUnknown(0);
444 JavaType vt = mapEntryType.containedTypeOrUnknown(1);
445 return buildMapEntrySerializer(prov, type, beanDesc, staticTyping, kt, vt);
446 }
447 if (ByteBuffer.class.isAssignableFrom(raw)) {
448 return new ByteBufferSerializer();
449 }
450 if (InetAddress.class.isAssignableFrom(raw)) {
451 return new InetAddressSerializer();
452 }
453 if (InetSocketAddress.class.isAssignableFrom(raw)) {
454 return new InetSocketAddressSerializer();
455 }
456 if (TimeZone.class.isAssignableFrom(raw)) {
457 return new TimeZoneSerializer();
458 }
459 if (java.nio.charset.Charset.class.isAssignableFrom(raw)) {
460 return ToStringSerializer.instance;
461 }
462 if (Number.class.isAssignableFrom(raw)) {
463
464 JsonFormat.Value format = beanDesc.findExpectedFormat(null);
465 if (format != null) {
466 switch (format.getShape()) {
467 case STRING:
468 return ToStringSerializer.instance;
469 case OBJECT:
470 case ARRAY:
471 return null;
472 default:
473 }
474 }
475 return NumberSerializer.instance;
476 }
477 return null;
478 }
479
480
485 protected JsonSerializer<?> findOptionalStdSerializer(SerializerProvider prov,
486 JavaType type, BeanDescription beanDesc, boolean staticTyping)
487 throws JsonMappingException
488 {
489 return OptionalHandlerFactory.instance.findSerializer(prov.getConfig(), type, beanDesc);
490 }
491
492
500 protected final JsonSerializer<?> findSerializerByAddonType(SerializationConfig config,
501 JavaType javaType, BeanDescription beanDesc, boolean staticTyping) throws JsonMappingException
502 {
503 Class<?> rawType = javaType.getRawClass();
504
505 if (Iterator.class.isAssignableFrom(rawType)) {
506 JavaType[] params = config.getTypeFactory().findTypeParameters(javaType, Iterator.class);
507 JavaType vt = (params == null || params.length != 1) ?
508 TypeFactory.unknownType() : params[0];
509 return buildIteratorSerializer(config, javaType, beanDesc, staticTyping, vt);
510 }
511 if (Iterable.class.isAssignableFrom(rawType)) {
512 JavaType[] params = config.getTypeFactory().findTypeParameters(javaType, Iterable.class);
513 JavaType vt = (params == null || params.length != 1) ?
514 TypeFactory.unknownType() : params[0];
515 return buildIterableSerializer(config, javaType, beanDesc, staticTyping, vt);
516 }
517 if (CharSequence.class.isAssignableFrom(rawType)) {
518 return ToStringSerializer.instance;
519 }
520 return null;
521 }
522
523
530 @SuppressWarnings("unchecked")
531 protected JsonSerializer<Object> findSerializerFromAnnotation(SerializerProvider prov,
532 Annotated a)
533 throws JsonMappingException
534 {
535 Object serDef = prov.getAnnotationIntrospector().findSerializer(a);
536 if (serDef == null) {
537 return null;
538 }
539 JsonSerializer<Object> ser = prov.serializerInstance(a, serDef);
540
541 return (JsonSerializer<Object>) findConvertingSerializer(prov, a, ser);
542 }
543
544
550 protected JsonSerializer<?> findConvertingSerializer(SerializerProvider prov,
551 Annotated a, JsonSerializer<?> ser)
552 throws JsonMappingException
553 {
554 Converter<Object,Object> conv = findConverter(prov, a);
555 if (conv == null) {
556 return ser;
557 }
558 JavaType delegateType = conv.getOutputType(prov.getTypeFactory());
559 return new StdDelegatingSerializer(conv, delegateType, ser);
560 }
561
562 protected Converter<Object,Object> findConverter(SerializerProvider prov,
563 Annotated a)
564 throws JsonMappingException
565 {
566 Object convDef = prov.getAnnotationIntrospector().findSerializationConverter(a);
567 if (convDef == null) {
568 return null;
569 }
570 return prov.converterInstance(a, convDef);
571 }
572
573
578
579
582 protected JsonSerializer<?> buildContainerSerializer(SerializerProvider prov,
583 JavaType type, BeanDescription beanDesc, boolean staticTyping)
584 throws JsonMappingException
585 {
586 final SerializationConfig config = prov.getConfig();
587
588
592 if (!staticTyping && type.useStaticType()) {
593 if (!type.isContainerType() || !type.getContentType().isJavaLangObject()) {
594 staticTyping = true;
595 }
596 }
597
598
599 JavaType elementType = type.getContentType();
600 TypeSerializer elementTypeSerializer = createTypeSerializer(config,
601 elementType);
602
603
604 if (elementTypeSerializer != null) {
605 staticTyping = false;
606 }
607 JsonSerializer<Object> elementValueSerializer = _findContentSerializer(prov,
608 beanDesc.getClassInfo());
609 if (type.isMapLikeType()) {
610 MapLikeType mlt = (MapLikeType) type;
611
616 JsonSerializer<Object> keySerializer = _findKeySerializer(prov, beanDesc.getClassInfo());
617 if (mlt instanceof MapType) {
618 return buildMapSerializer(prov, (MapType) mlt, beanDesc, staticTyping,
619 keySerializer, elementTypeSerializer, elementValueSerializer);
620 }
621
622 JsonSerializer<?> ser = null;
623 MapLikeType mlType = (MapLikeType) type;
624 for (Serializers serializers : customSerializers()) {
625 ser = serializers.findMapLikeSerializer(config,
626 mlType, beanDesc, keySerializer, elementTypeSerializer, elementValueSerializer);
627 if (ser != null) {
628 break;
629 }
630 }
631 if (ser == null) {
632 ser = findSerializerByAnnotations(prov, type, beanDesc);
633 }
634 if (ser != null) {
635 if (_factoryConfig.hasSerializerModifiers()) {
636 for (BeanSerializerModifier mod : _factoryConfig.serializerModifiers()) {
637 ser = mod.modifyMapLikeSerializer(config, mlType, beanDesc, ser);
638 }
639 }
640 }
641 return ser;
642 }
643 if (type.isCollectionLikeType()) {
644 CollectionLikeType clt = (CollectionLikeType) type;
645 if (clt instanceof CollectionType) {
646 return buildCollectionSerializer(prov, (CollectionType) clt, beanDesc, staticTyping,
647 elementTypeSerializer, elementValueSerializer);
648 }
649
650 JsonSerializer<?> ser = null;
651 CollectionLikeType clType = (CollectionLikeType) type;
652 for (Serializers serializers : customSerializers()) {
653 ser = serializers.findCollectionLikeSerializer(config,
654 clType, beanDesc, elementTypeSerializer, elementValueSerializer);
655 if (ser != null) {
656 break;
657 }
658 }
659 if (ser == null) {
660 ser = findSerializerByAnnotations(prov, type, beanDesc);
661 }
662 if (ser != null) {
663 if (_factoryConfig.hasSerializerModifiers()) {
664 for (BeanSerializerModifier mod : _factoryConfig.serializerModifiers()) {
665 ser = mod.modifyCollectionLikeSerializer(config, clType, beanDesc, ser);
666 }
667 }
668 }
669 return ser;
670 }
671 if (type.isArrayType()) {
672 return buildArraySerializer(prov, (ArrayType) type, beanDesc, staticTyping,
673 elementTypeSerializer, elementValueSerializer);
674 }
675 return null;
676 }
677
678
684 protected JsonSerializer<?> buildCollectionSerializer(SerializerProvider prov,
685 CollectionType type, BeanDescription beanDesc, boolean staticTyping,
686 TypeSerializer elementTypeSerializer, JsonSerializer<Object> elementValueSerializer)
687 throws JsonMappingException
688 {
689 SerializationConfig config = prov.getConfig();
690 JsonSerializer<?> ser = null;
691
692
693
694
695 for (Serializers serializers : customSerializers()) {
696 ser = serializers.findCollectionSerializer(config,
697 type, beanDesc, elementTypeSerializer, elementValueSerializer);
698 if (ser != null) {
699 break;
700 }
701 }
702
703 if (ser == null) {
704 ser = findSerializerByAnnotations(prov, type, beanDesc);
705 if (ser == null) {
706
707
708 JsonFormat.Value format = beanDesc.findExpectedFormat(null);
709 if ((format != null) && format.getShape() == JsonFormat.Shape.OBJECT) {
710 return null;
711 }
712 Class<?> raw = type.getRawClass();
713 if (EnumSet.class.isAssignableFrom(raw)) {
714
715 JavaType enumType = type.getContentType();
716
717 if (!enumType.isEnumImplType()) {
718 enumType = null;
719 }
720 ser = buildEnumSetSerializer(enumType);
721 } else {
722 Class<?> elementRaw = type.getContentType().getRawClass();
723 if (isIndexedList(raw)) {
724 if (elementRaw == String.class) {
725
726 if (ClassUtil.isJacksonStdImpl(elementValueSerializer)) {
727 ser = IndexedStringListSerializer.instance;
728 }
729 } else {
730 ser = buildIndexedListSerializer(type.getContentType(), staticTyping,
731 elementTypeSerializer, elementValueSerializer);
732 }
733 } else if (elementRaw == String.class) {
734
735 if (ClassUtil.isJacksonStdImpl(elementValueSerializer)) {
736 ser = StringCollectionSerializer.instance;
737 }
738 }
739 if (ser == null) {
740 ser = buildCollectionSerializer(type.getContentType(), staticTyping,
741 elementTypeSerializer, elementValueSerializer);
742 }
743 }
744 }
745 }
746
747 if (_factoryConfig.hasSerializerModifiers()) {
748 for (BeanSerializerModifier mod : _factoryConfig.serializerModifiers()) {
749 ser = mod.modifyCollectionSerializer(config, type, beanDesc, ser);
750 }
751 }
752 return ser;
753 }
754
755
760
761 protected boolean isIndexedList(Class<?> cls)
762 {
763 return RandomAccess.class.isAssignableFrom(cls);
764 }
765
766 public ContainerSerializer<?> buildIndexedListSerializer(JavaType elemType,
767 boolean staticTyping, TypeSerializer vts, JsonSerializer<Object> valueSerializer) {
768 return new IndexedListSerializer(elemType, staticTyping, vts, valueSerializer);
769 }
770
771 public ContainerSerializer<?> buildCollectionSerializer(JavaType elemType,
772 boolean staticTyping, TypeSerializer vts, JsonSerializer<Object> valueSerializer) {
773 return new CollectionSerializer(elemType, staticTyping, vts, valueSerializer);
774 }
775
776 public JsonSerializer<?> buildEnumSetSerializer(JavaType enumType) {
777 return new EnumSetSerializer(enumType);
778 }
779
780
785
786
790 protected JsonSerializer<?> buildMapSerializer(SerializerProvider prov,
791 MapType type, BeanDescription beanDesc,
792 boolean staticTyping, JsonSerializer<Object> keySerializer,
793 TypeSerializer elementTypeSerializer, JsonSerializer<Object> elementValueSerializer)
794 throws JsonMappingException
795 {
796
797
798 JsonFormat.Value format = beanDesc.findExpectedFormat(null);
799 if ((format != null) && format.getShape() == JsonFormat.Shape.OBJECT) {
800 return null;
801 }
802
803 JsonSerializer<?> ser = null;
804
805
806
807
808
809
810 final SerializationConfig config = prov.getConfig();
811 for (Serializers serializers : customSerializers()) {
812 ser = serializers.findMapSerializer(config, type, beanDesc,
813 keySerializer, elementTypeSerializer, elementValueSerializer);
814 if (ser != null) { break; }
815 }
816 if (ser == null) {
817 ser = findSerializerByAnnotations(prov, type, beanDesc);
818 if (ser == null) {
819 Object filterId = findFilterId(config, beanDesc);
820
821
822
823
824 JsonIgnoreProperties.Value ignorals = config.getDefaultPropertyIgnorals(Map.class,
825 beanDesc.getClassInfo());
826 Set<String> ignored = (ignorals == null) ? null
827 : ignorals.findIgnoredForSerialization();
828 MapSerializer mapSer = MapSerializer.construct(ignored,
829 type, staticTyping, elementTypeSerializer,
830 keySerializer, elementValueSerializer, filterId);
831 ser = _checkMapContentInclusion(prov, beanDesc, mapSer);
832 }
833 }
834
835 if (_factoryConfig.hasSerializerModifiers()) {
836 for (BeanSerializerModifier mod : _factoryConfig.serializerModifiers()) {
837 ser = mod.modifyMapSerializer(config, type, beanDesc, ser);
838 }
839 }
840 return ser;
841 }
842
843
849 @SuppressWarnings("deprecation")
850 protected MapSerializer _checkMapContentInclusion(SerializerProvider prov,
851 BeanDescription beanDesc, MapSerializer mapSer)
852 throws JsonMappingException
853 {
854 final JavaType contentType = mapSer.getContentType();
855 JsonInclude.Value inclV = _findInclusionWithContent(prov, beanDesc,
856 contentType, Map.class);
857
858
859 JsonInclude.Include incl = (inclV == null) ? JsonInclude.Include.USE_DEFAULTS : inclV.getContentInclusion();
860 if (incl == JsonInclude.Include.USE_DEFAULTS
861 || incl == JsonInclude.Include.ALWAYS) {
862 if (!prov.isEnabled(SerializationFeature.WRITE_NULL_MAP_VALUES)) {
863 return mapSer.withContentInclusion(null, true);
864 }
865 return mapSer;
866 }
867
868
869
870 Object valueToSuppress;
871 boolean suppressNulls = true;
872
873 switch (incl) {
874 case NON_DEFAULT:
875 valueToSuppress = BeanUtil.getDefaultValue(contentType);
876 if (valueToSuppress != null) {
877 if (valueToSuppress.getClass().isArray()) {
878 valueToSuppress = ArrayBuilders.getArrayComparator(valueToSuppress);
879 }
880 }
881 break;
882 case NON_ABSENT:
883
884 valueToSuppress = contentType.isReferenceType()
885 ? MapSerializer.MARKER_FOR_EMPTY : null;
886 break;
887 case NON_EMPTY:
888 valueToSuppress = MapSerializer.MARKER_FOR_EMPTY;
889 break;
890 case CUSTOM:
891 valueToSuppress = prov.includeFilterInstance(null, inclV.getContentFilter());
892 if (valueToSuppress == null) {
893 suppressNulls = true;
894 } else {
895 suppressNulls = prov.includeFilterSuppressNulls(valueToSuppress);
896 }
897 break;
898 case NON_NULL:
899 default:
900 valueToSuppress = null;
901 break;
902 }
903 return mapSer.withContentInclusion(valueToSuppress, suppressNulls);
904 }
905
906
909 protected JsonSerializer<?> buildMapEntrySerializer(SerializerProvider prov,
910 JavaType type, BeanDescription beanDesc, boolean staticTyping,
911 JavaType keyType, JavaType valueType)
912 throws JsonMappingException
913 {
914
915
916 JsonFormat.Value formatOverride = prov.getDefaultPropertyFormat(Map.Entry.class);
917 JsonFormat.Value formatFromAnnotation = beanDesc.findExpectedFormat(null);
918 JsonFormat.Value format = JsonFormat.Value.merge(formatFromAnnotation, formatOverride);
919 if (format.getShape() == JsonFormat.Shape.OBJECT) {
920 return null;
921 }
922 MapEntrySerializer ser = new MapEntrySerializer(valueType, keyType, valueType,
923 staticTyping, createTypeSerializer(prov.getConfig(), valueType), null);
924
925 final JavaType contentType = ser.getContentType();
926 JsonInclude.Value inclV = _findInclusionWithContent(prov, beanDesc,
927 contentType, Map.Entry.class);
928
929
930 JsonInclude.Include incl = (inclV == null) ? JsonInclude.Include.USE_DEFAULTS : inclV.getContentInclusion();
931 if (incl == JsonInclude.Include.USE_DEFAULTS
932 || incl == JsonInclude.Include.ALWAYS) {
933 return ser;
934 }
935
936
937
938 Object valueToSuppress;
939 boolean suppressNulls = true;
940
941 switch (incl) {
942 case NON_DEFAULT:
943 valueToSuppress = BeanUtil.getDefaultValue(contentType);
944 if (valueToSuppress != null) {
945 if (valueToSuppress.getClass().isArray()) {
946 valueToSuppress = ArrayBuilders.getArrayComparator(valueToSuppress);
947 }
948 }
949 break;
950 case NON_ABSENT:
951 valueToSuppress = contentType.isReferenceType()
952 ? MapSerializer.MARKER_FOR_EMPTY : null;
953 break;
954 case NON_EMPTY:
955 valueToSuppress = MapSerializer.MARKER_FOR_EMPTY;
956 break;
957 case CUSTOM:
958 valueToSuppress = prov.includeFilterInstance(null, inclV.getContentFilter());
959 if (valueToSuppress == null) {
960 suppressNulls = true;
961 } else {
962 suppressNulls = prov.includeFilterSuppressNulls(valueToSuppress);
963 }
964 break;
965 case NON_NULL:
966 default:
967 valueToSuppress = null;
968 break;
969 }
970 return ser.withContentInclusion(valueToSuppress, suppressNulls);
971 }
972
973
981 protected JsonInclude.Value _findInclusionWithContent(SerializerProvider prov,
982 BeanDescription beanDesc,
983 JavaType contentType, Class<?> configType)
984 throws JsonMappingException
985 {
986 final SerializationConfig config = prov.getConfig();
987
988
989
990
991
992
993 JsonInclude.Value inclV = beanDesc.findPropertyInclusion(config.getDefaultPropertyInclusion());
994 inclV = config.getDefaultPropertyInclusion(configType, inclV);
995
996
997
998 JsonInclude.Value valueIncl = config.getDefaultPropertyInclusion(contentType.getRawClass(), null);
999
1000 if (valueIncl != null) {
1001 switch (valueIncl.getValueInclusion()) {
1002 case USE_DEFAULTS:
1003 break;
1004 case CUSTOM:
1005 inclV = inclV.withContentFilter(valueIncl.getContentFilter());
1006 break;
1007 default:
1008 inclV = inclV.withContentInclusion(valueIncl.getValueInclusion());
1009 }
1010 }
1011 return inclV;
1012 }
1013
1014
1019
1020
1024 protected JsonSerializer<?> buildArraySerializer(SerializerProvider prov,
1025 ArrayType type, BeanDescription beanDesc,
1026 boolean staticTyping,
1027 TypeSerializer elementTypeSerializer, JsonSerializer<Object> elementValueSerializer)
1028 throws JsonMappingException
1029 {
1030
1031
1032
1033
1034 SerializationConfig config = prov.getConfig();
1035 JsonSerializer<?> ser = null;
1036
1037 for (Serializers serializers : customSerializers()) {
1038 ser = serializers.findArraySerializer(config,
1039 type, beanDesc, elementTypeSerializer, elementValueSerializer);
1040 if (ser != null) {
1041 break;
1042 }
1043 }
1044
1045 if (ser == null) {
1046 Class<?> raw = type.getRawClass();
1047
1048 if (elementValueSerializer == null || ClassUtil.isJacksonStdImpl(elementValueSerializer)) {
1049 if (String[].class == raw) {
1050 ser = StringArraySerializer.instance;
1051 } else {
1052
1053 ser = StdArraySerializers.findStandardImpl(raw);
1054 }
1055 }
1056 if (ser == null) {
1057 ser = new ObjectArraySerializer(type.getContentType(), staticTyping, elementTypeSerializer,
1058 elementValueSerializer);
1059 }
1060 }
1061
1062 if (_factoryConfig.hasSerializerModifiers()) {
1063 for (BeanSerializerModifier mod : _factoryConfig.serializerModifiers()) {
1064 ser = mod.modifyArraySerializer(config, type, beanDesc, ser);
1065 }
1066 }
1067 return ser;
1068 }
1069
1070
1076
1077
1080 public JsonSerializer<?> findReferenceSerializer(SerializerProvider prov, ReferenceType refType,
1081 BeanDescription beanDesc, boolean staticTyping)
1082 throws JsonMappingException
1083 {
1084 JavaType contentType = refType.getContentType();
1085 TypeSerializer contentTypeSerializer = contentType.getTypeHandler();
1086 final SerializationConfig config = prov.getConfig();
1087 if (contentTypeSerializer == null) {
1088 contentTypeSerializer = createTypeSerializer(config, contentType);
1089 }
1090 JsonSerializer<Object> contentSerializer = contentType.getValueHandler();
1091 for (Serializers serializers : customSerializers()) {
1092 JsonSerializer<?> ser = serializers.findReferenceSerializer(config, refType, beanDesc,
1093 contentTypeSerializer, contentSerializer);
1094 if (ser != null) {
1095 return ser;
1096 }
1097 }
1098 if (refType.isTypeOrSubTypeOf(AtomicReference.class)) {
1099 return buildAtomicReferenceSerializer(prov, refType, beanDesc, staticTyping,
1100 contentTypeSerializer, contentSerializer);
1101 }
1102 return null;
1103 }
1104
1105 protected JsonSerializer<?> buildAtomicReferenceSerializer(SerializerProvider prov,
1106 ReferenceType refType, BeanDescription beanDesc, boolean staticTyping,
1107 TypeSerializer contentTypeSerializer, JsonSerializer<Object> contentSerializer)
1108 throws JsonMappingException
1109 {
1110 final JavaType contentType = refType.getReferencedType();
1111 JsonInclude.Value inclV = _findInclusionWithContent(prov, beanDesc,
1112 contentType, AtomicReference.class);
1113
1114
1115 JsonInclude.Include incl = (inclV == null) ? JsonInclude.Include.USE_DEFAULTS : inclV.getContentInclusion();
1116 Object valueToSuppress;
1117 boolean suppressNulls;
1118
1119 if (incl == JsonInclude.Include.USE_DEFAULTS
1120 || incl == JsonInclude.Include.ALWAYS) {
1121 valueToSuppress = null;
1122 suppressNulls = false;
1123 } else {
1124 suppressNulls = true;
1125 switch (incl) {
1126 case NON_DEFAULT:
1127 valueToSuppress = BeanUtil.getDefaultValue(contentType);
1128 if (valueToSuppress != null) {
1129 if (valueToSuppress.getClass().isArray()) {
1130 valueToSuppress = ArrayBuilders.getArrayComparator(valueToSuppress);
1131 }
1132 }
1133 break;
1134 case NON_ABSENT:
1135 valueToSuppress = contentType.isReferenceType()
1136 ? MapSerializer.MARKER_FOR_EMPTY : null;
1137 break;
1138 case NON_EMPTY:
1139 valueToSuppress = MapSerializer.MARKER_FOR_EMPTY;
1140 break;
1141 case CUSTOM:
1142 valueToSuppress = prov.includeFilterInstance(null, inclV.getContentFilter());
1143 if (valueToSuppress == null) {
1144 suppressNulls = true;
1145 } else {
1146 suppressNulls = prov.includeFilterSuppressNulls(valueToSuppress);
1147 }
1148 break;
1149 case NON_NULL:
1150 default:
1151 valueToSuppress = null;
1152 break;
1153 }
1154 }
1155 AtomicReferenceSerializer ser = new AtomicReferenceSerializer(refType, staticTyping,
1156 contentTypeSerializer, contentSerializer);
1157 return ser.withContentInclusion(valueToSuppress, suppressNulls);
1158 }
1159
1160
1165
1166
1169 protected JsonSerializer<?> buildIteratorSerializer(SerializationConfig config,
1170 JavaType type, BeanDescription beanDesc, boolean staticTyping,
1171 JavaType valueType)
1172 throws JsonMappingException
1173 {
1174 return new IteratorSerializer(valueType, staticTyping, createTypeSerializer(config, valueType));
1175 }
1176
1177
1180 protected JsonSerializer<?> buildIterableSerializer(SerializationConfig config,
1181 JavaType type, BeanDescription beanDesc, boolean staticTyping,
1182 JavaType valueType)
1183 throws JsonMappingException
1184 {
1185 return new IterableSerializer(valueType, staticTyping, createTypeSerializer(config, valueType));
1186 }
1187
1188 protected JsonSerializer<?> buildEnumSerializer(SerializationConfig config,
1189 JavaType type, BeanDescription beanDesc)
1190 throws JsonMappingException
1191 {
1192
1197 JsonFormat.Value format = beanDesc.findExpectedFormat(null);
1198 if (format != null && format.getShape() == JsonFormat.Shape.OBJECT) {
1199
1200 ((BasicBeanDescription) beanDesc).removeProperty("declaringClass");
1201
1202 return null;
1203 }
1204 @SuppressWarnings("unchecked")
1205 Class<Enum<?>> enumClass = (Class<Enum<?>>) type.getRawClass();
1206 JsonSerializer<?> ser = EnumSerializer.construct(enumClass, config, beanDesc, format);
1207
1208 if (_factoryConfig.hasSerializerModifiers()) {
1209 for (BeanSerializerModifier mod : _factoryConfig.serializerModifiers()) {
1210 ser = mod.modifyEnumSerializer(config, type, beanDesc, ser);
1211 }
1212 }
1213 return ser;
1214 }
1215
1216
1221
1222
1227 protected JsonSerializer<Object> _findKeySerializer(SerializerProvider prov,
1228 Annotated a)
1229 throws JsonMappingException
1230 {
1231 AnnotationIntrospector intr = prov.getAnnotationIntrospector();
1232 Object serDef = intr.findKeySerializer(a);
1233 if (serDef != null) {
1234 return prov.serializerInstance(a, serDef);
1235 }
1236 return null;
1237 }
1238
1239
1244 protected JsonSerializer<Object> _findContentSerializer(SerializerProvider prov,
1245 Annotated a)
1246 throws JsonMappingException
1247 {
1248 AnnotationIntrospector intr = prov.getAnnotationIntrospector();
1249 Object serDef = intr.findContentSerializer(a);
1250 if (serDef != null) {
1251 return prov.serializerInstance(a, serDef);
1252 }
1253 return null;
1254 }
1255
1256
1260 protected Object findFilterId(SerializationConfig config, BeanDescription beanDesc) {
1261 return config.getAnnotationIntrospector().findFilterId((Annotated)beanDesc.getClassInfo());
1262 }
1263
1264
1272 protected boolean usesStaticTyping(SerializationConfig config,
1273 BeanDescription beanDesc, TypeSerializer typeSer)
1274 {
1275
1278 if (typeSer != null) {
1279 return false;
1280 }
1281 AnnotationIntrospector intr = config.getAnnotationIntrospector();
1282 JsonSerialize.Typing t = intr.findSerializationTyping(beanDesc.getClassInfo());
1283 if (t != null && t != JsonSerialize.Typing.DEFAULT_TYPING) {
1284 return (t == JsonSerialize.Typing.STATIC);
1285 }
1286 return config.isEnabled(MapperFeature.USE_STATIC_TYPING);
1287 }
1288
1289
1290
1306 }
1307