From 9038a7965375a8ddb160031572eb8926aa4c2fdd Mon Sep 17 00:00:00 2001 From: joohyukkim Date: Thu, 3 Aug 2023 00:30:40 +0900 Subject: [PATCH 1/8] Implement with basic test --- .../impl/SimpleClassNameIdResolver.java | 194 ++++++++++++++++++ .../jsontype/impl/StdTypeResolverBuilder.java | 2 + .../JsonTypeInfoSimpleClassName4061Test.java | 145 +++++++++++++ 3 files changed, 341 insertions(+) create mode 100644 src/main/java/com/fasterxml/jackson/databind/jsontype/impl/SimpleClassNameIdResolver.java create mode 100644 src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061Test.java diff --git a/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/SimpleClassNameIdResolver.java b/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/SimpleClassNameIdResolver.java new file mode 100644 index 0000000000..e7852d9ae1 --- /dev/null +++ b/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/SimpleClassNameIdResolver.java @@ -0,0 +1,194 @@ +package com.fasterxml.jackson.databind.jsontype.impl; + +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.databind.BeanDescription; +import com.fasterxml.jackson.databind.DatabindContext; +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.cfg.MapperConfig; +import com.fasterxml.jackson.databind.jsontype.NamedType; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.TreeSet; +import java.util.concurrent.ConcurrentHashMap; + +/** + * {@link com.fasterxml.jackson.databind.jsontype.TypeIdResolver} implementation + * that converts between (JSON) Strings and simple Java class names via {@link Class#getSimpleName()}. + *

+ * Note that this implementation is identical to {@link TypeNameIdResolver} except that instead of + * {@link TypeNameIdResolver#_defaultTypeId(Class)}, this implementation uses {@link Class#getSimpleName()}. + * + * @since 2.16 + */ +public class SimpleClassNameIdResolver + extends TypeIdResolverBase +{ + protected final MapperConfig _config; + + /** + * Mappings from class name to type id, used for serialization. + *

+ * Since lazily constructed will require synchronization (either internal + * by type, or external) + */ + protected final ConcurrentHashMap _typeToId; + + /** + * Mappings from type id to JavaType, used for deserialization. + *

+ * Eagerly constructed, not modified, can use regular unsynchronized {@link Map}. + */ + protected final Map _idToType; + + /** + * @since 2.11 + */ + protected final boolean _caseInsensitive; + + protected SimpleClassNameIdResolver(MapperConfig config, JavaType baseType, + ConcurrentHashMap typeToId, + HashMap idToType) + { + super(baseType, config.getTypeFactory()); + _config = config; + _typeToId = typeToId; + _idToType = idToType; + _caseInsensitive = config.isEnabled(MapperFeature.ACCEPT_CASE_INSENSITIVE_VALUES); + } + + public static SimpleClassNameIdResolver construct(MapperConfig config, JavaType baseType, + Collection subtypes, boolean forSer, boolean forDeser) + { + // sanity check + if (forSer == forDeser) throw new IllegalArgumentException(); + + final ConcurrentHashMap typeToId; + final HashMap idToType; + + if (forSer) { + // Only need Class-to-id for serialization; but synchronized since may be + // lazily built (if adding type-id-mappings dynamically) + typeToId = new ConcurrentHashMap<>(); + idToType = null; + } else { + idToType = new HashMap<>(); + // 14-Apr-2016, tatu: Apparently needed for special case of `defaultImpl`; + // see [databind#1198] for details: but essentially we only need room + // for a single value. + typeToId = new ConcurrentHashMap<>(4); + } + final boolean caseInsensitive = config.isEnabled(MapperFeature.ACCEPT_CASE_INSENSITIVE_VALUES); + + if (subtypes != null) { + for (NamedType t : subtypes) { + // no name? Need to figure out default; for now, let's just + // use non-qualified class name + Class cls = t.getType(); + String id = t.hasName() ? t.getName() : cls.getSimpleName(); // not {@code _defaultTypeId(cls);} + if (forSer) { + typeToId.put(cls.getName(), id); + } + if (forDeser) { + // [databind#1983]: for case-insensitive lookups must canonicalize: + if (caseInsensitive) { + id = id.toLowerCase(); + } + // One more problem; sometimes we have same name for multiple types; + // if so, use most specific + JavaType prev = idToType.get(id); // lgtm [java/dereferenced-value-may-be-null] + if (prev != null) { // Can only override if more specific + if (cls.isAssignableFrom(prev.getRawClass())) { // nope, more generic (or same) + continue; + } + } + idToType.put(id, config.constructType(cls)); + } + } + } + return new SimpleClassNameIdResolver(config, baseType, typeToId, idToType); + } + + @Override + public JsonTypeInfo.Id getMechanism() { return JsonTypeInfo.Id.SIMPLE_CLASS_NAME; } + + @Override + public String idFromValue(Object value) { + return idFromClass(value.getClass()); + } + + protected String idFromClass(Class clazz) + { + if (clazz == null) { + return null; + } + // NOTE: although we may need to let `TypeModifier` change actual type to use + // for id, we can use original type as key for more efficient lookup: + final String key = clazz.getName(); + String name = _typeToId.get(key); + + if (name == null) { + // 29-Nov-2019, tatu: As per test in `TestTypeModifierNameResolution` somehow + // we need to do this odd piece here which seems unnecessary but isn't. + Class cls = _typeFactory.constructType(clazz).getRawClass(); + // 24-Feb-2011, tatu: As per [JACKSON-498], may need to dynamically look up name + // can either throw an exception, or use default name... + if (_config.isAnnotationProcessingEnabled()) { + BeanDescription beanDesc = _config.introspectClassAnnotations(cls); + name = _config.getAnnotationIntrospector().findTypeName(beanDesc.getClassInfo()); + } + if (name == null) { + // And if still not found, let's choose default? + name = cls.getSimpleName(); + } + _typeToId.put(key, name); + } + return name; + } + + @Override + public String idFromValueAndType(Object value, Class type) { + // 18-Jan-2013, tatu: We may be called with null value occasionally + // it seems; nothing much we can figure out that way. + if (value == null) { + return idFromClass(type); + } + return idFromValue(value); + } + + @Override + public JavaType typeFromId(DatabindContext context, String id) { + return _typeFromId(id); + } + + protected JavaType _typeFromId(String id) { + // [databind#1983]: for case-insensitive lookups must canonicalize: + if (_caseInsensitive) { + id = id.toLowerCase(); + } + // Now: if no type is found, should we try to locate it by + // some other means? (specifically, if in same package as base type, + // could just try Class.forName) + // For now let's not add any such workarounds; can add if need be + return _idToType.get(id); + } + + @Override + public String getDescForKnownTypeIds() { + // 05-May-2020, tatu: As per [databind#1919], only include ids for + // non-abstract types + final TreeSet ids = new TreeSet<>(); + for (Map.Entry entry : _idToType.entrySet()) { + if (entry.getValue().isConcrete()) { + ids.add(entry.getKey()); + } + } + return ids.toString(); + } + + @Override + public String toString() { + return String.format("[%s; id-to-type=%s]", getClass().getName(), _idToType); + } +} 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 43580d0ec4..569359c0dd 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 @@ -368,6 +368,8 @@ protected TypeIdResolver idResolver(MapperConfig config, return ClassNameIdResolver.construct(baseType, config, subtypeValidator); case MINIMAL_CLASS: return MinimalClassNameIdResolver.construct(baseType, config, subtypeValidator); + case SIMPLE_CLASS_NAME: + return SimpleClassNameIdResolver.construct(config, baseType, subtypes, forSer, forDeser); case NAME: return TypeNameIdResolver.construct(config, baseType, subtypes, forSer, forDeser); case NONE: // hmmh. should never get this far with 'none' diff --git a/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061Test.java b/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061Test.java new file mode 100644 index 0000000000..25175cb409 --- /dev/null +++ b/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061Test.java @@ -0,0 +1,145 @@ +package com.fasterxml.jackson.databind.jsontype; + +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.databind.BaseMapTest; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * Test for + * [databind#4061] Add JsonTypeInfo.Id.SIMPLE_NAME using Class::getSimpleName + */ + +public class JsonTypeInfoSimpleClassName4061Test extends BaseMapTest { + + @JsonTypeInfo( + use = JsonTypeInfo.Id.SIMPLE_CLASS_NAME) + @JsonSubTypes({ + @JsonSubTypes.Type(value = InnerSub4061A.class), + @JsonSubTypes.Type(value = InnerSub4061B.class) + }) + static class InnerSuper4061 { } + + static class InnerSub4061A extends InnerSuper4061 { } + + static class InnerSub4061B extends InnerSuper4061 { } + + @JsonTypeInfo( + use = JsonTypeInfo.Id.MINIMAL_CLASS) + @JsonSubTypes({ + @JsonSubTypes.Type(value = MinimalInnerSub4061A.class), + @JsonSubTypes.Type(value = MinimalInnerSub4061B.class) + }) + static class MinimalInnerSuper4061 { } + + static class MinimalInnerSub4061A extends MinimalInnerSuper4061 { } + + static class MinimalInnerSub4061B extends MinimalInnerSuper4061 { } + + @JsonTypeInfo( + use = JsonTypeInfo.Id.SIMPLE_CLASS_NAME) + @JsonSubTypes({ + @JsonSubTypes.Type(value = MixedSub4061A.class), + @JsonSubTypes.Type(value = MixedSub4061B.class) + }) + static class MixedSuper4061 { } + + @JsonTypeInfo( + use = JsonTypeInfo.Id.MINIMAL_CLASS) + @JsonSubTypes({ + @JsonSubTypes.Type(value = MixedMinimalSub4061A.class), + @JsonSubTypes.Type(value = MixedMinimalSub4061B.class) + }) + static class MixedMinimalSuper4061 { } + + private final ObjectMapper MAPPER = newJsonMapper(); + + // inner class that has contains dollar sign + public void testInnerClass() throws Exception + { + // ser + assertEquals( + a2q("{'@simpl':'InnerSub4061A'}"), + MAPPER.writeValueAsString(new InnerSub4061A())); + + // deser <- breaks! + InnerSuper4061 bean = MAPPER.readValue(a2q("{'@simpl':'InnerSub4061B'}"), InnerSuper4061.class); + assertType(bean, InnerSuper4061.class); + } + + // inner class that has contains dollar sign + public void testMinimalInnerClass() throws Exception + { + // ser + assertEquals( + a2q("{'@c':'.JsonTypeInfoSimpleClassName4061Test$MinimalInnerSub4061A'}"), + MAPPER.writeValueAsString(new MinimalInnerSub4061A())); + + // deser <- breaks! + MinimalInnerSuper4061 bean = MAPPER.readValue(a2q("{'@c':'.JsonTypeInfoSimpleClassName4061Test$MinimalInnerSub4061A'}"), MinimalInnerSuper4061.class); + assertType(bean, MinimalInnerSuper4061.class); + } + + // Basic : non-inner class, without dollar sign + public void testBasicClass() throws Exception + { + // ser + assertEquals( + a2q("{'@simpl':'BasicSub4061A'}"), + MAPPER.writeValueAsString(new BasicSub4061A())); + + // deser + BasicSuper4061 bean = MAPPER.readValue(a2q("{'@simpl':'BasicSub4061B'}"), BasicSuper4061.class); + assertType(bean, BasicSuper4061.class); + assertType(bean, BasicSub4061B.class); + } + + // Mixed : parent as inner, subtype as basic + public void testMixedClass() throws Exception + { + // ser + assertEquals( + a2q("{'@simpl':'MixedSub4061A'}"), + MAPPER.writeValueAsString(new MixedSub4061A())); + + // deser + MixedSuper4061 bean = MAPPER.readValue(a2q("{'@simpl':'MixedSub4061B'}"), MixedSuper4061.class); + assertType(bean, MixedSuper4061.class); + assertType(bean, MixedSub4061B.class); + } + // Mixed : parent as inner, subtype as basic + public void testMixedMinimalClass() throws Exception + { + // ser + assertEquals( + a2q("{'@c':'.MixedMinimalSub4061A'}"), + MAPPER.writeValueAsString(new MixedMinimalSub4061A())); + + // deser + MixedMinimalSuper4061 bean = MAPPER.readValue(a2q("{'@c':'.MixedMinimalSub4061B'}"), MixedMinimalSuper4061.class); + assertType(bean, MixedMinimalSuper4061.class); + assertType(bean, MixedMinimalSub4061B.class); + } +} + +@JsonTypeInfo( + use = JsonTypeInfo.Id.SIMPLE_CLASS_NAME) +@JsonSubTypes({ + @JsonSubTypes.Type(value = BasicSub4061A.class), + @JsonSubTypes.Type(value = BasicSub4061B.class) +}) +class BasicSuper4061 { } + +class BasicSub4061A extends BasicSuper4061 { } + +class BasicSub4061B extends BasicSuper4061 { } + +class MixedSub4061A extends JsonTypeInfoSimpleClassName4061Test.MixedSuper4061 { } + +class MixedSub4061B extends JsonTypeInfoSimpleClassName4061Test.MixedSuper4061 { } + +class MixedMinimalSub4061A extends JsonTypeInfoSimpleClassName4061Test.MixedMinimalSuper4061 { } + +class MixedMinimalSub4061B extends JsonTypeInfoSimpleClassName4061Test.MixedMinimalSuper4061 { } + + From 38f495205f7e3313b2455e15c47e6afe77deff45 Mon Sep 17 00:00:00 2001 From: joohyukkim Date: Thu, 3 Aug 2023 21:01:32 +0900 Subject: [PATCH 2/8] Update JsonTypeInfoSimpleClassName4061Test.java --- .../JsonTypeInfoSimpleClassName4061Test.java | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061Test.java b/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061Test.java index 25175cb409..a3195c6ce0 100644 --- a/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061Test.java +++ b/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061Test.java @@ -10,7 +10,8 @@ * [databind#4061] Add JsonTypeInfo.Id.SIMPLE_NAME using Class::getSimpleName */ -public class JsonTypeInfoSimpleClassName4061Test extends BaseMapTest { +public class JsonTypeInfoSimpleClassName4061Test extends BaseMapTest +{ @JsonTypeInfo( use = JsonTypeInfo.Id.SIMPLE_CLASS_NAME) @@ -52,6 +53,12 @@ static class MixedSuper4061 { } }) static class MixedMinimalSuper4061 { } + /* + /********************************************************** + /* Unit tests + /********************************************************** + */ + private final ObjectMapper MAPPER = newJsonMapper(); // inner class that has contains dollar sign @@ -94,7 +101,7 @@ public void testBasicClass() throws Exception assertType(bean, BasicSub4061B.class); } - // Mixed : parent as inner, subtype as basic + // Mixed SimpleClassName : parent as inner, subtype as basic public void testMixedClass() throws Exception { // ser @@ -107,7 +114,8 @@ public void testMixedClass() throws Exception assertType(bean, MixedSuper4061.class); assertType(bean, MixedSub4061B.class); } - // Mixed : parent as inner, subtype as basic + + // Mixed MinimalClass : parent as inner, subtype as basic public void testMixedMinimalClass() throws Exception { // ser @@ -141,5 +149,3 @@ class MixedSub4061B extends JsonTypeInfoSimpleClassName4061Test.MixedSuper4061 { class MixedMinimalSub4061A extends JsonTypeInfoSimpleClassName4061Test.MixedMinimalSuper4061 { } class MixedMinimalSub4061B extends JsonTypeInfoSimpleClassName4061Test.MixedMinimalSuper4061 { } - - From ebe04f5aa2493c86305cef138b0abde00ecc40bc Mon Sep 17 00:00:00 2001 From: joohyukkim Date: Thu, 3 Aug 2023 22:18:43 +0900 Subject: [PATCH 3/8] `SimpleNameIdResolver` and `_defaultTypeId(cls);` --- ...esolver.java => SimpleNameIdResolver.java} | 37 ++++++++++++------- .../jsontype/impl/StdTypeResolverBuilder.java | 4 +- .../JsonTypeInfoSimpleClassName4061Test.java | 6 +-- 3 files changed, 29 insertions(+), 18 deletions(-) rename src/main/java/com/fasterxml/jackson/databind/jsontype/impl/{SimpleClassNameIdResolver.java => SimpleNameIdResolver.java} (88%) diff --git a/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/SimpleClassNameIdResolver.java b/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/SimpleNameIdResolver.java similarity index 88% rename from src/main/java/com/fasterxml/jackson/databind/jsontype/impl/SimpleClassNameIdResolver.java rename to src/main/java/com/fasterxml/jackson/databind/jsontype/impl/SimpleNameIdResolver.java index e7852d9ae1..88c2a8f3fd 100644 --- a/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/SimpleClassNameIdResolver.java +++ b/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/SimpleNameIdResolver.java @@ -16,13 +16,10 @@ /** * {@link com.fasterxml.jackson.databind.jsontype.TypeIdResolver} implementation * that converts between (JSON) Strings and simple Java class names via {@link Class#getSimpleName()}. - *

- * Note that this implementation is identical to {@link TypeNameIdResolver} except that instead of - * {@link TypeNameIdResolver#_defaultTypeId(Class)}, this implementation uses {@link Class#getSimpleName()}. * * @since 2.16 */ -public class SimpleClassNameIdResolver +public class SimpleNameIdResolver extends TypeIdResolverBase { protected final MapperConfig _config; @@ -42,12 +39,9 @@ public class SimpleClassNameIdResolver */ protected final Map _idToType; - /** - * @since 2.11 - */ protected final boolean _caseInsensitive; - protected SimpleClassNameIdResolver(MapperConfig config, JavaType baseType, + protected SimpleNameIdResolver(MapperConfig config, JavaType baseType, ConcurrentHashMap typeToId, HashMap idToType) { @@ -58,7 +52,7 @@ protected SimpleClassNameIdResolver(MapperConfig config, JavaType baseType, _caseInsensitive = config.isEnabled(MapperFeature.ACCEPT_CASE_INSENSITIVE_VALUES); } - public static SimpleClassNameIdResolver construct(MapperConfig config, JavaType baseType, + public static SimpleNameIdResolver construct(MapperConfig config, JavaType baseType, Collection subtypes, boolean forSer, boolean forDeser) { // sanity check @@ -86,7 +80,7 @@ public static SimpleClassNameIdResolver construct(MapperConfig config, JavaTy // no name? Need to figure out default; for now, let's just // use non-qualified class name Class cls = t.getType(); - String id = t.hasName() ? t.getName() : cls.getSimpleName(); // not {@code _defaultTypeId(cls);} + String id = t.hasName() ? t.getName() : _defaultTypeId(cls); if (forSer) { typeToId.put(cls.getName(), id); } @@ -107,11 +101,11 @@ public static SimpleClassNameIdResolver construct(MapperConfig config, JavaTy } } } - return new SimpleClassNameIdResolver(config, baseType, typeToId, idToType); + return new SimpleNameIdResolver(config, baseType, typeToId, idToType); } @Override - public JsonTypeInfo.Id getMechanism() { return JsonTypeInfo.Id.SIMPLE_CLASS_NAME; } + public JsonTypeInfo.Id getMechanism() { return JsonTypeInfo.Id.SIMPLE_NAME; } @Override public String idFromValue(Object value) { @@ -140,7 +134,7 @@ protected String idFromClass(Class clazz) } if (name == null) { // And if still not found, let's choose default? - name = cls.getSimpleName(); + name = _defaultTypeId(cls); } _typeToId.put(key, name); } @@ -191,4 +185,21 @@ public String getDescForKnownTypeIds() { public String toString() { return String.format("[%s; id-to-type=%s]", getClass().getName(), _idToType); } + + /* + /********************************************************* + /* Helper methods + /********************************************************* + */ + + /** + * If no name was explicitly given for a class, we will just + * use simple class name + */ + protected static String _defaultTypeId(Class cls) + { + String n = cls.getName(); + int ix = Math.max(n.lastIndexOf('.'), n.lastIndexOf('$')); + return (ix < 0) ? n : n.substring(ix+1); + } } 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 569359c0dd..ed6ff31fd9 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 @@ -368,8 +368,8 @@ protected TypeIdResolver idResolver(MapperConfig config, return ClassNameIdResolver.construct(baseType, config, subtypeValidator); case MINIMAL_CLASS: return MinimalClassNameIdResolver.construct(baseType, config, subtypeValidator); - case SIMPLE_CLASS_NAME: - return SimpleClassNameIdResolver.construct(config, baseType, subtypes, forSer, forDeser); + case SIMPLE_NAME: + return SimpleNameIdResolver.construct(config, baseType, subtypes, forSer, forDeser); case NAME: return TypeNameIdResolver.construct(config, baseType, subtypes, forSer, forDeser); case NONE: // hmmh. should never get this far with 'none' diff --git a/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061Test.java b/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061Test.java index a3195c6ce0..95bd7c5d49 100644 --- a/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061Test.java +++ b/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061Test.java @@ -14,7 +14,7 @@ public class JsonTypeInfoSimpleClassName4061Test extends BaseMapTest { @JsonTypeInfo( - use = JsonTypeInfo.Id.SIMPLE_CLASS_NAME) + use = JsonTypeInfo.Id.SIMPLE_NAME) @JsonSubTypes({ @JsonSubTypes.Type(value = InnerSub4061A.class), @JsonSubTypes.Type(value = InnerSub4061B.class) @@ -38,7 +38,7 @@ static class MinimalInnerSub4061A extends MinimalInnerSuper4061 { } static class MinimalInnerSub4061B extends MinimalInnerSuper4061 { } @JsonTypeInfo( - use = JsonTypeInfo.Id.SIMPLE_CLASS_NAME) + use = JsonTypeInfo.Id.SIMPLE_NAME) @JsonSubTypes({ @JsonSubTypes.Type(value = MixedSub4061A.class), @JsonSubTypes.Type(value = MixedSub4061B.class) @@ -131,7 +131,7 @@ public void testMixedMinimalClass() throws Exception } @JsonTypeInfo( - use = JsonTypeInfo.Id.SIMPLE_CLASS_NAME) + use = JsonTypeInfo.Id.SIMPLE_NAME) @JsonSubTypes({ @JsonSubTypes.Type(value = BasicSub4061A.class), @JsonSubTypes.Type(value = BasicSub4061B.class) From 22bdd8f1485a0fb197e1f8757e1f4fdf6fe77862 Mon Sep 17 00:00:00 2001 From: joohyukkim Date: Thu, 3 Aug 2023 23:33:20 +0900 Subject: [PATCH 4/8] Add more test cases --- .../JsonTypeInfoSimpleClassName4061Test.java | 197 +++++++++++++++--- ...eInfoSimpleClassName4061TestContainer.java | 12 ++ 2 files changed, 180 insertions(+), 29 deletions(-) create mode 100644 src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061TestContainer.java diff --git a/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061Test.java b/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061Test.java index 95bd7c5d49..429a94bf0e 100644 --- a/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061Test.java +++ b/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061Test.java @@ -1,9 +1,20 @@ package com.fasterxml.jackson.databind.jsontype; +import com.fasterxml.jackson.annotation.JsonAlias; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonMerge; +import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.databind.BaseMapTest; +import com.fasterxml.jackson.databind.DeserializationConfig; +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.MapperFeature; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.exc.InvalidTypeIdException; +import com.fasterxml.jackson.databind.jsontype.impl.SimpleNameIdResolver; +import java.util.ArrayList; +import java.util.List; /** * Test for @@ -52,7 +63,67 @@ static class MixedSuper4061 { } @JsonSubTypes.Type(value = MixedMinimalSub4061B.class) }) static class MixedMinimalSuper4061 { } + + static class Root { + @JsonMerge + public MergeChild child; + } + + @JsonTypeInfo(use = JsonTypeInfo.Id.SIMPLE_NAME) + @JsonSubTypes({ + @JsonSubTypes.Type(value = MergeChildA.class, name = "MergeChildA"), + @JsonSubTypes.Type(value = MergeChildB.class, name = "MergeChildB") + }) + static abstract class MergeChild { + } + + static class MergeChildA extends MergeChild { + public String name; + } + + static class MergeChildB extends MergeChild { + public String code; + } + + static class PolyWrapperForAlias { + @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.WRAPPER_ARRAY) + @JsonSubTypes({ + @JsonSubTypes.Type(value = AliasBean.class,name = "ab")}) + public Object value; + + protected PolyWrapperForAlias() { } + + public PolyWrapperForAlias(Object v) { value = v; } + } + + static class AliasBean { + @JsonAlias({ "nm", "Name" }) + public String name; + int _xyz; + int _a; + + @JsonCreator + public AliasBean(@JsonProperty("a") @JsonAlias("A") int a) { + _a = a; + } + + @JsonAlias({ "Xyz" }) + public void setXyz(int x) { + _xyz = x; + } + } + + @JsonTypeInfo( + use = JsonTypeInfo.Id.SIMPLE_NAME) + @JsonSubTypes({ + @JsonSubTypes.Type(value = DuplicateSubClass.class), + @JsonSubTypes.Type(value = JsonTypeInfoSimpleClassName4061TestContainer.DuplicateSubClass.class) + }) + static class DuplicateSuperClass { } + static class DuplicateSubClass extends DuplicateSuperClass { } + /* /********************************************************** /* Unit tests @@ -64,70 +135,138 @@ static class MixedMinimalSuper4061 { } // inner class that has contains dollar sign public void testInnerClass() throws Exception { + String jsonStr = a2q("{'@simpl':'InnerSub4061A'}"); + // ser - assertEquals( - a2q("{'@simpl':'InnerSub4061A'}"), - MAPPER.writeValueAsString(new InnerSub4061A())); - + assertEquals(jsonStr, MAPPER.writeValueAsString(new InnerSub4061A())); + // deser <- breaks! - InnerSuper4061 bean = MAPPER.readValue(a2q("{'@simpl':'InnerSub4061B'}"), InnerSuper4061.class); + InnerSuper4061 bean = MAPPER.readValue(jsonStr, InnerSuper4061.class); assertType(bean, InnerSuper4061.class); } // inner class that has contains dollar sign public void testMinimalInnerClass() throws Exception { + String jsonStr = a2q("{'@c':'.JsonTypeInfoSimpleClassName4061Test$MinimalInnerSub4061A'}"); + // ser - assertEquals( - a2q("{'@c':'.JsonTypeInfoSimpleClassName4061Test$MinimalInnerSub4061A'}"), - MAPPER.writeValueAsString(new MinimalInnerSub4061A())); - + assertEquals(jsonStr, MAPPER.writeValueAsString(new MinimalInnerSub4061A())); + // deser <- breaks! - MinimalInnerSuper4061 bean = MAPPER.readValue(a2q("{'@c':'.JsonTypeInfoSimpleClassName4061Test$MinimalInnerSub4061A'}"), MinimalInnerSuper4061.class); + MinimalInnerSuper4061 bean = MAPPER.readValue(jsonStr, MinimalInnerSuper4061.class); assertType(bean, MinimalInnerSuper4061.class); + assertNotNull(bean); } // Basic : non-inner class, without dollar sign public void testBasicClass() throws Exception { + String jsonStr = a2q("{'@simpl':'BasicSub4061A'}"); + // ser - assertEquals( - a2q("{'@simpl':'BasicSub4061A'}"), - MAPPER.writeValueAsString(new BasicSub4061A())); - + assertEquals(jsonStr, MAPPER.writeValueAsString(new BasicSub4061A())); + // deser - BasicSuper4061 bean = MAPPER.readValue(a2q("{'@simpl':'BasicSub4061B'}"), BasicSuper4061.class); + BasicSuper4061 bean = MAPPER.readValue(jsonStr, BasicSuper4061.class); assertType(bean, BasicSuper4061.class); - assertType(bean, BasicSub4061B.class); + assertType(bean, BasicSub4061A.class); } // Mixed SimpleClassName : parent as inner, subtype as basic public void testMixedClass() throws Exception { + String jsonStr = a2q("{'@simpl':'MixedSub4061A'}"); + // ser - assertEquals( - a2q("{'@simpl':'MixedSub4061A'}"), - MAPPER.writeValueAsString(new MixedSub4061A())); - + assertEquals(jsonStr, MAPPER.writeValueAsString(new MixedSub4061A())); + // deser - MixedSuper4061 bean = MAPPER.readValue(a2q("{'@simpl':'MixedSub4061B'}"), MixedSuper4061.class); + MixedSuper4061 bean = MAPPER.readValue(jsonStr, MixedSuper4061.class); assertType(bean, MixedSuper4061.class); - assertType(bean, MixedSub4061B.class); + assertType(bean, MixedSub4061A.class); } // Mixed MinimalClass : parent as inner, subtype as basic public void testMixedMinimalClass() throws Exception { + String jsonStr = a2q("{'@c':'.MixedMinimalSub4061A'}"); + // ser - assertEquals( - a2q("{'@c':'.MixedMinimalSub4061A'}"), - MAPPER.writeValueAsString(new MixedMinimalSub4061A())); - + assertEquals(jsonStr, MAPPER.writeValueAsString(new MixedMinimalSub4061A())); + // deser - MixedMinimalSuper4061 bean = MAPPER.readValue(a2q("{'@c':'.MixedMinimalSub4061B'}"), MixedMinimalSuper4061.class); + MixedMinimalSuper4061 bean = MAPPER.readValue(jsonStr, MixedMinimalSuper4061.class); assertType(bean, MixedMinimalSuper4061.class); - assertType(bean, MixedMinimalSub4061B.class); - } + assertType(bean, MixedMinimalSub4061A.class); + } + + public void testPolymorphicNewObject() throws Exception + { + String jsonStr = "{\"child\": { \"@simpl\": \"MergeChildA\", \"name\": \"I'm child A\" }}"; + + Root root = MAPPER.readValue(jsonStr, Root.class); + + assertTrue(root.child instanceof MergeChildA); + assertEquals("I'm child A", ((MergeChildA) root.child).name); + } + + // case insenstive type name + public void testPolymorphicNewObjectCaseInsensitive() throws Exception + { + String jsonStr = "{\"child\": { \"@simpl\": \"mergechilda\", \"name\": \"I'm child A\" }}"; + ObjectMapper mapper = jsonMapperBuilder() + .enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_VALUES) + .build(); + + Root root = mapper.readValue(jsonStr, Root.class); + + assertTrue(root.child instanceof MergeChildA); + assertEquals("I'm child A", ((MergeChildA) root.child).name); + } + + public void testPolymorphicNewObjectUnknownTypeId() throws Exception + { + try { + MAPPER.readValue("{\"child\": { \"@simpl\": \"UnknownChildA\", \"name\": \"I'm child A\" }}", Root.class); + } catch (InvalidTypeIdException e) { + verifyException(e, "Could not resolve type id 'UnknownChildA' as a subtype of"); + } + } + + public void testAliasWithPolymorphic() throws Exception + { + String jsonStr = a2q("{'value': ['ab', {'nm' : 'Bob', 'A' : 17} ] }"); + + PolyWrapperForAlias value = MAPPER.readValue(jsonStr, PolyWrapperForAlias.class); + + assertNotNull(value.value); + AliasBean bean = (AliasBean) value.value; + assertEquals("Bob", bean.name); + assertEquals(17, bean._a); + } + + public void testGetMechanism() + { + final DeserializationConfig config = MAPPER.getDeserializationConfig(); + JavaType javaType = config.constructType(InnerSub4061B.class); + List namedTypes = new ArrayList<>(); + namedTypes.add(new NamedType(InnerSub4061A.class)); + namedTypes.add(new NamedType(InnerSub4061B.class)); + + SimpleNameIdResolver idResolver = SimpleNameIdResolver.construct(config, javaType, namedTypes, false, true); + + assertEquals(JsonTypeInfo.Id.SIMPLE_NAME, idResolver.getMechanism()); + } + + public void testSameSimpleNameClass() throws Exception + { + String jsonStr = a2q("{'@simpl':'DuplicateSubClass'}"); + + // deser + DuplicateSuperClass bean = MAPPER.readValue(jsonStr, DuplicateSuperClass.class); + assertType(bean, JsonTypeInfoSimpleClassName4061TestContainer.DuplicateSubClass.class); + } } @JsonTypeInfo( diff --git a/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061TestContainer.java b/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061TestContainer.java new file mode 100644 index 0000000000..0a8df3382e --- /dev/null +++ b/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061TestContainer.java @@ -0,0 +1,12 @@ +package com.fasterxml.jackson.databind.jsontype; + +import com.fasterxml.jackson.databind.BaseMapTest; + +/** + * Test utility for {@link JsonTypeInfoSimpleClassName4061Test} + */ + +public class JsonTypeInfoSimpleClassName4061TestContainer extends BaseMapTest +{ + static class DuplicateSubClass extends JsonTypeInfoSimpleClassName4061Test.DuplicateSuperClass { } +} From 6cf8ad0c82c46069cc1e6823df4ad2ac1632ca77 Mon Sep 17 00:00:00 2001 From: joohyukkim Date: Thu, 3 Aug 2023 23:51:38 +0900 Subject: [PATCH 5/8] Add JavaDoc --- .../jsontype/JsonTypeInfoSimpleClassName4061Test.java | 5 +++-- .../JsonTypeInfoSimpleClassName4061TestContainer.java | 8 ++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061Test.java b/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061Test.java index 429a94bf0e..ab16cfc019 100644 --- a/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061Test.java +++ b/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061Test.java @@ -19,8 +19,9 @@ /** * Test for * [databind#4061] Add JsonTypeInfo.Id.SIMPLE_NAME using Class::getSimpleName + * + * @since 2.16 */ - public class JsonTypeInfoSimpleClassName4061Test extends BaseMapTest { @@ -259,7 +260,7 @@ public void testGetMechanism() assertEquals(JsonTypeInfo.Id.SIMPLE_NAME, idResolver.getMechanism()); } - public void testSameSimpleNameClass() throws Exception + public void testDuplicateNameLastOneWins() throws Exception { String jsonStr = a2q("{'@simpl':'DuplicateSubClass'}"); diff --git a/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061TestContainer.java b/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061TestContainer.java index 0a8df3382e..7e3ea699d8 100644 --- a/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061TestContainer.java +++ b/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061TestContainer.java @@ -3,10 +3,14 @@ import com.fasterxml.jackson.databind.BaseMapTest; /** - * Test utility for {@link JsonTypeInfoSimpleClassName4061Test} + * Test utility for {@link JsonTypeInfoSimpleClassName4061Test#testDuplicateNameLastOneWins()}. + * + * @since 2.16 */ - public class JsonTypeInfoSimpleClassName4061TestContainer extends BaseMapTest { + /** + * Class that matches {@link JsonTypeInfoSimpleClassName4061Test.DuplicateSubClass} with same name. + */ static class DuplicateSubClass extends JsonTypeInfoSimpleClassName4061Test.DuplicateSuperClass { } } From eae086edcda1cfadd778d910303f3e0921cf47b7 Mon Sep 17 00:00:00 2001 From: joohyukkim Date: Fri, 4 Aug 2023 13:08:07 +0900 Subject: [PATCH 6/8] Update JsonTypeInfoSimpleClassName4061Test.java --- .../JsonTypeInfoSimpleClassName4061Test.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061Test.java b/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061Test.java index ab16cfc019..2c44ca9f75 100644 --- a/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061Test.java +++ b/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061Test.java @@ -136,7 +136,7 @@ static class DuplicateSubClass extends DuplicateSuperClass { } // inner class that has contains dollar sign public void testInnerClass() throws Exception { - String jsonStr = a2q("{'@simpl':'InnerSub4061A'}"); + String jsonStr = a2q("{'@type':'InnerSub4061A'}"); // ser assertEquals(jsonStr, MAPPER.writeValueAsString(new InnerSub4061A())); @@ -163,7 +163,7 @@ public void testMinimalInnerClass() throws Exception // Basic : non-inner class, without dollar sign public void testBasicClass() throws Exception { - String jsonStr = a2q("{'@simpl':'BasicSub4061A'}"); + String jsonStr = a2q("{'@type':'BasicSub4061A'}"); // ser assertEquals(jsonStr, MAPPER.writeValueAsString(new BasicSub4061A())); @@ -177,7 +177,7 @@ public void testBasicClass() throws Exception // Mixed SimpleClassName : parent as inner, subtype as basic public void testMixedClass() throws Exception { - String jsonStr = a2q("{'@simpl':'MixedSub4061A'}"); + String jsonStr = a2q("{'@type':'MixedSub4061A'}"); // ser assertEquals(jsonStr, MAPPER.writeValueAsString(new MixedSub4061A())); @@ -204,7 +204,7 @@ public void testMixedMinimalClass() throws Exception public void testPolymorphicNewObject() throws Exception { - String jsonStr = "{\"child\": { \"@simpl\": \"MergeChildA\", \"name\": \"I'm child A\" }}"; + String jsonStr = "{\"child\": { \"@type\": \"MergeChildA\", \"name\": \"I'm child A\" }}"; Root root = MAPPER.readValue(jsonStr, Root.class); @@ -215,7 +215,7 @@ public void testPolymorphicNewObject() throws Exception // case insenstive type name public void testPolymorphicNewObjectCaseInsensitive() throws Exception { - String jsonStr = "{\"child\": { \"@simpl\": \"mergechilda\", \"name\": \"I'm child A\" }}"; + String jsonStr = "{\"child\": { \"@type\": \"mergechilda\", \"name\": \"I'm child A\" }}"; ObjectMapper mapper = jsonMapperBuilder() .enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_VALUES) .build(); @@ -229,7 +229,7 @@ public void testPolymorphicNewObjectCaseInsensitive() throws Exception public void testPolymorphicNewObjectUnknownTypeId() throws Exception { try { - MAPPER.readValue("{\"child\": { \"@simpl\": \"UnknownChildA\", \"name\": \"I'm child A\" }}", Root.class); + MAPPER.readValue("{\"child\": { \"@type\": \"UnknownChildA\", \"name\": \"I'm child A\" }}", Root.class); } catch (InvalidTypeIdException e) { verifyException(e, "Could not resolve type id 'UnknownChildA' as a subtype of"); } @@ -262,7 +262,7 @@ public void testGetMechanism() public void testDuplicateNameLastOneWins() throws Exception { - String jsonStr = a2q("{'@simpl':'DuplicateSubClass'}"); + String jsonStr = a2q("{'@type':'DuplicateSubClass'}"); // deser DuplicateSuperClass bean = MAPPER.readValue(jsonStr, DuplicateSuperClass.class); From cd39a4b618dd1a905862319043026db482276a7d Mon Sep 17 00:00:00 2001 From: joohyukkim Date: Sat, 19 Aug 2023 14:30:58 +0900 Subject: [PATCH 7/8] Remove additional Test class container and move dup class to same main level --- .../JsonTypeInfoSimpleClassName4061Test.java | 13 +++++-------- ...TypeInfoSimpleClassName4061TestContainer.java | 16 ---------------- 2 files changed, 5 insertions(+), 24 deletions(-) delete mode 100644 src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061TestContainer.java diff --git a/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061Test.java b/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061Test.java index 2c44ca9f75..90c73bf665 100644 --- a/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061Test.java +++ b/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061Test.java @@ -1,11 +1,6 @@ package com.fasterxml.jackson.databind.jsontype; -import com.fasterxml.jackson.annotation.JsonAlias; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonMerge; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonSubTypes; -import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.*; import com.fasterxml.jackson.databind.BaseMapTest; import com.fasterxml.jackson.databind.DeserializationConfig; import com.fasterxml.jackson.databind.JavaType; @@ -119,7 +114,7 @@ public void setXyz(int x) { use = JsonTypeInfo.Id.SIMPLE_NAME) @JsonSubTypes({ @JsonSubTypes.Type(value = DuplicateSubClass.class), - @JsonSubTypes.Type(value = JsonTypeInfoSimpleClassName4061TestContainer.DuplicateSubClass.class) + @JsonSubTypes.Type(value = com.fasterxml.jackson.databind.jsontype.DuplicateSubClass.class) }) static class DuplicateSuperClass { } @@ -266,7 +261,7 @@ public void testDuplicateNameLastOneWins() throws Exception // deser DuplicateSuperClass bean = MAPPER.readValue(jsonStr, DuplicateSuperClass.class); - assertType(bean, JsonTypeInfoSimpleClassName4061TestContainer.DuplicateSubClass.class); + assertType(bean, com.fasterxml.jackson.databind.jsontype.DuplicateSubClass.class); } } @@ -289,3 +284,5 @@ class MixedSub4061B extends JsonTypeInfoSimpleClassName4061Test.MixedSuper4061 { class MixedMinimalSub4061A extends JsonTypeInfoSimpleClassName4061Test.MixedMinimalSuper4061 { } class MixedMinimalSub4061B extends JsonTypeInfoSimpleClassName4061Test.MixedMinimalSuper4061 { } + +class DuplicateSubClass extends JsonTypeInfoSimpleClassName4061Test.DuplicateSuperClass { } diff --git a/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061TestContainer.java b/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061TestContainer.java deleted file mode 100644 index 7e3ea699d8..0000000000 --- a/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061TestContainer.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.fasterxml.jackson.databind.jsontype; - -import com.fasterxml.jackson.databind.BaseMapTest; - -/** - * Test utility for {@link JsonTypeInfoSimpleClassName4061Test#testDuplicateNameLastOneWins()}. - * - * @since 2.16 - */ -public class JsonTypeInfoSimpleClassName4061TestContainer extends BaseMapTest -{ - /** - * Class that matches {@link JsonTypeInfoSimpleClassName4061Test.DuplicateSubClass} with same name. - */ - static class DuplicateSubClass extends JsonTypeInfoSimpleClassName4061Test.DuplicateSuperClass { } -} From 1e5e3cde1510576c276dd11b3565e4d8153f1e1c Mon Sep 17 00:00:00 2001 From: joohyukkim Date: Sat, 19 Aug 2023 15:36:09 +0900 Subject: [PATCH 8/8] Make JavaDoc consistent --- .../jackson/databind/jsontype/impl/SimpleNameIdResolver.java | 2 +- .../databind/jsontype/JsonTypeInfoSimpleClassName4061Test.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/SimpleNameIdResolver.java b/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/SimpleNameIdResolver.java index 88c2a8f3fd..94724f5f64 100644 --- a/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/SimpleNameIdResolver.java +++ b/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/SimpleNameIdResolver.java @@ -15,7 +15,7 @@ /** * {@link com.fasterxml.jackson.databind.jsontype.TypeIdResolver} implementation - * that converts between (JSON) Strings and simple Java class names via {@link Class#getSimpleName()}. + * that converts between (JSON) Strings and simple Java class names. * * @since 2.16 */ diff --git a/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061Test.java b/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061Test.java index 90c73bf665..d5cc00eda6 100644 --- a/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061Test.java +++ b/src/test/java/com/fasterxml/jackson/databind/jsontype/JsonTypeInfoSimpleClassName4061Test.java @@ -13,7 +13,7 @@ /** * Test for - * [databind#4061] Add JsonTypeInfo.Id.SIMPLE_NAME using Class::getSimpleName + * [databind#4061] Add JsonTypeInfo.Id.SIMPLE_NAME * * @since 2.16 */