diff --git a/release-notes/VERSION b/release-notes/VERSION index 2b760305e2..28cd33b85a 100644 --- a/release-notes/VERSION +++ b/release-notes/VERSION @@ -6,6 +6,7 @@ Project: jackson-databind 2.8.0 (not released yet) +#1084: Change `TypeDeserializerBase` to take `JavaType` for `defaultImpl`, NOT `Class` #1126: Allow deserialization of unknown Enums using a predefined value (contributed by Alejandro R) #1136: Implement `TokenBuffer.writeEmbeddedObject(Object)` diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBase.java b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBase.java index 7d249e8bf8..48cadfc714 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBase.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBase.java @@ -1204,7 +1204,6 @@ public Object deserializeFromString(JsonParser p, DeserializationContext ctxt) t * Method called to deserialize POJO value from a JSON floating-point * number. */ - @SuppressWarnings("incomplete-switch") public Object deserializeFromDouble(JsonParser p, DeserializationContext ctxt) throws IOException { NumberType t = p.getNumberType(); diff --git a/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/AsArrayTypeDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/AsArrayTypeDeserializer.java index f5fdb2be0e..5965ebb87b 100644 --- a/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/AsArrayTypeDeserializer.java +++ b/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/AsArrayTypeDeserializer.java @@ -23,8 +23,11 @@ public class AsArrayTypeDeserializer { private static final long serialVersionUID = 1L; + /** + * @since 2.8 + */ public AsArrayTypeDeserializer(JavaType bt, TypeIdResolver idRes, - String typePropertyName, boolean typeIdVisible, Class defaultImpl) + String typePropertyName, boolean typeIdVisible, JavaType defaultImpl) { super(bt, idRes, typePropertyName, typeIdVisible, defaultImpl); } diff --git a/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/AsExistingPropertyTypeSerializer.java b/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/AsExistingPropertyTypeSerializer.java index 1fc5983cc0..232e6ac56e 100644 --- a/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/AsExistingPropertyTypeSerializer.java +++ b/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/AsExistingPropertyTypeSerializer.java @@ -18,45 +18,47 @@ public class AsExistingPropertyTypeSerializer extends AsPropertyTypeSerializer { - public AsExistingPropertyTypeSerializer(TypeIdResolver idRes, BeanProperty property, String propName) + public AsExistingPropertyTypeSerializer(TypeIdResolver idRes, + BeanProperty property, String propName) { super(idRes, property, propName); } @Override public AsExistingPropertyTypeSerializer forProperty(BeanProperty prop) { - return (_property == prop) ? this : new AsExistingPropertyTypeSerializer(this._idResolver, prop, this._typePropertyName); + return (_property == prop) ? this : + new AsExistingPropertyTypeSerializer(_idResolver, prop, _typePropertyName); } @Override public As getTypeInclusion() { return As.EXISTING_PROPERTY; } @Override - public void writeTypePrefixForObject(Object value, JsonGenerator jgen) throws IOException + public void writeTypePrefixForObject(Object value, JsonGenerator gen) throws IOException { final String typeId = idFromValue(value); - if ((typeId != null) && jgen.canWriteTypeId()) { - jgen.writeTypeId(typeId); + if ((typeId != null) && gen.canWriteTypeId()) { + gen.writeTypeId(typeId); } - jgen.writeStartObject(); + gen.writeStartObject(); } @Override - public void writeTypePrefixForObject(Object value, JsonGenerator jgen, Class type) throws IOException + public void writeTypePrefixForObject(Object value, JsonGenerator gen, Class type) throws IOException { final String typeId = idFromValueAndType(value, type); - if ((typeId != null) && jgen.canWriteTypeId()) { - jgen.writeTypeId(typeId); + if ((typeId != null) && gen.canWriteTypeId()) { + gen.writeTypeId(typeId); } - jgen.writeStartObject(); + gen.writeStartObject(); } @Override - public void writeCustomTypePrefixForObject(Object value, JsonGenerator jgen, String typeId) throws IOException + public void writeCustomTypePrefixForObject(Object value, JsonGenerator gen, String typeId) throws IOException { - if ((typeId != null) && jgen.canWriteTypeId()) { - jgen.writeTypeId(typeId); + if ((typeId != null) && gen.canWriteTypeId()) { + gen.writeTypeId(typeId); } - jgen.writeStartObject(); + gen.writeStartObject(); } } diff --git a/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/AsExternalTypeDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/AsExternalTypeDeserializer.java index 3bd453964a..c6b8d495f4 100644 --- a/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/AsExternalTypeDeserializer.java +++ b/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/AsExternalTypeDeserializer.java @@ -19,13 +19,17 @@ public class AsExternalTypeDeserializer extends AsArrayTypeDeserializer { private static final long serialVersionUID = 1L; + /** + * @since 2.8 + */ public AsExternalTypeDeserializer(JavaType bt, TypeIdResolver idRes, - String typePropertyName, boolean typeIdVisible, Class defaultImpl) + String typePropertyName, boolean typeIdVisible, JavaType defaultImpl) { super(bt, idRes, typePropertyName, typeIdVisible, defaultImpl); } - public AsExternalTypeDeserializer(AsExternalTypeDeserializer src, BeanProperty property) { + public AsExternalTypeDeserializer(AsExternalTypeDeserializer src, + BeanProperty property) { super(src, property); } diff --git a/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/AsPropertyTypeDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/AsPropertyTypeDeserializer.java index 101d8429ec..8a3f1bcb61 100644 --- a/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/AsPropertyTypeDeserializer.java +++ b/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/AsPropertyTypeDeserializer.java @@ -24,14 +24,20 @@ public class AsPropertyTypeDeserializer extends AsArrayTypeDeserializer protected final As _inclusion; + /** + * @since 2.8 + */ public AsPropertyTypeDeserializer(JavaType bt, TypeIdResolver idRes, - String typePropertyName, boolean typeIdVisible, Class defaultImpl) + String typePropertyName, boolean typeIdVisible, JavaType defaultImpl) { this(bt, idRes, typePropertyName, typeIdVisible, defaultImpl, As.PROPERTY); } + /** + * @since 2.8 + */ public AsPropertyTypeDeserializer(JavaType bt, TypeIdResolver idRes, - String typePropertyName, boolean typeIdVisible, Class defaultImpl, + String typePropertyName, boolean typeIdVisible, JavaType defaultImpl, As inclusion) { super(bt, idRes, typePropertyName, typeIdVisible, defaultImpl); diff --git a/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/AsWrapperTypeDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/AsWrapperTypeDeserializer.java index 8904b73c56..b46c41386f 100644 --- a/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/AsWrapperTypeDeserializer.java +++ b/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/AsWrapperTypeDeserializer.java @@ -23,8 +23,11 @@ public class AsWrapperTypeDeserializer { private static final long serialVersionUID = 1L; + /** + * @since 2.8 + */ public AsWrapperTypeDeserializer(JavaType bt, TypeIdResolver idRes, - String typePropertyName, boolean typeIdVisible, Class defaultImpl) + String typePropertyName, boolean typeIdVisible, JavaType defaultImpl) { super(bt, idRes, typePropertyName, typeIdVisible, defaultImpl); } diff --git a/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/StdTypeResolverBuilder.java b/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/StdTypeResolverBuilder.java index 1372a67243..8016d721fb 100644 --- a/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/StdTypeResolverBuilder.java +++ b/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/StdTypeResolverBuilder.java @@ -4,12 +4,14 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.databind.*; +import com.fasterxml.jackson.databind.annotation.NoClass; import com.fasterxml.jackson.databind.cfg.MapperConfig; import com.fasterxml.jackson.databind.jsontype.NamedType; import com.fasterxml.jackson.databind.jsontype.TypeDeserializer; import com.fasterxml.jackson.databind.jsontype.TypeIdResolver; import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder; import com.fasterxml.jackson.databind.jsontype.TypeSerializer; +import com.fasterxml.jackson.databind.type.TypeFactory; /** * Default {@link TypeResolverBuilder} implementation. @@ -101,22 +103,42 @@ public TypeDeserializer buildTypeDeserializer(DeserializationConfig config, if (_idType == JsonTypeInfo.Id.NONE) { return null; } TypeIdResolver idRes = idResolver(config, baseType, subtypes, false, true); - + + JavaType defaultImpl; + + if (_defaultImpl == null) { + defaultImpl = null; + } else { + // 20-Mar-2016, tatu: It is important to go specialization go through + // TypeFactory to ensure proper resolution; with 2.7 and before, direct + // call to JavaType was used, but that can not work reliably with 2.7 + // 20-Mar-2016, tatu: Can finally add a check for type compatibility BUT + // if so, need to add explicit checks for marker types. Not ideal, but + // seems like a reasonable compromise. + if ((_defaultImpl == Void.class) + || (_defaultImpl == NoClass.class)) { + defaultImpl = config.getTypeFactory().constructType(_defaultImpl); + } else { + defaultImpl = config.getTypeFactory() + .constructSpecializedType(baseType, _defaultImpl); + } + } + // First, method for converting type info to type id: switch (_includeAs) { case WRAPPER_ARRAY: return new AsArrayTypeDeserializer(baseType, idRes, - _typeProperty, _typeIdVisible, _defaultImpl); + _typeProperty, _typeIdVisible, defaultImpl); case PROPERTY: case EXISTING_PROPERTY: // as per [#528] same class as PROPERTY return new AsPropertyTypeDeserializer(baseType, idRes, - _typeProperty, _typeIdVisible, _defaultImpl, _includeAs); + _typeProperty, _typeIdVisible, defaultImpl, _includeAs); case WRAPPER_OBJECT: return new AsWrapperTypeDeserializer(baseType, idRes, - _typeProperty, _typeIdVisible, _defaultImpl); + _typeProperty, _typeIdVisible, defaultImpl); case EXTERNAL_PROPERTY: return new AsExternalTypeDeserializer(baseType, idRes, - _typeProperty, _typeIdVisible, _defaultImpl); + _typeProperty, _typeIdVisible, defaultImpl); } throw new IllegalStateException("Do not know how to construct standard type serializer for inclusion type: "+_includeAs); } diff --git a/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/TypeDeserializerBase.java b/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/TypeDeserializerBase.java index 962275964f..d697780acb 100644 --- a/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/TypeDeserializerBase.java +++ b/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/TypeDeserializerBase.java @@ -66,8 +66,11 @@ public abstract class TypeDeserializerBase /********************************************************** */ + /** + * @since 2.8 + */ protected TypeDeserializerBase(JavaType baseType, TypeIdResolver idRes, - String typePropertyName, boolean typeIdVisible, Class defaultImpl) + String typePropertyName, boolean typeIdVisible, JavaType defaultImpl) { _baseType = baseType; _idResolver = idRes; @@ -76,18 +79,7 @@ protected TypeDeserializerBase(JavaType baseType, TypeIdResolver idRes, _typeIdVisible = typeIdVisible; // defaults are fine, although shouldn't need much concurrency _deserializers = new ConcurrentHashMap>(16, 0.75f, 2); - if (defaultImpl == null) { - _defaultImpl = null; - } else { - /* 16-Oct-2011, tatu: should call this via TypeFactory; this is - * not entirely safe... however, since Collections/Maps are - * seldom (if ever) base types, may be ok. - */ - // 01-Nov-2015, tatu: Actually this is still exactly wrong. Should fix. - // 15-Jan-2016, tatu: ... as witnessed by [databind#1083], patched, but - // fundamentally this call can't be made to work for all cases - _defaultImpl = baseType.forcedNarrowBy(defaultImpl); - } + _defaultImpl = defaultImpl; _property = null; } diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/DateTimeSerializerBase.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/DateTimeSerializerBase.java index 996684c692..f5537a9419 100644 --- a/src/main/java/com/fasterxml/jackson/databind/ser/std/DateTimeSerializerBase.java +++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/DateTimeSerializerBase.java @@ -13,7 +13,6 @@ import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.*; -import com.fasterxml.jackson.databind.introspect.Annotated; import com.fasterxml.jackson.databind.jsonFormatVisitors.*; import com.fasterxml.jackson.databind.ser.ContextualSerializer; import com.fasterxml.jackson.databind.util.StdDateFormat;