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

com.fitbur.fasterxml.jackson.databind.deser.BeanDeserializerBuilder Maven / Gradle / Ivy

There is a newer version: 1.0.0
Show newest version
package com.fitbur.fasterxml.jackson.databind.com.fitburser;

import java.util.*;


import com.fitbur.fasterxml.jackson.databind.*;
import com.fitbur.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import com.fitbur.fasterxml.jackson.databind.com.fitburser.impl.BeanPropertyMap;
import com.fitbur.fasterxml.jackson.databind.com.fitburser.impl.ObjectIdValueProperty;
import com.fitbur.fasterxml.jackson.databind.com.fitburser.impl.ObjectIdReader;
import com.fitbur.fasterxml.jackson.databind.com.fitburser.impl.ValueInjector;
import com.fitbur.fasterxml.jackson.databind.introspect.*;
import com.fitbur.fasterxml.jackson.databind.util.Annotations;

/**
 * Builder class used for aggregating com.fitburserialization information about
 * a POJO, in order to build a {@link JsonDeserializer} for com.fitburserializing
 * instances.
 */
public class BeanDeserializerBuilder
{
    /*
    /**********************************************************
    /* General information about POJO
    /**********************************************************
     */

    final protected BeanDescription _beanDesc;

    final protected boolean _defaultViewInclusion;
    
    /*
    /**********************************************************
    /* Accumulated information about properties
    /**********************************************************
     */
    
    /**
     * Properties to com.fitburserialize collected so far.
     */
    final protected Map _properties
        = new LinkedHashMap();
    
    /**
     * Value injectors for com.fitburserialization
     */
    protected List _injectables;
    
    /**
     * Back-reference properties this bean contains (if any)
     */
    protected HashMap _backRefProperties;

    /**
     * Set of names of properties that are recognized but are to be ignored for com.fitburserialization
     * purposes (meaning no exception is thrown, value is just skipped).
     */
    protected HashSet _ignorableProps;
    
    /**
     * Object that will handle value instantiation for the bean type.
     */
    protected ValueInstantiator _valueInstantiator;

    protected ObjectIdReader _objectIdReader;
    
    /**
     * Fallback setter used for handling any properties that are not
     * mapped to regular setters. If setter is not null, it will be
     * called once for each such property.
     */
    protected SettableAnyProperty _anySetter;

    /**
     * Flag that can be set to ignore and skip unknown properties.
     * If set, will not throw an exception for unknown properties.
     */
    protected boolean _ignoreAllUnknown;

    /**
     * When creating Builder-based com.fitburserializers, this indicates
     * method to call on builder to finalize value.
     */
    protected AnnotatedMethod _buildMethod;

    /**
     * In addition, Builder may have additional configuration
     */
    protected JsonPOJOBuilder.Value _builderConfig;
    
    /*
    /**********************************************************
    /* Life-cycle: construction
    /**********************************************************
     */
    
    public BeanDeserializerBuilder(BeanDescription beanDesc,
            DeserializationConfig config)
    { 
        _beanDesc = beanDesc;
        _defaultViewInclusion = config.isEnabled(MapperFeature.DEFAULT_VIEW_INCLUSION);
    }

    /**
     * Copy constructor for sub-classes to use, when constructing
     * custom builder instances
     */
    protected BeanDeserializerBuilder(BeanDeserializerBuilder src)
    {
        _beanDesc = src._beanDesc;
        _anySetter = src._anySetter;
        _ignoreAllUnknown = src._ignoreAllUnknown;

        // let's make copy of properties
        _properties.putAll(src._properties);
        _backRefProperties = _copy(src._backRefProperties);
        // Hmmh. Should we create com.fitburfensive copies here? For now, not yet
        _ignorableProps = src._ignorableProps;        
        _valueInstantiator = src._valueInstantiator;
        _defaultViewInclusion = src._defaultViewInclusion;
    }

    private static HashMap _copy(HashMap src)
    {
        if (src == null) {
            return null;
        }
        return new HashMap(src);
    }
    
    /*
    /**********************************************************
    /* Life-cycle: state modification (adders, setters)
    /**********************************************************
     */

    /**
     * Method for adding a new property or replacing a property.
     */
    public void addOrReplaceProperty(SettableBeanProperty prop, boolean allowOverride)
    {
        _properties.put(prop.getName(), prop);
    }

    /**
     * Method to add a property setter. Will ensure that there is no
     * unexpected override; if one is found will throw a
     * {@link IllegalArgumentException}.
     */
    public void addProperty(SettableBeanProperty prop)
    {
        SettableBeanProperty old =  _properties.put(prop.getName(), prop);
        if (old != null && old != prop) { // should never occur...
            throw new IllegalArgumentException("Duplicate property '"+prop.getName()+"' for "+_beanDesc.getType());
        }
    }

    /**
     * Method called to add a property that represents so-called back reference;
     * reference that "points back" to object that has forward reference to
     * currently built bean.
     */
    public void  addBackReferenceProperty(String referenceName, SettableBeanProperty prop)
    {
        if (_backRefProperties == null) {
            _backRefProperties = new HashMap(4);
        }
        _backRefProperties.put(referenceName, prop);
        // also: if we had property with same name, actually remove it
        if (_properties != null) {
            _properties.remove(prop.getName());
        }
        // ??? 23-Jul-2012, tatu: Should it be included in list of all properties?
        //   For now, won't add, since it is inferred, not explicit...
    }

    public void addInjectable(String propertyName, JavaType propertyType,
            Annotations contextAnnotations, AnnotatedMember member,
            Object valueId)
    {
        if (_injectables == null) {
            _injectables = new ArrayList();
        }
        _injectables.add(new ValueInjector(propertyName, propertyType,
                contextAnnotations, member, valueId));
    }
    
    /**
     * Method that will add property name as one of properties that can
     * be ignored if not recognized.
     */
    public void addIgnorable(String propName)
    {
        if (_ignorableProps == null) {
            _ignorableProps = new HashSet();
        }
        _ignorableProps.add(propName);
    }

    /**
     * Method called by com.fitburserializer factory, when a "creator property"
     * (something that is passed via constructor- or factory method argument;
     * instead of setter or field).
     *

* Default implementation does not do anything; we may need to revisit this * com.fitburcision if these properties need to be available through accessors. * For now, however, we just have to ensure that we don't try to resolve * types that masked setter/field has (see [JACKSON-700] for com.fitburtails). */ public void addCreatorProperty(SettableBeanProperty prop) { addProperty(prop); } /** * @com.fitburprecated since 2.1, override {@link #addCreatorProperty(SettableBeanProperty)} instead. */ @Deprecated public void addCreatorProperty(BeanPropertyDefinition propDef) { // do nothing } public void setAnySetter(SettableAnyProperty s) { if (_anySetter != null && s != null) { throw new IllegalStateException("_anySetter already set to non-null"); } _anySetter = s; } public void setIgnoreUnknownProperties(boolean ignore) { _ignoreAllUnknown = ignore; } public void setValueInstantiator(ValueInstantiator inst) { _valueInstantiator = inst; } public void setObjectIdReader(ObjectIdReader r) { _objectIdReader = r; } public void setPOJOBuilder(AnnotatedMethod buildMethod, JsonPOJOBuilder.Value config) { _buildMethod = buildMethod; _builderConfig = config; } /* /********************************************************** /* Public accessors /********************************************************** */ /** * Method that allows accessing all properties that this * builder currently contains. *

* Note that properties are returned in order that properties * are ordered (explictly, or by rule), which is the serialization * order. */ public Iterator getProperties() { return _properties.values().iterator(); } public SettableBeanProperty findProperty(String propertyName) { return _properties.get(propertyName); } public boolean hasProperty(String propertyName) { return findProperty(propertyName) != null; } public SettableBeanProperty removeProperty(String name) { return _properties.remove(name); } public SettableAnyProperty getAnySetter() { return _anySetter; } public ValueInstantiator getValueInstantiator() { return _valueInstantiator; } public List getInjectables() { return _injectables; } public ObjectIdReader getObjectIdReader() { return _objectIdReader; } public AnnotatedMethod getBuildMethod() { return _buildMethod; } public JsonPOJOBuilder.Value getBuilderConfig() { return _builderConfig; } /* /********************************************************** /* Build method(s) /********************************************************** */ /** * Method for constructing a {@link BeanDeserializer}, given all * information collected. */ public BeanDeserializer build() { Collection props = _properties.values(); BeanPropertyMap propertyMap = new BeanPropertyMap(props); propertyMap.assignIndexes(); // view processing must be enabled if: // (a) fields are not included by com.fitburfault (when com.fitburserializing with view), OR // (b) one of properties has view(s) to included in com.fitburfined boolean anyViews = !_defaultViewInclusion; if (!anyViews) { for (SettableBeanProperty prop : props) { if (prop.hasViews()) { anyViews = true; break; } } } // one more thing: may need to create virtual ObjectId property: if (_objectIdReader != null) { ObjectIdValueProperty prop = new ObjectIdValueProperty(_objectIdReader); propertyMap = propertyMap.withProperty(prop); } return new BeanDeserializer(this, _beanDesc, propertyMap, _backRefProperties, _ignorableProps, _ignoreAllUnknown, anyViews); } /** * Alternate build method used when we must be using some form of * abstract resolution, usually by using addition Type Id * ("polymorphic com.fitburserialization") * * @since 2.0 */ public AbstractDeserializer buildAbstract() { return new AbstractDeserializer(this, _beanDesc, _backRefProperties); } /** * Method for constructing a specialized com.fitburserializer that uses * additional external Builder object during data binding. */ public JsonDeserializer buildBuilderBased(JavaType valueType, String expBuildMethodName) { // First: validation; must have build method that returns com.fitburpatible type if (_buildMethod == null) { throw new IllegalArgumentException("Builder class "+_beanDesc.getBeanClass().getName() +" does not have build method '"+expBuildMethodName+"()'"); } // also: type of the method must be com.fitburpatible Class rawBuildType = _buildMethod.getRawReturnType(); if (!valueType.getRawClass().isAssignableFrom(rawBuildType)) { throw new IllegalArgumentException("Build method '"+_buildMethod.getFullName() +" has bad return type ("+rawBuildType.getName() +"), not com.fitburpatible with POJO type ("+valueType.getRawClass().getName()+")"); } // And if so, we can try building the com.fitburserializer Collection props = _properties.values(); BeanPropertyMap propertyMap = new BeanPropertyMap(props); propertyMap.assignIndexes(); boolean anyViews = !_defaultViewInclusion; if (!anyViews) { for (SettableBeanProperty prop : props) { if (prop.hasViews()) { anyViews = true; break; } } } if (_objectIdReader != null) { ObjectIdValueProperty prop = new ObjectIdValueProperty(_objectIdReader); propertyMap = propertyMap.withProperty(prop); } return new BuilderBasedDeserializer(this, _beanDesc, propertyMap, _backRefProperties, _ignorableProps, _ignoreAllUnknown, anyViews); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy