package com.owlike.genson.reflect;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import com.owlike.genson.*;
import com.owlike.genson.stream.JsonWriter;
import com.owlike.genson.stream.ObjectWriter;
public abstract class PropertyAccessor extends BeanProperty implements Comparable<PropertyAccessor> {
Serializer<Object> propertySerializer;
private final char[] escapedName;
protected PropertyAccessor(String name, Type type, Class<?> declaringClass, Class<?> concreteClass,
Annotation[] annotations, int modifiers) {
super(name, type, declaringClass, concreteClass, annotations, modifiers);
escapedName = JsonWriter.escapeString(name);
}
public void serialize(Object propertySource, ObjectWriter writer, Context ctx) {
Object propertyValue = access(propertySource);
writer.writeEscapedName(escapedName);
try {
propertySerializer.serialize(propertyValue, writer, ctx);
} catch (Throwable th) {
throw couldNotSerialize(th);
}
}
public abstract Object access(final Object target);
public int compareTo(PropertyAccessor o) {
return o.priority() - priority();
}
protected JsonBindingException couldNotAccess(Exception e) {
return new JsonBindingException("Could not access value of property named '"
+ name + "' using accessor " + signature() + " from class "
+ declaringClass.getName(), e);
}
protected JsonBindingException couldNotSerialize(Throwable e) {
return new JsonBindingException("Could not serialize property '" + name
+ "' from class " + declaringClass.getName(), e);
}
public static class MethodAccessor extends PropertyAccessor {
protected final Method _getter;
public MethodAccessor(String name, Method getter, Type type, Class<?> concreteClass) {
super(name, type, getter.getDeclaringClass(), concreteClass, getter.getAnnotations(), getter.getModifiers());
this._getter = getter;
if (!_getter.isAccessible()) {
_getter.setAccessible(true);
}
}
@Override
public Object access(final Object target) {
try {
return _getter.invoke(target);
} catch (IllegalArgumentException e) {
throw couldNotAccess(e);
} catch (IllegalAccessException e) {
throw couldNotAccess(e);
} catch (InvocationTargetException e) {
throw couldNotAccess(e);
}
}
@Override
String signature() {
return _getter.toGenericString();
}
@Override
int priority() {
return 100;
}
}
public static class FieldAccessor extends PropertyAccessor {
protected final Field _field;
public FieldAccessor(String name, Field field, Type type, Class<?> concreteClass) {
super(name, type, field.getDeclaringClass(), concreteClass, field.getAnnotations(), field.getModifiers());
this._field = field;
if (!_field.isAccessible()) {
_field.setAccessible(true);
}
}
@Override
public Object access(final Object target) {
try {
return _field.get(target);
} catch (IllegalArgumentException e) {
throw couldNotAccess(e);
} catch (IllegalAccessException e) {
throw couldNotAccess(e);
}
}
@Override
public String signature() {
return _field.toGenericString();
}
@Override
public int priority() {
return 50;
}
}
}