nl.hsac.fitnesse.fixture.util.ReflectionHelper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hsac-fitnesse-fixtures Show documentation
Show all versions of hsac-fitnesse-fixtures Show documentation
Fixtures to assist in testing via FitNesse
package nl.hsac.fitnesse.fixture.util;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
/**
* Helps using Java reflection in an efficient way.
*/
public class ReflectionHelper {
private static final Map, Map> cache = new HashMap, Map>();
/**
* Finds the supplied annotation if present on the element, or on its parents.
* The parents in this sense are the super types and interfaces if the element is a class.
* Or, in case of a Method, the (overridden) method declaration by its super types or interfaces.
* @param annotationClass class of annotation looked for.
* @param element element (class or method) to look for the annotation on.
* @param type of annotation.
* @return annotation if present, null
otherwise.
*/
public A getAnnotation(Class annotationClass, AnnotatedElement element) {
A annotation;
Map cacheMap = cache.get(annotationClass);
if (cacheMap == null) {
cacheMap = new HashMap();
cache.put(annotationClass, cacheMap);
}
if (cacheMap.containsKey(element)) {
annotation = (A) cacheMap.get(element);
} else {
annotation = element.getAnnotation(annotationClass);
if (annotation == null && element instanceof Method) {
annotation = getOverriddenAnnotation(annotationClass, (Method) element);
}
cacheMap.put(element, annotation);
}
return annotation;
}
private static A getOverriddenAnnotation(Class annotationClass, Method method) {
A result = null;
Class> methodClass = method.getDeclaringClass();
String name = method.getName();
Class>[] params = method.getParameterTypes();
// prioritize all superclasses over all interfaces
Class> superclass = methodClass.getSuperclass();
if (superclass != null) {
result = getOverriddenAnnotationFrom(annotationClass, superclass, name, params);
}
if (result == null) {
// depth-first search over interface hierarchy
for (Class> intf : methodClass.getInterfaces()) {
result = getOverriddenAnnotationFrom(annotationClass, intf, name, params);
if (result != null) {
break;
}
}
}
return result;
}
private static A getOverriddenAnnotationFrom(
Class annotationClass, Class> searchClass, String name, Class>[] params) {
A result = null;
try {
Method method = searchClass.getMethod(name, params);
result = method.getAnnotation(annotationClass);
if (result == null) {
result = getOverriddenAnnotation(annotationClass, method);
}
} catch (final NoSuchMethodException e) {
// ignore, just return null
}
return result;
}
/**
* Sets (private) field of o (the field may be defined by o's class, or one of its superclasses).
*
* @param o instance to set field of.
* @param fieldName name of field.
* @param newValue value to set.
*/
public void setField(Object o, String fieldName, Object newValue) {
if (o == null) {
throw new IllegalArgumentException("No object to set on provided");
}
Field field = findField(o, fieldName);
if (field == null) {
throw new IllegalArgumentException(o.getClass() + " does not have a field " + fieldName);
} else {
if (!field.canAccess(o)) {
field.setAccessible(true);
}
try {
field.set(o, newValue);
} catch (IllegalAccessException e) {
throw new IllegalArgumentException("Unable to set " + newValue + " for " + fieldName, e);
}
}
}
/**
* Gets (private) field of o (the field may be defined by o's class, or one of its superclasses).
*
* @param o instance to set field of.
* @param fieldName name of field.
* @return value of field.
*/
public Object getField(Object o, String fieldName) {
if (o == null) {
throw new IllegalArgumentException("No object to get from provided");
}
Field field = findField(o, fieldName);
if (field == null) {
throw new IllegalArgumentException(o.getClass() + " does not have a field " + fieldName);
} else {
if (!field.canAccess(o)) {
field.setAccessible(true);
}
try {
return field.get(o);
} catch (IllegalAccessException e) {
throw new IllegalArgumentException("Unable to get " + fieldName, e);
}
}
}
private Field findField(Object o, String fieldName) {
Class> aClass = o.getClass();
Field result = null;
while (result == null && !Object.class.equals(aClass)) {
try {
result = aClass.getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
aClass = aClass.getSuperclass();
}
}
return result;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy