org.jboss.weld.introspector.jlr.AbstractWeldAnnotated Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of weld-osgi-bundle Show documentation
Show all versions of weld-osgi-bundle Show documentation
Weld runtime packaged as an OSGi bundle
/*
* 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.introspector.jlr;
import java.lang.annotation.Annotation;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.inject.Qualifier;
import org.jboss.weld.exceptions.WeldException;
import org.jboss.weld.introspector.WeldAnnotated;
import org.jboss.weld.literal.DefaultLiteral;
import org.jboss.weld.resources.ClassTransformer;
import org.jboss.weld.resources.SharedObjectFacade;
import org.jboss.weld.util.LazyValueHolder;
import org.jboss.weld.util.collections.ArraySet;
import org.jboss.weld.util.collections.ArraySetMultimap;
import org.jboss.weld.util.collections.Arrays2;
import org.jboss.weld.util.reflection.Reflections;
import static org.jboss.weld.logging.messages.ReflectionMessage.ANNOTATION_MAP_NULL;
import static org.jboss.weld.logging.messages.ReflectionMessage.DECLARED_ANNOTATION_MAP_NULL;
import static org.jboss.weld.util.reflection.Reflections.EMPTY_ANNOTATIONS;
/**
* Represents functionality common for all annotated items, mainly different
* mappings of the annotations and meta-annotations
*
* AbstractAnnotatedItem is an immutable class and therefore threadsafe
*
* @param
* @param
* @author Pete Muir
* @author Nicklas Karlsson
* @see org.jboss.weld.introspector.WeldAnnotated
*/
public abstract class AbstractWeldAnnotated implements WeldAnnotated {
// The set of default binding types
private static final Set DEFAULT_QUALIFIERS = Collections.singleton(DefaultLiteral.INSTANCE);
/**
* Builds the annotation map (annotation type -> annotation)
*
* @param annotations The array of annotations to map
* @return The annotation map
*/
protected static Map, Annotation> buildAnnotationMap(Annotation[] annotations) {
Map, Annotation> annotationMap = new HashMap, Annotation>();
for (Annotation annotation : annotations) {
annotationMap.put(annotation.annotationType(), annotation);
}
return annotationMap;
}
/**
* Builds the annotation map (annotation type -> annotation)
*
* @param annotations The array of annotations to map
* @return The annotation map
*/
protected static Map, Annotation> buildAnnotationMap(Iterable annotations) {
Map, Annotation> annotationMap = new HashMap, Annotation>();
for (Annotation annotation : annotations) {
annotationMap.put(annotation.annotationType(), annotation);
}
return annotationMap;
}
protected static void addMetaAnnotations(ArraySetMultimap, Annotation> metaAnnotationMap, Annotation annotation, Annotation[] metaAnnotations, boolean declared) {
for (Annotation metaAnnotation : metaAnnotations) {
addMetaAnnotation(metaAnnotationMap, annotation, metaAnnotation.annotationType(), declared);
}
}
protected static void addMetaAnnotations(ArraySetMultimap, Annotation> metaAnnotationMap, Annotation annotation, Iterable metaAnnotations, boolean declared) {
for (Annotation metaAnnotation : metaAnnotations) {
addMetaAnnotation(metaAnnotationMap, annotation, metaAnnotation.annotationType(), declared);
}
}
private static void addMetaAnnotation(ArraySetMultimap, Annotation> metaAnnotationMap, Annotation annotation, Class extends Annotation> metaAnnotationType, boolean declared) {
// Only map meta-annotations we are interested in
if (declared ? MAPPED_DECLARED_METAANNOTATIONS.contains(metaAnnotationType) : MAPPED_METAANNOTATIONS.contains(metaAnnotationType)) {
metaAnnotationMap.putSingleElement(metaAnnotationType, annotation);
}
}
// The annotation map (annotation type -> annotation) of the item
private final Map, Annotation> annotationMap;
// The meta-annotation map (annotation type -> set of annotations containing
// meta-annotation) of the item
private final ArraySetMultimap, Annotation> metaAnnotationMap;
private final Class rawType;
private final Type[] actualTypeArguments;
private final Type type;
private final LazyValueHolder> typeClosure;
/**
* Constructor
*
* Also builds the meta-annotation map. Throws a NullPointerException if
* trying to register a null map
*
* @param annotationMap A map of annotation to register
*/
public AbstractWeldAnnotated(Map, Annotation> annotationMap, Map, Annotation> declaredAnnotationMap, ClassTransformer classTransformer, Class rawType, Type type, final LazyValueHolder> typeClosure) {
if (annotationMap == null) {
throw new WeldException(ANNOTATION_MAP_NULL);
}
this.annotationMap = SharedObjectFacade.wrap(annotationMap);
if (!annotationMap.isEmpty()) {
ArraySetMultimap, Annotation> metaAnnotationMap = new ArraySetMultimap, Annotation>();
for (Annotation annotation : annotationMap.values()) {
addMetaAnnotations(metaAnnotationMap, annotation, annotation.annotationType().getAnnotations(), false);
addMetaAnnotations(metaAnnotationMap, annotation, classTransformer.getTypeStore().get(annotation.annotationType()), false);
}
metaAnnotationMap.trimToSize();
this.metaAnnotationMap = metaAnnotationMap;
} else {
this.metaAnnotationMap = null;
}
if (declaredAnnotationMap == null) {
throw new WeldException(DECLARED_ANNOTATION_MAP_NULL);
}
this.rawType = rawType;
this.type = type;
if (type instanceof ParameterizedType) {
this.actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();
} else {
this.actualTypeArguments = new Type[0];
}
this.typeClosure = typeClosure;
}
public Class getJavaClass() {
return rawType;
}
public Type[] getActualTypeArguments() {
return Arrays2.copyOf(actualTypeArguments, actualTypeArguments.length);
}
public Set getInterfaceClosure() {
Set interfaces = new HashSet();
for (Type t : getTypeClosure()) {
if (Reflections.getRawType(t).isInterface()) {
interfaces.add(t);
}
}
return Collections.unmodifiableSet(interfaces);
}
public abstract S getDelegate();
public boolean isParameterizedType() {
return rawType.getTypeParameters().length > 0;
}
public boolean isPrimitive() {
return getJavaClass().isPrimitive();
}
public Type getBaseType() {
return type;
}
public Set getTypeClosure() {
return typeClosure.get();
}
public Set getAnnotations() {
return Collections.unmodifiableSet(new ArraySet(annotationMap.values()));
}
public Set getMetaAnnotations(Class extends Annotation> metaAnnotationType) {
if (metaAnnotationMap == null) {
return Collections.emptySet();
} else {
final List annotations = metaAnnotationMap.get(metaAnnotationType);
if (annotations == null) {
return Collections.emptySet();
} else {
return Collections.unmodifiableSet(new ArraySet(annotations));
}
}
}
@Deprecated
public Set getQualifiers() {
if (getMetaAnnotations(Qualifier.class).size() > 0) {
return Collections.unmodifiableSet(getMetaAnnotations(Qualifier.class));
} else {
return Collections.unmodifiableSet(DEFAULT_QUALIFIERS);
}
}
@Deprecated
public Annotation[] getBindingsAsArray() {
return getQualifiers().toArray(EMPTY_ANNOTATIONS);
}
public A getAnnotation(Class annotationType) {
return annotationType.cast(annotationMap.get(annotationType));
}
public boolean isAnnotationPresent(Class extends Annotation> annotationType) {
return annotationMap.containsKey(annotationType);
}
Map, Annotation> getAnnotationMap() {
return annotationMap;
}
}