com.fasterxml.jackson.databind.deser.impl.PropertyValueBuffer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ehcache Show documentation
Show all versions of ehcache Show documentation
Ehcache is an open source, standards-based cache used to boost performance,
offload the database and simplify scalability. Ehcache is robust, proven and full-featured and
this has made it the most widely-used Java-based cache.
package com.fasterxml.jackson.databind.deser.impl;
import java.io.IOException;
import java.util.BitSet;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.deser.SettableAnyProperty;
import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
/**
* Simple container used for temporarily buffering a set of
* PropertyValue
s.
* Using during construction of beans (and Maps) that use Creators,
* and hence need buffering before instance (that will have properties
* to assign values to) is constructed.
*/
public class PropertyValueBuffer
{
/*
/**********************************************************
/* Configuration
/**********************************************************
*/
protected final JsonParser _parser;
protected final DeserializationContext _context;
protected final ObjectIdReader _objectIdReader;
/*
/**********************************************************
/* Accumulated properties, other stuff
/**********************************************************
*/
/**
* Buffer used for storing creator parameters for constructing
* instance.
*/
protected final Object[] _creatorParameters;
/**
* Number of creator parameters for which we have not yet received
* values.
*/
protected int _paramsNeeded;
/**
* Bitflag used to track parameters found from incoming data
* when number of parameters is
* less than 32 (fits in int).
*/
protected int _paramsSeen;
/**
* Bitflag used to track parameters found from incoming data
* when number of parameters is
* 32 or higher.
*/
protected final BitSet _paramsSeenBig;
/**
* If we get non-creator parameters before or between
* creator parameters, those need to be buffered. Buffer
* is just a simple linked list
*/
protected PropertyValue _buffered;
/**
* In case there is an Object Id property to handle, this is the value
* we have for it.
*/
protected Object _idValue;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
public PropertyValueBuffer(JsonParser p, DeserializationContext ctxt, int paramCount,
ObjectIdReader oir)
{
_parser = p;
_context = ctxt;
_paramsNeeded = paramCount;
_objectIdReader = oir;
_creatorParameters = new Object[paramCount];
if (paramCount < 32) {
_paramsSeenBig = null;
} else {
_paramsSeenBig = new BitSet();
}
}
/**
* Returns {@code true} if the given property was seen in the JSON source by
* this buffer.
*
* @since 2.8
*/
public final boolean hasParameter(SettableBeanProperty prop)
{
if (_paramsSeenBig == null) {
return ((_paramsSeen >> prop.getCreatorIndex()) & 1) == 1;
}
return _paramsSeenBig.get(prop.getCreatorIndex());
}
/**
* A variation of {@link #getParameters(SettableBeanProperty[])} that
* accepts a single property. Whereas the plural form eagerly fetches and
* validates all properties, this method may be used (along with
* {@link #hasParameter(SettableBeanProperty)}) to let applications only
* fetch the properties defined in the JSON source itself, and to have some
* other customized behavior for missing properties.
*
* @since 2.8
*/
public Object getParameter(SettableBeanProperty prop)
throws JsonMappingException
{
Object value;
if (hasParameter(prop)) {
value = _creatorParameters[prop.getCreatorIndex()];
} else {
value = _creatorParameters[prop.getCreatorIndex()] = _findMissing(prop);
}
if (value == null && _context.isEnabled(DeserializationFeature.FAIL_ON_NULL_CREATOR_PROPERTIES)) {
return _context.reportInputMismatch(prop,
"Null value for creator property '%s' (index %d); `DeserializationFeature.FAIL_ON_NULL_FOR_CREATOR_PARAMETERS` enabled",
prop.getName(), prop.getCreatorIndex());
}
return value;
}
/**
* Method called to do necessary post-processing such as injection of values
* and verification of values for required properties,
* after either {@link #assignParameter(SettableBeanProperty, Object)}
* returns true
(to indicate all creator properties are found), or when
* then whole JSON Object has been processed,
*/
public Object[] getParameters(SettableBeanProperty[] props)
throws JsonMappingException
{
// quick check to see if anything else is needed
if (_paramsNeeded > 0) {
if (_paramsSeenBig == null) {
int mask = _paramsSeen;
// not optimal, could use `Integer.trailingZeroes()`, but for now should not
// really matter for common cases
for (int ix = 0, len = _creatorParameters.length; ix < len; ++ix, mask >>= 1) {
if ((mask & 1) == 0) {
_creatorParameters[ix] = _findMissing(props[ix]);
}
}
} else {
final int len = _creatorParameters.length;
for (int ix = 0; (ix = _paramsSeenBig.nextClearBit(ix)) < len; ++ix) {
_creatorParameters[ix] = _findMissing(props[ix]);
}
}
}
if (_context.isEnabled(DeserializationFeature.FAIL_ON_NULL_CREATOR_PROPERTIES)) {
for (int ix = 0; ix < props.length; ++ix) {
if (_creatorParameters[ix] == null) {
SettableBeanProperty prop = props[ix];
_context.reportInputMismatch(prop.getType(),
"Null value for creator property '%s' (index %d); `DeserializationFeature.FAIL_ON_NULL_FOR_CREATOR_PARAMETERS` enabled",
prop.getName(), props[ix].getCreatorIndex());
}
}
}
return _creatorParameters;
}
protected Object _findMissing(SettableBeanProperty prop) throws JsonMappingException
{
// First: do we have injectable value?
Object injectableValueId = prop.getInjectableValueId();
if (injectableValueId != null) {
return _context.findInjectableValue(prop.getInjectableValueId(),
prop, null);
}
// Second: required?
if (prop.isRequired()) {
_context.reportInputMismatch(prop, "Missing required creator property '%s' (index %d)",
prop.getName(), prop.getCreatorIndex());
}
if (_context.isEnabled(DeserializationFeature.FAIL_ON_MISSING_CREATOR_PROPERTIES)) {
_context.reportInputMismatch(prop,
"Missing creator property '%s' (index %d); `DeserializationFeature.FAIL_ON_MISSING_CREATOR_PROPERTIES` enabled",
prop.getName(), prop.getCreatorIndex());
}
// Third: default value
JsonDeserializer
© 2015 - 2025 Weber Informatics LLC | Privacy Policy