blob: e905f95f8d207a6398c9459f77819d8be14153f2 [file] [log] [blame]
package com.fasterxml.jackson.databind.introspect;
import java.lang.reflect.*;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.util.ClassUtil;
/**
* Object that represents non-static (and usually non-transient/volatile)
* fields of a class.
*/
public final class AnnotatedField
extends AnnotatedMember
implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
/**
* Actual {@link Field} used for access.
*<p>
* Transient since it cannot be persisted directly using
* JDK serialization
*/
protected final transient Field _field;
/**
* Temporary field required for JDK serialization support
*/
protected Serialization _serialization;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
public AnnotatedField(TypeResolutionContext contextClass, Field field, AnnotationMap annMap)
{
super(contextClass, annMap);
_field = field;
}
@Override
public AnnotatedField withAnnotations(AnnotationMap ann) {
return new AnnotatedField(_typeContext, _field, ann);
}
/**
* Method used for JDK serialization support
*/
protected AnnotatedField(Serialization ser)
{
super(null, null);
_field = null;
_serialization = ser;
}
/*
/**********************************************************
/* Annotated impl
/**********************************************************
*/
@Override
public Field getAnnotated() { return _field; }
@Override
public int getModifiers() { return _field.getModifiers(); }
@Override
public String getName() { return _field.getName(); }
@Override
public Class<?> getRawType() {
return _field.getType();
}
@Override
public JavaType getType() {
return _typeContext.resolveType(_field.getGenericType());
}
/*
/**********************************************************
/* AnnotatedMember impl
/**********************************************************
*/
@Override
public Class<?> getDeclaringClass() { return _field.getDeclaringClass(); }
@Override
public Member getMember() { return _field; }
@Override
public void setValue(Object pojo, Object value) throws IllegalArgumentException
{
try {
_field.set(pojo, value);
} catch (IllegalAccessException e) {
throw new IllegalArgumentException("Failed to setValue() for field "
+getFullName()+": "+e.getMessage(), e);
}
}
@Override
public Object getValue(Object pojo) throws IllegalArgumentException
{
try {
return _field.get(pojo);
} catch (IllegalAccessException e) {
throw new IllegalArgumentException("Failed to getValue() for field "
+getFullName()+": "+e.getMessage(), e);
}
}
/*
/**********************************************************
/* Extended API, generic
/**********************************************************
*/
public int getAnnotationCount() { return _annotations.size(); }
/**
* @since 2.6
*/
public boolean isTransient() { return Modifier.isTransient(getModifiers()); }
@Override
public int hashCode() {
return _field.getName().hashCode();
}
@Override
public boolean equals(Object o) {
if (o == this) return true;
return ClassUtil.hasClass(o, getClass())
&& (((AnnotatedField) o)._field == _field);
}
@Override
public String toString() {
return "[field "+getFullName()+"]";
}
/*
/**********************************************************
/* JDK serialization handling
/**********************************************************
*/
Object writeReplace() {
return new AnnotatedField(new Serialization(_field));
}
Object readResolve() {
Class<?> clazz = _serialization.clazz;
try {
Field f = clazz.getDeclaredField(_serialization.name);
// 06-Oct-2012, tatu: Has "lost" its security override, may need to force back
if (!f.isAccessible()) {
ClassUtil.checkAndFixAccess(f, false);
}
return new AnnotatedField(null, f, null);
} catch (Exception e) {
throw new IllegalArgumentException("Could not find method '"+_serialization.name
+"' from Class '"+clazz.getName());
}
}
/**
* Helper class that is used as the workaround to persist
* Field references. It basically just stores declaring class
* and field name.
*/
private final static class Serialization
implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
protected Class<?> clazz;
protected String name;
public Serialization(Field f) {
clazz = f.getDeclaringClass();
name = f.getName();
}
}
}