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      * Flag that indicates whether (fulll) annotation resolution should
81      * occur: starting with 2.11 is disabled for JDK container types.
82      *
83      * @since 2.11
84      */

85     final protected boolean _collectAnnotations;
86
87     /*
88     /**********************************************************
89     /* Gathered information
90     /**********************************************************
91      */

92
93     /**
94      * Combined list of Jackson annotations that the class has,
95      * including inheritable ones from super classes and interfaces
96      */

97     final protected Annotations _classAnnotations;
98
99     /**
100      * @since 2.9
101      */

102     protected Creators _creators;
103
104     /**
105      * Member methods of interest; for now ones with 0 or 1 arguments
106      * (just optimization, since others won't be used now)
107      */

108     protected AnnotatedMethodMap _memberMethods;
109
110     /**
111      * Member fields of interest: ones that are either public,
112      * or have at least one annotation.
113      */

114     protected List<AnnotatedField> _fields;
115
116     /**
117      * Lazily determined property to see if this is a non-static inner
118      * class.
119      *
120      * @since 2.8.7
121      */

122     protected transient Boolean _nonStaticInnerClass;
123
124     /*
125     /**********************************************************
126     /* Life-cycle
127     /**********************************************************
128      */

129
130     /**
131      * Constructor will not do any initializations, to allow for
132      * configuring instances differently depending on use cases
133      *
134      * @param type Fully resolved type; may be `null`, but ONLY if no member fields or
135      *    methods are to be accessed
136      * @param rawType Type-erased class; pass if no `type` needed or available
137      */

138     AnnotatedClass(JavaType type, Class<?> rawType, List<JavaType> superTypes,
139             Class<?> primaryMixIn, Annotations classAnnotations, TypeBindings bindings, 
140             AnnotationIntrospector aintr, MixInResolver mir, TypeFactory tf,
141             boolean collectAnnotations)
142     {
143         _type = type;
144         _class = rawType;
145         _superTypes = superTypes;
146         _primaryMixIn = primaryMixIn;
147         _classAnnotations = classAnnotations;
148         _bindings = bindings;
149         _annotationIntrospector = aintr;
150         _mixInResolver = mir;
151         _typeFactory = tf;
152         _collectAnnotations = collectAnnotations;
153     }
154
155     @Deprecated // since 2.10
156     AnnotatedClass(JavaType type, Class<?> rawType, List<JavaType> superTypes,
157             Class<?> primaryMixIn, Annotations classAnnotations, TypeBindings bindings, 
158             AnnotationIntrospector aintr, MixInResolver mir, TypeFactory tf)
159     {
160         this(type, rawType, superTypes, primaryMixIn, classAnnotations, bindings,
161                 aintr, mir, tf, true);
162     }
163
164     /**
165      * Constructor (only) used for creating primordial simple types (during bootstrapping)
166      * and array type placeholders where no fields or methods are needed.
167      *
168      * @since 2.9
169      */

170     AnnotatedClass(Class<?> rawType) {
171         _type = null;
172         _class = rawType;
173         _superTypes = Collections.emptyList();
174         _primaryMixIn = null;
175         _classAnnotations = AnnotationCollector.emptyAnnotations();
176         _bindings = TypeBindings.emptyBindings();
177         _annotationIntrospector = null;
178         _mixInResolver = null;
179         _typeFactory = null;
180         _collectAnnotations = false;
181     }
182
183     /**
184      * @deprecated Since 2.9, use methods in {@link AnnotatedClassResolver} instead.
185      */

186     @Deprecated
187     public static AnnotatedClass construct(JavaType type, MapperConfig<?> config) {
188         return construct(type, config, (MixInResolver) config);
189     }
190
191     /**
192      * @deprecated Since 2.9, use methods in {@link AnnotatedClassResolver} instead.
193      */

194     @Deprecated
195     public static AnnotatedClass construct(JavaType type, MapperConfig<?> config,
196             MixInResolver mir)
197     {
198         return AnnotatedClassResolver.resolve(config, type, mir);
199     }
200
201     /**
202      * Method similar to {@link #construct}, but that will NOT include
203      * information from supertypes; only class itself and any direct
204      * mix-ins it may have.
205      */

206     /**
207      * @deprecated Since 2.9, use methods in {@link AnnotatedClassResolver} instead.
208      */

209     @Deprecated
210     public static AnnotatedClass constructWithoutSuperTypes(Class<?> raw, MapperConfig<?> config) {
211         return constructWithoutSuperTypes(raw, config, config);
212     }
213
214     /**
215      * @deprecated Since 2.9, use methods in {@link AnnotatedClassResolver} instead.
216      */

217     @Deprecated
218     public static AnnotatedClass constructWithoutSuperTypes(Class<?> raw, MapperConfig<?> config,
219             MixInResolver mir)
220     {
221         return AnnotatedClassResolver.resolveWithoutSuperTypes(config, raw, mir);
222     }
223
224     /*
225     /**********************************************************
226     /* TypeResolutionContext implementation
227     /**********************************************************
228      */

229
230     @Override
231     public JavaType resolveType(Type type) {
232         // 05-Sep-2020, tatu: [databind#2846][databind#2821] avoid
233         //    passing context in case of Raw class (generic type declared
234         //    without type parametrers) as that can lead to mismatch
235         if (type instanceof Class<?>) {
236             return _typeFactory.constructType(type);
237         }
238         return _typeFactory.constructType(type, _bindings);
239     }
240
241     /*
242     /**********************************************************
243     /* Annotated impl 
244     /**********************************************************
245      */

246
247     @Override
248     public Class<?> getAnnotated() { return _class; }
249
250     @Override
251     public int getModifiers() { return _class.getModifiers(); }
252
253     @Override
254     public String getName() { return _class.getName(); }
255
256     @Override
257     public <A extends Annotation> A getAnnotation(Class<A> acls) {
258         return _classAnnotations.get(acls);
259     }
260
261     @Override
262     public boolean hasAnnotation(Class<?> acls) {
263         return _classAnnotations.has(acls);
264     }
265
266     @Override
267     public boolean hasOneOf(Class<? extends Annotation>[] annoClasses) {
268         return _classAnnotations.hasOneOf(annoClasses);
269     }
270
271     @Override
272     public Class<?> getRawType() {
273         return _class;
274     }
275
276     @Override
277     @Deprecated
278     public Iterable<Annotation> annotations() {
279         if (_classAnnotations instanceof AnnotationMap) {
280             return ((AnnotationMap) _classAnnotations).annotations();
281         } else if (_classAnnotations instanceof AnnotationCollector.OneAnnotation ||
282            _classAnnotations instanceof AnnotationCollector.TwoAnnotations) {
283             throw new UnsupportedOperationException("please use getAnnotations/ hasAnnotation to check for Annotations");
284         }
285         return Collections.emptyList();
286     }
287
288     @Override
289     public JavaType getType() {
290         return _type;
291     }
292
293     /*
294     /**********************************************************
295     /* Public API, generic accessors
296     /**********************************************************
297      */

298
299     public Annotations getAnnotations() {
300         return _classAnnotations;
301     }
302
303     public boolean hasAnnotations() {
304         return _classAnnotations.size() > 0;
305     }
306
307     public AnnotatedConstructor getDefaultConstructor() {
308         return _creators().defaultConstructor;
309     }
310
311     public List<AnnotatedConstructor> getConstructors() {
312         return _creators().constructors;
313     }
314
315     /**
316      * @since 2.9
317      */

318     public List<AnnotatedMethod> getFactoryMethods() {
319         return _creators().creatorMethods;
320     }
321
322     /**
323      * @deprecated Since 2.9; use {@link #getFactoryMethods} instead.
324      */

325     @Deprecated
326     public List<AnnotatedMethod> getStaticMethods() {
327         return getFactoryMethods();
328     }
329
330     public Iterable<AnnotatedMethod> memberMethods() {
331         return _methods();
332     }
333
334     public int getMemberMethodCount() {
335         return _methods().size();
336     }
337
338     public AnnotatedMethod findMethod(String name, Class<?>[] paramTypes) {
339         return _methods().find(name, paramTypes);
340     }
341
342     public int getFieldCount() {
343         return _fields().size();
344     }
345
346     public Iterable<AnnotatedField> fields() {
347         return _fields();
348     }
349
350     /**
351      * @since 2.9
352      */

353     public boolean isNonStaticInnerClass()
354     {
355         Boolean B = _nonStaticInnerClass;
356         if (B == null) {
357             _nonStaticInnerClass = B = ClassUtil.isNonStaticInnerClass(_class);
358         }
359         return B.booleanValue();
360     }
361
362     /*
363     /**********************************************************
364     /* Lazily-operating accessors
365     /**********************************************************
366      */

367
368     private final List<AnnotatedField> _fields() {
369         List<AnnotatedField> f = _fields;
370         if (f == null) {
371             // 09-Jun-2017, tatu: _type only null for primordial, placeholder array types.
372             if (_type == null) {
373                 f = Collections.emptyList();
374             } else {
375                 f = AnnotatedFieldCollector.collectFields(_annotationIntrospector,
376                         this, _mixInResolver, _typeFactory, _type, _collectAnnotations);
377             }
378             _fields = f;
379         }
380         return f;
381     }
382
383     private final AnnotatedMethodMap _methods() {
384         AnnotatedMethodMap m = _memberMethods;
385         if (m == null) {
386             // 09-Jun-2017, tatu: _type only null for primordial, placeholder array types.
387             //    NOTE: would be great to have light-weight shareable maps; no such impl exists for now
388             if (_type == null) {
389                 m = new AnnotatedMethodMap();
390             } else {
391                 m = AnnotatedMethodCollector.collectMethods(_annotationIntrospector,
392                         this,
393                         _mixInResolver, _typeFactory,
394                         _type, _superTypes, _primaryMixIn, _collectAnnotations);
395             }
396             _memberMethods = m;
397         }
398         return m;
399     }
400
401     private final Creators _creators() {
402         Creators c = _creators;
403         if (c == null) {
404             if (_type == null) {
405                 c = NO_CREATORS;
406             } else {
407                 c = AnnotatedCreatorCollector.collectCreators(_annotationIntrospector,
408                         _typeFactory,
409                         this, _type, _primaryMixIn, _collectAnnotations);
410             }
411             _creators = c;
412         }
413         return c;
414     }
415
416     /*
417     /**********************************************************
418     /* Standard method overrides
419     /**********************************************************
420      */

421
422     @Override
423     public String toString() {
424         return "[AnnotedClass "+_class.getName()+"]";
425     }
426
427     @Override
428     public int hashCode() {
429         return _class.getName().hashCode();
430     }
431     
432     @Override
433     public boolean equals(Object o) {
434         if (o == thisreturn true;
435         if (!ClassUtil.hasClass(o, getClass())) {
436             return false;
437         }
438         return ((AnnotatedClass) o)._class == _class;
439     }
440
441     /*
442     /**********************************************************
443     /* Helper classes
444     /**********************************************************
445      */

446
447     public static final class Creators
448     {
449         /**
450          * Default constructor of the annotated classif it has one.
451          */

452         public final AnnotatedConstructor defaultConstructor;
453
454         /**
455          * Single argument constructors the class has, if any.
456          */

457         public final List<AnnotatedConstructor> constructors;
458
459         /**
460          * Single argument static methods that might be usable
461          * as factory methods
462          */

463         public final List<AnnotatedMethod> creatorMethods;
464
465         public Creators(AnnotatedConstructor defCtor,
466                 List<AnnotatedConstructor> ctors,
467                 List<AnnotatedMethod> ctorMethods)
468         {
469             defaultConstructor = defCtor;
470             constructors = ctors;
471             creatorMethods = ctorMethods;
472         }
473     }
474 }
475