1 package com.fasterxml.jackson.databind.introspect; 2 3 import java.lang.reflect.*; 4 5 import com.fasterxml.jackson.databind.JavaType; 6 import com.fasterxml.jackson.databind.util.ClassUtil; 7 8 /** 9 * Object that represents non-static (and usually non-transient/volatile) 10 * fields of a class. 11 */ 12 public final class AnnotatedField 13 extends AnnotatedMember 14 implements java.io.Serializable 15 { 16 private static final long serialVersionUID = 1L; 17 18 /** 19 * Actual {@link Field} used for access. 20 *<p> 21 * Transient since it cannot be persisted directly using 22 * JDK serialization 23 */ 24 protected final transient Field _field; 25 26 /** 27 * Temporary field required for JDK serialization support 28 */ 29 protected Serialization _serialization; 30 31 /* 32 /********************************************************** 33 /* Life-cycle 34 /********************************************************** 35 */ 36 AnnotatedField(TypeResolutionContext contextClass, Field field, AnnotationMap annMap)37 public AnnotatedField(TypeResolutionContext contextClass, Field field, AnnotationMap annMap) 38 { 39 super(contextClass, annMap); 40 _field = field; 41 } 42 43 @Override withAnnotations(AnnotationMap ann)44 public AnnotatedField withAnnotations(AnnotationMap ann) { 45 return new AnnotatedField(_typeContext, _field, ann); 46 } 47 48 /** 49 * Method used for JDK serialization support 50 */ AnnotatedField(Serialization ser)51 protected AnnotatedField(Serialization ser) 52 { 53 super(null, null); 54 _field = null; 55 _serialization = ser; 56 } 57 58 /* 59 /********************************************************** 60 /* Annotated impl 61 /********************************************************** 62 */ 63 64 @Override getAnnotated()65 public Field getAnnotated() { return _field; } 66 67 @Override getModifiers()68 public int getModifiers() { return _field.getModifiers(); } 69 70 @Override getName()71 public String getName() { return _field.getName(); } 72 73 @Override getRawType()74 public Class<?> getRawType() { 75 return _field.getType(); 76 } 77 78 @Override getType()79 public JavaType getType() { 80 return _typeContext.resolveType(_field.getGenericType()); 81 } 82 83 /* 84 /********************************************************** 85 /* AnnotatedMember impl 86 /********************************************************** 87 */ 88 89 @Override getDeclaringClass()90 public Class<?> getDeclaringClass() { return _field.getDeclaringClass(); } 91 92 @Override getMember()93 public Member getMember() { return _field; } 94 95 @Override setValue(Object pojo, Object value)96 public void setValue(Object pojo, Object value) throws IllegalArgumentException 97 { 98 try { 99 _field.set(pojo, value); 100 } catch (IllegalAccessException e) { 101 throw new IllegalArgumentException("Failed to setValue() for field " 102 +getFullName()+": "+e.getMessage(), e); 103 } 104 } 105 106 @Override getValue(Object pojo)107 public Object getValue(Object pojo) throws IllegalArgumentException 108 { 109 try { 110 return _field.get(pojo); 111 } catch (IllegalAccessException e) { 112 throw new IllegalArgumentException("Failed to getValue() for field " 113 +getFullName()+": "+e.getMessage(), e); 114 } 115 } 116 117 /* 118 /********************************************************** 119 /* Extended API, generic 120 /********************************************************** 121 */ 122 getAnnotationCount()123 public int getAnnotationCount() { return _annotations.size(); } 124 125 /** 126 * @since 2.6 127 */ isTransient()128 public boolean isTransient() { return Modifier.isTransient(getModifiers()); } 129 130 @Override hashCode()131 public int hashCode() { 132 return _field.getName().hashCode(); 133 } 134 135 @Override equals(Object o)136 public boolean equals(Object o) { 137 if (o == this) return true; 138 return ClassUtil.hasClass(o, getClass()) 139 && (((AnnotatedField) o)._field == _field); 140 } 141 142 @Override toString()143 public String toString() { 144 return "[field "+getFullName()+"]"; 145 } 146 147 /* 148 /********************************************************** 149 /* JDK serialization handling 150 /********************************************************** 151 */ 152 writeReplace()153 Object writeReplace() { 154 return new AnnotatedField(new Serialization(_field)); 155 } 156 readResolve()157 Object readResolve() { 158 Class<?> clazz = _serialization.clazz; 159 try { 160 Field f = clazz.getDeclaredField(_serialization.name); 161 // 06-Oct-2012, tatu: Has "lost" its security override, may need to force back 162 if (!f.isAccessible()) { 163 ClassUtil.checkAndFixAccess(f, false); 164 } 165 return new AnnotatedField(null, f, null); 166 } catch (Exception e) { 167 throw new IllegalArgumentException("Could not find method '"+_serialization.name 168 +"' from Class '"+clazz.getName()); 169 } 170 } 171 172 /** 173 * Helper class that is used as the workaround to persist 174 * Field references. It basically just stores declaring class 175 * and field name. 176 */ 177 private final static class Serialization 178 implements java.io.Serializable 179 { 180 private static final long serialVersionUID = 1L; 181 protected Class<?> clazz; 182 protected String name; 183 Serialization(Field f)184 public Serialization(Field f) { 185 clazz = f.getDeclaringClass(); 186 name = f.getName(); 187 188 } 189 } 190 } 191 192