From a3601f592085f4da9ea6e5f30dd7f270ff53fe6d Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Sun, 27 Nov 2016 14:49:55 -0800 Subject: [PATCH] Config refactoring by demoting shared funcitonality to MapperConfigBase --- .../databind/DeserializationConfig.java | 134 +------- .../jackson/databind/ObjectMapper.java | 6 +- .../jackson/databind/SerializationConfig.java | 175 ++--------- .../jackson/databind/cfg/ConfigOverrides.java | 20 ++ .../databind/cfg/MapperConfigBase.java | 296 ++++++++++++------ .../introspect/VisibilityChecker.java | 51 ++- 6 files changed, 322 insertions(+), 360 deletions(-) diff --git a/src/main/java/com/fasterxml/jackson/databind/DeserializationConfig.java b/src/main/java/com/fasterxml/jackson/databind/DeserializationConfig.java index f58052b1e3..34d2fb473f 100644 --- a/src/main/java/com/fasterxml/jackson/databind/DeserializationConfig.java +++ b/src/main/java/com/fasterxml/jackson/databind/DeserializationConfig.java @@ -1,10 +1,7 @@ package com.fasterxml.jackson.databind; -import java.text.DateFormat; import java.util.*; -import com.fasterxml.jackson.annotation.*; - import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.databind.cfg.*; @@ -12,7 +9,6 @@ import com.fasterxml.jackson.databind.introspect.*; import com.fasterxml.jackson.databind.jsontype.*; import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.type.TypeFactory; import com.fasterxml.jackson.databind.util.LinkedNode; import com.fasterxml.jackson.databind.util.RootNameLookup; @@ -29,8 +25,8 @@ public final class DeserializationConfig extends MapperConfigBase implements java.io.Serializable // since 2.1 { - // since 2.5 - private static final long serialVersionUID = 1; + // since 2.9 + private static final long serialVersionUID = 2; /* /********************************************************** @@ -261,86 +257,32 @@ protected DeserializationConfig(DeserializationConfig src, SimpleMixInResolver m /* /********************************************************** - /* Life-cycle, factory methods from MapperConfig + /* Life-cycle, general factory methods from MapperConfig(Base) /********************************************************** */ - @Override - public DeserializationConfig with(MapperFeature... features) - { - int newMapperFlags = _mapperFeatures; - for (MapperFeature f : features) { - newMapperFlags |= f.getMask(); - } - return (newMapperFlags == _mapperFeatures) ? this : - new DeserializationConfig(this, newMapperFlags, _deserFeatures, - _parserFeatures, _parserFeaturesToChange, - _formatReadFeatures, _formatReadFeaturesToChange); - - } - - @Override - public DeserializationConfig without(MapperFeature... features) - { - int newMapperFlags = _mapperFeatures; - for (MapperFeature f : features) { - newMapperFlags &= ~f.getMask(); - } - return (newMapperFlags == _mapperFeatures) ? this : - new DeserializationConfig(this, newMapperFlags, _deserFeatures, - _parserFeatures, _parserFeaturesToChange, - _formatReadFeatures, _formatReadFeaturesToChange); - } - - @Override - public DeserializationConfig with(MapperFeature feature, boolean state) - { - int newMapperFlags; - if (state) { - newMapperFlags = _mapperFeatures | feature.getMask(); - } else { - newMapperFlags = _mapperFeatures & ~feature.getMask(); - } - return (newMapperFlags == _mapperFeatures) ? this : - new DeserializationConfig(this, newMapperFlags, _deserFeatures, - _parserFeatures, _parserFeaturesToChange, - _formatReadFeatures, _formatReadFeaturesToChange); - } - - @Override - public DeserializationConfig with(ClassIntrospector ci) { - return _withBase(_base.withClassIntrospector(ci)); - } - - @Override - public DeserializationConfig with(AnnotationIntrospector ai) { - return _withBase(_base.withAnnotationIntrospector(ai)); + @Override // since 2.9 + protected final DeserializationConfig _withBase(BaseSettings newBase) { + return (_base == newBase) ? this : new DeserializationConfig(this, newBase); } - @Override - public DeserializationConfig with(VisibilityChecker vc) { - return _withBase(_base.withVisibilityChecker(vc)); + @Override // since 2.9 + protected final DeserializationConfig _withMapperFeatures(int mapperFeatures) { + return new DeserializationConfig(this, mapperFeatures, _deserFeatures, + _parserFeatures, _parserFeaturesToChange, + _formatReadFeatures, _formatReadFeaturesToChange); } - @Override - public DeserializationConfig withVisibility(PropertyAccessor forMethod, JsonAutoDetect.Visibility visibility) { - return _withBase( _base.withVisibility(forMethod, visibility)); - } - - @Override - public DeserializationConfig with(TypeResolverBuilder trb) { - return _withBase(_base.withTypeResolverBuilder(trb)); - } + /* + /********************************************************** + /* Life-cycle, specific factory methods from MapperConfig + /********************************************************** + */ @Override public DeserializationConfig with(SubtypeResolver str) { return (_subtypeResolver == str) ? this : new DeserializationConfig(this, str); } - - @Override - public DeserializationConfig with(PropertyNamingStrategy pns) { - return _withBase(_base.withPropertyNamingStrategy(pns)); - } @Override public DeserializationConfig withRootName(PropertyName rootName) { @@ -354,59 +296,15 @@ public DeserializationConfig withRootName(PropertyName rootName) { return new DeserializationConfig(this, rootName); } - @Override - public DeserializationConfig with(TypeFactory tf) { - return _withBase( _base.withTypeFactory(tf)); - } - - @Override - public DeserializationConfig with(DateFormat df) { - return _withBase(_base.withDateFormat(df)); - } - - @Override - public DeserializationConfig with(HandlerInstantiator hi) { - return _withBase(_base.withHandlerInstantiator(hi)); - } - - @Override - public DeserializationConfig withInsertedAnnotationIntrospector(AnnotationIntrospector ai) { - return _withBase(_base.withInsertedAnnotationIntrospector(ai)); - } - - @Override - public DeserializationConfig withAppendedAnnotationIntrospector(AnnotationIntrospector ai) { - return _withBase(_base.withAppendedAnnotationIntrospector(ai)); - } - @Override public DeserializationConfig withView(Class view) { return (_view == view) ? this : new DeserializationConfig(this, view); } - @Override - public DeserializationConfig with(Locale l) { - return _withBase(_base.with(l)); - } - - @Override - public DeserializationConfig with(TimeZone tz) { - return _withBase(_base.with(tz)); - } - - @Override - public DeserializationConfig with(Base64Variant base64) { - return _withBase(_base.with(base64)); - } - @Override public DeserializationConfig with(ContextAttributes attrs) { return (attrs == _attributes) ? this : new DeserializationConfig(this, attrs); } - - private final DeserializationConfig _withBase(BaseSettings newBase) { - return (_base == newBase) ? this : new DeserializationConfig(this, newBase); - } /* /********************************************************** diff --git a/src/main/java/com/fasterxml/jackson/databind/ObjectMapper.java b/src/main/java/com/fasterxml/jackson/databind/ObjectMapper.java index 87a6b5af55..3a4566bcef 100644 --- a/src/main/java/com/fasterxml/jackson/databind/ObjectMapper.java +++ b/src/main/java/com/fasterxml/jackson/databind/ObjectMapper.java @@ -1225,12 +1225,13 @@ public void setVisibilityChecker(VisibilityChecker vc) { * * @since 2.6 */ + @SuppressWarnings("deprecation") public ObjectMapper setVisibility(VisibilityChecker vc) { _deserializationConfig = _deserializationConfig.with(vc); _serializationConfig = _serializationConfig.with(vc); return this; } - + /** * Convenience method that allows changing configuration for * underlying {@link VisibilityChecker}s, to change details of what kinds of @@ -1255,13 +1256,14 @@ public ObjectMapper setVisibility(VisibilityChecker vc) { * @return Modified mapper instance (that is, "this"), to allow chaining * of configuration calls */ + @SuppressWarnings("deprecation") public ObjectMapper setVisibility(PropertyAccessor forMethod, JsonAutoDetect.Visibility visibility) { _deserializationConfig = _deserializationConfig.withVisibility(forMethod, visibility); _serializationConfig = _serializationConfig.withVisibility(forMethod, visibility); return this; } - + /** * Method for accessing subtype resolver in use. */ diff --git a/src/main/java/com/fasterxml/jackson/databind/SerializationConfig.java b/src/main/java/com/fasterxml/jackson/databind/SerializationConfig.java index ac59cbb481..eece8c62ea 100644 --- a/src/main/java/com/fasterxml/jackson/databind/SerializationConfig.java +++ b/src/main/java/com/fasterxml/jackson/databind/SerializationConfig.java @@ -1,7 +1,6 @@ package com.fasterxml.jackson.databind; import java.text.DateFormat; -import java.util.*; import com.fasterxml.jackson.annotation.*; @@ -10,14 +9,10 @@ import com.fasterxml.jackson.core.util.Instantiatable; import com.fasterxml.jackson.databind.cfg.*; -import com.fasterxml.jackson.databind.introspect.ClassIntrospector; import com.fasterxml.jackson.databind.introspect.SimpleMixInResolver; -import com.fasterxml.jackson.databind.introspect.VisibilityChecker; import com.fasterxml.jackson.databind.jsontype.SubtypeResolver; -import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder; import com.fasterxml.jackson.databind.ser.FilterProvider; import com.fasterxml.jackson.databind.ser.SerializerFactory; -import com.fasterxml.jackson.databind.type.TypeFactory; import com.fasterxml.jackson.databind.util.RootNameLookup; /** @@ -215,18 +210,6 @@ private SerializationConfig(SerializationConfig src, Class view) _formatWriteFeaturesToChange = src._formatWriteFeaturesToChange; } - private SerializationConfig(SerializationConfig src, JsonInclude.Value incl) - { - super(src); - _serFeatures = src._serFeatures; - _filterProvider = src._filterProvider; - _defaultPrettyPrinter = src._defaultPrettyPrinter; - _generatorFeatures = src._generatorFeatures; - _generatorFeaturesToChange = src._generatorFeaturesToChange; - _formatWriteFeatures = src._formatWriteFeatures; - _formatWriteFeaturesToChange = src._formatWriteFeaturesToChange; - } - private SerializationConfig(SerializationConfig src, PropertyName rootName) { super(src, rootName); @@ -286,106 +269,22 @@ protected SerializationConfig(SerializationConfig src, PrettyPrinter defaultPP) /* /********************************************************** - /* Life-cycle, factory methods from MapperConfig + /* Life-cycle, factory methods from MapperConfig(Base) /********************************************************** */ - /** - * Fluent factory method that will construct and return a new configuration - * object instance with specified features enabled. - */ - @Override - public SerializationConfig with(MapperFeature... features) - { - int newMapperFlags = _mapperFeatures; - for (MapperFeature f : features) { - newMapperFlags |= f.getMask(); - } - return (newMapperFlags == _mapperFeatures) ? this - : new SerializationConfig(this, newMapperFlags, _serFeatures, - _generatorFeatures, _generatorFeaturesToChange, - _formatWriteFeatures, _formatWriteFeaturesToChange); + @Override // since 2.9 + protected final SerializationConfig _withBase(BaseSettings newBase) { + return (_base == newBase) ? this : new SerializationConfig(this, newBase); } - - /** - * Fluent factory method that will construct and return a new configuration - * object instance with specified features disabled. - */ - @Override - public SerializationConfig without(MapperFeature... features) - { - int newMapperFlags = _mapperFeatures; - for (MapperFeature f : features) { - newMapperFlags &= ~f.getMask(); - } - return (newMapperFlags == _mapperFeatures) ? this - : new SerializationConfig(this, newMapperFlags, _serFeatures, + + @Override // since 2.9 + protected final SerializationConfig _withMapperFeatures(int mapperFeatures) { + return new SerializationConfig(this, mapperFeatures, _serFeatures, _generatorFeatures, _generatorFeaturesToChange, _formatWriteFeatures, _formatWriteFeaturesToChange); } - @Override - public SerializationConfig with(MapperFeature feature, boolean state) - { - int newMapperFlags; - if (state) { - newMapperFlags = _mapperFeatures | feature.getMask(); - } else { - newMapperFlags = _mapperFeatures & ~feature.getMask(); - } - return (newMapperFlags == _mapperFeatures) ? this - : new SerializationConfig(this, newMapperFlags, _serFeatures, - _generatorFeatures, _generatorFeaturesToChange, - _formatWriteFeatures, _formatWriteFeaturesToChange); - } - - @Override - public SerializationConfig with(AnnotationIntrospector ai) { - return _withBase(_base.withAnnotationIntrospector(ai)); - } - - @Override - public SerializationConfig withAppendedAnnotationIntrospector(AnnotationIntrospector ai) { - return _withBase(_base.withAppendedAnnotationIntrospector(ai)); - } - - @Override - public SerializationConfig withInsertedAnnotationIntrospector(AnnotationIntrospector ai) { - return _withBase(_base.withInsertedAnnotationIntrospector(ai)); - } - - @Override - public SerializationConfig with(ClassIntrospector ci) { - return _withBase(_base.withClassIntrospector(ci)); - } - - /** - * In addition to constructing instance with specified date format, - * will enable or disable SerializationFeature.WRITE_DATES_AS_TIMESTAMPS - * (enable if format set as null; disable if non-null) - */ - @Override - public SerializationConfig with(DateFormat df) { - SerializationConfig cfg = new SerializationConfig(this, _base.withDateFormat(df)); - // Also need to toggle this feature based on existence of date format: - if (df == null) { - cfg = cfg.with(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); - } else { - cfg = cfg.without(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); - } - return cfg; - } - - @Override - public SerializationConfig with(HandlerInstantiator hi) { - return _withBase(_base.withHandlerInstantiator(hi)); - } - - @Override - public SerializationConfig with(PropertyNamingStrategy pns) { - return _withBase(_base.withPropertyNamingStrategy(pns)); - } - @Override public SerializationConfig withRootName(PropertyName rootName) { if (rootName == null) { @@ -403,53 +302,35 @@ public SerializationConfig with(SubtypeResolver str) { return (str == _subtypeResolver)? this : new SerializationConfig(this, str); } - @Override - public SerializationConfig with(TypeFactory tf) { - return _withBase(_base.withTypeFactory(tf)); - } - - @Override - public SerializationConfig with(TypeResolverBuilder trb) { - return _withBase(_base.withTypeResolverBuilder(trb)); - } - @Override public SerializationConfig withView(Class view) { return (_view == view) ? this : new SerializationConfig(this, view); } - - @Override - public SerializationConfig with(VisibilityChecker vc) { - return _withBase(_base.withVisibilityChecker(vc)); - } - - @Override - public SerializationConfig withVisibility(PropertyAccessor forMethod, JsonAutoDetect.Visibility visibility) { - return _withBase(_base.withVisibility(forMethod, visibility)); - } - - @Override - public SerializationConfig with(Locale l) { - return _withBase(_base.with(l)); - } - - @Override - public SerializationConfig with(TimeZone tz) { - return _withBase(_base.with(tz)); - } - - @Override - public SerializationConfig with(Base64Variant base64) { - return _withBase(_base.with(base64)); - } - + @Override public SerializationConfig with(ContextAttributes attrs) { return (attrs == _attributes) ? this : new SerializationConfig(this, attrs); } - private final SerializationConfig _withBase(BaseSettings newBase) { - return (_base == newBase) ? this : new SerializationConfig(this, newBase); + /* + /********************************************************** + /* Factory method overrides + /********************************************************** + */ + + /** + * In addition to constructing instance with specified date format, + * will enable or disable SerializationFeature.WRITE_DATES_AS_TIMESTAMPS + * (enable if format set as null; disable if non-null) + */ + @Override + public SerializationConfig with(DateFormat df) { + SerializationConfig cfg = super.with(df); + // Also need to toggle this feature based on existence of date format: + if (df == null) { + return cfg.with(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + } + return cfg.without(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); } /* diff --git a/src/main/java/com/fasterxml/jackson/databind/cfg/ConfigOverrides.java b/src/main/java/com/fasterxml/jackson/databind/cfg/ConfigOverrides.java index 23e9e8684c..753e442fd0 100644 --- a/src/main/java/com/fasterxml/jackson/databind/cfg/ConfigOverrides.java +++ b/src/main/java/com/fasterxml/jackson/databind/cfg/ConfigOverrides.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonSetter; +import com.fasterxml.jackson.databind.introspect.VisibilityChecker; /** * Container for individual {@link ConfigOverride} values. @@ -32,6 +33,11 @@ public class ConfigOverrides */ protected JsonSetter.Value _defaultSetterInfo; + /** + * @since 2.9 + */ + protected VisibilityChecker _visibilityChecker; + /* /********************************************************** /* Life cycle @@ -106,6 +112,13 @@ public JsonSetter.Value getDefaultSetterInfo() { return _defaultSetterInfo; } + /** + * @since 2.9 + */ + public VisibilityChecker getDefaultVisibility() { + return _visibilityChecker; + } + public void setDefaultInclusion(JsonInclude.Value v) { _defaultInclusion = v; } @@ -114,6 +127,13 @@ public void setDefaultSetterInfo(JsonSetter.Value v) { _defaultSetterInfo = v; } + /** + * @since 2.9 + */ + public void setDefaultVisibility(VisibilityChecker v) { + _visibilityChecker = v; + } + /* /********************************************************** /* Helper methods diff --git a/src/main/java/com/fasterxml/jackson/databind/cfg/MapperConfigBase.java b/src/main/java/com/fasterxml/jackson/databind/cfg/MapperConfigBase.java index 19ba8444c1..60b22c371d 100644 --- a/src/main/java/com/fasterxml/jackson/databind/cfg/MapperConfigBase.java +++ b/src/main/java/com/fasterxml/jackson/databind/cfg/MapperConfigBase.java @@ -227,7 +227,7 @@ protected MapperConfigBase(MapperConfigBase src, SimpleMixInResolver mixi _attributes = src._attributes; _configOverrides = src._configOverrides; } - + /** * @since 2.3 */ @@ -245,10 +245,84 @@ protected MapperConfigBase(MapperConfigBase src, ContextAttributes attr) /* /********************************************************** - /* Addition fluent factory methods, common to all sub-types + /* Abstract fluent factory methods to be implemented by subtypes + /********************************************************** + */ + + /** + * @since 2.9 (in this case, demoted from sub-classes) + */ + protected abstract T _withBase(BaseSettings newBase); + + /** + * @since 2.9 (in this case, demoted from sub-classes) + */ + protected abstract T _withMapperFeatures(int mapperFeatures); + + /* + /********************************************************** + /* Additional shared fluent factory methods; features /********************************************************** */ + + /** + * Fluent factory method that will construct and return a new configuration + * object instance with specified features enabled. + */ + @SuppressWarnings("unchecked") + @Override + public final T with(MapperFeature... features) + { + int newMapperFlags = _mapperFeatures; + for (MapperFeature f : features) { + newMapperFlags |= f.getMask(); + } + if (newMapperFlags == _mapperFeatures) { + return (T) this; + } + return _withMapperFeatures(newMapperFlags); + } + + /** + * Fluent factory method that will construct and return a new configuration + * object instance with specified features disabled. + */ + @SuppressWarnings("unchecked") + @Override + public final T without(MapperFeature... features) + { + int newMapperFlags = _mapperFeatures; + for (MapperFeature f : features) { + newMapperFlags &= ~f.getMask(); + } + if (newMapperFlags == _mapperFeatures) { + return (T) this; + } + return _withMapperFeatures(newMapperFlags); + } + @SuppressWarnings("unchecked") + @Override + public final T with(MapperFeature feature, boolean state) + { + int newMapperFlags; + if (state) { + newMapperFlags = _mapperFeatures | feature.getMask(); + } else { + newMapperFlags = _mapperFeatures & ~feature.getMask(); + } + if (newMapperFlags == _mapperFeatures) { + return (T) this; + } + return _withMapperFeatures(newMapperFlags); + } + + /* + /********************************************************** + /* Additional shared fluent factory methods; introspectors + /********************************************************** + */ + /** * Method for constructing and returning a new instance with different * {@link AnnotationIntrospector} to use (replacing old one). @@ -256,19 +330,25 @@ protected MapperConfigBase(MapperConfigBase src, ContextAttributes attr) * NOTE: make sure to register new instance with ObjectMapper * if directly calling this method. */ - public abstract T with(AnnotationIntrospector ai); + public final T with(AnnotationIntrospector ai) { + return _withBase(_base.withAnnotationIntrospector(ai)); + } /** * Method for constructing and returning a new instance with additional * {@link AnnotationIntrospector} appended (as the lowest priority one) */ - public abstract T withAppendedAnnotationIntrospector(AnnotationIntrospector introspector); + public final T withAppendedAnnotationIntrospector(AnnotationIntrospector ai) { + return _withBase(_base.withAppendedAnnotationIntrospector(ai)); + } /** * Method for constructing and returning a new instance with additional * {@link AnnotationIntrospector} inserted (as the highest priority one) */ - public abstract T withInsertedAnnotationIntrospector(AnnotationIntrospector introspector); + public final T withInsertedAnnotationIntrospector(AnnotationIntrospector ai) { + return _withBase(_base.withInsertedAnnotationIntrospector(ai)); + } /** * Method for constructing and returning a new instance with different @@ -278,17 +358,88 @@ protected MapperConfigBase(MapperConfigBase src, ContextAttributes attr) * NOTE: make sure to register new instance with ObjectMapper * if directly calling this method. */ - public abstract T with(ClassIntrospector ci); + public final T with(ClassIntrospector ci) { + return _withBase(_base.withClassIntrospector(ci)); + } + + /* + /********************************************************** + /* Additional shared fluent factory methods; attributes + /********************************************************** + */ + + /** + * Method for constructing an instance that has specified + * contextual attributes. + * + * @since 2.3 + */ + public abstract T with(ContextAttributes attrs); + + /** + * Method for constructing an instance that has only specified + * attributes, removing any attributes that exist before the call. + * + * @since 2.3 + */ + public T withAttributes(Map attributes) { + return with(getAttributes().withSharedAttributes(attributes)); + } + + /** + * Method for constructing an instance that has specified + * value for attribute for given key. + * + * @since 2.3 + */ + public T withAttribute(Object key, Object value) { + return with(getAttributes().withSharedAttribute(key, value)); + } + + /** + * Method for constructing an instance that has no + * value for attribute for given key. + * + * @since 2.3 + */ + public T withoutAttribute(Object key) { + return with(getAttributes().withoutSharedAttribute(key)); + } + + /* + /********************************************************** + /* Additional shared fluent factory methods; factories + /********************************************************** + */ /** * Method for constructing and returning a new instance with different - * {@link DateFormat} + * {@link TypeFactory} + * to use. + */ + public final T with(TypeFactory tf) { + return _withBase( _base.withTypeFactory(tf)); + } + + /** + * Method for constructing and returning a new instance with different + * {@link TypeResolverBuilder} to use. + */ + public final T with(TypeResolverBuilder trb) { + return _withBase(_base.withTypeResolverBuilder(trb)); + } + + /** + * Method for constructing and returning a new instance with different + * {@link PropertyNamingStrategy} * to use. *

