66import java .util .LinkedHashSet ;
77import java .util .Set ;
88
9+ import com .fasterxml .jackson .annotation .JsonTypeInfo .As ;
910import com .fasterxml .jackson .core .*;
1011import com .fasterxml .jackson .databind .*;
1112import com .fasterxml .jackson .databind .annotation .JacksonStdImpl ;
1415import com .fasterxml .jackson .databind .jsonFormatVisitors .JsonFormatVisitorWrapper ;
1516import com .fasterxml .jackson .databind .jsonFormatVisitors .JsonStringFormatVisitor ;
1617import com .fasterxml .jackson .databind .jsonschema .SchemaAware ;
18+ import com .fasterxml .jackson .databind .jsontype .TypeIdResolver ;
1719import com .fasterxml .jackson .databind .jsontype .TypeSerializer ;
1820import com .fasterxml .jackson .databind .ser .BeanSerializer ;
1921import com .fasterxml .jackson .databind .ser .ContextualSerializer ;
@@ -44,7 +46,7 @@ public class JsonValueSerializer
4446 protected final JsonSerializer <Object > _valueSerializer ;
4547
4648 protected final BeanProperty _property ;
47-
49+
4850 /**
4951 * This is a flag that is set in rare (?) cases where this serializer
5052 * is used for "natural" types (boolean, int, String, double); and where
@@ -156,12 +158,12 @@ public JsonSerializer<?> createContextual(SerializerProvider provider,
156158 */
157159
158160 @ Override
159- public void serialize (Object bean , JsonGenerator jgen , SerializerProvider prov ) throws IOException
161+ public void serialize (Object bean , JsonGenerator gen , SerializerProvider prov ) throws IOException
160162 {
161163 try {
162164 Object value = _accessorMethod .getValue (bean );
163165 if (value == null ) {
164- prov .defaultSerializeNull (jgen );
166+ prov .defaultSerializeNull (gen );
165167 return ;
166168 }
167169 JsonSerializer <Object > ser = _valueSerializer ;
@@ -174,7 +176,7 @@ public void serialize(Object bean, JsonGenerator jgen, SerializerProvider prov)
174176 // let's cache it, may be needed soon again
175177 ser = prov .findTypedValueSerializer (c , true , _property );
176178 }
177- ser .serialize (value , jgen , prov );
179+ ser .serialize (value , gen , prov );
178180 } catch (IOException ioe ) {
179181 throw ioe ;
180182 } catch (Exception e ) {
@@ -193,7 +195,7 @@ public void serialize(Object bean, JsonGenerator jgen, SerializerProvider prov)
193195 }
194196
195197 @ Override
196- public void serializeWithType (Object bean , JsonGenerator jgen , SerializerProvider provider ,
198+ public void serializeWithType (Object bean , JsonGenerator gen , SerializerProvider provider ,
197199 TypeSerializer typeSer0 ) throws IOException
198200 {
199201 // Regardless of other parts, first need to find value to serialize:
@@ -202,30 +204,29 @@ public void serializeWithType(Object bean, JsonGenerator jgen, SerializerProvide
202204 value = _accessorMethod .getValue (bean );
203205 // and if we got null, can also just write it directly
204206 if (value == null ) {
205- provider .defaultSerializeNull (jgen );
207+ provider .defaultSerializeNull (gen );
206208 return ;
207209 }
208210 JsonSerializer <Object > ser = _valueSerializer ;
209- if (ser == null ) { // already got a serializer? fabulous, that be easy...
211+ if (ser == null ) { // no serializer yet? Need to fetch
210212// ser = provider.findTypedValueSerializer(value.getClass(), true, _property);
211213 ser = provider .findValueSerializer (value .getClass (), _property );
212214 } else {
213215 /* 09-Dec-2010, tatu: To work around natural type's refusal to add type info, we do
214216 * this (note: type is for the wrapper type, not enclosed value!)
215217 */
216218 if (_forceTypeInformation ) {
217- typeSer0 .writeTypePrefixForScalar (bean , jgen );
218- ser .serialize (value , jgen , provider );
219- typeSer0 .writeTypeSuffixForScalar (bean , jgen );
219+ typeSer0 .writeTypePrefixForScalar (bean , gen );
220+ ser .serialize (value , gen , provider );
221+ typeSer0 .writeTypeSuffixForScalar (bean , gen );
220222 return ;
221223 }
222224 }
223- /* 13-Feb-2013, tatu: Turns out that work-around should NOT be required
224- * at all; it would not lead to correct behavior (as per #167).
225- */
226- // and then redirect type id lookups
227- // TypeSerializer typeSer = new TypeSerializerWrapper(typeSer0, bean);
228- ser .serializeWithType (value , jgen , provider , typeSer0 );
225+ // 28-Sep-2016, tatu: As per [databind#1385], we do need to do some juggling
226+ // to use different Object for type id (logical type) and actual serialization
227+ // (delegat type).
228+ TypeSerializerRerouter rr = new TypeSerializerRerouter (typeSer0 , bean );
229+ ser .serializeWithType (value , gen , provider , rr );
229230 } catch (IOException ioe ) {
230231 throw ioe ;
231232 } catch (Exception e ) {
@@ -339,7 +340,7 @@ protected boolean isNaturalTypeWithStdHandling(Class<?> rawType, JsonSerializer<
339340 }
340341 return isDefaultSerializer (ser );
341342 }
342-
343+
343344 /*
344345 /**********************************************************
345346 /* Other methods
@@ -350,4 +351,120 @@ protected boolean isNaturalTypeWithStdHandling(Class<?> rawType, JsonSerializer<
350351 public String toString () {
351352 return "(@JsonValue serializer for method " + _accessorMethod .getDeclaringClass () + "#" + _accessorMethod .getName () + ")" ;
352353 }
354+
355+ /*
356+ /**********************************************************
357+ /* Helper class
358+ /**********************************************************
359+ */
360+
361+ /**
362+ * Silly little wrapper class we need to re-route type serialization so that we can
363+ * override Object to use for type id (logical type) even when asking serialization
364+ * of something else (delegate type)
365+ */
366+ static class TypeSerializerRerouter
367+ extends TypeSerializer
368+ {
369+ protected final TypeSerializer _typeSerializer ;
370+ protected final Object _forObject ;
371+
372+ public TypeSerializerRerouter (TypeSerializer ts , Object ob ) {
373+ _typeSerializer = ts ;
374+ _forObject = ob ;
375+ }
376+
377+ @ Override
378+ public TypeSerializer forProperty (BeanProperty prop ) { // should never get called
379+ throw new UnsupportedOperationException ();
380+ }
381+
382+ @ Override
383+ public As getTypeInclusion () {
384+ return _typeSerializer .getTypeInclusion ();
385+ }
386+
387+ @ Override
388+ public String getPropertyName () {
389+ return _typeSerializer .getPropertyName ();
390+ }
391+
392+ @ Override
393+ public TypeIdResolver getTypeIdResolver () {
394+ return _typeSerializer .getTypeIdResolver ();
395+ }
396+
397+ @ Override
398+ public void writeTypePrefixForScalar (Object value , JsonGenerator gen ) throws IOException {
399+ _typeSerializer .writeTypePrefixForScalar (_forObject , gen );
400+ }
401+
402+ @ Override
403+ public void writeTypePrefixForObject (Object value , JsonGenerator gen ) throws IOException {
404+ _typeSerializer .writeTypePrefixForObject (_forObject , gen );
405+ }
406+
407+ @ Override
408+ public void writeTypePrefixForArray (Object value , JsonGenerator gen ) throws IOException {
409+ _typeSerializer .writeTypePrefixForArray (_forObject , gen );
410+ }
411+
412+ @ Override
413+ public void writeTypeSuffixForScalar (Object value , JsonGenerator gen ) throws IOException {
414+ _typeSerializer .writeTypeSuffixForScalar (_forObject , gen );
415+ }
416+
417+ @ Override
418+ public void writeTypeSuffixForObject (Object value , JsonGenerator gen ) throws IOException {
419+ _typeSerializer .writeTypeSuffixForObject (_forObject , gen );
420+ }
421+
422+ @ Override
423+ public void writeTypeSuffixForArray (Object value , JsonGenerator gen ) throws IOException {
424+ _typeSerializer .writeTypeSuffixForArray (_forObject , gen );
425+ }
426+
427+ public void writeTypePrefixForScalar (Object value , JsonGenerator gen , Class <?> type ) throws IOException {
428+ _typeSerializer .writeTypePrefixForScalar (_forObject , gen , type );
429+ }
430+
431+ public void writeTypePrefixForObject (Object value , JsonGenerator gen , Class <?> type ) throws IOException {
432+ _typeSerializer .writeTypePrefixForObject (_forObject , gen , type );
433+ }
434+
435+ public void writeTypePrefixForArray (Object value , JsonGenerator gen , Class <?> type ) throws IOException {
436+ _typeSerializer .writeTypePrefixForArray (_forObject , gen , type );
437+ }
438+
439+ @ Override
440+ public void writeCustomTypePrefixForScalar (Object value , JsonGenerator gen , String typeId )
441+ throws IOException {
442+ _typeSerializer .writeCustomTypePrefixForScalar (_forObject , gen , typeId );
443+ }
444+
445+ @ Override
446+ public void writeCustomTypePrefixForObject (Object value , JsonGenerator gen , String typeId ) throws IOException {
447+ _typeSerializer .writeCustomTypePrefixForObject (_forObject , gen , typeId );
448+ }
449+
450+ @ Override
451+ public void writeCustomTypePrefixForArray (Object value , JsonGenerator gen , String typeId ) throws IOException {
452+ _typeSerializer .writeCustomTypePrefixForArray (_forObject , gen , typeId );
453+ }
454+
455+ @ Override
456+ public void writeCustomTypeSuffixForScalar (Object value , JsonGenerator gen , String typeId ) throws IOException {
457+ _typeSerializer .writeCustomTypeSuffixForScalar (_forObject , gen , typeId );
458+ }
459+
460+ @ Override
461+ public void writeCustomTypeSuffixForObject (Object value , JsonGenerator gen , String typeId ) throws IOException {
462+ _typeSerializer .writeCustomTypeSuffixForObject (_forObject , gen , typeId );
463+ }
464+
465+ @ Override
466+ public void writeCustomTypeSuffixForArray (Object value , JsonGenerator gen , String typeId ) throws IOException {
467+ _typeSerializer .writeCustomTypeSuffixForArray (_forObject , gen , typeId );
468+ }
469+ }
353470}
0 commit comments