You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
715 lines
29 KiB
715 lines
29 KiB
package com.fasterxml.classmate; |
|
|
|
import java.lang.annotation.Annotation; |
|
import java.lang.annotation.Inherited; |
|
import java.lang.reflect.Constructor; |
|
import java.lang.reflect.Field; |
|
import java.lang.reflect.Method; |
|
import java.lang.reflect.Type; |
|
import java.util.*; |
|
|
|
import com.fasterxml.classmate.members.*; |
|
import com.fasterxml.classmate.util.MethodKey; |
|
|
|
/** |
|
* Class that contains information about fully resolved members of a |
|
* type; resolution meaning that masking is handled for methods, and |
|
* all inheritable annotations are flattened using optional overrides |
|
* as well ("mix-in annotations"). |
|
* Instances are created by {@link com.fasterxml.classmate.MemberResolver}. |
|
*<p> |
|
* Note that instances are not thread-safe, as the expectation is that instances |
|
* will not be shared (unlike raw members or resolved types) |
|
*/ |
|
public class ResolvedTypeWithMembers |
|
{ |
|
private final static ResolvedType[] NO_RESOLVED_TYPES = new ResolvedType[0]; |
|
|
|
private final static ResolvedMethod[] NO_RESOLVED_METHODS = new ResolvedMethod[0]; |
|
private final static ResolvedField[] NO_RESOLVED_FIELDS = new ResolvedField[0]; |
|
private final static ResolvedConstructor[] NO_RESOLVED_CONSTRUCTORS = new ResolvedConstructor[0]; |
|
|
|
/** |
|
* Default annotation configuration is to ignore all annotations types. |
|
*/ |
|
protected final static AnnotationConfiguration DEFAULT_ANNOTATION_CONFIG |
|
= new AnnotationConfiguration.StdConfiguration(AnnotationInclusion.DONT_INCLUDE); |
|
|
|
/** |
|
* Need to be able to resolve member types still |
|
*/ |
|
protected final TypeResolver _typeResolver; |
|
|
|
/** |
|
* Handler for resolving annotation information |
|
*/ |
|
protected final AnnotationHandler _annotationHandler; |
|
|
|
/** |
|
* Leaf of the type hierarchy, i.e. type from which this hierarchy |
|
* was generated. |
|
*/ |
|
protected final HierarchicType _mainType; |
|
|
|
/** |
|
* All types that hierarchy contains, in order of increasing precedence |
|
* (that is, later entries override members of earlier members) |
|
*/ |
|
protected final HierarchicType[] _types; |
|
|
|
/** |
|
* Filter to use for selecting fields to include |
|
*/ |
|
protected Filter<RawField> _fieldFilter; |
|
|
|
/** |
|
* Filter to use for selecting constructors to include |
|
*/ |
|
protected Filter<RawConstructor> _constructorFilter; |
|
|
|
/** |
|
* Filter to use for selecting methods to include |
|
*/ |
|
protected Filter<RawMethod> _methodFilter; |
|
|
|
/* |
|
/********************************************************************** |
|
/* Lazily constructed members |
|
/********************************************************************** |
|
*/ |
|
|
|
protected ResolvedMethod[] _staticMethods = null; |
|
|
|
protected ResolvedField[] _staticFields = null; |
|
|
|
protected ResolvedMethod[] _memberMethods = null; |
|
|
|
protected ResolvedField[] _memberFields = null; |
|
|
|
protected ResolvedConstructor[] _constructors = null; |
|
|
|
/* |
|
/********************************************************************** |
|
/* Life cycle at this point |
|
/********************************************************************** |
|
*/ |
|
|
|
public ResolvedTypeWithMembers(TypeResolver typeResolver, AnnotationConfiguration annotationConfig, |
|
HierarchicType mainType, HierarchicType[] types, |
|
Filter<RawConstructor> constructorFilter, Filter<RawField> fieldFilter, Filter<RawMethod> methodFilter) |
|
{ |
|
_typeResolver = typeResolver; |
|
_mainType = mainType; |
|
_types = types; |
|
if (annotationConfig == null) { |
|
annotationConfig = DEFAULT_ANNOTATION_CONFIG; |
|
} |
|
_annotationHandler = new AnnotationHandler(annotationConfig); |
|
_constructorFilter = constructorFilter; |
|
_fieldFilter = fieldFilter; |
|
_methodFilter = methodFilter; |
|
} |
|
|
|
/* |
|
/********************************************************************** |
|
/* Public API, access to component types |
|
/********************************************************************** |
|
*/ |
|
|
|
public int size() { return _types.length; } |
|
|
|
/** |
|
* Accessor for getting full type hierarchy as priority-ordered list, from |
|
* the lowest precedence to highest precedence (main type, its mix-in overrides) |
|
*/ |
|
public List<HierarchicType> allTypesAndOverrides() { |
|
return Arrays.asList(_types); |
|
} |
|
|
|
/** |
|
* Accessor for getting subset of type hierarchy which only contains main type |
|
* and possible overrides (mix-ins) it has, but not supertypes or their overrides. |
|
*/ |
|
public List<HierarchicType> mainTypeAndOverrides() |
|
{ |
|
List<HierarchicType> l = Arrays.asList(_types); |
|
int end = _mainType.getPriority() + 1; |
|
if (end < l.size()) { |
|
l = l.subList(0, end); |
|
} |
|
return l; |
|
} |
|
|
|
/** |
|
* Accessor for finding just overrides for the main type (if any). |
|
*/ |
|
public List<HierarchicType> overridesOnly() |
|
{ |
|
int index = _mainType.getPriority(); |
|
if (index == 0) { |
|
return Collections.emptyList(); |
|
} |
|
List<HierarchicType> l = Arrays.asList(_types); |
|
return l.subList(0, index); |
|
} |
|
|
|
/* |
|
/********************************************************************** |
|
/* Public API, actual resolution of members |
|
/********************************************************************** |
|
*/ |
|
|
|
/** |
|
* Method for finding all static fields of the main type (except for ones |
|
* possibly filtered out by filter) and applying annotation overrides, if any, |
|
* to annotations. |
|
* |
|
* @since 1.2.0 |
|
*/ |
|
public ResolvedField[] getStaticFields() |
|
{ |
|
if (_staticFields == null) { |
|
_staticFields = resolveStaticFields(); |
|
} |
|
return _staticFields; |
|
} |
|
|
|
/** |
|
* Method for finding all static methods of the main type (except for ones |
|
* possibly filtered out by filter) and applying annotation overrides, if any, |
|
* to annotations. |
|
*/ |
|
public ResolvedMethod[] getStaticMethods() |
|
{ |
|
if (_staticMethods == null) { |
|
_staticMethods = resolveStaticMethods(); |
|
} |
|
return _staticMethods; |
|
} |
|
|
|
public ResolvedField[] getMemberFields() |
|
{ |
|
if (_memberFields == null) { |
|
_memberFields = resolveMemberFields(); |
|
} |
|
return _memberFields; |
|
} |
|
|
|
public ResolvedMethod[] getMemberMethods() |
|
{ |
|
if (_memberMethods == null) { |
|
_memberMethods = resolveMemberMethods(); |
|
} |
|
return _memberMethods; |
|
} |
|
|
|
public ResolvedConstructor[] getConstructors() |
|
{ |
|
if (_constructors == null) { |
|
_constructors = resolveConstructors(); |
|
} |
|
return _constructors; |
|
} |
|
|
|
/* |
|
/********************************************************************** |
|
/* Internal methods: actual resolution |
|
/********************************************************************** |
|
*/ |
|
|
|
/** |
|
* Method that will actually resolve full information (types, annotations) |
|
* for constructors of the main type. |
|
*/ |
|
protected ResolvedConstructor[] resolveConstructors() |
|
{ |
|
// First get static methods for main type, filter |
|
LinkedHashMap<MethodKey, ResolvedConstructor> constructors = new LinkedHashMap<MethodKey, ResolvedConstructor>(); |
|
for (RawConstructor constructor : _mainType.getType().getConstructors()) { |
|
// no filter for constructors (yet?) |
|
if (_constructorFilter == null || _constructorFilter.include(constructor)) { |
|
constructors.put(constructor.createKey(), resolveConstructor(constructor)); |
|
} |
|
} |
|
// then apply overrides (mix-ins): |
|
for (HierarchicType type : overridesOnly()) { |
|
for (RawConstructor raw : type.getType().getConstructors()) { |
|
ResolvedConstructor constructor = constructors.get(raw.createKey()); |
|
// must override something, otherwise to ignore |
|
if (constructor != null) { |
|
for (Annotation ann : raw.getAnnotations()) { |
|
if (_annotationHandler.includeMethodAnnotation(ann)) { |
|
constructor.applyOverride(ann); |
|
} |
|
} |
|
|
|
// and parameter annotations |
|
Annotation[][] params = raw.getRawMember().getParameterAnnotations(); |
|
for (int i = 0; i < params.length; i++) { |
|
for (Annotation annotation : params[i]) { |
|
if (_annotationHandler.includeParameterAnnotation(annotation)) { |
|
constructor.applyParamOverride(i, annotation); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
if (constructors.size() == 0) { |
|
return NO_RESOLVED_CONSTRUCTORS; |
|
} |
|
return constructors.values().toArray(new ResolvedConstructor[constructors.size()]); |
|
} |
|
|
|
/** |
|
* Method for fully resolving field definitions and associated annotations. |
|
* Neither field definitions nor associated annotations inherit, but we may |
|
* still need to add annotation overrides, as well as filter out filters |
|
* and annotations that caller is not interested in. |
|
*/ |
|
protected ResolvedField[] resolveMemberFields() |
|
{ |
|
LinkedHashMap<String, ResolvedField> fields = new LinkedHashMap<String, ResolvedField>(); |
|
|
|
/* Fields need different handling: must start from bottom; and annotations only get added |
|
* as overrides, never as defaults. And sub-classes fully mask fields. This makes |
|
* handling bit simpler than that of member methods. |
|
*/ |
|
for (int typeIndex = _types.length; --typeIndex >= 0; ) { |
|
HierarchicType thisType = _types[typeIndex]; |
|
// If it's just a mix-in, add annotations as overrides |
|
if (thisType.isMixin()) { |
|
for (RawField raw : thisType.getType().getMemberFields()) { |
|
if ((_fieldFilter != null) && !_fieldFilter.include(raw)) { |
|
continue; |
|
} |
|
ResolvedField field = fields.get(raw.getName()); |
|
if (field != null) { |
|
for (Annotation ann : raw.getAnnotations()) { |
|
if (_annotationHandler.includeMethodAnnotation(ann)) { |
|
field.applyOverride(ann); |
|
} |
|
} |
|
} |
|
} |
|
} else { // If actual type, add fields, masking whatever might have existed before: |
|
for (RawField field : thisType.getType().getMemberFields()) { |
|
if ((_fieldFilter != null) && !_fieldFilter.include(field)) { |
|
continue; |
|
} |
|
fields.put(field.getName(), resolveField(field)); |
|
} |
|
} |
|
} |
|
// and that's it? |
|
if (fields.size() == 0) { |
|
return NO_RESOLVED_FIELDS; |
|
} |
|
return fields.values().toArray(new ResolvedField[fields.size()]); |
|
} |
|
|
|
protected ResolvedMethod[] resolveMemberMethods() |
|
{ |
|
LinkedHashMap<MethodKey, ResolvedMethod> methods = new LinkedHashMap<MethodKey, ResolvedMethod>(); |
|
LinkedHashMap<MethodKey, Annotations> overrides = new LinkedHashMap<MethodKey, Annotations>(); |
|
LinkedHashMap<MethodKey, Annotations[]> paramOverrides = new LinkedHashMap<MethodKey, Annotations[]>(); |
|
|
|
/* Member methods are handled from top to bottom; and annotations are tracked |
|
* alongside (for overrides), as well as "merged down" for inheritable |
|
* annotations. |
|
*/ |
|
for (HierarchicType type : allTypesAndOverrides()) { |
|
for (RawMethod method : type.getType().getMemberMethods()) { |
|
// First: ignore methods caller is not interested |
|
if (_methodFilter != null && !_methodFilter.include(method)) { |
|
continue; |
|
} |
|
|
|
MethodKey key = method.createKey(); |
|
ResolvedMethod old = methods.get(key); |
|
|
|
// Ok, now, mix-ins only contribute annotations; whereas 'real' types methods |
|
if (type.isMixin()) { // mix-in: only get annotations |
|
for (Annotation ann : method.getAnnotations()) { |
|
// If already have a method, must be inheritable to include |
|
if (old != null) { |
|
if (!methodCanInherit(ann)) { |
|
continue; |
|
} |
|
// and if so, apply as default (i.e. do not override) |
|
old.applyDefault(ann); |
|
} else { // If no method, need to add to annotation override map |
|
Annotations oldAnn = overrides.get(key); |
|
if (oldAnn == null) { |
|
oldAnn = new Annotations(); |
|
oldAnn.add(ann); |
|
overrides.put(key, oldAnn); |
|
} else { |
|
oldAnn.addAsDefault(ann); |
|
} |
|
} |
|
} |
|
|
|
// override argument annotations |
|
final Annotation[][] argAnnotations = method.getRawMember().getParameterAnnotations(); |
|
if (old == null) { // no method (yet), add argument annotations to override map |
|
Annotations[] oldParamAnns = paramOverrides.get(key); |
|
if (oldParamAnns == null) { // no existing argument annotations for method |
|
oldParamAnns = new Annotations[argAnnotations.length]; |
|
for (int i = 0; i < argAnnotations.length; i++) { |
|
oldParamAnns[i] = new Annotations(); |
|
for (final Annotation annotation : argAnnotations[i]) { |
|
if (parameterCanInherit(annotation)) { |
|
oldParamAnns[i].add(annotation); |
|
} |
|
} |
|
} |
|
paramOverrides.put(key, oldParamAnns); |
|
} else { |
|
for (int i = 0; i < argAnnotations.length; i++) { |
|
for (final Annotation annotation : argAnnotations[i]) { |
|
if (parameterCanInherit(annotation)) { |
|
oldParamAnns[i].addAsDefault(annotation); |
|
} |
|
} |
|
} |
|
} |
|
} else { // already have a method, apply argument annotations as defaults |
|
for (int i = 0; i < argAnnotations.length; i++) { |
|
for (final Annotation annotation : argAnnotations[i]) { |
|
if (parameterCanInherit(annotation)) { |
|
old.applyParamDefault(i, annotation); |
|
} |
|
} |
|
} |
|
} |
|
} else { // "real" methods; add if not present, possibly add defaults as well |
|
if (old == null) { // new one to add |
|
ResolvedMethod newMethod = resolveMethod(method); |
|
methods.put(key, newMethod); |
|
// But we may also have annotation overrides, so: |
|
Annotations overrideAnn = overrides.get(key); |
|
if (overrideAnn != null) { |
|
newMethod.applyOverrides(overrideAnn); |
|
} |
|
// and apply parameter annotation overrides |
|
Annotations[] annotations = paramOverrides.get(key); |
|
if (annotations != null) { |
|
for (int i = 0; i < annotations.length; i++) { |
|
newMethod.applyParamOverrides(i, annotations[i]); |
|
} |
|
} |
|
} else { // method masked by something else? can only contribute annotations |
|
for (Annotation ann : method.getAnnotations()) { |
|
if (methodCanInherit(ann)) { |
|
old.applyDefault(ann); |
|
} |
|
} |
|
// and parameter annotations |
|
final Annotation[][] parameterAnnotations = method.getRawMember().getParameterAnnotations(); |
|
for (int i = 0; i < parameterAnnotations.length; i++) { |
|
for (final Annotation annotation : parameterAnnotations[i]) { |
|
if (parameterCanInherit(annotation)) { |
|
old.applyParamDefault(i, annotation); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
if (methods.size() == 0) { |
|
return NO_RESOLVED_METHODS; |
|
} |
|
return methods.values().toArray(new ResolvedMethod[methods.size()]); |
|
} |
|
|
|
/** |
|
* Method for fully resolving static field definitions and associated annotations. |
|
* Neither field definitions nor associated annotations inherit, but we may |
|
* still need to add annotation overrides, as well as filter out filters |
|
* and annotations that caller is not interested in. |
|
* |
|
* @since 1.2.0 |
|
*/ |
|
protected ResolvedField[] resolveStaticFields() |
|
{ |
|
// First get static methods for main type, filter |
|
LinkedHashMap<String, ResolvedField> fields = new LinkedHashMap<String, ResolvedField>(); |
|
for (RawField field : _mainType.getType().getStaticFields()) { |
|
if (_fieldFilter == null || _fieldFilter.include(field)) { |
|
fields.put(field.getName(), resolveField(field)); |
|
} |
|
} |
|
// then apply overrides (mix-ins): |
|
for (HierarchicType type : overridesOnly()) { |
|
for (RawField raw : type.getType().getStaticFields()) { |
|
ResolvedField field = fields.get(raw.getName()); |
|
// must override something, otherwise to ignore |
|
if (field != null) { |
|
for (Annotation ann : raw.getAnnotations()) { |
|
if (_annotationHandler.includeFieldAnnotation(ann)) { |
|
field.applyOverride(ann); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
// and that's it? |
|
if (fields.isEmpty()) { |
|
return NO_RESOLVED_FIELDS; |
|
} |
|
return fields.values().toArray(new ResolvedField[ fields.size()]); |
|
} |
|
|
|
/** |
|
* Method that will actually resolve full information (types, annotations) |
|
* for static methods, using configured filter. |
|
*/ |
|
protected ResolvedMethod[] resolveStaticMethods() |
|
{ |
|
// First get static methods for main type, filter |
|
LinkedHashMap<MethodKey, ResolvedMethod> methods = new LinkedHashMap<MethodKey, ResolvedMethod>(); |
|
for (RawMethod method : _mainType.getType().getStaticMethods()) { |
|
if (_methodFilter == null || _methodFilter.include(method)) { |
|
methods.put(method.createKey(), resolveMethod(method)); |
|
} |
|
} |
|
// then apply overrides (mix-ins): |
|
for (HierarchicType type : overridesOnly()) { |
|
for (RawMethod raw : type.getType().getStaticMethods()) { |
|
ResolvedMethod method = methods.get(raw.createKey()); |
|
// must override something, otherwise to ignore |
|
if (method != null) { |
|
for (Annotation ann : raw.getAnnotations()) { |
|
if (_annotationHandler.includeMethodAnnotation(ann)) { |
|
method.applyOverride(ann); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
if (methods.size() == 0) { |
|
return NO_RESOLVED_METHODS; |
|
} |
|
return methods.values().toArray(new ResolvedMethod[methods.size()]); |
|
} |
|
|
|
/* |
|
/********************************************************************** |
|
/* Helper methods |
|
/********************************************************************** |
|
*/ |
|
|
|
/** |
|
* Method for resolving individual constructor completely |
|
*/ |
|
protected ResolvedConstructor resolveConstructor(RawConstructor raw) |
|
{ |
|
final ResolvedType context = raw.getDeclaringType(); |
|
final TypeBindings bindings = context.getTypeBindings(); |
|
Constructor<?> ctor = raw.getRawMember(); |
|
Type[] rawTypes = ctor.getGenericParameterTypes(); |
|
ResolvedType[] argTypes; |
|
if (rawTypes == null || rawTypes.length == 0) { |
|
argTypes = NO_RESOLVED_TYPES; |
|
} else { |
|
argTypes = new ResolvedType[rawTypes.length]; |
|
for (int i = 0, len = rawTypes.length; i < len; ++i) { |
|
argTypes[i] = _typeResolver.resolve(bindings, rawTypes[i]); |
|
} |
|
} |
|
// And then annotations |
|
Annotations anns = new Annotations(); |
|
for (Annotation ann : ctor.getAnnotations()) { |
|
if (_annotationHandler.includeConstructorAnnotation(ann)) { |
|
anns.add(ann); |
|
} |
|
} |
|
|
|
ResolvedConstructor constructor = new ResolvedConstructor(context, anns, ctor, argTypes); |
|
|
|
// and parameter annotations |
|
Annotation[][] annotations = ctor.getParameterAnnotations(); |
|
for (int i = 0; i < argTypes.length; i++) { |
|
for (Annotation ann : annotations[i]) { |
|
constructor.applyParamOverride(i, ann); |
|
} |
|
} |
|
|
|
return constructor; |
|
} |
|
|
|
/** |
|
* Method for resolving individual field completely |
|
*/ |
|
protected ResolvedField resolveField(RawField raw) |
|
{ |
|
final ResolvedType context = raw.getDeclaringType(); |
|
Field field = raw.getRawMember(); |
|
ResolvedType type = _typeResolver.resolve(context.getTypeBindings(), field.getGenericType()); |
|
// And then annotations |
|
Annotations anns = new Annotations(); |
|
for (Annotation ann : field.getAnnotations()) { |
|
if (_annotationHandler.includeFieldAnnotation(ann)) { |
|
anns.add(ann); |
|
} |
|
} |
|
return new ResolvedField(context, anns, field, type); |
|
} |
|
|
|
/** |
|
* Method for resolving individual method completely |
|
*/ |
|
protected ResolvedMethod resolveMethod(RawMethod raw) |
|
{ |
|
final ResolvedType context = raw.getDeclaringType(); |
|
final TypeBindings bindings = context.getTypeBindings(); |
|
Method m = raw.getRawMember(); |
|
Type rawType = m.getGenericReturnType(); |
|
ResolvedType rt = (rawType == Void.TYPE) ? null : _typeResolver.resolve(bindings, rawType); |
|
Type[] rawTypes = m.getGenericParameterTypes(); |
|
ResolvedType[] argTypes; |
|
if (rawTypes == null || rawTypes.length == 0) { |
|
argTypes = NO_RESOLVED_TYPES; |
|
} else { |
|
argTypes = new ResolvedType[rawTypes.length]; |
|
for (int i = 0, len = rawTypes.length; i < len; ++i) { |
|
argTypes[i] = _typeResolver.resolve(bindings, rawTypes[i]); |
|
} |
|
} |
|
// And then annotations |
|
Annotations anns = new Annotations(); |
|
for (Annotation ann : m.getAnnotations()) { |
|
if (_annotationHandler.includeMethodAnnotation(ann)) { |
|
anns.add(ann); |
|
} |
|
} |
|
|
|
ResolvedMethod method = new ResolvedMethod(context, anns, m, rt, argTypes); |
|
|
|
// and argument annotations |
|
Annotation[][] annotations = m.getParameterAnnotations(); |
|
for (int i = 0; i < argTypes.length; i++) { |
|
for (Annotation ann : annotations[i]) { |
|
method.applyParamOverride(i, ann); |
|
} |
|
} |
|
return method; |
|
} |
|
|
|
protected boolean methodCanInherit(Annotation annotation) { |
|
AnnotationInclusion annotationInclusion = _annotationHandler.methodInclusion(annotation); |
|
if (annotationInclusion == AnnotationInclusion.INCLUDE_AND_INHERIT_IF_INHERITED) { |
|
return annotation.annotationType().isAnnotationPresent(Inherited.class); |
|
} |
|
return (annotationInclusion == AnnotationInclusion.INCLUDE_AND_INHERIT); |
|
} |
|
|
|
protected boolean parameterCanInherit(Annotation annotation) { |
|
AnnotationInclusion annotationInclusion = _annotationHandler.parameterInclusion(annotation); |
|
if (annotationInclusion == AnnotationInclusion.INCLUDE_AND_INHERIT_IF_INHERITED) { |
|
return annotation.annotationType().isAnnotationPresent(Inherited.class); |
|
} |
|
return (annotationInclusion == AnnotationInclusion.INCLUDE_AND_INHERIT); |
|
} |
|
|
|
/* |
|
/********************************************************************** |
|
/* Helper types |
|
/********************************************************************** |
|
*/ |
|
|
|
/** |
|
* Helper class we use to reduce number of calls to {@link AnnotationConfiguration}; |
|
* mostly because determination may be expensive. |
|
*/ |
|
private final static class AnnotationHandler |
|
{ |
|
private final AnnotationConfiguration _annotationConfig; |
|
|
|
private HashMap<Class<? extends Annotation>, AnnotationInclusion> _fieldInclusions; |
|
private HashMap<Class<? extends Annotation>, AnnotationInclusion> _constructorInclusions; |
|
private HashMap<Class<? extends Annotation>, AnnotationInclusion> _methodInclusions; |
|
private HashMap<Class<? extends Annotation>, AnnotationInclusion> _parameterInclusions; |
|
|
|
public AnnotationHandler(AnnotationConfiguration annotationConfig) { |
|
_annotationConfig = annotationConfig; |
|
} |
|
|
|
public boolean includeConstructorAnnotation(Annotation ann) |
|
{ |
|
Class<? extends Annotation> annType = ann.annotationType(); |
|
if (_constructorInclusions == null) { |
|
_constructorInclusions = new HashMap<Class<? extends Annotation>, AnnotationInclusion>(); |
|
} else { |
|
AnnotationInclusion incl = _constructorInclusions.get(annType); |
|
if (incl != null) { |
|
return (incl != AnnotationInclusion.DONT_INCLUDE); |
|
} |
|
} |
|
AnnotationInclusion incl = _annotationConfig.getInclusionForConstructor(annType); |
|
_constructorInclusions.put(annType, incl); |
|
return (incl != AnnotationInclusion.DONT_INCLUDE); |
|
} |
|
|
|
public boolean includeFieldAnnotation(Annotation ann) |
|
{ |
|
Class<? extends Annotation> annType = ann.annotationType(); |
|
if (_fieldInclusions == null) { |
|
_fieldInclusions = new HashMap<Class<? extends Annotation>, AnnotationInclusion>(); |
|
} else { |
|
AnnotationInclusion incl = _fieldInclusions.get(annType); |
|
if (incl != null) { |
|
return (incl != AnnotationInclusion.DONT_INCLUDE); |
|
} |
|
} |
|
AnnotationInclusion incl = _annotationConfig.getInclusionForField(annType); |
|
_fieldInclusions.put(annType, incl); |
|
return (incl != AnnotationInclusion.DONT_INCLUDE); |
|
} |
|
|
|
public boolean includeMethodAnnotation(Annotation ann) |
|
{ |
|
return methodInclusion(ann) != AnnotationInclusion.DONT_INCLUDE; |
|
} |
|
|
|
public AnnotationInclusion methodInclusion(Annotation ann) |
|
{ |
|
Class<? extends Annotation> annType = ann.annotationType(); |
|
if (_methodInclusions == null) { |
|
_methodInclusions = new HashMap<Class<? extends Annotation>, AnnotationInclusion>(); |
|
} else { |
|
AnnotationInclusion incl = _methodInclusions.get(annType); |
|
if (incl != null) { |
|
return incl; |
|
} |
|
} |
|
AnnotationInclusion incl = _annotationConfig.getInclusionForMethod(annType); |
|
_methodInclusions.put(annType, incl); |
|
return incl; |
|
} |
|
|
|
public boolean includeParameterAnnotation(Annotation ann) |
|
{ |
|
return parameterInclusion(ann) != AnnotationInclusion.DONT_INCLUDE; |
|
} |
|
|
|
public AnnotationInclusion parameterInclusion(Annotation ann) |
|
{ |
|
Class<? extends Annotation> annType = ann.annotationType(); |
|
if (_parameterInclusions == null) { |
|
_parameterInclusions = new HashMap<Class<? extends Annotation>, AnnotationInclusion>(); |
|
} else { |
|
AnnotationInclusion incl = _parameterInclusions.get(annType); |
|
if (incl != null) { |
|
return incl; |
|
} |
|
} |
|
AnnotationInclusion incl = _annotationConfig.getInclusionForParameter(annType); |
|
_parameterInclusions.put(annType, incl); |
|
return incl; |
|
} |
|
} |
|
}
|
|
|