use of org.springframework.asm.ClassVisitor in project grails-core by grails.
the class GrailsAwareInjectionOperation method initializeState.
private static void initializeState() {
if (classInjectors != null) {
return;
}
String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + ClassUtils.convertClassNameToResourcePath(INJECTOR_CODEHAUS_SCAN_PACKAGE) + "/**/*.class";
String pattern2 = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + ClassUtils.convertClassNameToResourcePath(INJECTOR_SCAN_PACKAGE) + "/**/*.class";
ClassLoader classLoader = GrailsAwareInjectionOperation.class.getClassLoader();
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(classLoader);
Resource[] resources;
try {
resources = scanForPatterns(resolver, pattern2, pattern);
if (resources.length == 0) {
classLoader = Thread.currentThread().getContextClassLoader();
resolver = new PathMatchingResourcePatternResolver(classLoader);
resources = scanForPatterns(resolver, pattern2, pattern);
}
final List<ClassInjector> injectors = new ArrayList<ClassInjector>();
final List<ClassInjector> globalInjectors = new ArrayList<ClassInjector>();
final Set<Class> injectorClasses = new HashSet<Class>();
for (Resource resource : resources) {
// ignore not readable classes and closures
if (!resource.isReadable() || resource.getFilename().contains("$_"))
continue;
InputStream inputStream = resource.getInputStream();
try {
final ClassReader classReader = new ClassReader(inputStream);
final String astTransformerClassName = AstTransformer.class.getSimpleName();
final ClassLoader finalClassLoader = classLoader;
classReader.accept(new ClassVisitor(Opcodes.ASM4) {
@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
try {
if (visible && desc.contains(astTransformerClassName)) {
Class<?> injectorClass = finalClassLoader.loadClass(classReader.getClassName().replace('/', '.'));
if (injectorClasses.contains(injectorClass))
return super.visitAnnotation(desc, true);
if (ClassInjector.class.isAssignableFrom(injectorClass)) {
injectorClasses.add(injectorClass);
ClassInjector classInjector = (ClassInjector) injectorClass.newInstance();
injectors.add(classInjector);
if (GlobalClassInjector.class.isAssignableFrom(injectorClass)) {
globalInjectors.add(classInjector);
}
}
}
} catch (ClassNotFoundException e) {
// ignore
} catch (InstantiationException e) {
// ignore
} catch (IllegalAccessException e) {
// ignore
}
return super.visitAnnotation(desc, visible);
}
}, ClassReader.SKIP_CODE);
} catch (IOException e) {
// ignore
} catch (NoClassDefFoundError e) {
// ignore
} finally {
inputStream.close();
}
}
Collections.sort(injectors, new Comparator<ClassInjector>() {
@SuppressWarnings({ "unchecked", "rawtypes" })
public int compare(ClassInjector classInjectorA, ClassInjector classInjectorB) {
if (classInjectorA instanceof Comparable) {
return ((Comparable) classInjectorA).compareTo(classInjectorB);
}
return 0;
}
});
classInjectors = injectors.toArray(new ClassInjector[injectors.size()]);
globalClassInjectors = globalInjectors.toArray(new ClassInjector[globalInjectors.size()]);
} catch (IOException e) {
// ignore
}
}
Aggregations