diff options
author | Tatu Saloranta <tatu.saloranta@iki.fi> | 2020-07-24 19:42:31 -0700 |
---|---|---|
committer | Tatu Saloranta <tatu.saloranta@iki.fi> | 2020-07-24 19:42:31 -0700 |
commit | 65cab14b5a699ce47bf7a14c555daa444df0c16c (patch) | |
tree | ff01aa68c8a73004a313a538eed69867c8d79f06 | |
parent | 825ab66f492c1a9061ac76f1695870ae0fd3ad80 (diff) | |
download | jackson-databind-65cab14b5a699ce47bf7a14c555daa444df0c16c.tar.gz |
Yet more refactoring
6 files changed, 102 insertions, 70 deletions
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializer.java index dc7bddb3d..bf7efb79f 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializer.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializer.java @@ -148,7 +148,8 @@ public class BeanDeserializer } @Override - public BeanDeserializer withIgnorableProperties(Set<String> ignorableProps, Set<String> includableProps) { + public BeanDeserializer withByNameInclusion(Set<String> ignorableProps, + Set<String> includableProps) { return new BeanDeserializer(this, ignorableProps, includableProps); } 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 87b05c90c..537126603 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBase.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBase.java @@ -360,15 +360,11 @@ public abstract class BeanDeserializerBase } } - public BeanDeserializerBase(BeanDeserializerBase src, Set<String> ignorableProps) - { - this(src, ignorableProps, src._includableProps); - } - /** * @since 2.12 */ - public BeanDeserializerBase(BeanDeserializerBase src, Set<String> ignorableProps, Set<String> includableProps) + public BeanDeserializerBase(BeanDeserializerBase src, + Set<String> ignorableProps, Set<String> includableProps) { super(src._beanType); _beanType = src._beanType; @@ -397,7 +393,6 @@ public abstract class BeanDeserializerBase _beanProperties = src._beanProperties.withoutProperties(ignorableProps, includableProps); } - /** * @since 2.8 */ @@ -426,39 +421,27 @@ public abstract class BeanDeserializerBase _vanillaProcessing = src._vanillaProcessing; } + + @Deprecated // since 2.12 + protected BeanDeserializerBase(BeanDeserializerBase src, Set<String> ignorableProps) + { + this(src, ignorableProps, src._includableProps); + } @Override public abstract JsonDeserializer<Object> unwrappingDeserializer(NameTransformer unwrapper); public abstract BeanDeserializerBase withObjectIdReader(ObjectIdReader oir); - public BeanDeserializerBase withIgnorableProperties(Set<String> ignorableProps) { - return withIgnorableProperties(ignorableProps, _includableProps); - } - /** * @since 2.12 */ - public abstract BeanDeserializerBase withIgnorableProperties(Set<String> ignorableProps, Set<String> includableProps); + public abstract BeanDeserializerBase withByNameInclusion(Set<String> ignorableProps, Set<String> includableProps); /** - * @since 2.12 - */ - public BeanDeserializerBase withIncludableProperties(Set<String> includableProperties) { - return withIgnorableProperties(_ignorableProps, includableProperties); - } - - // NOTE! To be made `abstract` in 2.12 or later - /** * @since 2.11 */ - public BeanDeserializerBase withIgnoreAllUnknown(boolean ignoreUnknown) { - // Only to prevent some backwards-compatibility issues - if (ignoreUnknown == _ignoreAllUnknown) { - return this; - } - return withIgnorableProperties(_ignorableProps, _includableProps); - } + public abstract BeanDeserializerBase withIgnoreAllUnknown(boolean ignoreUnknown); /** * Mutant factory method that custom sub-classes must override; not left as @@ -480,6 +463,14 @@ public abstract class BeanDeserializerBase */ protected abstract BeanDeserializerBase asArrayDeserializer(); + /** + * @deprecated Since 2.12 use {@link #withByNameInclusion} instead + */ + @Deprecated + public BeanDeserializerBase withIgnorableProperties(Set<String> ignorableProps) { + return withByNameInclusion(ignorableProps, _includableProps); + } + /* /********************************************************** /* Validation, post-processing @@ -789,41 +780,7 @@ public abstract class BeanDeserializerBase } // And possibly add more properties to ignore if (accessor != null) { - final DeserializationConfig config = ctxt.getConfig(); - JsonIgnoreProperties.Value ignorals = intr.findPropertyIgnoralByName(config, accessor); - if (ignorals != null) { - Set<String> ignored = ignorals.findIgnoredForDeserialization(); - if (!ignored.isEmpty()) { - Set<String> prev = contextual._ignorableProps; - if ((prev != null) && !prev.isEmpty()) { - ignored = new HashSet<String>(ignored); - ignored.addAll(prev); - } - contextual = contextual.withIgnorableProperties(ignored); - } - // 30-Mar-2020, tatu: As per [databind#2627], need to also allow - // per-property override to "ignore all unknown". - // NOTE: there is no way to override with `false` because annotation - // defaults to `false` (i.e. can not know if `false` is explicit value) - if (ignorals.getIgnoreUnknown() && !_ignoreAllUnknown) { - contextual = contextual.withIgnoreAllUnknown(true); - } - } - JsonIncludeProperties.Value inclusions = intr.findPropertyInclusionByName(config, accessor); - if (inclusions != null) { - Set<String> included = inclusions.getIncluded(); - Set<String> prev = contextual._includableProps; - if (prev != null && included != null) { - Set<String> newIncluded = new HashSet<>(); - // Make the intersection with the previously included properties. - for(String prop : prev) { - if (included.contains(prop)) { - newIncluded.add(prop); - } - } - contextual = contextual.withIncludableProperties(newIncluded); - } - } + contextual = _handleByNameInclusion(ctxt, intr, contextual, accessor); } // One more thing: are we asked to serialize POJO as array? @@ -853,6 +810,47 @@ public abstract class BeanDeserializerBase return contextual; } + // @since 2.12 + protected BeanDeserializerBase _handleByNameInclusion(DeserializationContext ctxt, + AnnotationIntrospector intr, + BeanDeserializerBase contextual, + AnnotatedMember accessor) throws JsonMappingException + { + final DeserializationConfig config = ctxt.getConfig(); + JsonIgnoreProperties.Value ignorals = intr.findPropertyIgnoralByName(config, accessor); + + // 30-Mar-2020, tatu: As per [databind#2627], need to also allow + // per-property override to "ignore all unknown". + // NOTE: there is no way to override with `false` because annotation + // defaults to `false` (i.e. can not know if `false` is explicit value) + if (ignorals.getIgnoreUnknown() && !_ignoreAllUnknown) { + contextual = contextual.withIgnoreAllUnknown(true); + } + + final Set<String> namesToIgnore = ignorals.findIgnoredForDeserialization(); + final Set<String> prevNamesToIgnore = contextual._ignorableProps; + final Set<String> newNamesToIgnore; + + if (namesToIgnore.isEmpty()) { + newNamesToIgnore = prevNamesToIgnore; + } else if ((prevNamesToIgnore == null) || prevNamesToIgnore.isEmpty()) { + newNamesToIgnore = namesToIgnore; + } else { + newNamesToIgnore = new HashSet<String>(prevNamesToIgnore); + newNamesToIgnore.addAll(namesToIgnore); + } + + final Set<String> prevNamesToInclude = contextual._includableProps; + final Set<String> newNamesToInclude = IgnorePropertiesUtil.combineNamesToInclude(prevNamesToInclude, + intr.findPropertyInclusionByName(config, accessor).getIncluded()); + + if ((newNamesToIgnore != prevNamesToIgnore) + || (newNamesToInclude != prevNamesToInclude)) { + contextual = contextual.withByNameInclusion(newNamesToIgnore, newNamesToInclude); + } + return contextual; + } + /** * Helper method called to see if given property is part of 'managed' property * pair (managed + back reference), and if so, handle resolution details. diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/BuilderBasedDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/BuilderBasedDeserializer.java index d89ddeb07..450cd2705 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/BuilderBasedDeserializer.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/BuilderBasedDeserializer.java @@ -150,7 +150,8 @@ public class BuilderBasedDeserializer } @Override - public BeanDeserializerBase withIgnorableProperties(Set<String> ignorableProps, Set<String> includableProps) { + public BeanDeserializerBase withByNameInclusion(Set<String> ignorableProps, + Set<String> includableProps) { return new BuilderBasedDeserializer(this, ignorableProps, includableProps); } diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/impl/BeanAsArrayBuilderDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/impl/BeanAsArrayBuilderDeserializer.java index 73ab84871..1b1d94ceb 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/impl/BeanAsArrayBuilderDeserializer.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/impl/BeanAsArrayBuilderDeserializer.java @@ -77,8 +77,9 @@ public class BeanAsArrayBuilderDeserializer } @Override - public BeanDeserializerBase withIgnorableProperties(Set<String> ignorableProps, Set<String> includableProps) { - return new BeanAsArrayBuilderDeserializer(_delegate.withIgnorableProperties(ignorableProps, includableProps), + public BeanDeserializerBase withByNameInclusion(Set<String> ignorableProps, + Set<String> includableProps) { + return new BeanAsArrayBuilderDeserializer(_delegate.withByNameInclusion(ignorableProps, includableProps), _targetType, _orderedProperties, _buildMethod); } diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/impl/BeanAsArrayDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/impl/BeanAsArrayDeserializer.java index aad5b1f52..782c21a8f 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/impl/BeanAsArrayDeserializer.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/impl/BeanAsArrayDeserializer.java @@ -67,8 +67,9 @@ public class BeanAsArrayDeserializer } @Override - public BeanDeserializerBase withIgnorableProperties(Set<String> ignorableProps, Set<String> includableProps) { - return new BeanAsArrayDeserializer(_delegate.withIgnorableProperties(ignorableProps, includableProps), + public BeanDeserializerBase withByNameInclusion(Set<String> ignorableProps, + Set<String> includableProps) { + return new BeanAsArrayDeserializer(_delegate.withByNameInclusion(ignorableProps, includableProps), _orderedProperties); } diff --git a/src/main/java/com/fasterxml/jackson/databind/util/IgnorePropertiesUtil.java b/src/main/java/com/fasterxml/jackson/databind/util/IgnorePropertiesUtil.java index 4fd701874..88984289f 100644 --- a/src/main/java/com/fasterxml/jackson/databind/util/IgnorePropertiesUtil.java +++ b/src/main/java/com/fasterxml/jackson/databind/util/IgnorePropertiesUtil.java @@ -1,6 +1,8 @@ package com.fasterxml.jackson.databind.util; import java.util.Collection; +import java.util.HashSet; +import java.util.Set; /** * @since 2.12 @@ -9,8 +11,6 @@ public class IgnorePropertiesUtil { /** * Decide if we need to ignore a property or not, given a set of field to ignore and a set of field to include. - * - * @since 2.12 */ public static boolean shouldIgnore(Object value, Collection<String> toIgnore, Collection<String> toInclude) { if (toIgnore == null && toInclude ==null) { @@ -28,4 +28,34 @@ public class IgnorePropertiesUtil // NOTE: conflict between both, JsonIncludeProperties will take priority. return !toInclude.contains(value) || toIgnore.contains(value); } + + /** + * Helper that encapsulates logic for combining two sets of "included names": + * default logic is to do intersection (name must be in both to be included + * in result) + * + * @param prevToInclude Existing set of names to include, if defined; null means "not defined" + * @param newToInclude New set of names to included, if defined; null means "not defined" + * + * @return Resulting set of names, using intersection if neither {@code null}; or the + * non-null one (if only one is {@code null}); or {@code null} if both arguments {@code null}. + */ + public static Set<String> combineNamesToInclude(Set<String> prevToInclude, + Set<String> newToInclude) { + if (prevToInclude == null) { + return newToInclude; + } + if (newToInclude == null) { + return prevToInclude; + } + final Set<String> result = new HashSet<>(); + + // Make the intersection with the previously included properties + for (String prop : newToInclude) { + if (prevToInclude.contains(prop)) { + result.add(prop); + } + } + return result; + } } |