package com.fasterxml.jackson.jr.ob.impl;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import com.fasterxml.jackson.jr.ob.JSONObjectException;
import com.fasterxml.jackson.jr.ob.api.ValueReader;
public final class BeanPropertyReader
{
private final String _name;
private final ValueReader _valueReader;
private final Method _setter;
private final Field _field;
public BeanPropertyReader(String name, Field f, Method setter) {
if ((f == null) && (setter == null)) {
throw new IllegalArgumentException("Both `field` and `setter` can not be null");
}
_name = name;
_field = f;
_setter = setter;
_valueReader = null;
}
protected BeanPropertyReader(BeanPropertyReader src, ValueReader vr) {
_name = src._name;
_field = src._field;
_setter = src._setter;
_valueReader = vr;
}
public BeanPropertyReader withReader(ValueReader vr) {
return new BeanPropertyReader(this, vr);
}
public Type genericSetterType() {
if (_setter != null) {
return _setter.getGenericParameterTypes()[0];
}
return _field.getGenericType();
}
public Class<?> rawSetterType() {
if (_setter != null) {
return _setter.getParameterTypes()[0];
}
return _field.getType();
}
public ValueReader getReader() { return _valueReader; }
public String getName() { return _name; }
public void setValueFor(Object bean, Object value) throws IOException
{
try {
if (_setter == null) {
_field.set(bean, value);
} else {
_setter.invoke(bean, value);
}
} catch (Exception e) {
Throwable t = e;
if (t instanceof InvocationTargetException) {
t = t.getCause();
}
final String valueTypeDesc = (value == null) ? "NULL" : value.getClass().getName();
throw new JSONObjectException(String.format(
"Failed to set property '%s' (raw type %s) to value of type %s; exception (%s): %s",
_name, _rawType().getName(), valueTypeDesc, e.getClass().getName(), t.getMessage()),
t);
}
}
protected String _bean() {
if (_setter != null) {
return _setter.getDeclaringClass().getName();
}
return _field.getDeclaringClass().getName();
}
protected Class<?> _rawType() {
if (_setter != null) {
return _setter.getParameterTypes()[0];
}
return _field.getType();
}
@Override
public String toString() {
return _name;
}
}