org.milyn.annotation.AnnotatedClassImpl Maven / Gradle / Ivy
The newest version!
// Copyright 2007 Fusionsoft, Inc. All rights reserved.
// Use is subject to license terms.
package org.milyn.annotation;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
/** The standard implementation for the annotated class.
*
* Note: This class is a modified version of the original Fusionsoft Annotation
* library. See: {@link http://www.fusionsoft-online.com/articles-java-annotations.php}
*
* @author Vladimir Ovchinnikov
* @author [email protected]
*
* @version 1.0
*/
class AnnotatedClassImpl implements AnnotatedClass {
private final Class> theClass;
private Map, Annotation> classToAnnotationMap = null;
private Map methodToAnnotatedMap = null;
private Annotation[] annotations = null;
private AnnotatedMethod[] annotatedMethods = null;
AnnotatedClassImpl (final Class> theClass){
super();
this.theClass = theClass;
}
/**
* @return the cached map of classes to annotations
*/
private Map, Annotation> getAllAnnotationMap(){
if (classToAnnotationMap == null) {
classToAnnotationMap = getAllAnnotationMapCalculated();
}
return classToAnnotationMap;
}
/**
* @return the calculated map of classes to annotations
*/
private Map, Annotation> getAllAnnotationMapCalculated(){
final HashMap, Annotation> result = new HashMap, Annotation>();
final Class> superClass = getTheClass().getSuperclass();
// Get the superclass's annotations
if (superClass != null) {
fillAnnotationsForOneClass(result, superClass);
}
// Get the superinterfaces' annotations
for (final Class> c : getTheClass().getInterfaces()) {
fillAnnotationsForOneClass(result, c);
}
// Get its own annotations. They have preferece to inherited annotations.
for (final Annotation annotation : getTheClass().getDeclaredAnnotations()) {
result.put(annotation.getClass().getInterfaces()[0], annotation);
}
return result;
}
/**
* @param result map of classes to annotations
* @param baseClass is the superclass or one of the superinterfaces.
*/
private void fillAnnotationsForOneClass(final HashMap, Annotation> result,
final Class> baseClass) {
addAnnotations(result, AnnotationManager.getAnnotatedClass(baseClass).getAllAnnotations());
}
/**
* @param result map of classes to annotations
* @param annotations to add to the result
*/
private void addAnnotations(final HashMap, Annotation> result,
final Annotation[] annotations) {
for (final Annotation annotation : annotations){
if (annotation != null) {
if (result.containsKey(annotation.getClass().getInterfaces()[0])) {
result.put(annotation.getClass().getInterfaces()[0], null /*it means not to take the annotation at all*/);
} else {
result.put(annotation.getClass().getInterfaces()[0], annotation);
}
}
}
}
public Class> getTheClass() {
return theClass;
}
public Annotation[] getAllAnnotations() {
if (annotations == null) {
annotations = getAllAnnotationsCalculated();
}
return annotations;
}
private Annotation[] getAllAnnotationsCalculated() {
return getAllAnnotationMap().values().toArray(new Annotation[0]);
}
@SuppressWarnings("unchecked")
public T getAnnotation(final Class annotationClass) {
return (T) getAllAnnotationMap().get(annotationClass);
}
private Map getMethodMap(){
if (methodToAnnotatedMap == null) {
methodToAnnotatedMap = getMethodMapCalculated();
}
return methodToAnnotatedMap;
}
private Map getMethodMapCalculated(){
final HashMap result = new HashMap();
for (final Method method : getTheClass().getMethods()) {
result.put(method, new AnnotatedMethodImpl(this, method));
}
return result;
}
public AnnotatedMethod getAnnotatedMethod(final Method method) {
return getMethodMap().get(method);
}
public AnnotatedMethod[] getAnnotatedMethods() {
if (annotatedMethods == null) {
annotatedMethods = getAnnotatedMethodsCalculated();
}
return annotatedMethods;
}
private AnnotatedMethod[] getAnnotatedMethodsCalculated() {
final Collection values = getMethodMap().values();
return values.toArray(new AnnotatedMethod[0]);
}
public AnnotatedMethod getAnnotatedMethod(final String name, final Class>[] parameterType) {
try {
return getAnnotatedMethod(getTheClass().getMethod(name, parameterType));
} catch (final SecurityException e) {
throw new RuntimeException(e);
} catch (final NoSuchMethodException e) {
return null;
}
}
/* (non-Javadoc)
* @see com.fusionsoft.annotation.AnnotatedClass#isAnnotationPresent(java.lang.Class)
*/
public boolean isAnnotationPresent(
final Class extends Annotation> annotationClass) {
return getAnnotation(annotationClass) != null;
}
}