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

com.fasterxml.jackson.databind.deser.impl.ManagedReferenceProperty Maven / Gradle / Ivy

There is a newer version: 2.22.2
Show newest version
package com.fasterxml.jackson.databind.deser.impl;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.Collection;
import java.util.Map;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.PropertyName;
import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
import com.fasterxml.jackson.databind.util.Annotations;

/**
 * Wrapper property that is used to handle managed (forward) properties
 * (see [JACKSON-235] for more information). Basically just need to
 * delegate first to actual forward property, and 
 */
public final class ManagedReferenceProperty
    extends SettableBeanProperty
{
    private static final long serialVersionUID = 1L;

    protected final String _referenceName;
    
    /**
     * Flag that indicates whether property to handle is a container type
     * (array, Collection, Map) or not.
     */
    protected final boolean _isContainer;
    
    protected final SettableBeanProperty _managedProperty;

    protected final SettableBeanProperty _backProperty;
    
    public ManagedReferenceProperty(SettableBeanProperty forward,
            String refName, SettableBeanProperty backward,
            Annotations contextAnnotations, boolean isContainer)
    {
        super(forward.getFullName(), forward.getType(), forward.getWrapperName(),
                forward.getValueTypeDeserializer(), contextAnnotations,
                forward.getMetadata());
        _referenceName = refName;
        _managedProperty = forward;
        _backProperty = backward;
        _isContainer = isContainer;
    }

    protected ManagedReferenceProperty(ManagedReferenceProperty src, JsonDeserializer deser)
    {
        super(src, deser);
        _referenceName = src._referenceName;
        _isContainer = src._isContainer;
        _managedProperty = src._managedProperty;
        _backProperty = src._backProperty;
    }

    protected ManagedReferenceProperty(ManagedReferenceProperty src, PropertyName newName) {
        super(src, newName);
        _referenceName = src._referenceName;
        _isContainer = src._isContainer;
        _managedProperty = src._managedProperty;
        _backProperty = src._backProperty;
    }

    @Override
    public ManagedReferenceProperty withName(PropertyName newName) {
        return new ManagedReferenceProperty(this, newName);
    }
    
    @Override
    public ManagedReferenceProperty withValueDeserializer(JsonDeserializer deser) {
        return new ManagedReferenceProperty(this, deser);
    }
    
    /*
    /**********************************************************
    /* BeanProperty impl
    /**********************************************************
     */
    
    @Override
    public  A getAnnotation(Class acls) {
        return _managedProperty.getAnnotation(acls);
    }

    @Override public AnnotatedMember getMember() {  return _managedProperty.getMember(); }

    /*
    /**********************************************************
    /* Overridden methods
    /**********************************************************
     */

    @Override
    public void deserializeAndSet(JsonParser jp, DeserializationContext ctxt,
                                  Object instance)
        throws IOException, JsonProcessingException
    {
        set(instance, _managedProperty.deserialize(jp, ctxt));
    }

    @Override
    public Object deserializeSetAndReturn(JsonParser jp,
    		DeserializationContext ctxt, Object instance)
        throws IOException, JsonProcessingException
    {
        return setAndReturn(instance, deserialize(jp, ctxt));
    }
    
    @Override
    public final void set(Object instance, Object value)
        throws IOException
    {
    	setAndReturn(instance, value);
    }

    @Override
    public Object setAndReturn(Object instance, Object value)
   		throws IOException
	{
        Object result = _managedProperty.setAndReturn(instance, value);
        /* And then back reference, if (and only if!) we actually have a non-null
         * reference
         */
        if (value != null) {
            if (_isContainer) { // ok, this gets ugly... but has to do for now
                if (value instanceof Object[]) {
                    for (Object ob : (Object[]) value) {
                        if (ob != null) {
                            _backProperty.set(ob, instance);                            
                        }
                    }
                } else if (value instanceof Collection) {
                    for (Object ob : (Collection) value) {
                        if (ob != null) {
                            _backProperty.set(ob, instance);                            
                        }
                    }
                } else if (value instanceof Map) {
                    for (Object ob : ((Map) value).values()) {
                        if (ob != null) {
                            _backProperty.set(ob, instance);                            
                        }
                    }
                } else {
                    throw new IllegalStateException("Unsupported container type ("+value.getClass().getName()
                            +") when resolving reference '"+_referenceName+"'");
                }
            } else {
                _backProperty.set(value, instance);
            }
        }
        return result;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy