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