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

net.stickycode.configured.guice3.StickyClasspathScanner Maven / Gradle / Ivy

package net.stickycode.configured.guice3;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.JarURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.regex.Pattern;

import org.objectweb.asm.ClassReader;

import com.google.inject.Inject;
import com.google.inject.name.Named;

import de.devsurf.injection.guice.scanner.ClasspathScanner;
import de.devsurf.injection.guice.scanner.PackageFilter;
import de.devsurf.injection.guice.scanner.asm.AnnotationCollector;
import de.devsurf.injection.guice.scanner.features.ScannerFeature;

public class StickyClasspathScanner
    implements ClasspathScanner {

  public static String LINE_SEPARATOR = System.getProperty("line.separator");

  @Inject
  @Named("classpath")
  private URL[] classPath;

  private List patterns = new ArrayList();

  private Set visited;

  private AnnotationCollector collector;

  @Inject
  public StickyClasspathScanner(Set listeners,
      @Named("packages") PackageFilter... filter) {
    this.collector = new AnnotationCollector();

    for (PackageFilter p : filter) {
      includePackage(p);
    }

    for (ScannerFeature listener : listeners) {
      addFeature(listener);
    }
    visited = new HashSet();
  }

  @Override
  public void addFeature(ScannerFeature feature) {
    collector.addScannerFeature(feature);
  }

  @Override
  public void removeFeature(ScannerFeature feature) {
    collector.addScannerFeature(feature);
  }

  @Override
  public List getFeatures() {
    return collector.getScannerFeatures();
  }

  @Override
  public void includePackage(final PackageFilter filter) {
    String packageName = filter.getPackage();
    String pattern = ".*" + packageName.replace(".", "/");

    if (filter.deep()) {
      pattern = pattern + "/(?:\\w|/)*([A-Z](?:\\w|\\$)+)\\.class$";
    }
    else {
      pattern = pattern + "/([A-Z](?:\\w|\\$)+)\\.class$";
    }

    patterns.add(Pattern.compile(pattern));
  }

  @Override
  public void excludePackage(final PackageFilter filter) {
    // TODO Could use Predicate of Google
  }

  public void scan() throws IOException {
    for (final URL url : classPath) {
      visitUrl(url);
    }
    destroy();
  }

  protected void visitUrl(URL url) {
    try {
      if (url.toString().startsWith("jar:")) {
        visitJar(url);
        return;
      }
      URI uri;
      File entry;
      try {
        uri = url.toURI();
        entry = new File(uri);
        if (!entry.exists()) {
          return;
        }
      }
      catch (URISyntaxException e) {
        return;
      }
      catch (Throwable e) {
        return;
      }

      if (entry.isDirectory()) {
        visitFolder(entry);
      }
      else {
        String path = uri.toString();
        if (matches(path)) {
          if (!visited.contains(entry.getAbsolutePath())) {
            visitClass(new FileInputStream(entry));
            visited.add(entry.getAbsolutePath());
          }
        }
        else
          if (path.endsWith(".jar")) {
            visitJar(entry);
          }
      }
    }
    catch (FileNotFoundException e) {
    }
    catch (IOException e) {
    }
    catch (Throwable e) {
    }
  }

  public void destroy() {
    classPath = null;
    collector = null;
    patterns.clear();
    patterns = null;
    visited.clear();
    visited = null;
  }

  private void visitFolder(File folder) throws IOException {
    File[] files = folder.listFiles();
    for (File file : files) {
      if (file.isDirectory()) {
        visitFolder(file);
      }
      else {
        String path = file.toURI().toString();
        if (matches(path)) {
          if (!visited.contains(file.getAbsolutePath())) {
            visitClass(new FileInputStream(file));
            visited.add(file.getAbsolutePath());
          }
        }
        else
          if (path.endsWith(".jar")) {
            visitJar(file);
          }
      }
    }
  }

  private void visitJar(URL url) throws IOException {
    JarURLConnection conn = (JarURLConnection) url.openConnection();
    _visitJar(conn.getJarFile());
  }

  private void visitJar(File file) throws IOException {
    JarFile jarFile = new JarFile(file);
    _visitJar(jarFile);
  }

  private void _visitJar(JarFile jarFile) throws IOException {
    Enumeration jarEntries = jarFile.entries();
    for (JarEntry jarEntry = null; jarEntries.hasMoreElements();) {
      jarEntry = jarEntries.nextElement();
      String name = jarEntry.getName();

      if (!jarEntry.isDirectory() && matches(name)) {
        if (!visited.contains(name)) {
          visitClass(jarFile.getInputStream(jarEntry));
          visited.add(name);
        }
      }
    }
  }

  private void visitClass(InputStream in) throws IOException {
    ClassReader reader = new ClassReader(new BufferedInputStream(in));
    reader.accept(collector, AnnotationCollector.ASM_FLAGS);
  }

  private boolean matches(String name) {
    for (Pattern pattern : patterns) {
      if (pattern.matcher(name).matches()) {
        return true;
      }
    }
    return false;
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy