package com.fasterxml.jackson.databind.deser.impl;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.NullValueProvider;
import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
import com.fasterxml.jackson.databind.introspect.AnnotatedMethod;
import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
import com.fasterxml.jackson.databind.util.Annotations;
public final class SetterlessProperty
extends SettableBeanProperty
{
private static final long serialVersionUID = 1L;
protected final AnnotatedMethod _annotated;
protected final Method _getter;
public SetterlessProperty(BeanPropertyDefinition propDef, JavaType type,
TypeDeserializer typeDeser, Annotations contextAnnotations, AnnotatedMethod method)
{
super(propDef, type, typeDeser, contextAnnotations);
_annotated = method;
_getter = method.getAnnotated();
}
protected SetterlessProperty(SetterlessProperty src, JsonDeserializer<?> deser,
NullValueProvider nva) {
super(src, deser, nva);
_annotated = src._annotated;
_getter = src._getter;
}
protected SetterlessProperty(SetterlessProperty src, PropertyName newName) {
super(src, newName);
_annotated = src._annotated;
_getter = src._getter;
}
@Override
public SettableBeanProperty withName(PropertyName newName) {
return new SetterlessProperty(this, newName);
}
@Override
public SettableBeanProperty withValueDeserializer(JsonDeserializer<?> deser) {
if (_valueDeserializer == deser) {
return this;
}
NullValueProvider nvp = (_valueDeserializer == _nullProvider) ? deser : _nullProvider;
return new SetterlessProperty(this, deser, nvp);
}
@Override
public SettableBeanProperty withNullProvider(NullValueProvider nva) {
return new SetterlessProperty(this, _valueDeserializer, nva);
}
@Override
public void fixAccess(DeserializationConfig config) {
_annotated.fixAccess(
config.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS));
}
@Override
public <A extends Annotation> A getAnnotation(Class<A> acls) {
return _annotated.getAnnotation(acls);
}
@Override public AnnotatedMember getMember() { return _annotated; }
@Override
public final void deserializeAndSet(JsonParser p, DeserializationContext ctxt,
Object instance) throws IOException
{
if (p.hasToken(JsonToken.VALUE_NULL)) {
return;
}
if (_valueTypeDeserializer != null) {
ctxt.reportBadDefinition(getType(), String.format(
"Problem deserializing 'setterless' property (\"%s\"): no way to handle typed deser with setterless yet",
getName()));
}
Object toModify;
try {
toModify = _getter.invoke(instance, (Object[]) null);
} catch (Exception e) {
_throwAsIOE(p, e);
return;
}
if (toModify == null) {
ctxt.reportBadDefinition(getType(), String.format(
"Problem deserializing 'setterless' property '%s': get method returned null",
getName()));
}
_valueDeserializer.deserialize(p, ctxt, toModify);
}
@Override
public Object deserializeSetAndReturn(JsonParser p,
DeserializationContext ctxt, Object instance) throws IOException
{
deserializeAndSet(p, ctxt, instance);
return instance;
}
@Override
public final void set(Object instance, Object value) throws IOException {
throw new UnsupportedOperationException("Should never call `set()` on setterless property ('"+getName()+"')");
}
@Override
public Object setAndReturn(Object instance, Object value) throws IOException
{
set(instance, value);
return instance;
}
}