Skip to content

Commit

Permalink
Fixed #2796 (or part of it at least)
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Jul 16, 2020
1 parent a8182ea commit 925c7c1
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 30 deletions.
4 changes: 4 additions & 0 deletions release-notes/CREDITS-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -1140,3 +1140,7 @@ Joshua Shannon (retrodaredevil@github)
* Reported, contributed fix for #2785: Polymorphic subtypes not registering on copied
ObjectMapper (2.11.1)
(2.11.2)
Daniel Hrabovcak (TheSpiritXIII@github)
* Reported #2796: `TypeFactory.constructType()` does not take `TypeBindings` correctly
(2.11.2)
2 changes: 2 additions & 0 deletions release-notes/VERSION-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ Project: jackson-databind
`createGenerator()`
#2785: Polymorphic subtypes not registering on copied ObjectMapper (2.11.1)
(reported, fix contributed by Joshua S)
#2796: `TypeFactory.constructType()` does not take `TypeBindings` correctly
(reported by Daniel H)

2.11.1 (25-Jun-2020)

Expand Down
69 changes: 41 additions & 28 deletions src/main/java/com/fasterxml/jackson/databind/type/TypeFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -699,9 +699,15 @@ public JavaType constructType(Type type) {
}

public JavaType constructType(Type type, TypeBindings bindings) {
// 15-Jun-2020, tatu: To resolve (parts of) [databind#2796], need to
// call _fromClass() directly if we get `Class` argument
if (type instanceof Class<?>) {
JavaType resultType = _fromClass(null, (Class<?>) type, bindings);
return _applyModifiers(type, resultType);
}
return _fromAny(null, type, bindings);
}

public JavaType constructType(TypeReference<?> typeRef)
{
// 19-Oct-2015, tatu: Simpler variant like so should work
Expand Down Expand Up @@ -1274,51 +1280,58 @@ protected JavaType _findWellKnownSimple(Class<?> clz) {
* as Java typing returned from <code>getGenericXxx</code> methods
* (usually for a return or argument type).
*/
protected JavaType _fromAny(ClassStack context, Type type, TypeBindings bindings)
protected JavaType _fromAny(ClassStack context, Type srcType, TypeBindings bindings)
{
JavaType resultType;

// simple class?
if (type instanceof Class<?>) {
if (srcType instanceof Class<?>) {
// Important: remove possible bindings since this is type-erased thingy
resultType = _fromClass(context, (Class<?>) type, EMPTY_BINDINGS);
resultType = _fromClass(context, (Class<?>) srcType, EMPTY_BINDINGS);
}
// But if not, need to start resolving.
else if (type instanceof ParameterizedType) {
resultType = _fromParamType(context, (ParameterizedType) type, bindings);
else if (srcType instanceof ParameterizedType) {
resultType = _fromParamType(context, (ParameterizedType) srcType, bindings);
}
else if (type instanceof JavaType) { // [databind#116]
else if (srcType instanceof JavaType) { // [databind#116]
// no need to modify further if we already had JavaType
return (JavaType) type;
return (JavaType) srcType;
}
else if (type instanceof GenericArrayType) {
resultType = _fromArrayType(context, (GenericArrayType) type, bindings);
else if (srcType instanceof GenericArrayType) {
resultType = _fromArrayType(context, (GenericArrayType) srcType, bindings);
}
else if (type instanceof TypeVariable<?>) {
resultType = _fromVariable(context, (TypeVariable<?>) type, bindings);
else if (srcType instanceof TypeVariable<?>) {
resultType = _fromVariable(context, (TypeVariable<?>) srcType, bindings);
}
else if (type instanceof WildcardType) {
resultType = _fromWildcard(context, (WildcardType) type, bindings);
else if (srcType instanceof WildcardType) {
resultType = _fromWildcard(context, (WildcardType) srcType, bindings);
} else {
// sanity check
throw new IllegalArgumentException("Unrecognized Type: "+((type == null) ? "[null]" : type.toString()));
throw new IllegalArgumentException("Unrecognized Type: "+((srcType == null) ? "[null]" : srcType.toString()));
}
// 21-Feb-2016, nateB/tatu: as per [databind#1129] (applied for 2.7.2),
// we do need to let all kinds of types to be refined, esp. for Scala module.
if (_modifiers != null) {
TypeBindings b = resultType.getBindings();
if (b == null) {
b = EMPTY_BINDINGS;
}
for (TypeModifier mod : _modifiers) {
JavaType t = mod.modifyType(resultType, type, b, this);
if (t == null) {
throw new IllegalStateException(String.format(
"TypeModifier %s (of type %s) return null for type %s",
mod, mod.getClass().getName(), resultType));
}
resultType = t;
return _applyModifiers(srcType, resultType);
}

protected JavaType _applyModifiers(Type srcType, JavaType resolvedType)
{
if (_modifiers == null) {
return resolvedType;
}
JavaType resultType = resolvedType;
TypeBindings b = resultType.getBindings();
if (b == null) {
b = EMPTY_BINDINGS;
}
for (TypeModifier mod : _modifiers) {
JavaType t = mod.modifyType(resultType, srcType, b, this);
if (t == null) {
throw new IllegalStateException(String.format(
"TypeModifier %s (of type %s) return null for type %s",
mod, mod.getClass().getName(), resultType));
}
resultType = t;
}
return resultType;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ public void testCanonicalWithSpaces()
public void testCollections()
{
// Ok, first: let's test what happens when we pass 'raw' Collection:
TypeFactory tf = TypeFactory.defaultInstance();
final TypeFactory tf = TypeFactory.defaultInstance();
JavaType t = tf.constructType(ArrayList.class);
assertEquals(CollectionType.class, t.getClass());
assertSame(ArrayList.class, t.getRawClass());
Expand All @@ -299,7 +299,19 @@ public void testCollections()
assertEquals(CollectionType.class, t.getClass());
assertSame(String.class, ((CollectionType) t).getContentType().getRawClass());
}


// [databind#2796]
public void testCollectionsWithBindings()
{
final TypeFactory tf = TypeFactory.defaultInstance();
TypeBindings tb = TypeBindings.create(Set.class, new JavaType[] {
tf.constructType(String.class) });
JavaType t = tf.constructType(ArrayList.class, tb);
assertEquals(CollectionType.class, t.getClass());
assertSame(ArrayList.class, t.getRawClass());
assertSame(String.class, ((CollectionType) t).getContentType().getRawClass());
}

// since 2.7
public void testCollectionTypesRefined()
{
Expand Down

0 comments on commit 925c7c1

Please sign in to comment.