All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.googlecode.gwt.test.internal.ClassesScanner Maven / Gradle / Ivy

There is a newer version: 0.63
Show newest version
package com.googlecode.gwt.test.internal;

import com.googlecode.gwt.test.exceptions.GwtTestPatchException;
import javassist.CtClass;
import javassist.NotFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 * The class used to scan and filter classes. For internal use only.
 *
 * @author Gael Lazzari
 */
final class ClassesScanner {

    static interface ClassVisitor {

        void visit(CtClass ctClass);
    }

    private static final ClassesScanner INSTANCE = new ClassesScanner();

    private static Logger logger = LoggerFactory.getLogger(ClassesScanner.class);

    public static ClassesScanner getInstance() {
        return INSTANCE;
    }

    private ClassesScanner() {
    }

    public void scanPackages(ClassVisitor classVisitor, Set rootPackages) {

        for (String rootPackage : rootPackages) {
            String path = rootPackage.replaceAll("\\.", "/");
            logger.debug("Scan package " + rootPackage);

            if (rootPackage.endsWith(".")) {
                rootPackage = rootPackage.substring(0, rootPackage.length() - 1);
            }
            try {
                Enumeration l = Thread.currentThread().getContextClassLoader().getResources(path);
                while (l.hasMoreElements()) {
                    URL url = l.nextElement();
                    String u = url.toExternalForm();
                    if (u.startsWith("file:")) {
                        String directoryName = u.substring("file:".length());
                        directoryName = URLDecoder.decode(directoryName, "UTF-8");
                        scanClassesFromDirectory(new File(directoryName), rootPackage, classVisitor);
                    } else if (u.startsWith("jar:file:")) {
                        scanClassesFromJarFile(u.substring("jar:file:".length()), path, classVisitor);
                    } else {
                        throw new IllegalArgumentException("Not managed class container " + u);
                    }
                }
            } catch (Exception e) {
                throw new GwtTestPatchException("Error while scanning package '" + rootPackage + "'", e);
            }
        }
    }

    private void scanClassesFromDirectory(File directoryToScan, String scanPackage,
                                          ClassVisitor classVisitor) {
        logger.debug("Scan directory " + directoryToScan);
        for (File f : directoryToScan.listFiles()) {
            if (f.isDirectory()) {
                if (!".".equals(f.getName()) && !"..".equals(f.getName())) {
                    scanClassesFromDirectory(f, scanPackage + "." + f.getName(), classVisitor);
                }
            } else if (f.getName().endsWith(".class")) {
                visitClass(scanPackage + "." + f.getName(), classVisitor);
            }
        }
        logger.debug("Directory scanned " + directoryToScan);
    }

    private void scanClassesFromJarFile(String path, String scanPackage, ClassVisitor classVisitor)
            throws Exception {
        String prefix = path.substring(path.indexOf("!") + 2);
        String jarName = path.substring(0, path.indexOf("!"));
        jarName = URLDecoder.decode(jarName, "UTF-8");
        logger.debug("Load classes from jar " + jarName);
        JarFile jar = new JarFile(jarName);
        Enumeration entries = jar.entries();
        while (entries.hasMoreElements()) {
            JarEntry entry = entries.nextElement();
            if (entry.getName().startsWith(prefix) && entry.getName().endsWith(".class")) {
                visitClass(entry.getName().replaceAll("\\/", "."), classVisitor);
            }
        }
        logger.debug("Classes loaded from jar " + jarName);
    }

    private void visitClass(String classFileName, ClassVisitor classVisitor) {
        try {
            CtClass current = GwtClassPool.getClass(classFileName.substring(0, classFileName.length()
                    - ".class".length()));

            classVisitor.visit(current);

            for (CtClass innerClass : current.getNestedClasses()) {
                classVisitor.visit(innerClass);
            }

        } catch (NotFoundException e) {
            // do nothing
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy