diff options
author | Tatu Saloranta <tatu.saloranta@iki.fi> | 2020-07-15 20:45:55 -0700 |
---|---|---|
committer | Tatu Saloranta <tatu.saloranta@iki.fi> | 2020-07-15 20:45:55 -0700 |
commit | 925c7c11858db33a95870256b1e9931e4e33beea (patch) | |
tree | 5cfe0af55ce7e39733fccda66a450448b29c6364 | |
parent | a8182eaaad61b0dcd1664fffab6f8f913194ae64 (diff) | |
download | jackson-databind-925c7c11858db33a95870256b1e9931e4e33beea.tar.gz |
Fixed #2796 (or part of it at least)
-rw-r--r-- | release-notes/CREDITS-2.x | 4 | ||||
-rw-r--r-- | release-notes/VERSION-2.x | 2 | ||||
-rw-r--r-- | src/main/java/com/fasterxml/jackson/databind/type/TypeFactory.java | 69 | ||||
-rw-r--r-- | src/test/java/com/fasterxml/jackson/databind/type/TestTypeFactory.java | 16 |
4 files changed, 61 insertions, 30 deletions
diff --git a/release-notes/CREDITS-2.x b/release-notes/CREDITS-2.x index 61ed80fdd..be405fbab 100644 --- a/release-notes/CREDITS-2.x +++ b/release-notes/CREDITS-2.x @@ -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) diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x index 0a136e553..197a86c11 100644 --- a/release-notes/VERSION-2.x +++ b/release-notes/VERSION-2.x @@ -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) diff --git a/src/main/java/com/fasterxml/jackson/databind/type/TypeFactory.java b/src/main/java/com/fasterxml/jackson/databind/type/TypeFactory.java index ecef0a6b7..17d1d3196 100644 --- a/src/main/java/com/fasterxml/jackson/databind/type/TypeFactory.java +++ b/src/main/java/com/fasterxml/jackson/databind/type/TypeFactory.java @@ -699,9 +699,15 @@ public class TypeFactory // note: was final in 2.9, removed from 2.10 } 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 @@ -1274,51 +1280,58 @@ public class TypeFactory // note: was final in 2.9, removed from 2.10 * 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; } diff --git a/src/test/java/com/fasterxml/jackson/databind/type/TestTypeFactory.java b/src/test/java/com/fasterxml/jackson/databind/type/TestTypeFactory.java index aba0a2830..35ab67214 100644 --- a/src/test/java/com/fasterxml/jackson/databind/type/TestTypeFactory.java +++ b/src/test/java/com/fasterxml/jackson/databind/type/TestTypeFactory.java @@ -278,7 +278,7 @@ public class TestTypeFactory 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()); @@ -299,7 +299,19 @@ public class TestTypeFactory 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() { |