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