@@ -48,6 +48,11 @@ public class JsonValueSerializer
4848 */
4949 protected final AnnotatedMember _accessor ;
5050
51+ /**
52+ * @since 2.12
53+ */
54+ protected final TypeSerializer _valueTypeSerializer ;
55+
5156 protected final JsonSerializer <Object > _valueSerializer ;
5257
5358 protected final BeanProperty _property ;
@@ -86,29 +91,40 @@ public class JsonValueSerializer
8691 * occurs if and only if the "value method" was annotated with
8792 * {@link com.fasterxml.jackson.databind.annotation.JsonSerialize#using}), otherwise
8893 * null
89- *
90- * @since 2.8 Earlier method took "raw" Method, but that does not work with access
91- * to information we need
94+ *
95+ * @since 2.12 added {@link TypeSerializer} since 2.11
9296 */
9397 @ SuppressWarnings ("unchecked" )
94- public JsonValueSerializer (AnnotatedMember accessor , JsonSerializer <?> ser )
98+ public JsonValueSerializer (AnnotatedMember accessor ,
99+ TypeSerializer vts , JsonSerializer <?> ser )
95100 {
96101 super (accessor .getType ());
97102 _accessor = accessor ;
98103 _valueType = accessor .getType ();
104+ _valueTypeSerializer = vts ;
99105 _valueSerializer = (JsonSerializer <Object >) ser ;
100106 _property = null ;
101107 _forceTypeInformation = true ; // gets reconsidered when we are contextualized
102108 _dynamicSerializers = PropertySerializerMap .emptyForProperties ();
103109 }
104110
111+ /**
112+ * @deprecated Since 2.12
113+ */
114+ @ Deprecated
115+ public JsonValueSerializer (AnnotatedMember accessor , JsonSerializer <?> ser ) {
116+ this (accessor , null , ser );
117+ }
118+
119+ // @since 2.12
105120 @ SuppressWarnings ("unchecked" )
106121 public JsonValueSerializer (JsonValueSerializer src , BeanProperty property ,
107- JsonSerializer <?> ser , boolean forceTypeInfo )
122+ TypeSerializer vts , JsonSerializer <?> ser , boolean forceTypeInfo )
108123 {
109124 super (_notNullClass (src .handledType ()));
110125 _accessor = src ._accessor ;
111126 _valueType = src ._valueType ;
127+ _valueTypeSerializer = vts ;
112128 _valueSerializer = (JsonSerializer <Object >) ser ;
113129 _property = property ;
114130 _forceTypeInformation = forceTypeInfo ;
@@ -120,14 +136,15 @@ private final static Class<Object> _notNullClass(Class<?> cls) {
120136 return (cls == null ) ? Object .class : (Class <Object >) cls ;
121137 }
122138
123- public JsonValueSerializer withResolved (BeanProperty property ,
124- JsonSerializer <?> ser , boolean forceTypeInfo )
139+ protected JsonValueSerializer withResolved (BeanProperty property ,
140+ TypeSerializer vts , JsonSerializer <?> ser , boolean forceTypeInfo )
125141 {
126- if (_property == property && _valueSerializer == ser
127- && forceTypeInfo == _forceTypeInformation ) {
142+ if ((_property == property )
143+ && (_valueTypeSerializer == vts ) && (_valueSerializer == ser )
144+ && (forceTypeInfo == _forceTypeInformation )) {
128145 return this ;
129146 }
130- return new JsonValueSerializer (this , property , ser , forceTypeInfo );
147+ return new JsonValueSerializer (this , property , vts , ser , forceTypeInfo );
131148 }
132149
133150 /*
@@ -147,7 +164,7 @@ public boolean isEmpty(SerializerProvider ctxt, Object bean)
147164 JsonSerializer <Object > ser = _valueSerializer ;
148165 if (ser == null ) {
149166 try {
150- ser = _findDynamicSerializer (ctxt , referenced );
167+ ser = _findDynamicSerializer (ctxt , referenced . getClass () );
151168 } catch (JsonMappingException e ) {
152169 throw new RuntimeJsonMappingException (e );
153170 }
@@ -170,6 +187,10 @@ public JsonSerializer<?> createContextual(SerializerProvider ctxt,
170187 BeanProperty property )
171188 throws JsonMappingException
172189 {
190+ TypeSerializer typeSer = _valueTypeSerializer ;
191+ if (typeSer != null ) {
192+ typeSer = typeSer .forProperty (property );
193+ }
173194 JsonSerializer <?> ser = _valueSerializer ;
174195 if (ser == null ) {
175196 // Can only assign serializer statically if the declared type is final:
@@ -188,16 +209,16 @@ public JsonSerializer<?> createContextual(SerializerProvider ctxt,
188209 * using standard serializer
189210 */
190211 boolean forceTypeInformation = isNaturalTypeWithStdHandling (_valueType .getRawClass (), ser );
191- return withResolved (property , ser , forceTypeInformation );
212+ return withResolved (property , typeSer , ser , forceTypeInformation );
192213 }
193214 // [databind#2822]: better hold on to "property", regardless
194215 if (property != _property ) {
195- return withResolved (property , ser , _forceTypeInformation );
216+ return withResolved (property , typeSer , ser , _forceTypeInformation );
196217 }
197218 } else {
198219 // 05-Sep-2013, tatu: I _think_ this can be considered a primary property...
199220 ser = ctxt .handlePrimaryContextualization (ser , property );
200- return withResolved (property , ser , _forceTypeInformation );
221+ return withResolved (property , typeSer , ser , _forceTypeInformation );
201222 }
202223 return this ;
203224 }
@@ -221,13 +242,17 @@ public void serialize(Object bean, JsonGenerator gen, SerializerProvider ctxt) t
221242
222243 if (value == null ) {
223244 ctxt .defaultSerializeNull (gen );
224- return ;
225- }
226- JsonSerializer <Object > ser = _valueSerializer ;
227- if (ser == null ) {
228- ser = _findDynamicSerializer (ctxt , value );
245+ } else {
246+ JsonSerializer <Object > ser = _valueSerializer ;
247+ if (ser == null ) {
248+ ser = _findDynamicSerializer (ctxt , value .getClass ());
249+ }
250+ if (_valueTypeSerializer != null ) {
251+ ser .serializeWithType (value , gen , ctxt , _valueTypeSerializer );
252+ } else {
253+ ser .serialize (value , gen , ctxt );
254+ }
229255 }
230- ser .serialize (value , gen , ctxt );
231256 }
232257
233258 @ Override
@@ -250,7 +275,7 @@ public void serializeWithType(Object bean, JsonGenerator gen, SerializerProvider
250275 }
251276 JsonSerializer <Object > ser = _valueSerializer ;
252277 if (ser == null ) { // no serializer yet? Need to fetch
253- ser = _findDynamicSerializer (ctxt , value );
278+ ser = _findDynamicSerializer (ctxt , value . getClass () );
254279 } else {
255280 // 09-Dec-2010, tatu: To work around natural type's refusal to add type info, we do
256281 // this (note: type is for the wrapper type, not enclosed value!)
@@ -379,15 +404,26 @@ protected boolean isNaturalTypeWithStdHandling(Class<?> rawType, JsonSerializer<
379404
380405 // @since 2.12
381406 protected JsonSerializer <Object > _findDynamicSerializer (SerializerProvider ctxt ,
382- Object value ) throws JsonMappingException
407+ Class <?> valueClass ) throws JsonMappingException
383408 {
384- Class <?> cc = value .getClass ();
385- JsonSerializer <Object > serializer = _dynamicSerializers .serializerFor (cc );
386- if (serializer != null ) {
387- return serializer ;
409+ JsonSerializer <Object > serializer = _dynamicSerializers .serializerFor (valueClass );
410+ if (serializer == null ) {
411+ if (_valueType .hasGenericTypes ()) {
412+ final JavaType fullType = ctxt .constructSpecializedType (_valueType , valueClass );
413+ serializer = ctxt .findPrimaryPropertySerializer (fullType , _property );
414+ PropertySerializerMap .SerializerAndMapResult result = _dynamicSerializers .addSerializer (fullType , serializer );
415+ _dynamicSerializers = result .map ;
416+ } else {
417+ serializer = ctxt .findPrimaryPropertySerializer (valueClass , _property );
418+ PropertySerializerMap .SerializerAndMapResult result = _dynamicSerializers .addSerializer (valueClass , serializer );
419+ _dynamicSerializers = result .map ;
420+ }
388421 }
422+ return serializer ;
423+
424+ /*
389425 if (_valueType.hasGenericTypes()) {
390- JavaType fullType = ctxt .constructSpecializedType (_valueType , cc );
426+ JavaType fullType = ctxt.constructSpecializedType(_valueType, valueClass );
391427 // 31-Oct-2020, tatu: Should not get typed/root serializer, but for now has to do:
392428 serializer = ctxt.findTypedValueSerializer(fullType, false, _property);
393429 PropertySerializerMap.SerializerAndMapResult result = _dynamicSerializers.addSerializer(fullType, serializer);
@@ -396,12 +432,13 @@ protected JsonSerializer<Object> _findDynamicSerializer(SerializerProvider ctxt,
396432 return serializer;
397433 } else {
398434 // 31-Oct-2020, tatu: Should not get typed/root serializer, but for now has to do:
399- serializer = ctxt .findTypedValueSerializer (cc , false , _property );
400- PropertySerializerMap .SerializerAndMapResult result = _dynamicSerializers .addSerializer (cc , serializer );
435+ serializer = ctxt.findTypedValueSerializer(valueClass , false, _property);
436+ PropertySerializerMap.SerializerAndMapResult result = _dynamicSerializers.addSerializer(valueClass , serializer);
401437 // did we get a new map of serializers? If so, start using it
402438 _dynamicSerializers = result.map;
403439 return serializer;
404440 }
441+ */
405442 }
406443
407444 /*
0 commit comments