Skip to content

Commit

Permalink
More work towards solving #2632
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Mar 28, 2020
1 parent 80a3e11 commit 09ce4be
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -254,9 +254,12 @@ public final TypeFactory getTypeFactory() {

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

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -335,9 +335,12 @@ public final TypeFactory getTypeFactory() {

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

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,8 @@ public final JavaType constructType(TypeReference<?> valueTypeRef) {
}

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

/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1246,7 +1246,8 @@ protected CollectionType _mapAbstractCollectionType(JavaType type, Deserializati
{
final Class<?> collectionClass = ContainerDefaultMappings.findCollectionFallback(type);
if (collectionClass != null) {
return (CollectionType) config.constructSpecializedType(type, collectionClass);
return (CollectionType) config.getTypeFactory()
.constructSpecializedType(type, collectionClass, true);
}
return null;
}
Expand Down Expand Up @@ -1394,12 +1395,12 @@ protected MapType _mapAbstractMapType(JavaType type, DeserializationConfig confi
{
final Class<?> mapClass = ContainerDefaultMappings.findMapFallback(type);
if (mapClass != null) {
return (MapType) config.constructSpecializedType(type, mapClass);
return (MapType) config.getTypeFactory()
.constructSpecializedType(type, mapClass, true);
}
return null;
}


// Copied almost verbatim from "createMapDeserializer" -- should try to share more code
@Override
public JsonDeserializer<?> createMapLikeDeserializer(DeserializationContext ctxt,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -359,8 +359,36 @@ protected Class<?> _findPrimitive(String className)
* Can be used, for example, to get equivalent of "HashMap&lt;String,Integer&gt;"
* from "Map&lt;String,Integer&gt;" by giving <code>HashMap.class</code>
* as subclass.
* Short-cut for:
*<pre>
* constructSpecializedType(baseType, subclass, class);
*</pre>
* that is, will use "strict" compatibility checking, usually used for
* deserialization purposes (but often not for serialization).
*/
public JavaType constructSpecializedType(JavaType baseType, Class<?> subclass) {
return constructSpecializedType(baseType, subclass, false);
}

/**
* Factory method for creating a subtype of given base type, as defined
* by specified subclass; but retaining generic type information if any.
* Can be used, for example, to get equivalent of "HashMap&lt;String,Integer&gt;"
* from "Map&lt;String,Integer&gt;" by giving <code>HashMap.class</code>
* as subclass.
*
* @param baseType Declared base type with resolved type parameters
* @param subclass Runtime subtype to use for resolving
* @param relaxedCompatibilityCheck Whether checking for type-assignment compatibility
* should be "relaxed" ({@code true}) or "strict" ({@code false}): typically
* serialization uses relaxed, deserialization strict checking.
*
* @return Resolved sub-type
*
* @since 2.11
*/
public JavaType constructSpecializedType(JavaType baseType, Class<?> subclass)
public JavaType constructSpecializedType(JavaType baseType, Class<?> subclass,
boolean relaxedCompatibilityCheck)
{
// simple optimization to avoid costly introspection if type-erased type does NOT differ
final Class<?> rawBase = baseType.getRawClass();
Expand Down

0 comments on commit 09ce4be

Please sign in to comment.