All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.fasterxml.jackson.databind.ser.BeanSerializerBuilder Maven / Gradle / Ivy

The newest version!
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 {@link JsonSerializer} for serializing
 * instances.
 * 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
     */
    protected List _properties = Collections.emptyList();

    /**
     * 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.
     */
    protected AnyGetterWriter _anyGetter;

    /**
     * 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)
     */
    protected AnnotatedMember _typeId;

    /**
     * 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
     */
    protected BeanSerializerBuilder(BeanSerializerBuilder src) {
        _beanDesc = src._beanDesc;
        _config = src._config;
        _properties = src._properties;
        _filteredProperties = src._filteredProperties;
        _anyGetter = src._anyGetter;
        _filterId = src._filterId;
        _typeId = src._typeId;
        _objectIdWriter = src._objectIdWriter;
    }

    /**
     * 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 */ protected void setConfig(SerializationConfig config) { _config = config; } public void setProperties(List properties) { _properties = properties; } /** * @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 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 {@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) */ public BeanSerializer createDummy() { // 20-Sep-2019, tatu: Can not skimp on passing builder (see [databind#2077]) return BeanSerializer.createDummy(_beanDesc.getType(), this); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy