@@ -121,9 +121,13 @@ public boolean handlePropertyValue(JsonParser jp, DeserializationContext ctxt,
121
121
}
122
122
return true ;
123
123
}
124
-
124
+
125
+ /**
126
+ * Method called after JSON Object closes, and has to ensure that all external
127
+ * type ids have been handled.
128
+ */
125
129
@ SuppressWarnings ("resource" )
126
- public Object complete (JsonParser jp , DeserializationContext ctxt , Object bean )
130
+ public Object complete (JsonParser p , DeserializationContext ctxt , Object bean )
127
131
throws IOException
128
132
{
129
133
for (int i = 0 , len = _properties .length ; i < len ; ++i ) {
@@ -135,20 +139,19 @@ public Object complete(JsonParser jp, DeserializationContext ctxt, Object bean)
135
139
if (tokens == null ) {
136
140
continue ;
137
141
}
138
- /* [Issue#118]: Need to mind natural types, for which no type id
139
- * will be included.
140
- */
142
+ // [databind#118]: Need to mind natural types, for which no type id
143
+ // will be included.
141
144
JsonToken t = tokens .firstToken ();
142
145
if (t != null && t .isScalarValue ()) {
143
- JsonParser buffered = tokens .asParser (jp );
146
+ JsonParser buffered = tokens .asParser (p );
144
147
buffered .nextToken ();
145
148
SettableBeanProperty extProp = _properties [i ].getProperty ();
146
149
Object result = TypeDeserializer .deserializeIfNatural (buffered , ctxt , extProp .getType ());
147
150
if (result != null ) {
148
151
extProp .set (bean , result );
149
152
continue ;
150
153
}
151
- // 26-Oct-2012, tatu: As per [Issue #94], must allow use of 'defaultImpl'
154
+ // 26-Oct-2012, tatu: As per [databind #94], must allow use of 'defaultImpl'
152
155
if (!_properties [i ].hasDefaultType ()) {
153
156
throw ctxt .mappingException ("Missing external type id property '%s'" ,
154
157
_properties [i ].getTypePropertyName ());
@@ -160,7 +163,7 @@ public Object complete(JsonParser jp, DeserializationContext ctxt, Object bean)
160
163
throw ctxt .mappingException ("Missing property '%s' for external type id '%s'" ,
161
164
prop .getName (), _properties [i ].getTypePropertyName ());
162
165
}
163
- _deserializeAndSet (jp , ctxt , bean , i , typeId );
166
+ _deserializeAndSet (p , ctxt , bean , i , typeId );
164
167
}
165
168
return bean ;
166
169
}
@@ -216,41 +219,52 @@ public Object complete(JsonParser jp, DeserializationContext ctxt,
216
219
}
217
220
218
221
@ SuppressWarnings ("resource" )
219
- protected final Object _deserialize (JsonParser jp , DeserializationContext ctxt ,
222
+ protected final Object _deserialize (JsonParser p , DeserializationContext ctxt ,
220
223
int index , String typeId ) throws IOException
221
224
{
222
- TokenBuffer merged = new TokenBuffer (jp );
225
+ JsonParser p2 = _tokens [index ].asParser (p );
226
+ JsonToken t = p2 .nextToken ();
227
+ // 29-Sep-2015, tatu: As per [databind#942], nulls need special support
228
+ if (t == JsonToken .VALUE_NULL ) {
229
+ return null ;
230
+ }
231
+
232
+ TokenBuffer merged = new TokenBuffer (p );
223
233
merged .writeStartArray ();
224
234
merged .writeString (typeId );
225
- JsonParser p2 = _tokens [index ].asParser (jp );
226
- p2 .nextToken ();
227
235
merged .copyCurrentStructure (p2 );
228
236
merged .writeEndArray ();
229
237
230
238
// needs to point to START_OBJECT (or whatever first token is)
231
- p2 = merged .asParser (jp );
232
- p2 .nextToken ();
233
- return _properties [index ].getProperty ().deserialize (p2 , ctxt );
239
+ JsonParser mp = merged .asParser (p );
240
+ mp .nextToken ();
241
+ return _properties [index ].getProperty ().deserialize (mp , ctxt );
234
242
}
235
243
236
244
@ SuppressWarnings ("resource" )
237
- protected final void _deserializeAndSet (JsonParser jp , DeserializationContext ctxt ,
245
+ protected final void _deserializeAndSet (JsonParser p , DeserializationContext ctxt ,
238
246
Object bean , int index , String typeId ) throws IOException
239
247
{
240
248
/* Ok: time to mix type id, value; and we will actually use "wrapper-array"
241
249
* style to ensure we can handle all kinds of JSON constructs.
242
250
*/
243
- TokenBuffer merged = new TokenBuffer (jp );
251
+ JsonParser p2 = _tokens [index ].asParser (p );
252
+ JsonToken t = p2 .nextToken ();
253
+ // 29-Sep-2015, tatu: As per [databind#942], nulls need special support
254
+ if (t == JsonToken .VALUE_NULL ) {
255
+ _properties [index ].getProperty ().set (bean , null );
256
+ return ;
257
+ }
258
+ TokenBuffer merged = new TokenBuffer (p );
244
259
merged .writeStartArray ();
245
260
merged .writeString (typeId );
246
- JsonParser p2 = _tokens [index ].asParser (jp );
247
- p2 .nextToken ();
261
+
248
262
merged .copyCurrentStructure (p2 );
249
263
merged .writeEndArray ();
250
264
// needs to point to START_OBJECT (or whatever first token is)
251
- p2 = merged .asParser (jp );
252
- p2 .nextToken ();
253
- _properties [index ].getProperty ().deserializeAndSet (p2 , ctxt , bean );
265
+ JsonParser mp = merged .asParser (p );
266
+ mp .nextToken ();
267
+ _properties [index ].getProperty ().deserializeAndSet (mp , ctxt , bean );
254
268
}
255
269
256
270
/*
0 commit comments