package com.fasterxml.jackson.databind.introspect;
import java.lang.annotation.Annotation;
import java.lang.reflect.*;
import java.util.*;
import com.fasterxml.jackson.databind.AnnotationIntrospector;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.cfg.MapperConfig;
import com.fasterxml.jackson.databind.introspect.ClassIntrospector.MixInResolver;
import com.fasterxml.jackson.databind.type.TypeBindings;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.fasterxml.jackson.databind.util.Annotations;
import com.fasterxml.jackson.databind.util.ClassUtil;
public final class AnnotatedClass
extends Annotated
implements TypeResolutionContext
{
/*
/**********************************************************
/* Configuration
/**********************************************************
*/
/**
* @since 2.7
*/
final protected JavaType _type;
/**
* Class for which annotations apply, and that owns other
* components (constructors, methods)
*/
final protected Class<?> _class;
/**
* Type bindings to use for members of {@link #_class}.
*
* @since 2.7
*/
final protected TypeBindings _bindings;
/**
* Ordered set of super classes and interfaces of the
* class itself: included in order of precedence
*/
final protected List<JavaType> _superTypes;
/**
* Filter used to determine which annotations to gather; used
* to optimize things so that unnecessary annotations are
* ignored.
*/
final protected AnnotationIntrospector _annotationIntrospector;
/**
* @since 2.7
*/
final protected TypeFactory _typeFactory;
/**
* Object that knows mapping of mix-in classes (ones that contain
* annotations to add) with their target classes (ones that
* get these additional annotations "mixed in").
*/
final protected MixInResolver _mixInResolver;
/**
* Primary mix-in class; one to use for the annotated class
* itself. Can be null.
*/
final protected Class<?> _primaryMixIn;
/*
/**********************************************************
/* Gathered information
/**********************************************************
*/
/**
* Combined list of Jackson annotations that the class has,
* including inheritable ones from super classes and interfaces
*/
final protected Annotations _classAnnotations;
/**
* @since 2.9
*/
protected Creators _creators;
/**
* Member methods of interest; for now ones with 0 or 1 arguments
* (just optimization, since others won't be used now)
*/
protected AnnotatedMethodMap _memberMethods;
/**
* Member fields of interest: ones that are either public,
* or have at least one annotation.
*/
protected List<AnnotatedField> _fields;
/**
* Lazily determined property to see if this is a non-static inner
* class.
*
* @since 2.8.7
*/
protected transient Boolean _nonStaticInnerClass;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
/**
* Constructor will not do any initializations, to allow for
* configuring instances differently depending on use cases
*/
AnnotatedClass(JavaType type, Class<?> rawType, List<JavaType> superTypes,
Class<?> primaryMixIn, Annotations classAnnotations, TypeBindings bindings,
AnnotationIntrospector aintr, MixInResolver mir, TypeFactory tf)
{
_type = type;
_class = rawType;
_classAnnotations = classAnnotations;
_bindings = bindings;
_superTypes = superTypes;
_annotationIntrospector = aintr;
_typeFactory = tf;
_mixInResolver = mir;
_primaryMixIn = primaryMixIn;
}
/**
* @deprecated Since 2.9, use methods in {@link AnnotatedClassResolver} instead.
*/
@Deprecated
public static AnnotatedClass construct(JavaType type, MapperConfig<?> config) {
return construct(type, config, (MixInResolver) config);
}
/**
* @deprecated Since 2.9, use methods in {@link AnnotatedClassResolver} instead.
*/
@Deprecated
public static AnnotatedClass construct(JavaType type, MapperConfig<?> config,
MixInResolver mir)
{
return AnnotatedClassResolver.resolve(config, type, mir);
}
/**
* Method similar to {@link #construct}, but that will NOT include
* information from supertypes; only class itself and any direct
* mix-ins it may have.
*/
/**
* @deprecated Since 2.9, use methods in {@link AnnotatedClassResolver} instead.
*/
@Deprecated
public static AnnotatedClass constructWithoutSuperTypes(Class<?> raw, MapperConfig<?> config) {
return constructWithoutSuperTypes(raw, config, config);
}
/**
* @deprecated Since 2.9, use methods in {@link AnnotatedClassResolver} instead.
*/
@Deprecated
public static AnnotatedClass constructWithoutSuperTypes(Class<?> raw, MapperConfig<?> config,
MixInResolver mir)
{
return AnnotatedClassResolver.resolveWithoutSuperTypes(config, raw, mir);
}
/*
/**********************************************************
/* TypeResolutionContext implementation
/**********************************************************
*/
@Override
public JavaType resolveType(Type type) {
return _typeFactory.constructType(type, _bindings);
}
/*
/**********************************************************
/* Annotated impl
/**********************************************************
*/
@Override
public Class<?> getAnnotated() { return _class; }
@Override
public int getModifiers() { return _class.getModifiers(); }
@Override
public String getName() { return _class.getName(); }
@Override
public <A extends Annotation> A getAnnotation(Class<A> acls) {
return _classAnnotations.get(acls);
}
@Override
public boolean hasAnnotation(Class<?> acls) {
return _classAnnotations.has(acls);
}
@Override
public boolean hasOneOf(Class<? extends Annotation>[] annoClasses) {
return _classAnnotations.hasOneOf(annoClasses);
}
@Override
public Class<?> getRawType() {
return _class;
}
@Override
public JavaType getType() {
return _type;
}
/*
/**********************************************************
/* Public API, generic accessors
/**********************************************************
*/
public Annotations getAnnotations() {
return _classAnnotations;
}
public boolean hasAnnotations() {
return _classAnnotations.size() > 0;
}
public AnnotatedConstructor getDefaultConstructor() {
return _creators().defaultConstructor;
}
public List<AnnotatedConstructor> getConstructors() {
return _creators().constructors;
}
/**
* @since 2.9
*/
public List<AnnotatedMethod> getFactoryMethods() {
return _creators().creatorMethods;
}
/**
* @deprecated Since 2.9; use {@link #getFactoryMethods} instead.
*/
@Deprecated
public List<AnnotatedMethod> getStaticMethods() {
return getFactoryMethods();
}
private final Creators _creators() {
Creators c = _creators;
if (c == null) {
_creators = c = AnnotatedCreatorCollector.collectCreators(_annotationIntrospector,
this,
_type, _primaryMixIn);
}
return c;
}
public Iterable<AnnotatedMethod> memberMethods() {
return _methods();
}
public int getMemberMethodCount() {
return _methods().size();
}
public AnnotatedMethod findMethod(String name, Class<?>[] paramTypes) {
return _methods().find(name, paramTypes);
}
private final AnnotatedMethodMap _methods() {
AnnotatedMethodMap m = _memberMethods;
if (m == null) {
_memberMethods = m = AnnotatedMethodCollector.collectMethods(_annotationIntrospector,
this,
_mixInResolver, _typeFactory,
_type, _superTypes, _primaryMixIn);
}
return m;
}
public int getFieldCount() {
return _fields().size();
}
public Iterable<AnnotatedField> fields() {
return _fields();
}
private final List<AnnotatedField> _fields() {
List<AnnotatedField> f = _fields;
if (f == null) {
_fields = f = AnnotatedFieldCollector.collectFields(_annotationIntrospector,
this,
_mixInResolver, _typeFactory,
_type);
}
return f;
}
/**
* @since 2.9
*/
public boolean isNonStaticInnerClass()
{
Boolean B = _nonStaticInnerClass;
if (B == null) {
_nonStaticInnerClass = B = ClassUtil.isNonStaticInnerClass(_class);
}
return B.booleanValue();
}
/*
/**********************************************************
/* Standard method overrides
/**********************************************************
*/
@Override
public String toString() {
return "[AnnotedClass "+_class.getName()+"]";
}
@Override
public int hashCode() {
return _class.getName().hashCode();
}
@Override
public boolean equals(Object o) {
if (o == this) return true;
if (!ClassUtil.hasClass(o, getClass())) {
return false;
}
return ((AnnotatedClass) o)._class == _class;
}
/*
/**********************************************************
/* Helper classes
/**********************************************************
*/
public static final class Creators
{
/**
* Default constructor of the annotated class, if it has one.
*/
public final AnnotatedConstructor defaultConstructor;
/**
* Single argument constructors the class has, if any.
*/
public final List<AnnotatedConstructor> constructors;
/**
* Single argument static methods that might be usable
* as factory methods
*/
public final List<AnnotatedMethod> creatorMethods;
public Creators(AnnotatedConstructor defCtor,
List<AnnotatedConstructor> ctors,
List<AnnotatedMethod> ctorMethods)
{
defaultConstructor = defCtor;
constructors = ctors;
creatorMethods = ctorMethods;
}
}
}