44import java .util .*;
55
66import com .fasterxml .jackson .annotation .JsonFormat ;
7+
78import com .fasterxml .jackson .core .*;
9+
810import com .fasterxml .jackson .databind .*;
911import com .fasterxml .jackson .databind .annotation .JacksonStdImpl ;
10- import com .fasterxml .jackson .databind .deser .ContextualDeserializer ;
11- import com .fasterxml .jackson .databind .deser .UnresolvedForwardReference ;
12- import com .fasterxml .jackson .databind .deser .ValueInstantiator ;
12+ import com .fasterxml .jackson .databind .deser .*;
1313import com .fasterxml .jackson .databind .deser .impl .ReadableObjectId .Referring ;
1414import com .fasterxml .jackson .databind .deser .std .ContainerDeserializerBase ;
1515import com .fasterxml .jackson .databind .jsontype .TypeDeserializer ;
@@ -54,6 +54,13 @@ public class CollectionDeserializer
5454 */
5555 protected final JsonDeserializer <Object > _delegateDeserializer ;
5656
57+ /**
58+ * Handler we need for dealing with nulls
59+ *
60+ * @since 2.9
61+ */
62+ protected final NullValueProvider _nullProvider ;
63+
5764 /**
5865 * Specific override for this instance (from proper, or global per-type overrides)
5966 * to indicate whether single value may be taken to mean an unwrapped one-element array
@@ -79,24 +86,26 @@ public CollectionDeserializer(JavaType collectionType,
7986 JsonDeserializer <Object > valueDeser ,
8087 TypeDeserializer valueTypeDeser , ValueInstantiator valueInstantiator )
8188 {
82- this (collectionType , valueDeser , valueTypeDeser , valueInstantiator , null , null );
89+ this (collectionType , valueDeser , valueTypeDeser , valueInstantiator , null , null , null );
8390 }
8491
8592 /**
8693 * Constructor used when creating contextualized instances.
94+ *
95+ * @since 2.9
8796 */
8897 protected CollectionDeserializer (JavaType collectionType ,
8998 JsonDeserializer <Object > valueDeser , TypeDeserializer valueTypeDeser ,
90- ValueInstantiator valueInstantiator ,
91- JsonDeserializer <Object > delegateDeser ,
92- Boolean unwrapSingle )
99+ ValueInstantiator valueInstantiator , JsonDeserializer <Object > delegateDeser ,
100+ NullValueProvider nuller , Boolean unwrapSingle )
93101 {
94102 super (collectionType );
95103 _valueDeserializer = valueDeser ;
96104 _valueTypeDeserializer = valueTypeDeser ;
97105 _valueInstantiator = valueInstantiator ;
98106 _delegateDeserializer = delegateDeser ;
99107 _unwrapSingle = unwrapSingle ;
108+ _nullProvider = nuller ;
100109 }
101110
102111 /**
@@ -111,21 +120,23 @@ protected CollectionDeserializer(CollectionDeserializer src)
111120 _valueInstantiator = src ._valueInstantiator ;
112121 _delegateDeserializer = src ._delegateDeserializer ;
113122 _unwrapSingle = src ._unwrapSingle ;
123+ _nullProvider = src ._nullProvider ;
114124 }
115125
116126 /**
117127 * Fluent-factory method call to construct contextual instance.
118128 *
119- * @since 2.7
129+ * @since 2.9
120130 */
121131 @ SuppressWarnings ("unchecked" )
122132 protected CollectionDeserializer withResolved (JsonDeserializer <?> dd ,
123133 JsonDeserializer <?> vd , TypeDeserializer vtd ,
124- Boolean unwrapSingle )
134+ NullValueProvider nuller , Boolean unwrapSingle )
125135 {
126136 return new CollectionDeserializer (_containerType ,
127137 (JsonDeserializer <Object >) vd , vtd ,
128- _valueInstantiator , (JsonDeserializer <Object >) dd , unwrapSingle );
138+ _valueInstantiator , (JsonDeserializer <Object >) dd ,
139+ nuller , unwrapSingle );
129140 }
130141
131142 /**
@@ -135,7 +146,7 @@ protected CollectionDeserializer withResolved(JsonDeserializer<?> dd,
135146 protected CollectionDeserializer withResolved (JsonDeserializer <?> dd ,
136147 JsonDeserializer <?> vd , TypeDeserializer vtd )
137148 {
138- return withResolved (dd , vd , vtd , _unwrapSingle );
149+ return withResolved (dd , vd , vtd , vd , _unwrapSingle );
139150 }
140151
141152 // Important: do NOT cache if polymorphic values
@@ -212,7 +223,9 @@ public CollectionDeserializer createContextual(DeserializationContext ctxt,
212223 || (valueDeser != _valueDeserializer )
213224 || (valueTypeDeser != _valueTypeDeserializer )
214225 ) {
215- return withResolved (delegateDeser , valueDeser , valueTypeDeser , unwrapSingle );
226+ return withResolved (delegateDeser , valueDeser , valueTypeDeser ,
227+ findContentNullProvider (ctxt , property , valueDeser ),
228+ unwrapSingle );
216229 }
217230 return this ;
218231 }
@@ -293,7 +306,7 @@ public Collection<Object> deserialize(JsonParser p, DeserializationContext ctxt,
293306 try {
294307 Object value ;
295308 if (t == JsonToken .VALUE_NULL ) {
296- value = valueDes .getNullValue (ctxt );
309+ value = _nullProvider .getNullValue (ctxt );
297310 } else if (typeDeser == null ) {
298311 value = valueDes .deserialize (p , ctxt );
299312 } else {
@@ -356,7 +369,7 @@ protected final Collection<Object> handleNonArray(JsonParser p, DeserializationC
356369
357370 try {
358371 if (t == JsonToken .VALUE_NULL ) {
359- value = valueDes .getNullValue (ctxt );
372+ value = _nullProvider .getNullValue (ctxt );
360373 } else if (typeDeser == null ) {
361374 value = valueDes .deserialize (p , ctxt );
362375 } else {
0 commit comments