Skip to content

Commit 09ce4be

Browse files
committed
More work towards solving #2632
1 parent 80a3e11 commit 09ce4be

File tree

5 files changed

+47
-11
lines changed

5 files changed

+47
-11
lines changed

src/main/java/com/fasterxml/jackson/databind/DeserializationContext.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -254,9 +254,12 @@ public final TypeFactory getTypeFactory() {
254254

255255
@Override // since 2.11
256256
public JavaType constructSpecializedType(JavaType baseType, Class<?> subclass) {
257-
// No specialized handling for deserialization, but needs to be implemented
258-
return baseType.hasRawClass(subclass) ? baseType
259-
: getConfig().constructSpecializedType(baseType, subclass);
257+
if (baseType.hasRawClass(subclass)) {
258+
return baseType;
259+
}
260+
// On deserialization side, still uses "strict" type-compatibility checking;
261+
// see [databind#2632] about serialization side
262+
return getConfig().getTypeFactory().constructSpecializedType(baseType, subclass, false);
260263
}
261264

262265
/**

src/main/java/com/fasterxml/jackson/databind/SerializerProvider.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -335,9 +335,12 @@ public final TypeFactory getTypeFactory() {
335335

336336
@Override // since 2.11
337337
public JavaType constructSpecializedType(JavaType baseType, Class<?> subclass) {
338-
// Need little bit different handling due to [databind#2632]
339-
return baseType.hasRawClass(subclass) ? baseType
340-
: getConfig().constructSpecializedType(baseType, subclass);
338+
if (baseType.hasRawClass(subclass)) {
339+
return baseType;
340+
}
341+
// Need little bit different handling due to [databind#2632]; pass `true` for
342+
// "relaxed" type assingment checks.
343+
return getConfig().getTypeFactory().constructSpecializedType(baseType, subclass, true);
341344
}
342345

343346
@Override

src/main/java/com/fasterxml/jackson/databind/cfg/MapperConfig.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,8 @@ public final JavaType constructType(TypeReference<?> valueTypeRef) {
319319
}
320320

321321
public JavaType constructSpecializedType(JavaType baseType, Class<?> subclass) {
322-
return getTypeFactory().constructSpecializedType(baseType, subclass);
322+
// note: since 2.11 specify "strict" resolution
323+
return getTypeFactory().constructSpecializedType(baseType, subclass, true);
323324
}
324325

325326
/*

src/main/java/com/fasterxml/jackson/databind/deser/BasicDeserializerFactory.java

+4-3
Original file line numberDiff line numberDiff line change
@@ -1246,7 +1246,8 @@ protected CollectionType _mapAbstractCollectionType(JavaType type, Deserializati
12461246
{
12471247
final Class<?> collectionClass = ContainerDefaultMappings.findCollectionFallback(type);
12481248
if (collectionClass != null) {
1249-
return (CollectionType) config.constructSpecializedType(type, collectionClass);
1249+
return (CollectionType) config.getTypeFactory()
1250+
.constructSpecializedType(type, collectionClass, true);
12501251
}
12511252
return null;
12521253
}
@@ -1394,12 +1395,12 @@ protected MapType _mapAbstractMapType(JavaType type, DeserializationConfig confi
13941395
{
13951396
final Class<?> mapClass = ContainerDefaultMappings.findMapFallback(type);
13961397
if (mapClass != null) {
1397-
return (MapType) config.constructSpecializedType(type, mapClass);
1398+
return (MapType) config.getTypeFactory()
1399+
.constructSpecializedType(type, mapClass, true);
13981400
}
13991401
return null;
14001402
}
14011403

1402-
14031404
// Copied almost verbatim from "createMapDeserializer" -- should try to share more code
14041405
@Override
14051406
public JsonDeserializer<?> createMapLikeDeserializer(DeserializationContext ctxt,

src/main/java/com/fasterxml/jackson/databind/type/TypeFactory.java

+29-1
Original file line numberDiff line numberDiff line change
@@ -359,8 +359,36 @@ protected Class<?> _findPrimitive(String className)
359359
* Can be used, for example, to get equivalent of "HashMap&lt;String,Integer&gt;"
360360
* from "Map&lt;String,Integer&gt;" by giving <code>HashMap.class</code>
361361
* as subclass.
362+
* Short-cut for:
363+
*<pre>
364+
* constructSpecializedType(baseType, subclass, class);
365+
*</pre>
366+
* that is, will use "strict" compatibility checking, usually used for
367+
* deserialization purposes (but often not for serialization).
368+
*/
369+
public JavaType constructSpecializedType(JavaType baseType, Class<?> subclass) {
370+
return constructSpecializedType(baseType, subclass, false);
371+
}
372+
373+
/**
374+
* Factory method for creating a subtype of given base type, as defined
375+
* by specified subclass; but retaining generic type information if any.
376+
* Can be used, for example, to get equivalent of "HashMap&lt;String,Integer&gt;"
377+
* from "Map&lt;String,Integer&gt;" by giving <code>HashMap.class</code>
378+
* as subclass.
379+
*
380+
* @param baseType Declared base type with resolved type parameters
381+
* @param subclass Runtime subtype to use for resolving
382+
* @param relaxedCompatibilityCheck Whether checking for type-assignment compatibility
383+
* should be "relaxed" ({@code true}) or "strict" ({@code false}): typically
384+
* serialization uses relaxed, deserialization strict checking.
385+
*
386+
* @return Resolved sub-type
387+
*
388+
* @since 2.11
362389
*/
363-
public JavaType constructSpecializedType(JavaType baseType, Class<?> subclass)
390+
public JavaType constructSpecializedType(JavaType baseType, Class<?> subclass,
391+
boolean relaxedCompatibilityCheck)
364392
{
365393
// simple optimization to avoid costly introspection if type-erased type does NOT differ
366394
final Class<?> rawBase = baseType.getRawClass();

0 commit comments

Comments
 (0)