package de.invesdwin.util.lang;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import javax.annotation.concurrent.Immutable;
import org.springframework.util.ClassUtils;
import de.invesdwin.norva.apt.staticfacade.StaticFacadeDefinition;
import de.invesdwin.norva.beanpath.BeanPathReflections;
import de.invesdwin.util.assertions.Assertions;
import de.invesdwin.util.lang.internal.AReflectionsStaticFacade;
@StaticFacadeDefinition(name = "de.invesdwin.util.lang.internal.AReflectionsStaticFacade", targets = {
org.fest.reflect.core.Reflection.class, BeanPathReflections.class,
org.springframework.core.GenericTypeResolver.class })
@Immutable
public final class Reflections extends AReflectionsStaticFacade {
private Reflections() {}
public static boolean classExists(final String className) {
try {
Assertions.assertThat(Class.forName(className, false, ClassUtils.getDefaultClassLoader())).isNotNull();
return true;
} catch (final ClassNotFoundException e) {
return false;
}
}
@SuppressWarnings("unchecked")
public static <T> Class<T> classForName(final String className) {
try {
return (Class<T>) Class.forName(className);
} catch (final ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
public static ClassLoader getRootClassLoader(final ClassLoader classLoader) {
ClassLoader parent = classLoader;
while (true) {
final ClassLoader newParent = parent.getParent();
if (newParent == null) {
return parent;
} else {
parent = newParent;
}
}
}
public static void makeAccessibleFinal(final Field field) {
try {
makeAccessible(field);
final Field modifiersField = Field.class.getDeclaredField("modifiers");
makeAccessible(modifiersField);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
} catch (final NoSuchFieldException e) {
handleReflectionException(e);
} catch (final IllegalArgumentException e) {
handleReflectionException(e);
} catch (final IllegalAccessException e) {
handleReflectionException(e);
}
}
public static boolean isSynchronized(final Method method) {
return Modifier.isSynchronized(method.getModifiers());
}
public static <T extends Annotation> T getAnnotation(final Class<T> annotationType) {
// Get the caller by inspecting the stackTrace
final StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
// Iterate on the stack trace. the outer most annotation wins here
for (int i = stackTrace.length - 1; i >= 0; i--) {
Class<?> classCaller = null;
// Get the current class
try {
classCaller = Class.forName(stackTrace[i].getClassName());
} catch (final ClassNotFoundException cnfe) {
// Corner case : we just have to go higher in the stack in this case.
continue;
}
// Get the current method
final String methodCaller = stackTrace[i].getMethodName();
T instance = null;
// Check if we have any annotation associated with the method
final Method method = findMethodByName(classCaller, methodCaller);
if (method != null) {
instance = getAnnotation(method, annotationType);
}
if (instance == null) {
instance = getAnnotation(classCaller, annotationType);
}
if (instance != null) {
return instance;
}
}
return null;
}
}