* NOTE: make sure to register new instance with ObjectMapper * if directly calling this method. */ - public abstract T with(DateFormat df); + public final T with(PropertyNamingStrategy pns) { + return _withBase(_base.withPropertyNamingStrategy(pns)); + } /** * Method for constructing and returning a new instance with different @@ -298,18 +449,51 @@ protected MapperConfigBase(MapperConfigBase src, ContextAttributes attr) * NOTE: make sure to register new instance with ObjectMapper * if directly calling this method. */ - public abstract T with(HandlerInstantiator hi); - + public final T with(HandlerInstantiator hi) { + return _withBase(_base.withHandlerInstantiator(hi)); + } + + /* + /********************************************************** + /* Additional shared fluent factory methods; other + /********************************************************** + */ + /** * Method for constructing and returning a new instance with different - * {@link PropertyNamingStrategy} + * default {@link Base64Variant} to use with base64-encoded binary values. + */ + public final T with(Base64Variant base64) { + return _withBase(_base.with(base64)); + } + + /** + * Method for constructing and returning a new instance with different + * {@link DateFormat} * to use. *

- * NOTE: make sure to register new instance with ObjectMapper - * if directly calling this method. + * NOTE: non-final since SerializationConfig needs to override this */ - public abstract T with(PropertyNamingStrategy strategy); - + public T with(DateFormat df) { + return _withBase(_base.withDateFormat(df)); + } + + /** + * Method for constructing and returning a new instance with different + * default {@link java.util.Locale} to use for formatting. + */ + public final T with(Locale l) { + return _withBase(_base.with(l)); + } + + /** + * Method for constructing and returning a new instance with different + * default {@link java.util.TimeZone} to use for formatting of date values. + */ + public final T with(TimeZone tz) { + return _withBase(_base.with(tz)); + } + /** * Method for constructing and returning a new instance with different * root name to use (none, if null). @@ -344,93 +528,27 @@ public T withRootName(String rootName) { * if directly calling this method. */ public abstract T with(SubtypeResolver str); - - /** - * Method for constructing and returning a new instance with different - * {@link TypeFactory} - * to use. - */ - public abstract T with(TypeFactory typeFactory); - - /** - * Method for constructing and returning a new instance with different - * {@link TypeResolverBuilder} to use. - */ - public abstract T with(TypeResolverBuilder trb); /** * Method for constructing and returning a new instance with different * view to use. */ public abstract T withView(Class view); - - /** - * Method for constructing and returning a new instance with different - * {@link VisibilityChecker} - * to use. - */ - public abstract T with(VisibilityChecker vc); - - /** - * Method for constructing and returning a new instance with different - * minimal visibility level for specified property type - */ - public abstract T withVisibility(PropertyAccessor forMethod, JsonAutoDetect.Visibility visibility); - - /** - * Method for constructing and returning a new instance with different - * default {@link java.util.Locale} to use for formatting. - */ - public abstract T with(Locale l); - - /** - * Method for constructing and returning a new instance with different - * default {@link java.util.TimeZone} to use for formatting of date values. - */ - public abstract T with(TimeZone tz); /** - * Method for constructing and returning a new instance with different - * default {@link Base64Variant} to use with base64-encoded binary values. + * @deprecated Since 2.9 use configuration methods in {@link ObjectMapper} */ - public abstract T with(Base64Variant base64); - - /** - * Method for constructing an instance that has specified - * contextual attributes. - * - * @since 2.3 - */ - public abstract T with(ContextAttributes attrs); - - /** - * Method for constructing an instance that has only specified - * attributes, removing any attributes that exist before the call. - * - * @since 2.3 - */ - public T withAttributes(Map attributes) { - return with(getAttributes().withSharedAttributes(attributes)); - } - - /** - * Method for constructing an instance that has specified - * value for attribute for given key. - * - * @since 2.3 - */ - public T withAttribute(Object key, Object value) { - return with(getAttributes().withSharedAttribute(key, value)); + @Deprecated + public T with(VisibilityChecker vc) { + return _withBase(_base.withVisibilityChecker(vc)); } /** - * Method for constructing an instance that has no - * value for attribute for given key. - * - * @since 2.3 + * @deprecated Since 2.9 use configuration methods in {@link ObjectMapper} */ - public T withoutAttribute(Object key) { - return with(getAttributes().withoutSharedAttribute(key)); + @Deprecated + public T withVisibility(PropertyAccessor forMethod, JsonAutoDetect.Visibility visibility) { + return _withBase(_base.withVisibility(forMethod, visibility)); } /* diff --git a/src/main/java/com/fasterxml/jackson/databind/introspect/VisibilityChecker.java b/src/main/java/com/fasterxml/jackson/databind/introspect/VisibilityChecker.java index 0e2d0ad5bf..f5dc230d13 100644 --- a/src/main/java/com/fasterxml/jackson/databind/introspect/VisibilityChecker.java +++ b/src/main/java/com/fasterxml/jackson/databind/introspect/VisibilityChecker.java @@ -28,6 +28,15 @@ public interface VisibilityChecker> */ public T with(JsonAutoDetect ann); + /** + * Method that can be used for merging default values from given + * source with values from this instance, and either return `this` + * instance (if no changes), or a new instance with applicable defaults. + * + * @since 2.9 + */ + public T withDefaults(VisibilityChecker defaults); + /** * Builder method that will create and return an instance that has specified * {@link Visibility} value to use for all property elements. @@ -168,7 +177,7 @@ public static class Std * visibility values */ protected final static Std DEFAULT = new Std(Std.class.getAnnotation(JsonAutoDetect.class)); - + protected final Visibility _getterMinLevel; protected final Visibility _isGetterMinLevel; protected final Visibility _setterMinLevel; @@ -185,7 +194,7 @@ public static class Std */ public Std(JsonAutoDetect ann) { - // let's combine checks for enabled/disabled, with minimimum level checks: + // let's combine checks for enabled/disabled, with minimum level checks: _getterMinLevel = ann.getterVisibility(); _isGetterMinLevel = ann.isGetterVisibility(); _setterMinLevel = ann.setterVisibility(); @@ -196,7 +205,8 @@ public Std(JsonAutoDetect ann) /** * Constructor that allows directly specifying minimum visibility levels to use */ - public Std(Visibility getter, Visibility isGetter, Visibility setter, Visibility creator, Visibility field) + public Std(Visibility getter, Visibility isGetter, Visibility setter, + Visibility creator, Visibility field) { _getterMinLevel = getter; _isGetterMinLevel = isGetter; @@ -250,6 +260,39 @@ public Std with(JsonAutoDetect ann) return curr; } + @Override + public Std withDefaults(VisibilityChecker defaults0) + { + if (defaults0 == null) { + return this; + } + // !!! 25-Nov-2016, tatu: not optimal, but without generic access + // best we can do. Plan is to rewrite the whole thing for 3.x + Std defaults = (Std) defaults0; + Visibility getterMin = _defaultOrOverride(defaults._getterMinLevel, _getterMinLevel); + Visibility isGetterMin = _defaultOrOverride(defaults._isGetterMinLevel, _isGetterMinLevel); + Visibility setterMin = _defaultOrOverride(defaults._setterMinLevel, _setterMinLevel); + Visibility creatorMin = _defaultOrOverride(defaults._creatorMinLevel, _creatorMinLevel); + Visibility fieldMin = _defaultOrOverride(defaults._fieldMinLevel, _fieldMinLevel); + + if ((getterMin == _getterMinLevel) + && (isGetterMin == _isGetterMinLevel) + && (setterMin == _setterMinLevel) + && (creatorMin == _creatorMinLevel) + && (fieldMin == _fieldMinLevel) + ) { + return this; + } + return new Std(getterMin, isGetterMin, setterMin, creatorMin, fieldMin); + } + + private Visibility _defaultOrOverride(Visibility defaults, Visibility override) { + if (override == Visibility.DEFAULT) { + return defaults; + } + return override; + } + @Override public Std with(Visibility v) { @@ -258,7 +301,7 @@ public Std with(Visibility v) } return new Std(v); } - + @Override public Std withVisibility(PropertyAccessor method, Visibility v) {