From 554b8530fd50c7a7bf96425ce9c82b775f0174d2 Mon Sep 17 00:00:00 2001 From: zrlw Date: Fri, 9 Sep 2022 16:33:17 +0800 Subject: [PATCH 01/15] add tuple type for list with fixed element types format --- .../deser/BasicDeserializerFactory.java | 42 +++++--- .../databind/deser/DeserializerCache.java | 8 +- .../databind/deser/DeserializerFactory.java | 8 +- .../databind/deser/std/TupleDeserializer.java | 95 +++++++++++++++++++ .../jackson/databind/type/TupleType.java | 27 ++++++ .../jackson/databind/type/TypeBindings.java | 28 +++++- .../jackson/databind/type/TypeFactory.java | 26 ++--- .../jackson/databind/ObjectMapperTest.java | 46 +++++++-- 8 files changed, 241 insertions(+), 39 deletions(-) create mode 100644 src/main/java/com/fasterxml/jackson/databind/deser/std/TupleDeserializer.java create mode 100644 src/main/java/com/fasterxml/jackson/databind/type/TupleType.java diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/BasicDeserializerFactory.java b/src/main/java/com/fasterxml/jackson/databind/deser/BasicDeserializerFactory.java index e8ca72191e..7fb74da4cf 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/BasicDeserializerFactory.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/BasicDeserializerFactory.java @@ -716,7 +716,7 @@ protected void _addImplicitFactoryCreators(DeserializationContext ctxt, } continue; } - AnnotatedParameter nonAnnotatedParam = null; + AnnotatedParameter nonAnnotatedParam = null; SettableBeanProperty[] properties = new SettableBeanProperty[argCount]; int implicitNameCount = 0; int explicitNameCount = 0; @@ -1474,6 +1474,18 @@ public JsonDeserializer createCollectionLikeDeserializer(DeserializationConte return deser; } + @Override + public JsonDeserializer createTupleDeserializer(DeserializationContext ctxt, + TupleType type, BeanDescription beanDesc) + throws JsonMappingException + { + CollectionType ct = ctxt.getTypeFactory().constructCollectionType(Collection.class, + TypeFactory.unknownType()); + CollectionDeserializer deser = (CollectionDeserializer) createCollectionDeserializer(ctxt, + ct, beanDesc); + return new TupleDeserializer(deser, type); + } + /* /********************************************************** /* DeserializerFactory impl: Map(-like) deserializers @@ -2010,7 +2022,7 @@ public TypeDeserializer findPropertyTypeDeserializer(DeserializationConfig confi throws JsonMappingException { AnnotationIntrospector ai = config.getAnnotationIntrospector(); - TypeResolverBuilder b = ai.findPropertyTypeResolver(config, annotated, baseType); + TypeResolverBuilder b = ai.findPropertyTypeResolver(config, annotated, baseType); // Defaulting: if no annotations on member, check value class if (b == null) { return findTypeDeserializer(config, baseType); @@ -2037,13 +2049,13 @@ public TypeDeserializer findPropertyTypeDeserializer(DeserializationConfig confi * * @param containerType Type of property; must be a container type * @param propertyEntity Field or method that contains container property - */ + */ public TypeDeserializer findPropertyContentTypeDeserializer(DeserializationConfig config, JavaType containerType, AnnotatedMember propertyEntity) throws JsonMappingException { AnnotationIntrospector ai = config.getAnnotationIntrospector(); - TypeResolverBuilder b = ai.findPropertyContentTypeResolver(config, propertyEntity, containerType); + TypeResolverBuilder b = ai.findPropertyContentTypeResolver(config, propertyEntity, containerType); JavaType contentType = containerType.getContentType(); // Defaulting: if no annotations on member, check class if (b == null) { @@ -2086,13 +2098,17 @@ public JsonDeserializer findDefaultDeserializer(DeserializationContext ctxt, return StringDeserializer.instance; } if (rawType == CLASS_ITERABLE) { - // [databind#199]: Can and should 'upgrade' to a Collection type: - TypeFactory tf = ctxt.getTypeFactory(); - JavaType[] tps = tf.findTypeParameters(type, CLASS_ITERABLE); - JavaType elemType = (tps == null || tps.length != 1) ? TypeFactory.unknownType() : tps[0]; - CollectionType ct = tf.constructCollectionType(Collection.class, elemType); - // Should we re-introspect beanDesc? For now let's not... - return createCollectionDeserializer(ctxt, ct, beanDesc); + if (type instanceof TupleType) { + return createTupleDeserializer(ctxt, (TupleType) type, beanDesc); + } else { + // [databind#199]: Can and should 'upgrade' to a Collection type: + TypeFactory tf = ctxt.getTypeFactory(); + JavaType[] tps = tf.findTypeParameters(type, CLASS_ITERABLE); + // Should we re-introspect beanDesc? For now let's not... + JavaType elemType = (tps == null || tps.length != 1) ? TypeFactory.unknownType() : tps[0]; + CollectionType ct = tf.constructCollectionType(Collection.class, elemType); + return createCollectionDeserializer(ctxt, ct, beanDesc); + } } if (rawType == CLASS_MAP_ENTRY) { // 28-Apr-2015, tatu: TypeFactory does it all for us already so @@ -2375,7 +2391,7 @@ protected JavaType resolveMemberAndTypeAnnotations(DeserializationContext ctxt, type = type.withContentValueHandler(cd); } TypeDeserializer contentTypeDeser = findPropertyContentTypeDeserializer( - ctxt.getConfig(), type, (AnnotatedMember) member); + ctxt.getConfig(), type, (AnnotatedMember) member); if (contentTypeDeser != null) { type = type.withContentTypeHandler(contentTypeDeser); } @@ -2418,7 +2434,7 @@ protected boolean _hasCreatorAnnotation(DeserializationContext ctxt, AnnotationIntrospector intr = ctxt.getAnnotationIntrospector(); if (intr != null) { JsonCreator.Mode mode = intr.findCreatorAnnotation(ctxt.getConfig(), ann); - return (mode != null) && (mode != JsonCreator.Mode.DISABLED); + return (mode != null) && (mode != JsonCreator.Mode.DISABLED); } return false; } diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/DeserializerCache.java b/src/main/java/com/fasterxml/jackson/databind/deser/DeserializerCache.java index 69b4a2b204..3898e5bf27 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/DeserializerCache.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/DeserializerCache.java @@ -79,7 +79,7 @@ Object writeReplace() { /** * Method that can be used to determine how many deserializers this - * provider is caching currently + * provider is caching currently * (if it does caching: default implementation does) * Exact count depends on what kind of deserializers get cached; * default implementation caches only dynamically constructed deserializers, @@ -101,7 +101,7 @@ public int cachedDeserializersCount() { * configuration changes for mapper than owns the provider. */ public void flushCachedDeserializers() { - _cachedDeserializers.clear(); + _cachedDeserializers.clear(); } /* @@ -460,7 +460,7 @@ protected Converter findConverter(DeserializationContext ctxt, return null; } return ctxt.converterInstance(a, convDef); - } + } /** * Method called to see if given method has annotations that indicate * a more specific type than what the argument specifies. @@ -503,7 +503,7 @@ private JavaType modifyTypeByAnnotation(DeserializationContext ctxt, // keyType = type.getKeyType(); // just in case it's used below } } - } + } } JavaType contentType = type.getContentType(); if (contentType != null) { diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/DeserializerFactory.java b/src/main/java/com/fasterxml/jackson/databind/deser/DeserializerFactory.java index 4451fccffe..6fb8503a67 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/DeserializerFactory.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/DeserializerFactory.java @@ -10,7 +10,7 @@ * {@link JsonDeserializer} instances (which are then cached by * context and/or dedicated cache). *

- * Since there are multiple broad categories of deserializers, there are + * Since there are multiple broad categories of deserializers, there are * multiple factory methods: *