Package com.googlecode.gwt.test.internal

Source Code of com.googlecode.gwt.test.internal.ClassesScanner$ClassVisitor

package com.googlecode.gwt.test.internal;

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;

import javassist.CtClass;
import javassist.NotFoundException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.googlecode.gwt.test.exceptions.GwtTestPatchException;

/**
* The class used to scan and filter classes. <strong>For internal use only.</strong>
*
* @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<String> 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<URL> 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<JarEntry> 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
      }
   }

}
TOP

Related Classes of com.googlecode.gwt.test.internal.ClassesScanner$ClassVisitor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.