From feb4ce1bc824ff98f67820299bcce9c92500915b Mon Sep 17 00:00:00 2001 From: "Kim, Joo Hyuk" Date: Sat, 27 May 2023 03:01:30 +0900 Subject: [PATCH] Apply `JsonTypeInfo.Value` usages from Jackson 3.0 (#3953) --- .../jackson/databind/ObjectMapper.java | 11 +++--- .../JacksonAnnotationIntrospector.java | 39 ++++++++++++------- .../jsontype/impl/StdTypeResolverBuilder.java | 21 +++++++--- 3 files changed, 46 insertions(+), 25 deletions(-) diff --git a/src/main/java/com/fasterxml/jackson/databind/ObjectMapper.java b/src/main/java/com/fasterxml/jackson/databind/ObjectMapper.java index 0ce19c8689..b263403d64 100644 --- a/src/main/java/com/fasterxml/jackson/databind/ObjectMapper.java +++ b/src/main/java/com/fasterxml/jackson/databind/ObjectMapper.java @@ -1993,8 +1993,9 @@ public ObjectMapper activateDefaultTyping(PolymorphicTypeValidator ptv, TypeResolverBuilder typer = _constructDefaultTypeResolverBuilder(applicability, ptv); // we'll always use full class name, when using defaulting - typer = typer.init(JsonTypeInfo.Id.CLASS, null); - typer = typer.inclusion(includeAs); + JsonTypeInfo.Value typeInfo = JsonTypeInfo.Value.construct(JsonTypeInfo.Id.CLASS, includeAs, + null, null, false, null); + typer = typer.init(typeInfo, null); return setDefaultTyping(typer); } @@ -2023,9 +2024,9 @@ public ObjectMapper activateDefaultTypingAsProperty(PolymorphicTypeValidator ptv TypeResolverBuilder typer = _constructDefaultTypeResolverBuilder(applicability, ptv); // we'll always use full class name, when using defaulting - typer = typer.init(JsonTypeInfo.Id.CLASS, null); - typer = typer.inclusion(JsonTypeInfo.As.PROPERTY); - typer = typer.typeProperty(propertyName); + JsonTypeInfo.Value typeInfo = JsonTypeInfo.Value.construct(JsonTypeInfo.Id.CLASS, JsonTypeInfo.As.PROPERTY, + propertyName, null, false, null); + typer = typer.init(typeInfo, null); return setDefaultTyping(typer); } diff --git a/src/main/java/com/fasterxml/jackson/databind/introspect/JacksonAnnotationIntrospector.java b/src/main/java/com/fasterxml/jackson/databind/introspect/JacksonAnnotationIntrospector.java index dfeaee6888..6ff5b7d08f 100644 --- a/src/main/java/com/fasterxml/jackson/databind/introspect/JacksonAnnotationIntrospector.java +++ b/src/main/java/com/fasterxml/jackson/databind/introspect/JacksonAnnotationIntrospector.java @@ -1508,27 +1508,29 @@ protected PropertyName _findConstructorName(Annotated a) protected TypeResolverBuilder _findTypeResolver(MapperConfig config, Annotated ann, JavaType baseType) { + // since 2.16 : backporting {@link JsonTypeInfo.Value} from 3.0 + JsonTypeInfo.Value typeInfo = findPolymorphicTypeInfo(config, ann); + // First: maybe we have explicit type resolver? TypeResolverBuilder b; - JsonTypeInfo info = _findAnnotation(ann, JsonTypeInfo.class); JsonTypeResolver resAnn = _findAnnotation(ann, JsonTypeResolver.class); if (resAnn != null) { - if (info == null) { + if (typeInfo == null) { return null; } // let's not try to force access override (would need to pass // settings through if we did, since that's not doable on some platforms) b = config.typeResolverBuilderInstance(ann, resAnn.value()); } else { // if not, use standard one, if indicated by annotations - if (info == null) { + if (typeInfo == null) { return null; } // bit special; must return 'marker' to block use of default typing: - if (info.use() == JsonTypeInfo.Id.NONE) { + if (typeInfo.getIdType() == JsonTypeInfo.Id.NONE) { return _constructNoTypeResolverBuilder(); } - b = _constructStdTypeResolverBuilder(); + b = _constructStdTypeResolverBuilder(config, typeInfo, baseType); } // Does it define a custom type id resolver? JsonTypeIdResolver idResInfo = _findAnnotation(ann, JsonTypeIdResolver.class); @@ -1537,26 +1539,24 @@ protected TypeResolverBuilder _findTypeResolver(MapperConfig config, if (idRes != null) { idRes.init(baseType); } - b = b.init(info.use(), idRes); // 13-Aug-2011, tatu: One complication; external id only works for properties; // so if declared for a Class, we will need to map it to "PROPERTY" // instead of "EXTERNAL_PROPERTY" - JsonTypeInfo.As inclusion = info.include(); + JsonTypeInfo.As inclusion = typeInfo.getInclusionType(); if (inclusion == JsonTypeInfo.As.EXTERNAL_PROPERTY && (ann instanceof AnnotatedClass)) { - inclusion = JsonTypeInfo.As.PROPERTY; + typeInfo = typeInfo.withInclusionType(JsonTypeInfo.As.PROPERTY); } - b = b.inclusion(inclusion); - b = b.typeProperty(info.property()); - Class defaultImpl = info.defaultImpl(); + Class defaultImpl = typeInfo.getDefaultImpl(); // 08-Dec-2014, tatu: To deprecate `JsonTypeInfo.None` we need to use other placeholder(s); // and since `java.util.Void` has other purpose (to indicate "deser as null"), we'll instead // use `JsonTypeInfo.class` itself. But any annotation type will actually do, as they have no // valid use (cannot instantiate as default) - if (defaultImpl != JsonTypeInfo.None.class && !defaultImpl.isAnnotation()) { - b = b.defaultImpl(defaultImpl); + if (defaultImpl != null && defaultImpl != JsonTypeInfo.None.class && !defaultImpl.isAnnotation()) { + typeInfo = typeInfo.withDefaultImpl(defaultImpl); } - b = b.typeIdVisibility(info.visible()); + + b = b.init(typeInfo, idRes); return b; } @@ -1568,6 +1568,17 @@ protected StdTypeResolverBuilder _constructStdTypeResolverBuilder() { return new StdTypeResolverBuilder(); } + /** + * Helper method for constructing standard {@link TypeResolverBuilder} + * implementation. + * + * @since 2.16 (backported from Jackson 3.0) + */ + protected TypeResolverBuilder _constructStdTypeResolverBuilder(MapperConfig config, + JsonTypeInfo.Value typeInfo, JavaType baseType) { + return new StdTypeResolverBuilder(typeInfo); + } + /** * Helper method for dealing with "no type info" marker; can't be null * (as it'd be replaced by default typing) 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 df9c66ed21..32da2e1795 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 @@ -1,5 +1,6 @@ package com.fasterxml.jackson.databind.jsontype.impl; +import com.fasterxml.jackson.databind.introspect.Annotated; import java.util.Collection; import com.fasterxml.jackson.annotation.JsonTypeInfo; @@ -35,6 +36,11 @@ public class StdTypeResolverBuilder */ protected boolean _typeIdVisible = false; + /** + * @since 2.16 (backported from Jackson 3.0) + */ + protected Boolean _requireTypeIdForSubtypes; + /** * Default class to use in case type information is not available * or is broken. @@ -78,6 +84,7 @@ protected StdTypeResolverBuilder(StdTypeResolverBuilder base, _customIdResolver = base._customIdResolver; _defaultImpl = defaultImpl; + _requireTypeIdForSubtypes = base._requireTypeIdForSubtypes; } /** @@ -92,6 +99,8 @@ public StdTypeResolverBuilder(JsonTypeInfo.Value settings) { _includeAs = settings.getInclusionType(); _typeProperty = _propName(settings.getPropertyName(), _idType); _defaultImpl = settings.getDefaultImpl(); + _typeIdVisible = settings.getIdVisible(); + _requireTypeIdForSubtypes = settings.getRequireTypeIdForSubtypes(); } } @@ -106,7 +115,9 @@ protected static String _propName(String propName, JsonTypeInfo.Id idType) { } public static StdTypeResolverBuilder noTypeInfoBuilder() { - return new StdTypeResolverBuilder().init(JsonTypeInfo.Id.NONE, null); + JsonTypeInfo.Value typeInfo = JsonTypeInfo.Value.construct(JsonTypeInfo.Id.NONE, null, + null, null, false, null); + return new StdTypeResolverBuilder().init(typeInfo, null); } @Override @@ -123,9 +134,6 @@ public StdTypeResolverBuilder init(JsonTypeInfo.Id idType, TypeIdResolver idRes) return this; } - /** - * @since 2.16 (backported from Jackson 3.0) - */ @Override public StdTypeResolverBuilder init(JsonTypeInfo.Value settings, TypeIdResolver idRes) @@ -146,6 +154,7 @@ public StdTypeResolverBuilder init(JsonTypeInfo.Value settings, } _typeIdVisible = settings.getIdVisible(); _defaultImpl = settings.getDefaultImpl(); + _requireTypeIdForSubtypes = settings.getRequireTypeIdForSubtypes(); } return this; } @@ -488,11 +497,11 @@ protected boolean _strictTypeIdHandling(DeserializationConfig config, JavaType b * * @return true if the class has type resolver annotations, false otherwise * - * @since 2.15 + * @since 2.15, using {@code ai.findPolymorphicTypeInfo(config, ac)} since 2.16. */ protected boolean _hasTypeResolver(DeserializationConfig config, JavaType baseType) { AnnotatedClass ac = AnnotatedClassResolver.resolveWithoutSuperTypes(config, baseType.getRawClass()); AnnotationIntrospector ai = config.getAnnotationIntrospector(); - return ai.findTypeResolver(config, ac, baseType) != null; + return ai.findPolymorphicTypeInfo(config, ac) != null; } }