package com.fasterxml.jackson.databind.ser;

import java.util.*;

import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.introspect.AnnotatedClass;
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
import com.fasterxml.jackson.databind.ser.impl.ObjectIdWriter;

Builder class used for aggregating deserialization information about a POJO, in order to build a JsonSerializer for serializing intances. Main reason for using separate builder class is that this makes it easier to make actual serializer class fully immutable.
/** * Builder class used for aggregating deserialization information about * a POJO, in order to build a {@link JsonSerializer} for serializing * intances. * Main reason for using separate builder class is that this makes it easier * to make actual serializer class fully immutable. */
public class BeanSerializerBuilder { private final static BeanPropertyWriter[] NO_PROPERTIES = new BeanPropertyWriter[0]; /* /********************************************************** /* Basic configuration we start with /********************************************************** */ final protected BeanDescription _beanDesc; protected SerializationConfig _config; /* /********************************************************** /* Accumulated information about properties /********************************************************** */
Bean properties, in order of serialization
/** * Bean properties, in order of serialization */
protected List<BeanPropertyWriter> _properties = Collections.emptyList();
Optional array of filtered property writers; if null, no view-based filtering is performed.
/** * Optional array of filtered property writers; if null, no * view-based filtering is performed. */
protected BeanPropertyWriter[] _filteredProperties;
Writer used for "any getter" properties, if any.
/** * Writer used for "any getter" properties, if any. */
protected AnyGetterWriter _anyGetter;
Id of the property filter to use for POJO, if any.
/** * Id of the property filter to use for POJO, if any. */
protected Object _filterId;
Property that is used for type id (and not serialized as regular property)
/** * Property that is used for type id (and not serialized as regular * property) */
protected AnnotatedMember _typeId;
Object responsible for serializing Object Ids for the handled type, if any.
/** * Object responsible for serializing Object Ids for the handled * type, if any. */
protected ObjectIdWriter _objectIdWriter; /* /********************************************************** /* Construction and setter methods /********************************************************** */ public BeanSerializerBuilder(BeanDescription beanDesc) { _beanDesc = beanDesc; }
Copy-constructor that may be used for sub-classing
/** * Copy-constructor that may be used for sub-classing */
protected BeanSerializerBuilder(BeanSerializerBuilder src) { _beanDesc = src._beanDesc; _properties = src._properties; _filteredProperties = src._filteredProperties; _anyGetter = src._anyGetter; _filterId = src._filterId; }
Initialization method called right after construction, to specify configuration to use.

Note: ideally should be passed in constructor, but for backwards compatibility, needed to add a setter instead

Since:2.1
/** * Initialization method called right after construction, to specify * configuration to use. *<p> * Note: ideally should be passed in constructor, but for backwards * compatibility, needed to add a setter instead * * @since 2.1 */
protected void setConfig(SerializationConfig config) { _config = config; } public void setProperties(List<BeanPropertyWriter> properties) { _properties = properties; }
Params:
/** * @param properties Number and order of properties here MUST match that * of "regular" properties set earlier using {@link #setProperties(List)}; if not, * an {@link IllegalArgumentException} will be thrown */
public void setFilteredProperties(BeanPropertyWriter[] properties) { if (properties != null) { if (properties.length != _properties.size()) { // as per [databind#1612] throw new IllegalArgumentException(String.format( "Trying to set %d filtered properties; must match length of non-filtered `properties` (%d)", properties.length, _properties.size())); } } _filteredProperties = properties; } public void setAnyGetter(AnyGetterWriter anyGetter) { _anyGetter = anyGetter; } public void setFilterId(Object filterId) { _filterId = filterId; } public void setTypeId(AnnotatedMember idProp) { // Not legal to use multiple ones... if (_typeId != null) { throw new IllegalArgumentException("Multiple type ids specified with "+_typeId+" and "+idProp); } _typeId = idProp; } public void setObjectIdWriter(ObjectIdWriter w) { _objectIdWriter = w; } /* /********************************************************** /* Accessors for things BeanSerializer cares about: /* note -- likely to change between minor revisions /* by new methods getting added. /********************************************************** */ public AnnotatedClass getClassInfo() { return _beanDesc.getClassInfo(); } public BeanDescription getBeanDescription() { return _beanDesc; } public List<BeanPropertyWriter> getProperties() { return _properties; } public boolean hasProperties() { return (_properties != null) && (_properties.size() > 0); } public BeanPropertyWriter[] getFilteredProperties() { return _filteredProperties; } public AnyGetterWriter getAnyGetter() { return _anyGetter; } public Object getFilterId() { return _filterId; } public AnnotatedMember getTypeId() { return _typeId; } public ObjectIdWriter getObjectIdWriter() { return _objectIdWriter; } /* /********************************************************** /* Build methods for actually creating serializer instance /********************************************************** */
Method called to create BeanSerializer instance with all accumulated information. Will construct a serializer if we have enough information, or return null if not.
/** * Method called to create {@link BeanSerializer} instance with * all accumulated information. Will construct a serializer if we * have enough information, or return null if not. */
public JsonSerializer<?> build() { // [databind#2789]: There can be a case wherein `_typeId` is used, but // nothing else. Rare but has happened; so force access. if (_typeId != null) { if (_config.isEnabled(MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS)) { _typeId.fixAccess(_config.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS)); } } if (_anyGetter != null) { _anyGetter.fixAccess(_config); } BeanPropertyWriter[] properties; // No properties, any getter or object id writer? // No real serializer; caller gets to handle if (_properties == null || _properties.isEmpty()) { if (_anyGetter == null && _objectIdWriter == null) { // NOTE! Caller may still call `createDummy()` later on return null; } properties = NO_PROPERTIES; } else { properties = _properties.toArray(new BeanPropertyWriter[_properties.size()]); if (_config.isEnabled(MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS)) { for (int i = 0, end = properties.length; i < end; ++i) { properties[i].fixAccess(_config); } } } // 27-Apr-2017, tatu: Verify that filtered-properties settings are compatible if (_filteredProperties != null) { if (_filteredProperties.length != _properties.size()) { // lgtm [java/dereferenced-value-may-be-null] throw new IllegalStateException(String.format( "Mismatch between `properties` size (%d), `filteredProperties` (%s): should have as many (or `null` for latter)", _properties.size(), _filteredProperties.length)); } } return new BeanSerializer(_beanDesc.getType(), this, properties, _filteredProperties); }
Factory method for constructing an "empty" serializer; one that outputs no properties (but handles JSON objects properly, including type information)
/** * Factory method for constructing an "empty" serializer; one that * outputs no properties (but handles JSON objects properly, including * type information) */
public BeanSerializer createDummy() { // 20-Sep-2019, tatu: Can not skimp on passing builder (see [databind#2077]) return BeanSerializer.createDummy(_beanDesc.getType(), this); } }