Search in sources :

Example 1 with ClassVisitor

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
    }
}
Also used : ClassVisitor(org.springframework.asm.ClassVisitor) GlobalClassInjector(grails.compiler.ast.GlobalClassInjector) ClassInjector(grails.compiler.ast.ClassInjector) InputStream(java.io.InputStream) FileSystemResource(org.grails.io.support.FileSystemResource) Resource(org.grails.io.support.Resource) GlobalClassInjector(grails.compiler.ast.GlobalClassInjector) IOException(java.io.IOException) AnnotationVisitor(org.springframework.asm.AnnotationVisitor) ClassReader(org.springframework.asm.ClassReader) PathMatchingResourcePatternResolver(org.grails.io.support.PathMatchingResourcePatternResolver)

Aggregations

ClassInjector (grails.compiler.ast.ClassInjector)1 GlobalClassInjector (grails.compiler.ast.GlobalClassInjector)1 IOException (java.io.IOException)1 InputStream (java.io.InputStream)1 FileSystemResource (org.grails.io.support.FileSystemResource)1 PathMatchingResourcePatternResolver (org.grails.io.support.PathMatchingResourcePatternResolver)1 Resource (org.grails.io.support.Resource)1 AnnotationVisitor (org.springframework.asm.AnnotationVisitor)1 ClassReader (org.springframework.asm.ClassReader)1 ClassVisitor (org.springframework.asm.ClassVisitor)1