• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.fasterxml.jackson.databind.introspect;
2 
3 import java.lang.annotation.Annotation;
4 import java.lang.reflect.*;
5 import java.util.*;
6 
7 import com.fasterxml.jackson.databind.AnnotationIntrospector;
8 import com.fasterxml.jackson.databind.JavaType;
9 import com.fasterxml.jackson.databind.cfg.MapperConfig;
10 import com.fasterxml.jackson.databind.introspect.ClassIntrospector.MixInResolver;
11 import com.fasterxml.jackson.databind.type.TypeBindings;
12 import com.fasterxml.jackson.databind.type.TypeFactory;
13 import com.fasterxml.jackson.databind.util.Annotations;
14 import com.fasterxml.jackson.databind.util.ClassUtil;
15 
16 public final class AnnotatedClass
17     extends Annotated
18     implements TypeResolutionContext
19 {
20     private final static Creators NO_CREATORS = new Creators(null,
21             Collections.<AnnotatedConstructor>emptyList(),
22             Collections.<AnnotatedMethod>emptyList());
23 
24     /*
25     /**********************************************************
26     /* Configuration
27     /**********************************************************
28      */
29 
30     /**
31      * @since 2.7
32      */
33     final protected JavaType _type;
34 
35     /**
36      * Class for which annotations apply, and that owns other
37      * components (constructors, methods)
38      */
39     final protected Class<?> _class;
40 
41     /**
42      * Type bindings to use for members of {@link #_class}.
43      *
44      * @since 2.7
45      */
46     final protected TypeBindings _bindings;
47 
48     /**
49      * Ordered set of super classes and interfaces of the
50      * class itself: included in order of precedence
51      */
52     final protected List<JavaType> _superTypes;
53 
54     /**
55      * Filter used to determine which annotations to gather; used
56      * to optimize things so that unnecessary annotations are
57      * ignored.
58      */
59     final protected AnnotationIntrospector _annotationIntrospector;
60 
61     /**
62      * @since 2.7
63      */
64     final protected TypeFactory _typeFactory;
65 
66     /**
67      * Object that knows mapping of mix-in classes (ones that contain
68      * annotations to add) with their target classes (ones that
69      * get these additional annotations "mixed in").
70      */
71     final protected MixInResolver _mixInResolver;
72 
73     /**
74      * Primary mix-in class; one to use for the annotated class
75      * itself. Can be null.
76      */
77     final protected Class<?> _primaryMixIn;
78 
79     /**
80      * @since 2.11
81      */
82     final protected boolean _collectAnnotations;
83 
84     /*
85     /**********************************************************
86     /* Gathered information
87     /**********************************************************
88      */
89 
90     /**
91      * Combined list of Jackson annotations that the class has,
92      * including inheritable ones from super classes and interfaces
93      */
94     final protected Annotations _classAnnotations;
95 
96     /**
97      * @since 2.9
98      */
99     protected Creators _creators;
100 
101     /**
102      * Member methods of interest; for now ones with 0 or 1 arguments
103      * (just optimization, since others won't be used now)
104      */
105     protected AnnotatedMethodMap _memberMethods;
106 
107     /**
108      * Member fields of interest: ones that are either public,
109      * or have at least one annotation.
110      */
111     protected List<AnnotatedField> _fields;
112 
113     /**
114      * Lazily determined property to see if this is a non-static inner
115      * class.
116      *
117      * @since 2.8.7
118      */
119     protected transient Boolean _nonStaticInnerClass;
120 
121     /*
122     /**********************************************************
123     /* Life-cycle
124     /**********************************************************
125      */
126 
127     /**
128      * Constructor will not do any initializations, to allow for
129      * configuring instances differently depending on use cases
130      *
131      * @param type Fully resolved type; may be `null`, but ONLY if no member fields or
132      *    methods are to be accessed
133      * @param rawType Type-erased class; pass if no `type` needed or available
134      */
AnnotatedClass(JavaType type, Class<?> rawType, List<JavaType> superTypes, Class<?> primaryMixIn, Annotations classAnnotations, TypeBindings bindings, AnnotationIntrospector aintr, MixInResolver mir, TypeFactory tf, boolean collectAnnotations)135     AnnotatedClass(JavaType type, Class<?> rawType, List<JavaType> superTypes,
136             Class<?> primaryMixIn, Annotations classAnnotations, TypeBindings bindings,
137             AnnotationIntrospector aintr, MixInResolver mir, TypeFactory tf,
138             boolean collectAnnotations)
139     {
140         _type = type;
141         _class = rawType;
142         _superTypes = superTypes;
143         _primaryMixIn = primaryMixIn;
144         _classAnnotations = classAnnotations;
145         _bindings = bindings;
146         _annotationIntrospector = aintr;
147         _mixInResolver = mir;
148         _typeFactory = tf;
149         _collectAnnotations = collectAnnotations;
150     }
151 
152     @Deprecated // since 2.10
AnnotatedClass(JavaType type, Class<?> rawType, List<JavaType> superTypes, Class<?> primaryMixIn, Annotations classAnnotations, TypeBindings bindings, AnnotationIntrospector aintr, MixInResolver mir, TypeFactory tf)153     AnnotatedClass(JavaType type, Class<?> rawType, List<JavaType> superTypes,
154             Class<?> primaryMixIn, Annotations classAnnotations, TypeBindings bindings,
155             AnnotationIntrospector aintr, MixInResolver mir, TypeFactory tf)
156     {
157         this(type, rawType, superTypes, primaryMixIn, classAnnotations, bindings,
158                 aintr, mir, tf, true);
159     }
160 
161     /**
162      * Constructor (only) used for creating primordial simple types (during bootstrapping)
163      * and array type placeholders where no fields or methods are needed.
164      *
165      * @since 2.9
166      */
AnnotatedClass(Class<?> rawType)167     AnnotatedClass(Class<?> rawType) {
168         _type = null;
169         _class = rawType;
170         _superTypes = Collections.emptyList();
171         _primaryMixIn = null;
172         _classAnnotations = AnnotationCollector.emptyAnnotations();
173         _bindings = TypeBindings.emptyBindings();
174         _annotationIntrospector = null;
175         _mixInResolver = null;
176         _typeFactory = null;
177         _collectAnnotations = false;
178     }
179 
180     /**
181      * @deprecated Since 2.9, use methods in {@link AnnotatedClassResolver} instead.
182      */
183     @Deprecated
construct(JavaType type, MapperConfig<?> config)184     public static AnnotatedClass construct(JavaType type, MapperConfig<?> config) {
185         return construct(type, config, (MixInResolver) config);
186     }
187 
188     /**
189      * @deprecated Since 2.9, use methods in {@link AnnotatedClassResolver} instead.
190      */
191     @Deprecated
construct(JavaType type, MapperConfig<?> config, MixInResolver mir)192     public static AnnotatedClass construct(JavaType type, MapperConfig<?> config,
193             MixInResolver mir)
194     {
195         return AnnotatedClassResolver.resolve(config, type, mir);
196     }
197 
198     /**
199      * Method similar to {@link #construct}, but that will NOT include
200      * information from supertypes; only class itself and any direct
201      * mix-ins it may have.
202      */
203     /**
204      * @deprecated Since 2.9, use methods in {@link AnnotatedClassResolver} instead.
205      */
206     @Deprecated
constructWithoutSuperTypes(Class<?> raw, MapperConfig<?> config)207     public static AnnotatedClass constructWithoutSuperTypes(Class<?> raw, MapperConfig<?> config) {
208         return constructWithoutSuperTypes(raw, config, config);
209     }
210 
211     /**
212      * @deprecated Since 2.9, use methods in {@link AnnotatedClassResolver} instead.
213      */
214     @Deprecated
constructWithoutSuperTypes(Class<?> raw, MapperConfig<?> config, MixInResolver mir)215     public static AnnotatedClass constructWithoutSuperTypes(Class<?> raw, MapperConfig<?> config,
216             MixInResolver mir)
217     {
218         return AnnotatedClassResolver.resolveWithoutSuperTypes(config, raw, mir);
219     }
220 
221     /*
222     /**********************************************************
223     /* TypeResolutionContext implementation
224     /**********************************************************
225      */
226 
227     @Override
resolveType(Type type)228     public JavaType resolveType(Type type) {
229         return _typeFactory.constructType(type, _bindings);
230     }
231 
232     /*
233     /**********************************************************
234     /* Annotated impl
235     /**********************************************************
236      */
237 
238     @Override
getAnnotated()239     public Class<?> getAnnotated() { return _class; }
240 
241     @Override
getModifiers()242     public int getModifiers() { return _class.getModifiers(); }
243 
244     @Override
getName()245     public String getName() { return _class.getName(); }
246 
247     @Override
getAnnotation(Class<A> acls)248     public <A extends Annotation> A getAnnotation(Class<A> acls) {
249         return _classAnnotations.get(acls);
250     }
251 
252     @Override
hasAnnotation(Class<?> acls)253     public boolean hasAnnotation(Class<?> acls) {
254         return _classAnnotations.has(acls);
255     }
256 
257     @Override
hasOneOf(Class<? extends Annotation>[] annoClasses)258     public boolean hasOneOf(Class<? extends Annotation>[] annoClasses) {
259         return _classAnnotations.hasOneOf(annoClasses);
260     }
261 
262     @Override
getRawType()263     public Class<?> getRawType() {
264         return _class;
265     }
266 
267     @Override
268     @Deprecated
annotations()269     public Iterable<Annotation> annotations() {
270         if (_classAnnotations instanceof AnnotationMap) {
271             return ((AnnotationMap) _classAnnotations).annotations();
272         } else if (_classAnnotations instanceof AnnotationCollector.OneAnnotation ||
273            _classAnnotations instanceof AnnotationCollector.TwoAnnotations) {
274             throw new UnsupportedOperationException("please use getAnnotations/ hasAnnotation to check for Annotations");
275         }
276         return Collections.emptyList();
277     }
278 
279     @Override
getType()280     public JavaType getType() {
281         return _type;
282     }
283 
284     /*
285     /**********************************************************
286     /* Public API, generic accessors
287     /**********************************************************
288      */
289 
getAnnotations()290     public Annotations getAnnotations() {
291         return _classAnnotations;
292     }
293 
hasAnnotations()294     public boolean hasAnnotations() {
295         return _classAnnotations.size() > 0;
296     }
297 
getDefaultConstructor()298     public AnnotatedConstructor getDefaultConstructor() {
299         return _creators().defaultConstructor;
300     }
301 
getConstructors()302     public List<AnnotatedConstructor> getConstructors() {
303         return _creators().constructors;
304     }
305 
306     /**
307      * @since 2.9
308      */
getFactoryMethods()309     public List<AnnotatedMethod> getFactoryMethods() {
310         return _creators().creatorMethods;
311     }
312 
313     /**
314      * @deprecated Since 2.9; use {@link #getFactoryMethods} instead.
315      */
316     @Deprecated
getStaticMethods()317     public List<AnnotatedMethod> getStaticMethods() {
318         return getFactoryMethods();
319     }
320 
memberMethods()321     public Iterable<AnnotatedMethod> memberMethods() {
322         return _methods();
323     }
324 
getMemberMethodCount()325     public int getMemberMethodCount() {
326         return _methods().size();
327     }
328 
findMethod(String name, Class<?>[] paramTypes)329     public AnnotatedMethod findMethod(String name, Class<?>[] paramTypes) {
330         return _methods().find(name, paramTypes);
331     }
332 
getFieldCount()333     public int getFieldCount() {
334         return _fields().size();
335     }
336 
fields()337     public Iterable<AnnotatedField> fields() {
338         return _fields();
339     }
340 
341     /**
342      * @since 2.9
343      */
isNonStaticInnerClass()344     public boolean isNonStaticInnerClass()
345     {
346         Boolean B = _nonStaticInnerClass;
347         if (B == null) {
348             _nonStaticInnerClass = B = ClassUtil.isNonStaticInnerClass(_class);
349         }
350         return B.booleanValue();
351     }
352 
353     /*
354     /**********************************************************
355     /* Lazily-operating accessors
356     /**********************************************************
357      */
358 
_fields()359     private final List<AnnotatedField> _fields() {
360         List<AnnotatedField> f = _fields;
361         if (f == null) {
362             // 09-Jun-2017, tatu: _type only null for primordial, placeholder array types.
363             if (_type == null) {
364                 f = Collections.emptyList();
365             } else {
366                 f = AnnotatedFieldCollector.collectFields(_annotationIntrospector,
367                         this, _mixInResolver, _typeFactory, _type, _collectAnnotations);
368             }
369             _fields = f;
370         }
371         return f;
372     }
373 
_methods()374     private final AnnotatedMethodMap _methods() {
375         AnnotatedMethodMap m = _memberMethods;
376         if (m == null) {
377             // 09-Jun-2017, tatu: _type only null for primordial, placeholder array types.
378             //    NOTE: would be great to have light-weight shareable maps; no such impl exists for now
379             if (_type == null) {
380                 m = new AnnotatedMethodMap();
381             } else {
382                 m = AnnotatedMethodCollector.collectMethods(_annotationIntrospector,
383                         this,
384                         _mixInResolver, _typeFactory,
385                         _type, _superTypes, _primaryMixIn, _collectAnnotations);
386             }
387             _memberMethods = m;
388         }
389         return m;
390     }
391 
_creators()392     private final Creators _creators() {
393         Creators c = _creators;
394         if (c == null) {
395             if (_type == null) {
396                 c = NO_CREATORS;
397             } else {
398                 c = AnnotatedCreatorCollector.collectCreators(_annotationIntrospector,
399                         this, _type, _primaryMixIn, _collectAnnotations);
400             }
401             _creators = c;
402         }
403         return c;
404     }
405 
406     /*
407     /**********************************************************
408     /* Standard method overrides
409     /**********************************************************
410      */
411 
412     @Override
toString()413     public String toString() {
414         return "[AnnotedClass "+_class.getName()+"]";
415     }
416 
417     @Override
hashCode()418     public int hashCode() {
419         return _class.getName().hashCode();
420     }
421 
422     @Override
equals(Object o)423     public boolean equals(Object o) {
424         if (o == this) return true;
425         if (!ClassUtil.hasClass(o, getClass())) {
426             return false;
427         }
428         return ((AnnotatedClass) o)._class == _class;
429     }
430 
431     /*
432     /**********************************************************
433     /* Helper classes
434     /**********************************************************
435      */
436 
437     public static final class Creators
438     {
439         /**
440          * Default constructor of the annotated class, if it has one.
441          */
442         public final AnnotatedConstructor defaultConstructor;
443 
444         /**
445          * Single argument constructors the class has, if any.
446          */
447         public final List<AnnotatedConstructor> constructors;
448 
449         /**
450          * Single argument static methods that might be usable
451          * as factory methods
452          */
453         public final List<AnnotatedMethod> creatorMethods;
454 
Creators(AnnotatedConstructor defCtor, List<AnnotatedConstructor> ctors, List<AnnotatedMethod> ctorMethods)455         public Creators(AnnotatedConstructor defCtor,
456                 List<AnnotatedConstructor> ctors,
457                 List<AnnotatedMethod> ctorMethods)
458         {
459             defaultConstructor = defCtor;
460             constructors = ctors;
461             creatorMethods = ctorMethods;
462         }
463     }
464 }
465