/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat, Inc., and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.weld.annotated.enhanced.jlr;
import static org.jboss.weld.util.collections.WeldCollections.immutableSetView;
import java.lang.annotation.Annotation;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.enterprise.event.Observes;
import javax.enterprise.event.ObservesAsync;
import javax.enterprise.inject.Disposes;
import javax.enterprise.inject.spi.AnnotatedConstructor;
import javax.enterprise.inject.spi.AnnotatedField;
import javax.enterprise.inject.spi.AnnotatedMethod;
import javax.inject.Inject;
import org.jboss.weld.annotated.enhanced.ConstructorSignature;
import org.jboss.weld.annotated.enhanced.EnhancedAnnotatedConstructor;
import org.jboss.weld.annotated.enhanced.EnhancedAnnotatedField;
import org.jboss.weld.annotated.enhanced.EnhancedAnnotatedMethod;
import org.jboss.weld.annotated.enhanced.EnhancedAnnotatedType;
import org.jboss.weld.annotated.enhanced.MethodSignature;
import org.jboss.weld.annotated.slim.AnnotatedTypeIdentifier;
import org.jboss.weld.annotated.slim.SlimAnnotatedType;
import org.jboss.weld.annotated.slim.backed.BackedAnnotatedType;
import org.jboss.weld.interceptor.spi.model.InterceptionType;
import org.jboss.weld.interceptor.util.InterceptionTypeRegistry;
import org.jboss.weld.resources.ClassTransformer;
import org.jboss.weld.util.collections.ImmutableSet;
import org.jboss.weld.util.collections.ListMultimap;
import org.jboss.weld.util.collections.Multimap;
import org.jboss.weld.util.collections.Multimaps;
import org.jboss.weld.util.collections.SetMultimap;
import org.jboss.weld.util.collections.Sets;
import org.jboss.weld.util.reflection.Formats;
import org.jboss.weld.util.reflection.Reflections;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
/**
* Represents an annotated class
* <p/>
* This class is immutable, and therefore threadsafe
*
* @param <T> the type of the class
* @author Pete Muir
* @author David Allen
* @author Ales Justin
*/
public class EnhancedAnnotatedTypeImpl<T> extends AbstractEnhancedAnnotated<T, Class<T>> implements EnhancedAnnotatedType<T> {
private static final Set<Class<? extends Annotation>> MAPPED_METHOD_ANNOTATIONS;
static {
Set<Class<? extends Annotation>> annotations = new HashSet<Class<? extends Annotation>>();
for (InterceptionType interceptionType : InterceptionTypeRegistry.getSupportedInterceptionTypes()) {
annotations.add(InterceptionTypeRegistry.getAnnotationClass(interceptionType));
}
annotations.add(Inject.class);
MAPPED_METHOD_ANNOTATIONS = ImmutableSet.copyOf(annotations);
}
@SuppressFBWarnings("unchecked")
private static final Set<Class<? extends Annotation>> MAPPED_METHOD_PARAMETER_ANNOTATIONS = ImmutableSet.of(Observes.class, ObservesAsync.class);
@SuppressFBWarnings("unchecked")
private static final Set<Class<? extends Annotation>> MAPPED_DECLARED_METHOD_PARAMETER_ANNOTATIONS = ImmutableSet.of(Disposes.class);
// Class attributes
private final EnhancedAnnotatedType<? super T> superclass;
// The set of abstracted fields
private final Set<EnhancedAnnotatedField<?, ? super T>> fields;
// The map from annotation type to abstracted field with annotation
private final Multimap<Class<? extends Annotation>, EnhancedAnnotatedField<?, ?>> annotatedFields;
// The set of abstracted fields
private final Set<EnhancedAnnotatedField<?, ? super T>> declaredFields;
// The map from annotation type to abstracted field with annotation
private final Multimap<Class<? extends Annotation>, EnhancedAnnotatedField<?, ? super T>> declaredAnnotatedFields;
// The set of abstracted methods
private final Set<EnhancedAnnotatedMethod<?, ? super T>> methods;
// The map from annotation type to abstracted method with annotation
private final Multimap<Class<? extends Annotation>, EnhancedAnnotatedMethod<?, ? super T>> annotatedMethods;
// Methods that are overridden by other methods
private Set<EnhancedAnnotatedMethod<?, ? super T>> overriddenMethods;
private final Multimap<Class<? extends Annotation>, EnhancedAnnotatedMethod<?, ? super T>> annotatedMethodsByAnnotatedParameters;
// The set of abstracted methods
private final Set<EnhancedAnnotatedMethod<?, ? super T>> declaredMethods;
// The map from annotation type to abstracted method with annotation
private final Multimap<Class<? extends Annotation>, EnhancedAnnotatedMethod<?, ? super T>> declaredAnnotatedMethods;
// The map from annotation type to method with a parameter with annotation
private final Multimap<Class<? extends Annotation>, EnhancedAnnotatedMethod<?, ? super T>> declaredMethodsByAnnotatedParameters;
// The set of abstracted constructors
private final Set<EnhancedAnnotatedConstructor<T>> constructors;
private final Map<ConstructorSignature, EnhancedAnnotatedConstructor<?>> declaredConstructorsBySignature;
// The meta-annotation map (annotation type -> set of annotations containing
// meta-annotation) of the item
private final Multimap<Class<? extends Annotation>, Annotation> declaredMetaAnnotationMap;
private final boolean discovered;
private final SlimAnnotatedType<T> slim;
public static <T> EnhancedAnnotatedType<T> of(SlimAnnotatedType<T> annotatedType, ClassTransformer classTransformer) {
if (annotatedType instanceof BackedAnnotatedType<?>) {
return new EnhancedAnnotatedTypeImpl<T>(annotatedType, buildAnnotationMap(annotatedType.getAnnotations()), buildAnnotationMap(classTransformer.getReflectionCache().getDeclaredAnnotations(annotatedType.getJavaClass())), classTransformer);
} else {
return new EnhancedAnnotatedTypeImpl<T>(annotatedType, buildAnnotationMap(annotatedType.getAnnotations()), buildAnnotationMap(annotatedType.getAnnotations()), classTransformer);
}
}
@SuppressWarnings("unchecked")
protected EnhancedAnnotatedTypeImpl(SlimAnnotatedType<T> annotatedType, Map<Class<? extends Annotation>, Annotation> annotationMap, Map<Class<? extends Annotation>, Annotation> declaredAnnotationMap, ClassTransformer classTransformer) {
super(annotatedType, annotationMap, declaredAnnotationMap, classTransformer);
this.slim = annotatedType;
discovered = annotatedType instanceof BackedAnnotatedType<?>;
if (discovered) {
Class<? super T> superclass = annotatedType.getJavaClass().getSuperclass();
if (superclass == null) {
this.superclass = null;
} else {
this.superclass = classTransformer.getEnhancedAnnotatedType(superclass, slim.getIdentifier().getBdaId());
}
} else {
this.superclass = classTransformer.getEnhancedAnnotatedType(Object.class, AnnotatedTypeIdentifier.NULL_BDA_ID);
}
// Assign class field information
Multimap<Class<? extends Annotation>, EnhancedAnnotatedField<?, ? super T>> declaredAnnotatedFields = new ListMultimap<Class<? extends Annotation>, EnhancedAnnotatedField<?, ? super T>>();
Set<EnhancedAnnotatedField<?, ? super T>> fieldsTemp = null;
ArrayList<EnhancedAnnotatedField<?, ? super T>> declaredFieldsTemp = new ArrayList<EnhancedAnnotatedField<?, ? super T>>();
Class<T> javaClass = annotatedType.getJavaClass();
if (discovered) {
this.annotatedFields = null;
if (javaClass != Object.class) {
for (AnnotatedField<? super T> field : annotatedType.getFields()) {
if (field.getJavaMember().getDeclaringClass().equals(javaClass)) {
EnhancedAnnotatedField<?, ? super T> annotatedField = EnhancedAnnotatedFieldImpl.of(field, this, classTransformer);
declaredFieldsTemp.add(annotatedField);
for (Annotation annotation : annotatedField.getAnnotations()) {
declaredAnnotatedFields.put(annotation.annotationType(), annotatedField);
}
}
}
fieldsTemp = new HashSet<EnhancedAnnotatedField<?, ? super T>>(declaredFieldsTemp);
if ((superclass != null) && (superclass.getJavaClass() != Object.class)) {
fieldsTemp = Sets.union(fieldsTemp, Reflections.<Set<EnhancedAnnotatedField<?, ? super T>>>cast(superclass.getFields()));
}
}
this.declaredFields = new HashSet<EnhancedAnnotatedField<?, ? super T>>(declaredFieldsTemp);
} else {
Multimap<Class<? extends Annotation>, EnhancedAnnotatedField<?, ?>> annotatedFields = new ListMultimap<Class<? extends Annotation>, EnhancedAnnotatedField<?, ?>>();
fieldsTemp = new HashSet<EnhancedAnnotatedField<?, ? super T>>();
for (AnnotatedField<? super T> annotatedField : annotatedType.getFields()) {
EnhancedAnnotatedField<?, ? super T> weldField = EnhancedAnnotatedFieldImpl.of(annotatedField, this, classTransformer);
fieldsTemp.add(weldField);
if (annotatedField.getDeclaringType().getJavaClass().equals(javaClass)) {
declaredFieldsTemp.add(weldField);
}
for (Annotation annotation : weldField.getAnnotations()) {
annotatedFields.put(annotation.annotationType(), weldField);
if (annotatedField.getDeclaringType().getJavaClass().equals(javaClass)) {
declaredAnnotatedFields.put(annotation.annotationType(), weldField);
}
}
}
this.annotatedFields = Multimaps.unmodifiableMultimap(annotatedFields);
this.declaredFields = new HashSet<EnhancedAnnotatedField<?, ? super T>>(declaredFieldsTemp);
}
this.fields = fieldsTemp;
this.declaredAnnotatedFields = Multimaps.unmodifiableMultimap(declaredAnnotatedFields);
// Assign constructor information
this.constructors = new HashSet<EnhancedAnnotatedConstructor<T>>();
this.declaredConstructorsBySignature = new HashMap<ConstructorSignature, EnhancedAnnotatedConstructor<?>>();
for (AnnotatedConstructor<T> constructor : annotatedType.getConstructors()) {
EnhancedAnnotatedConstructor<T> weldConstructor = EnhancedAnnotatedConstructorImpl.of(constructor, this, classTransformer);
this.constructors.add(weldConstructor);
this.declaredConstructorsBySignature.put(weldConstructor.getSignature(), weldConstructor);
}
// Assign method information
Multimap<Class<? extends Annotation>, EnhancedAnnotatedMethod<?, ? super T>> declaredAnnotatedMethods = new ListMultimap<Class<? extends Annotation>, EnhancedAnnotatedMethod<?, ? super T>>();
Multimap<Class<? extends Annotation>, EnhancedAnnotatedMethod<?, ? super T>> declaredMethodsByAnnotatedParameters = new ListMultimap<Class<? extends Annotation>, EnhancedAnnotatedMethod<?, ? super T>>();
Set<EnhancedAnnotatedMethod<?, ? super T>> methodsTemp = new HashSet<EnhancedAnnotatedMethod<?,? super T>>();
ArrayList<EnhancedAnnotatedMethod<?, ? super T>> declaredMethodsTemp = new ArrayList<EnhancedAnnotatedMethod<?, ? super T>>();
if (discovered) {
if (!(javaClass.equals(Object.class))) {
for (AnnotatedMethod<? super T> method : annotatedType.getMethods()) {
if (method.getJavaMember().getDeclaringClass().equals(javaClass)) {
EnhancedAnnotatedMethod<?, ? super T> weldMethod = EnhancedAnnotatedMethodImpl.of(method, this, classTransformer);
declaredMethodsTemp.add(weldMethod);
for (Annotation annotation : weldMethod.getAnnotations()) {
declaredAnnotatedMethods.put(annotation.annotationType(), weldMethod);
}
for (Class<? extends Annotation> annotationType : MAPPED_DECLARED_METHOD_PARAMETER_ANNOTATIONS) {
if (weldMethod.getEnhancedParameters(annotationType).size() > 0) {
declaredMethodsByAnnotatedParameters.put(annotationType, weldMethod);
}
}
}
}
methodsTemp.addAll(declaredMethodsTemp);
if (superclass != null) {
EnhancedAnnotatedType<?> current = superclass;
while (current.getJavaClass() != Object.class) {
Set<EnhancedAnnotatedMethod<?, ? super T>> superClassMethods = Reflections.cast(current.getDeclaredEnhancedMethods());
methodsTemp.addAll(superClassMethods);
current = current.getEnhancedSuperclass();
}
}
// Also add default methods
for (Class<?> interfaceClazz : Reflections.getInterfaceClosure(javaClass)) {
EnhancedAnnotatedType<?> interfaceType = classTransformer.getEnhancedAnnotatedType(interfaceClazz, slim.getIdentifier().getBdaId());
for (EnhancedAnnotatedMethod<?, ?> interfaceMethod : interfaceType.getEnhancedMethods()) {
if(Reflections.isDefault(interfaceMethod.getJavaMember())) {
methodsTemp.add((EnhancedAnnotatedMethod<?, ? super T>) interfaceMethod);
}
}
}
}
this.declaredMethods = new HashSet<>(declaredMethodsTemp);
} else {
for (AnnotatedMethod<? super T> method : annotatedType.getMethods()) {
EnhancedAnnotatedMethod<?, ? super T> enhancedMethod = EnhancedAnnotatedMethodImpl.of(method, this, classTransformer);
methodsTemp.add(enhancedMethod);
if (method.getJavaMember().getDeclaringClass().equals(javaClass)) {
declaredMethodsTemp.add(enhancedMethod);
}
for (Annotation annotation : enhancedMethod.getAnnotations()) {
if (method.getJavaMember().getDeclaringClass().equals(javaClass)) {
declaredAnnotatedMethods.put(annotation.annotationType(), enhancedMethod);
}
}
for (Class<? extends Annotation> annotationType : MAPPED_DECLARED_METHOD_PARAMETER_ANNOTATIONS) {
if (enhancedMethod.getEnhancedParameters(annotationType).size() > 0) {
if (method.getJavaMember().getDeclaringClass().equals(javaClass)) {
declaredMethodsByAnnotatedParameters.put(annotationType, enhancedMethod);
}
}
}
}
this.declaredMethods = ImmutableSet.copyOf(declaredMethodsTemp);
}
this.declaredAnnotatedMethods = Multimaps.unmodifiableMultimap(declaredAnnotatedMethods);
this.declaredMethodsByAnnotatedParameters = Multimaps.unmodifiableMultimap(declaredMethodsByAnnotatedParameters);
SetMultimap<Class<? extends Annotation>, Annotation> declaredMetaAnnotationMap = SetMultimap.newSetMultimap();
processMetaAnnotations(declaredMetaAnnotationMap, declaredAnnotationMap.values(), classTransformer, true);
this.declaredMetaAnnotationMap = Multimaps.unmodifiableMultimap(declaredMetaAnnotationMap);
this.overriddenMethods = getOverriddenMethods(this, methodsTemp);
// WELD-1548 remove all overriden methods except for those which are overriden by a bridge method
methodsTemp.removeAll(getOverriddenMethods(this, methodsTemp, true));
this.methods = methodsTemp;
this.annotatedMethods = buildAnnotatedMethodMultimap(this.methods);
this.annotatedMethodsByAnnotatedParameters = buildAnnotatedParameterMethodMultimap(this.methods);
}
protected Set<EnhancedAnnotatedMethod<?, ? super T>> getOverriddenMethods(EnhancedAnnotatedType<T> annotatedType,
Set<EnhancedAnnotatedMethod<?, ? super T>> methods) {
return getOverriddenMethods(annotatedType, methods, false);
}
/**
*
* @param annotatedType
* @param methods
* @param skipOverridingBridgeMethods If set to <code>true</code> the returning set will not contain methods overriden by a bridge method
* @return the set of overriden methods
*/
protected Set<EnhancedAnnotatedMethod<?, ? super T>> getOverriddenMethods(EnhancedAnnotatedType<T> annotatedType,
Set<EnhancedAnnotatedMethod<?, ? super T>> methods, boolean skipOverridingBridgeMethods) {
Set<EnhancedAnnotatedMethod<?, ? super T>> overriddenMethods = new HashSet<EnhancedAnnotatedMethod<?, ? super T>>();
Multimap<MethodSignature, Package> seenMethods = SetMultimap.newSetMultimap();
for (Class<? super T> clazz = annotatedType.getJavaClass(); clazz != null && clazz != Object.class; clazz = clazz.getSuperclass()) {
for (EnhancedAnnotatedMethod<?, ? super T> method : methods) {
if (method.getJavaMember().getDeclaringClass().equals(clazz)) {
if (skipOverridingBridgeMethods && method.getJavaMember().isBridge()) {
continue;
}
if (isOverridden(method, seenMethods)) {
overriddenMethods.add(method);
}
seenMethods.put(method.getSignature(), method.getPackage());
}
}
}
return immutableSetView(overriddenMethods);
}
protected Multimap<Class<? extends Annotation>, EnhancedAnnotatedMethod<?, ? super T>> buildAnnotatedMethodMultimap(Set<EnhancedAnnotatedMethod<?, ? super T>> effectiveMethods) {
Multimap<Class<? extends Annotation>, EnhancedAnnotatedMethod<?, ? super T>> result = SetMultimap.newSetMultimap();
for (EnhancedAnnotatedMethod<?, ? super T> method : effectiveMethods) {
for (Class<? extends Annotation> annotation : MAPPED_METHOD_ANNOTATIONS) {
if (method.isAnnotationPresent(annotation)) {
result.put(annotation, method);
}
}
}
return Multimaps.unmodifiableMultimap(result);
}
protected Multimap<Class<? extends Annotation>, EnhancedAnnotatedMethod<?, ? super T>> buildAnnotatedParameterMethodMultimap(Set<EnhancedAnnotatedMethod<?, ? super T>> effectiveMethods) {
Multimap<Class<? extends Annotation>, EnhancedAnnotatedMethod<?, ? super T>> result = SetMultimap.newSetMultimap();
for (EnhancedAnnotatedMethod<?, ? super T> method : effectiveMethods) {
for (Class<? extends Annotation> annotation : MAPPED_METHOD_PARAMETER_ANNOTATIONS) {
if (!method.getEnhancedParameters(annotation).isEmpty()) {
result.put(annotation, method);
}
}
}
return Multimaps.unmodifiableMultimap(result);
}
private static boolean isOverridden(EnhancedAnnotatedMethod<?, ?> method, Multimap<MethodSignature, Package> seenMethods) {
if (method.isPrivate()) {
return false;
} else if (method.isPackagePrivate() && seenMethods.containsKey(method.getSignature())) {
return seenMethods.get(method.getSignature()).contains(method.getPackage());
} else {
return seenMethods.containsKey(method.getSignature());
}
}
/**
* Gets the implementing class
*
* @return The class
*/
public Class<? extends T> getAnnotatedClass() {
return getJavaClass();
}
/**
* Gets the delegate (class)
*
* @return The class
*/
@Override
public Class<T> getDelegate() {
return getJavaClass();
}
/**
* Gets the abstracted fields of the class
* <p/>
* Initializes the fields if they are null
*
* @return The set of abstracted fields
*/
@Override
public Collection<EnhancedAnnotatedField<?, ? super T>> getEnhancedFields() {
return Collections.unmodifiableCollection(fields);
}
@Override
public Collection<EnhancedAnnotatedField<?, ? super T>> getDeclaredEnhancedFields() {
return Collections.unmodifiableCollection(declaredFields);
}
@Override
public <F> EnhancedAnnotatedField<F, ?> getDeclaredEnhancedField(String fieldName) {
for (EnhancedAnnotatedField<?, ?> field : declaredFields) {
if (field.getName().equals(fieldName)) {
return cast(field);
}
}
return null;
}
@Override
public Collection<EnhancedAnnotatedField<?, ? super T>> getDeclaredEnhancedFields(Class<? extends Annotation> annotationType) {
return declaredAnnotatedFields.get(annotationType);
}
@Override
public EnhancedAnnotatedConstructor<T> getDeclaredEnhancedConstructor(ConstructorSignature signature) {
return cast(declaredConstructorsBySignature.get(signature));
}
/**
* Gets the abstracted field annotated with a specific annotation type
* <p/>
* If the fields map is null, initialize it first
*
* @param annotationType The annotation type to match
* @return A set of matching abstracted fields, null if none are found.
*/
@Override
public Collection<EnhancedAnnotatedField<?, ?>> getEnhancedFields(Class<? extends Annotation> annotationType) {
if (annotatedFields == null) {
// Build collection from class hierarchy
ArrayList<EnhancedAnnotatedField<?, ?>> aggregatedFields = new ArrayList<EnhancedAnnotatedField<?, ?>>(this.declaredAnnotatedFields.get(annotationType));
if ((superclass != null) && (superclass.getJavaClass() != Object.class)) {
aggregatedFields.addAll(superclass.getEnhancedFields(annotationType));
}
return Collections.unmodifiableCollection(aggregatedFields);
} else {
// Return results collected directly from AnnotatedType
return annotatedFields.get(annotationType);
}
}
@Override
public boolean isLocalClass() {
return getJavaClass().isLocalClass();
}
@Override
public boolean isAnonymousClass() {
return getJavaClass().isAnonymousClass();
}
@Override
public boolean isMemberClass() {
return getJavaClass().isMemberClass();
}
@Override
public boolean isAbstract() {
return Modifier.isAbstract(getJavaClass().getModifiers());
}
@Override
public boolean isEnum() {
return getJavaClass().isEnum();
}
@Override
public boolean isSerializable() {
return Reflections.isSerializable(getJavaClass());
}
/**
* Gets the abstracted methods that have a certain annotation type present
* <p/>
* If the annotated methods map is null, initialize it first
*
* @param annotationType The annotation type to match
* @return A set of matching method abstractions. Returns an empty set if no
* matches are found.
* @see org.jboss.weld.annotated.enhanced.EnhancedAnnotatedType#getEnhancedMethods(Class)
*/
@Override
public Collection<EnhancedAnnotatedMethod<?, ? super T>> getEnhancedMethods(Class<? extends Annotation> annotationType) {
return Collections.unmodifiableCollection(annotatedMethods.get(annotationType));
}
@Override
public Collection<EnhancedAnnotatedMethod<?, ? super T>> getDeclaredEnhancedMethods(Class<? extends Annotation> annotationType) {
return Collections.unmodifiableCollection(declaredAnnotatedMethods.get(annotationType));
}
@Override
public Collection<EnhancedAnnotatedConstructor<T>> getEnhancedConstructors() {
return Collections.unmodifiableCollection(constructors);
}
/**
* Gets constructors with given annotation type
*
* @param annotationType The annotation type to match
* @return A set of abstracted constructors with given annotation type. If
* the constructors set is empty, initialize it first. Returns an
* empty set if there are no matches.
* @see org.jboss.weld.annotated.enhanced.EnhancedAnnotatedType#getEnhancedConstructors(Class)
*/
@Override
public Collection<EnhancedAnnotatedConstructor<T>> getEnhancedConstructors(Class<? extends Annotation> annotationType) {
Set<EnhancedAnnotatedConstructor<T>> ret = new HashSet<EnhancedAnnotatedConstructor<T>>();
for (EnhancedAnnotatedConstructor<T> constructor : constructors) {
if (constructor.isAnnotationPresent(annotationType)) {
ret.add(constructor);
}
}
return ret;
}
@Override
public EnhancedAnnotatedConstructor<T> getNoArgsEnhancedConstructor() {
return cast(declaredConstructorsBySignature.get(ConstructorSignatureImpl.NO_ARGS_SIGNATURE));
}
@Override
public Collection<EnhancedAnnotatedMethod<?, ? super T>> getDeclaredEnhancedMethodsWithAnnotatedParameters(Class<? extends Annotation> annotationType) {
return Collections.unmodifiableCollection(declaredMethodsByAnnotatedParameters.get(annotationType));
}
@Override
public Collection<EnhancedAnnotatedMethod<?, ? super T>> getEnhancedMethods() {
return methods;
}
@Override
public Collection<EnhancedAnnotatedMethod<?, ? super T>> getDeclaredEnhancedMethods() {
return Collections.unmodifiableSet(declaredMethods);
}
@Override
public <M> EnhancedAnnotatedMethod<M, ?> getDeclaredEnhancedMethod(MethodSignature signature) {
for (EnhancedAnnotatedMethod<?, ? super T> method : declaredMethods) {
if (method.getSignature().equals(signature)) {
return cast(method);
}
}
return null;
}
@Override
public <M> EnhancedAnnotatedMethod<M, ?> getEnhancedMethod(MethodSignature signature) {
EnhancedAnnotatedMethod<M, ?> method = cast(getDeclaredEnhancedMethod(signature));
if ((method == null) && (superclass != null) && (superclass.getJavaClass() != Object.class)) {
method = superclass.getEnhancedMethod(signature);
}
return method;
}
/**
* Gets a string representation of the class
*
* @return A string representation
*/
@Override
public String toString() {
return Formats.formatAnnotatedType(this);
}
@Override
public String getSimpleName() {
return getJavaClass().getSimpleName();
}
/**
* Indicates if the type is static
*
* @return True if static, false otherwise
* @see org.jboss.weld.annotated.enhanced.EnhancedAnnotated#isStatic()
*/
@Override
public boolean isStatic() {
return Reflections.isStatic(getDelegate());
}
/**
* Indicates if the type if final
*
* @return True if final, false otherwise
* @see org.jboss.weld.annotated.enhanced.EnhancedAnnotated#isFinal()
*/
@Override
public boolean isFinal() {
return Reflections.isFinal(getDelegate());
}
@Override
public boolean isPublic() {
return Modifier.isFinal(getJavaClass().getModifiers());
}
@Override
public boolean isGeneric() {
return getJavaClass().getTypeParameters().length > 0;
}
/**
* Gets the name of the type
*
* @returns The name
* @see org.jboss.weld.annotated.enhanced.EnhancedAnnotated#getName()
*/
@Override
public String getName() {
return getJavaClass().getName();
}
/**
* Gets the superclass abstraction of the type
*
* @return The superclass abstraction
*/
@Override
public EnhancedAnnotatedType<? super T> getEnhancedSuperclass() {
return superclass;
}
@Override
public boolean isEquivalent(Class<?> clazz) {
return getDelegate().equals(clazz);
}
@Override
public boolean isPrivate() {
return Modifier.isPrivate(getJavaClass().getModifiers());
}
@Override
public boolean isPackagePrivate() {
return Reflections.isPackagePrivate(getJavaClass().getModifiers());
}
@Override
public Package getPackage() {
return getJavaClass().getPackage();
}
@Override
public <U> EnhancedAnnotatedType<? extends U> asEnhancedSubclass(EnhancedAnnotatedType<U> clazz) {
return cast(this);
}
@Override
public <S> S cast(Object object) {
return Reflections.<S>cast(object);
}
@Override
public Set<AnnotatedConstructor<T>> getConstructors() {
return Collections.unmodifiableSet(Reflections.<Set<AnnotatedConstructor<T>>>cast(constructors));
}
@Override
public Set<AnnotatedField<? super T>> getFields() {
return cast(fields);
}
@Override
public Set<AnnotatedMethod<? super T>> getMethods() {
return cast(Sets.union(methods, overriddenMethods));
}
@Override
public Set<Annotation> getDeclaredMetaAnnotations(Class<? extends Annotation> metaAnnotationType) {
return declaredMetaAnnotationMap.containsKey(metaAnnotationType) ? ImmutableSet.copyOf(declaredMetaAnnotationMap.get(metaAnnotationType))
: Collections.emptySet();
}
@Override
public boolean isDiscovered() {
return discovered;
}
@Override
public SlimAnnotatedType<T> slim() {
return slim;
}
@Override
public Collection<EnhancedAnnotatedMethod<?, ? super T>> getEnhancedMethodsWithAnnotatedParameters(Class<? extends Annotation> annotationType) {
return annotatedMethodsByAnnotatedParameters.get(annotationType);
}
@Override
public int hashCode() {
return slim.hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (this == obj) {
return true;
}
if (getClass() != obj.getClass()) {
return false;
}
EnhancedAnnotatedTypeImpl<?> that = cast(obj);
return slim.equals(that.slim);
}
}