diff options
Diffstat (limited to 'src/main/java/com/fasterxml/jackson/databind/SerializationConfig.java')
-rw-r--r-- | src/main/java/com/fasterxml/jackson/databind/SerializationConfig.java | 469 |
1 files changed, 469 insertions, 0 deletions
diff --git a/src/main/java/com/fasterxml/jackson/databind/SerializationConfig.java b/src/main/java/com/fasterxml/jackson/databind/SerializationConfig.java new file mode 100644 index 000000000..546b439a2 --- /dev/null +++ b/src/main/java/com/fasterxml/jackson/databind/SerializationConfig.java @@ -0,0 +1,469 @@ +package com.fasterxml.jackson.databind; + +import java.text.DateFormat; +import java.util.*; + +import com.fasterxml.jackson.annotation.*; +import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; +import com.fasterxml.jackson.databind.cfg.BaseSettings; +import com.fasterxml.jackson.databind.cfg.HandlerInstantiator; +import com.fasterxml.jackson.databind.cfg.MapperConfigBase; +import com.fasterxml.jackson.databind.introspect.ClassIntrospector; +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.ClassKey; +import com.fasterxml.jackson.databind.type.TypeFactory; + +/** + * Object that contains baseline configuration for serialization + * process. An instance is owned by {@link ObjectMapper}, which + * passes an immutable instance for serialization process to + * {@link SerializerProvider} and {@link SerializerFactory} + * (either directly, or through {@link ObjectWriter}. + *<p> + * Note that instances are considered immutable and as such no copies + * should need to be created (there are some implementation details + * with respect to mix-in annotations; where this is guaranteed as + * long as caller follow "copy-then-use" pattern) + */ +public final class SerializationConfig + extends MapperConfigBase<SerializationFeature, SerializationConfig> +{ + /** + * Set of features enabled; actual type (kind of features) + * depends on sub-classes. + */ + protected final int _serFeatures; + + /** + * Which Bean/Map properties are to be included in serialization? + * Default settings is to include all regardless of value; can be + * changed to only include non-null properties, or properties + * with non-default values. + */ + protected JsonInclude.Include _serializationInclusion = null; + + /** + * Object used for resolving filter ids to filter instances. + * Non-null if explicitly defined; null by default. + */ + protected final FilterProvider _filterProvider; + + /* + /********************************************************** + /* Life-cycle, constructors + /********************************************************** + */ + + /** + * Constructor used by ObjectMapper to create default configuration object instance. + */ + public SerializationConfig(BaseSettings base, + SubtypeResolver str, Map<ClassKey,Class<?>> mixins) + { + super(base, str, mixins); + _serFeatures = collectFeatureDefaults(SerializationFeature.class); + _filterProvider = null; + } + + private SerializationConfig(SerializationConfig src, SubtypeResolver str) + { + super(src, str); + _serFeatures = src._serFeatures; + _serializationInclusion = src._serializationInclusion; + _filterProvider = src._filterProvider; + } + + private SerializationConfig(SerializationConfig src, + int mapperFeatures, int serFeatures) + { + super(src, mapperFeatures); + _serFeatures = serFeatures; + _serializationInclusion = src._serializationInclusion; + _filterProvider = src._filterProvider; + } + + private SerializationConfig(SerializationConfig src, BaseSettings base) + { + super(src, base); + _serFeatures = src._serFeatures; + _serializationInclusion = src._serializationInclusion; + _filterProvider = src._filterProvider; + } + + private SerializationConfig(SerializationConfig src, FilterProvider filters) + { + super(src); + _serFeatures = src._serFeatures; + _serializationInclusion = src._serializationInclusion; + _filterProvider = filters; + } + + private SerializationConfig(SerializationConfig src, Class<?> view) + { + super(src, view); + _serFeatures = src._serFeatures; + _serializationInclusion = src._serializationInclusion; + _filterProvider = src._filterProvider; + } + + private SerializationConfig(SerializationConfig src, JsonInclude.Include incl) + { + super(src); + _serFeatures = src._serFeatures; + _serializationInclusion = incl; + _filterProvider = src._filterProvider; + } + + private SerializationConfig(SerializationConfig src, String rootName) + { + super(src, rootName); + _serFeatures = src._serFeatures; + _serializationInclusion = src._serializationInclusion; + _filterProvider = src._filterProvider; + } + + /* + /********************************************************** + /* Life-cycle, factory methods from MapperConfig + /********************************************************** + */ + + /** + * 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); + } + + /** + * 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 + public SerializationConfig withAnnotationIntrospector(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 withClassIntrospector(ClassIntrospector ci) { + return _withBase(_base.withClassIntrospector(ci)); + } + + /** + * In addition to constructing instance with specified date format, + * will enable or disable <code>SerializationFeature.WRITE_DATES_AS_TIMESTAMPS</code> + * (enable if format set as null; disable if non-null) + */ + @Override + public SerializationConfig withDateFormat(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 withHandlerInstantiator(HandlerInstantiator hi) { + return _withBase(_base.withHandlerInstantiator(hi)); + } + + @Override + public SerializationConfig withPropertyNamingStrategy(PropertyNamingStrategy pns) { + return _withBase(_base.withPropertyNamingStrategy(pns)); + } + + @Override + public SerializationConfig withRootName(String rootName) { + if (rootName == null) { + if (_rootName == null) { + return this; + } + } else if (rootName.equals(_rootName)) { + return this; + } + return new SerializationConfig(this, rootName); + } + + @Override + public SerializationConfig withSubtypeResolver(SubtypeResolver str) { + return (str == _subtypeResolver)? this : new SerializationConfig(this, str); + } + + @Override + public SerializationConfig withTypeFactory(TypeFactory tf) { + return _withBase(_base.withTypeFactory(tf)); + } + + @Override + public SerializationConfig withTypeResolverBuilder(TypeResolverBuilder<?> trb) { + return _withBase(_base.withTypeResolverBuilder(trb)); + } + + public SerializationConfig withView(Class<?> view) { + return (_view == view) ? this : new SerializationConfig(this, view); + } + + @Override + public SerializationConfig withVisibilityChecker(VisibilityChecker<?> vc) { + return _withBase(_base.withVisibilityChecker(vc)); + } + + @Override + public SerializationConfig withVisibility(PropertyAccessor forMethod, JsonAutoDetect.Visibility visibility) { + return _withBase(_base.withVisibility(forMethod, visibility)); + } + + private final SerializationConfig _withBase(BaseSettings newBase) { + return (_base == newBase) ? this : new SerializationConfig(this, newBase); + } + + /* + /********************************************************** + /* Life-cycle, SerializationConfig specific factory methods + /********************************************************** + */ + + /** + * Fluent factory method that will construct and return a new configuration + * object instance with specified feature enabled. + */ + public SerializationConfig with(SerializationFeature feature) + { + int newSerFeatures = _serFeatures | feature.getMask(); + return (newSerFeatures == _serFeatures) ? this + : new SerializationConfig(this, _mapperFeatures, newSerFeatures); + } + + /** + * Fluent factory method that will construct and return a new configuration + * object instance with specified features enabled. + */ + public SerializationConfig with(SerializationFeature first, SerializationFeature... features) + { + int newSerFeatures = _serFeatures | first.getMask(); + for (SerializationFeature f : features) { + newSerFeatures |= f.getMask(); + } + return (newSerFeatures == _serFeatures) ? this + : new SerializationConfig(this, _mapperFeatures, newSerFeatures); + } + + /** + * Fluent factory method that will construct and return a new configuration + * object instance with specified features enabled. + */ + public SerializationConfig withFeatures(SerializationFeature... features) + { + int newSerFeatures = _serFeatures; + for (SerializationFeature f : features) { + newSerFeatures |= f.getMask(); + } + return (newSerFeatures == _serFeatures) ? this + : new SerializationConfig(this, _mapperFeatures, newSerFeatures); + } + + /** + * Fluent factory method that will construct and return a new configuration + * object instance with specified feature disabled. + */ + public SerializationConfig without(SerializationFeature feature) + { + int newSerFeatures = _serFeatures & ~feature.getMask(); + return (newSerFeatures == _serFeatures) ? this + : new SerializationConfig(this, _mapperFeatures, newSerFeatures); + } + + /** + * Fluent factory method that will construct and return a new configuration + * object instance with specified features disabled. + */ + public SerializationConfig without(SerializationFeature first, SerializationFeature... features) + { + int newSerFeatures = _serFeatures & ~first.getMask(); + for (SerializationFeature f : features) { + newSerFeatures &= ~f.getMask(); + } + return (newSerFeatures == _serFeatures) ? this + : new SerializationConfig(this, _mapperFeatures, newSerFeatures); + } + + /** + * Fluent factory method that will construct and return a new configuration + * object instance with specified features disabled. + */ + public SerializationConfig withoutFeatures(SerializationFeature... features) + { + int newSerFeatures = _serFeatures; + for (SerializationFeature f : features) { + newSerFeatures &= ~f.getMask(); + } + return (newSerFeatures == _serFeatures) ? this + : new SerializationConfig(this, _mapperFeatures, newSerFeatures); + } + + public SerializationConfig withFilters(FilterProvider filterProvider) { + return (filterProvider == _filterProvider) ? this : new SerializationConfig(this, filterProvider); + } + + public SerializationConfig withSerializationInclusion(JsonInclude.Include incl) { + return (_serializationInclusion == incl) ? this: new SerializationConfig(this, incl); + } + + /* + /********************************************************** + /* MapperConfig implementation/overrides + /********************************************************** + */ + + @Override + public boolean useRootWrapping() + { + if (_rootName != null) { // empty String disables wrapping; non-empty enables + return (_rootName.length() > 0); + } + return isEnabled(SerializationFeature.WRAP_ROOT_VALUE); + } + + @Override + public AnnotationIntrospector getAnnotationIntrospector() + { + /* 29-Jul-2009, tatu: it's now possible to disable use of + * annotations; can be done using "no-op" introspector + */ + if (isEnabled(MapperFeature.USE_ANNOTATIONS)) { + return super.getAnnotationIntrospector(); + } + return AnnotationIntrospector.nopInstance(); + } + + /** + * Accessor for getting bean description that only contains class + * annotations: useful if no getter/setter/creator information is needed. + */ + @Override + public BeanDescription introspectClassAnnotations(JavaType type) { + return getClassIntrospector().forClassAnnotations(this, type, this); + } + + /** + * Accessor for getting bean description that only contains immediate class + * annotations: ones from the class, and its direct mix-in, if any, but + * not from super types. + */ + @Override + public BeanDescription introspectDirectClassAnnotations(JavaType type) { + return getClassIntrospector().forDirectClassAnnotations(this, type, this); + } + + @Override + public VisibilityChecker<?> getDefaultVisibilityChecker() + { + VisibilityChecker<?> vchecker = super.getDefaultVisibilityChecker(); + if (!isEnabled(MapperFeature.AUTO_DETECT_GETTERS)) { + vchecker = vchecker.withGetterVisibility(Visibility.NONE); + } + // then global overrides (disabling) + if (!isEnabled(MapperFeature.AUTO_DETECT_IS_GETTERS)) { + vchecker = vchecker.withIsGetterVisibility(Visibility.NONE); + } + if (!isEnabled(MapperFeature.AUTO_DETECT_FIELDS)) { + vchecker = vchecker.withFieldVisibility(Visibility.NONE); + } + return vchecker; + } + + /* + /********************************************************** + /* Configuration: other + /********************************************************** + */ + + public final boolean isEnabled(SerializationFeature f) { + return (_serFeatures & f.getMask()) != 0; + } + + public final int getSerializationFeatures() { + return _serFeatures; + } + + public JsonInclude.Include getSerializationInclusion() + { + if (_serializationInclusion != null) { + return _serializationInclusion; + } + return JsonInclude.Include.ALWAYS; + } + + /** + * Method for getting provider used for locating filters given + * id (which is usually provided with filter annotations). + * Will be null if no provided was set for {@link ObjectWriter} + * (or if serialization directly called from {@link ObjectMapper}) + */ + public FilterProvider getFilterProvider() { + return _filterProvider; + } + + /* + /********************************************************** + /* Introspection methods + /********************************************************** + */ + + /** + * Method that will introspect full bean properties for the purpose + * of building a bean serializer + */ + @SuppressWarnings("unchecked") + public <T extends BeanDescription> T introspect(JavaType type) { + return (T) getClassIntrospector().forSerialization(this, type, this); + } + + /* + /********************************************************** + /* Debug support + /********************************************************** + */ + + @Override public String toString() + { + return "[SerializationConfig: flags=0x"+Integer.toHexString(_serFeatures)+"]"; + } +} |