
org.jamon.util.AnnotationReflector Maven / Gradle / Ivy
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.jamon.util;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;
/**
* A reflection tool to convert annotations loaded under a different class loader into an annotation
* implementing a specified annotation class. Because TemplateDescription is working with classes
* loaded from a client-defined ClassLoader, it is possible that said ClassLoader will contain it's
* own copy of jamon.jar, meaning that annotations we load from classes it returns will not be class
* compatible with our copies of the annotation classes.
*/
public class AnnotationReflector {
private Map annotations = new HashMap();
public AnnotationReflector(Class> clazz) {
for (Annotation annotation : clazz.getAnnotations()) {
annotations.put(annotation.annotationType().getName(), annotation);
}
}
public T getAnnotation(Class clazz) {
final Annotation annotation = annotations.get(clazz.getName());
return clazz.cast(proxyAnnotation(clazz, annotation));
}
private Object proxyAnnotation(Class> clazz, final Object annotation) {
return clazz.cast(Proxy.newProxyInstance(getClass().getClassLoader(),
new Class>[] { clazz }, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = annotation.getClass().getMethod(method.getName()).invoke(annotation);
return maybeProxyAnnotation(method.getReturnType(), result);
}
}));
}
private Object maybeProxyAnnotation(Class> type, Object object) {
if (object == null) {
return null;
}
if (type.isAnnotation()) {
return proxyAnnotation(type, object);
}
if (type.isArray() && type.getComponentType().isAnnotation()) {
int arrayLength = Array.getLength(object);
Object array = Array.newInstance(type.getComponentType(), arrayLength);
for (int i = 0; i < arrayLength; i++) {
Array.set(array, i, proxyAnnotation(type.getComponentType(), Array.get(object, i)));
}
return array;
}
else {
return object;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy