下面列出了怎么用com.fasterxml.jackson.databind.deser.SettableBeanProperty的API类实例代码及写法,或者点击链接到github查看源代码。
protected Object deserializeEnumUsingPropertyBased(final JsonParser p, final DeserializationContext ctxt,
final PropertyBasedCreator creator) throws IOException
{
PropertyValueBuffer buffer = creator.startBuilding(p, ctxt, null);
JsonToken t = p.getCurrentToken();
for (; t == JsonToken.FIELD_NAME; t = p.nextToken()) {
String propName = p.getCurrentName();
p.nextToken(); // to point to value
SettableBeanProperty creatorProp = creator.findCreatorProperty(propName);
if (creatorProp != null) {
buffer.assignParameter(creatorProp, _deserializeWithErrorWrapping(p, ctxt, creatorProp));
continue;
}
if (buffer.readIdProperty(propName)) {
continue;
}
}
return creator.build(ctxt, buffer);
}
@SuppressWarnings("unused") // Used from PairInstantiatorsPopulator
static <P> void purePrimitiveInstantiator(
Class<P> pairClass, Class<?> one, Class<?> two,
BiFunction<Object, Object, P> factory
) {
PURE_PRIMITIVE_INSTANTIATORS.put(pairClass, new ValueInstantiator.Base(pairClass) {
@Override
public boolean canCreateFromObjectWith() {
return true;
}
@Override
public SettableBeanProperty[] getFromObjectArguments(DeserializationConfig config) {
JavaType oneType = config.constructType(one);
JavaType twoType = config.constructType(two);
return makeProperties(config, oneType, twoType);
}
@Override
public Object createFromObjectWith(DeserializationContext ctxt, Object[] args) {
return factory.apply(args[0], args[1]);
}
});
}
/**
* Mutant factory method that will use this instance as the base, and
* construct an instance that is otherwise same except for excluding
* properties with specified names.
*
* @since 2.8
*/
public BeanPropertyMap withoutProperties(Collection<String> toExclude)
{
if (toExclude.isEmpty()) {
return this;
}
final int len = _propsInOrder.length;
ArrayList<SettableBeanProperty> newProps = new ArrayList<SettableBeanProperty>(len);
for (int i = 0; i < len; ++i) {
SettableBeanProperty prop = _propsInOrder[i];
// 01-May-2015, tatu: Not 100% sure if existing `null`s should be retained;
// or, if entries to ignore should be retained as nulls. For now just
// prune them out
if (prop != null) { // may contain holes, too, check.
if (!toExclude.contains(prop.getName())) {
newProps.add(prop);
}
}
}
// should we try to re-index? Apparently no need
return new BeanPropertyMap(_caseInsensitive, newProps, _aliasDefs);
}
/**
* Specialized method that can be used to replace an existing entry
* (note: entry MUST exist; otherwise exception is thrown) with
* specified replacement.
*
* @since 2.9.4
*/
public void replace(SettableBeanProperty origProp, SettableBeanProperty newProp)
{
int i = 1;
int end = _hashArea.length;
for (;; i += 2) {
if (i > end) {
throw new NoSuchElementException("No entry '"+origProp.getName()+"' found, can't replace");
}
if (_hashArea[i] == origProp) {
_hashArea[i] = newProp;
break;
}
}
_propsInOrder[_findFromOrdered(origProp)] = newProp;
}
@SuppressWarnings("unused") // Used from PairInstantiatorsPopulator
static <P> ValueInstantiator primitiveObjectInstantiator(
JavaType inputType, Class<?> one,
BiFunction<Object, Object, P> factory
) {
return new ValueInstantiator.Base(inputType) {
@Override
public boolean canCreateFromObjectWith() {
return true;
}
@Override
public SettableBeanProperty[] getFromObjectArguments(DeserializationConfig config) {
JavaType oneType = config.constructType(one);
JavaType twoType = inputType.containedType(0);
return makeProperties(config, oneType, twoType);
}
@Override
public Object createFromObjectWith(DeserializationContext ctxt, Object[] args) {
return factory.apply(args[0], args[1]);
}
};
}
private final SettableBeanProperty _find2(String key, int slot, Object match)
{
if (match == null) {
// 26-Feb-2017, tatu: Need to consider aliases
return _findWithAlias(_aliasMapping.get(key));
}
// no? secondary?
int hashSize = _hashMask+1;
int ix = hashSize + (slot>>1) << 1;
match = _hashArea[ix];
if (key.equals(match)) {
return (SettableBeanProperty) _hashArea[ix+1];
}
if (match != null) { // _findFromSpill(...)
int i = (hashSize + (hashSize>>1)) << 1;
for (int end = i + _spillCount; i < end; i += 2) {
match = _hashArea[i];
if ((match == key) || key.equals(match)) {
return (SettableBeanProperty) _hashArea[i+1];
}
}
}
// 26-Feb-2017, tatu: Need to consider aliases
return _findWithAlias(_aliasMapping.get(key));
}
private SettableBeanProperty _findWithAlias(String keyFromAlias)
{
if (keyFromAlias == null) {
return null;
}
// NOTE: need to inline much of handling do avoid cyclic calls via alias
// first, inlined main `find(String)`
int slot = _hashCode(keyFromAlias);
int ix = (slot<<1);
Object match = _hashArea[ix];
if (keyFromAlias.equals(match)) {
return (SettableBeanProperty) _hashArea[ix+1];
}
if (match == null) {
return null;
}
return _find2ViaAlias(keyFromAlias, slot, match);
}
private SettableBeanProperty _find2ViaAlias(String key, int slot, Object match)
{
// no? secondary?
int hashSize = _hashMask+1;
int ix = hashSize + (slot>>1) << 1;
match = _hashArea[ix];
if (key.equals(match)) {
return (SettableBeanProperty) _hashArea[ix+1];
}
if (match != null) { // _findFromSpill(...)
int i = (hashSize + (hashSize>>1)) << 1;
for (int end = i + _spillCount; i < end; i += 2) {
match = _hashArea[i];
if ((match == key) || key.equals(match)) {
return (SettableBeanProperty) _hashArea[i+1];
}
}
}
return null;
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("Properties=[");
int count = 0;
Iterator<SettableBeanProperty> it = iterator();
while (it.hasNext()) {
SettableBeanProperty prop = it.next();
if (count++ > 0) {
sb.append(", ");
}
sb.append(prop.getName());
sb.append('(');
sb.append(prop.getType());
sb.append(')');
}
sb.append(']');
if (!_aliasDefs.isEmpty()) {
sb.append("(aliases: ");
sb.append(_aliasDefs);
sb.append(")");
}
return sb.toString();
}
protected SettableBeanProperty _rename(SettableBeanProperty prop, NameTransformer xf)
{
if (prop == null) {
return prop;
}
String newName = xf.transform(prop.getName());
prop = prop.withSimpleName(newName);
JsonDeserializer<?> deser = prop.getValueDeserializer();
if (deser != null) {
@SuppressWarnings("unchecked")
JsonDeserializer<Object> newDeser = (JsonDeserializer<Object>)
deser.unwrappingDeserializer(xf);
if (newDeser != deser) {
prop = prop.withValueDeserializer(newDeser);
}
}
return prop;
}
/**
* 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;
}
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<Object> deser = prop.getValueDeserializer();
return deser.getNullValue(_context);
}
/**
* Method called to buffer value for given property, as well as check whether
* we now have values for all (creator) properties that we expect to get values for.
*
* @return True if we have received all creator parameters
*
* @since 2.6
*/
public boolean assignParameter(SettableBeanProperty prop, Object value)
{
final int ix = prop.getCreatorIndex();
_creatorParameters[ix] = value;
if (_paramsSeenBig == null) {
int old = _paramsSeen;
int newValue = (old | (1 << ix));
if (old != newValue) {
_paramsSeen = newValue;
if (--_paramsNeeded <= 0) {
// 29-Nov-2016, tatu: But! May still require Object Id value
return (_objectIdReader == null) || (_idValue != null);
}
}
} else {
if (!_paramsSeenBig.get(ix)) {
_paramsSeenBig.set(ix);
if (--_paramsNeeded <= 0) {
// 29-Nov-2016, tatu: But! May still require Object Id value
}
}
}
return false;
}
/**
* Factory method used for building actual instances to be used with types
* OTHER than POJOs.
* resolves deserializers and checks for "null values".
*
* @since 2.9
*/
public static PropertyBasedCreator construct(DeserializationContext ctxt,
ValueInstantiator valueInstantiator, SettableBeanProperty[] srcCreatorProps,
boolean caseInsensitive)
throws JsonMappingException
{
final int len = srcCreatorProps.length;
SettableBeanProperty[] creatorProps = new SettableBeanProperty[len];
for (int i = 0; i < len; ++i) {
SettableBeanProperty prop = srcCreatorProps[i];
if (!prop.hasValueDeserializer()) {
prop = prop.withValueDeserializer(ctxt.findContextualValueDeserializer(prop.getType(), prop));
}
creatorProps[i] = prop;
}
return new PropertyBasedCreator(ctxt, valueInstantiator, creatorProps,
caseInsensitive, false);
}
/**
* Method called to find {@link NullValueProvider} for a primary property, using
* "value nulls" setting. If no provider found (not defined, or is "skip"),
* will return `null`.
*
* @since 2.9
*/
protected final NullValueProvider findValueNullProvider(DeserializationContext ctxt,
SettableBeanProperty prop, PropertyMetadata propMetadata)
throws JsonMappingException
{
if (prop != null) {
return _findNullProvider(ctxt, prop, propMetadata.getValueNulls(),
prop.getValueDeserializer());
}
return null;
}
@Override
public SettableBeanProperty[] getFromObjectArguments(DeserializationConfig config) {
JavaType intType = config.constructType(Integer.TYPE);
JavaType longType = config.constructType(Long.TYPE);
return new SettableBeanProperty[] {
creatorProp("sourceRef", config.constructType(Object.class), 0),
creatorProp("byteOffset", longType, 1),
creatorProp("charOffset", longType, 2),
creatorProp("lineNr", intType, 3),
creatorProp("columnNr", intType, 4)
};
}
@Override
public SettableBeanProperty findBackReference(String refName) {
JsonDeserializer<Object> valueDeser = getContentDeserializer();
if (valueDeser == null) {
throw new IllegalArgumentException(String.format(
"Cannot handle managed/back reference '%s': type: container deserializer of type %s returned null for 'getContentDeserializer()'",
refName, getClass().getName()));
}
return valueDeser.findBackReference(refName);
}
@Override
public SettableBeanProperty withValueDeserializer(JsonDeserializer<?> deser) {
if (_valueDeserializer == deser) {
return this;
}
return new ObjectIdReferenceProperty(this, deser, _nullProvider);
}
public AbstractBeanDeserializer(BeanDeserializerBuilder builder,
BeanDescription beanDesc,
BeanPropertyMap properties,
Map<String, SettableBeanProperty> backRefs, HashSet<String> ignorableProps,
boolean ignoreAllUnknown, boolean hasViews) {
super(builder, beanDesc, properties, backRefs, ignorableProps, ignoreAllUnknown, hasViews);
}
public BeanPropertyMap assignIndexes()
{
// order is arbitrary, but stable:
int index = 0;
for (int i = 1, end = _hashArea.length; i < end; i += 2) {
SettableBeanProperty prop = (SettableBeanProperty) _hashArea[i];
if (prop != null) {
prop.assignIndex(index++);
}
}
return this;
}
@Deprecated // in 2.9.4 -- must call method that takes old and new property to avoid mismatch
public void replace(SettableBeanProperty newProp)
{
String key = getPropertyName(newProp);
int ix = _findIndexInHash(key);
if (ix < 0) {
throw new NoSuchElementException("No entry '"+key+"' found, can't replace");
}
SettableBeanProperty prop = (SettableBeanProperty) _hashArea[ix];
_hashArea[ix] = newProp;
// also, replace in in-order
_propsInOrder[_findFromOrdered(prop)] = newProp;
}
/**
* Specialized method for removing specified existing entry.
* NOTE: entry MUST exist, otherwise an exception is thrown.
*/
public void remove(SettableBeanProperty propToRm)
{
ArrayList<SettableBeanProperty> props = new ArrayList<SettableBeanProperty>(_size);
String key = getPropertyName(propToRm);
boolean found = false;
for (int i = 1, end = _hashArea.length; i < end; i += 2) {
SettableBeanProperty prop = (SettableBeanProperty) _hashArea[i];
if (prop == null) {
continue;
}
if (!found) {
// 09-Jan-2017, tatu: Important: must check name slot and NOT property name,
// as only former is lower-case in case-insensitive case
found = key.equals(_hashArea[i-1]);
if (found) {
// need to leave a hole here
_propsInOrder[_findFromOrdered(prop)] = null;
continue;
}
}
props.add(prop);
}
if (!found) {
throw new NoSuchElementException("No entry '"+propToRm.getName()+"' found, can't remove");
}
init(props);
}
private List<SettableBeanProperty> _properties() {
ArrayList<SettableBeanProperty> p = new ArrayList<SettableBeanProperty>(_size);
for (int i = 1, end = _hashArea.length; i < end; i += 2) {
SettableBeanProperty prop = (SettableBeanProperty) _hashArea[i];
if (prop != null) {
p.add(prop);
}
}
return p;
}
/**
* Constructor used with JDK Serialization; needed to handle transient
* Constructor, wrap/unwrap in/out-of Annotated variant.
*/
protected InnerClassProperty(SettableBeanProperty src, AnnotatedConstructor ann)
{
super(src);
_annotated = ann;
_creator = (_annotated == null) ? null : _annotated.getAnnotated();
if (_creator == null) {
throw new IllegalArgumentException("Missing constructor (broken JDK (de)serialization?)");
}
}
private static SettableBeanProperty[] makeProperties(DeserializationConfig config,
JavaType oneType,
JavaType twoType
) {
// 08-Jun-2020, tatu: as per [databind#2748] do not have access to DeserializationContext
// so can not get `TypeDeserializer`s...
// Must be changed to use `ValueInstantiator.createContextual()` (added in 2.12)
// to get access
return new SettableBeanProperty[]{
CreatorProperty.construct(
PropertyName.construct("one"), oneType, null,
// as per above:
// config.findTypeDeserializer(oneType),
null,
AnnotationCollector.emptyAnnotations(), null,
0, null, PropertyMetadata.STD_REQUIRED
),
CreatorProperty.construct(
PropertyName.construct("two"), twoType, null,
// as per above:
// config.findTypeDeserializer(oneType),
null,
AnnotationCollector.emptyAnnotations(), null,
1, null, PropertyMetadata.STD_REQUIRED
)
};
}
/**
* 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());
}
@SuppressWarnings("resource")
public Object processUnwrapped(JsonParser originalParser, DeserializationContext ctxt,
Object bean, TokenBuffer buffered)
throws IOException
{
for (int i = 0, len = _properties.size(); i < len; ++i) {
SettableBeanProperty prop = _properties.get(i);
JsonParser p = buffered.asParser();
p.nextToken();
prop.deserializeAndSet(p, ctxt, bean);
}
return bean;
}
@Deprecated // since 2.9
public static PropertyBasedCreator construct(DeserializationContext ctxt,
ValueInstantiator valueInstantiator, SettableBeanProperty[] srcCreatorProps)
throws JsonMappingException
{
return construct(ctxt, valueInstantiator, srcCreatorProps,
ctxt.isEnabled(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES));
}
public SettableBeanProperty findCreatorProperty(int propertyIndex) {
for (SettableBeanProperty prop : _propertyLookup.values()) {
if (prop.getPropertyIndex() == propertyIndex) {
return prop;
}
}
return null;
}
public void addExternal(SettableBeanProperty property, TypeDeserializer typeDeser)
{
Integer index = _properties.size();
_properties.add(new ExtTypedProperty(property, typeDeser));
_addPropertyIndex(property.getName(), index);
_addPropertyIndex(typeDeser.getPropertyName(), index);
}