Ultrakompakter HTTP Server
ulrich
2024-12-01 47e67b0aa12758fcbe6eb68f95a35ceb66c268e7
src/de/uhilger/neon/JarScanner.java
@@ -31,65 +31,93 @@
import java.util.zip.ZipFile;
/**
 * Die Klasse JarScanner enthaelt Methoden, um fuer eine Klasse zu bestimmen, in
 * welcher JAR-Datei sie liegt und diese JAR-Datei nach Klassen zu durchsuchen.
 *
 * Die Klasse JarScanner enthaelt Methoden, um fuer eine Klasse zu bestimmen, in welcher JAR-Datei
 * sie liegt und diese JAR-Datei nach Klassen zu durchsuchen.
 *
 * @author Ulrich Hilger
 * @version 0.1, 30.11.2024
 */
public class JarScanner {
  public void processZipContent(ClassLoader urlCL, File archive, String packageName, JarScannerListener l, Handler h, String contextName) {
public final class JarScanner {
  private final URI path;
  private final Class annotation;
  private final Class cls;
  private final ClassLoader urlCL;
  /**
   * Einen JarScanner erzeugen, der das Archiv, in dem sich eine gegebene Klasse befindet, nach
   * Klassen durchsucht, die eine bestimmte Annotation besitzen
   *
   * @param c eine Klasse die sich im Archiv befindet, das durchsucht werden soll
   * @param annotation die Annotation, nach der gesucht wird
   */
  public JarScanner(Class c, Class annotation) {
    this.annotation = annotation;
    this.cls = c;
    this.urlCL = getUrlClassLoader(cls);
    this.path = getPath(c);
 }
  /**
   * Den Inhalt einer Jar-Datei nach Klassen durchsuchen, die die dem Konstruktor gegebene
   * Annotation besitzen.
   *
   * @param packageName Name der Package, die einschl. Unterpackages durchsucht wird, nur Klassen
   * dieser Package und ihrer Unterpackages werden geladen und auf die Anotation ueberprueft
   * @param l eine Klasse, die verstaendigt wird, wenn eine annotierte Klasse gefunden wurde
   * @param h der Handler, dem die gefundene Klasse hinzugefuegt werden soll
   * @param contextName Name des Kontext, dem gefundene Klassen hinzugefuegt werden sollen
   */
  public void processZipContent(String packageName, JarScannerListener l, Handler h, String contextName) {
    try {
      ZipFile zipfile = new ZipFile(archive);
      ZipFile zipfile = new ZipFile(new File(path));
      Enumeration en = zipfile.entries();
      //ClassLoader cl = getUrlClassLoader(cls);
      while (en.hasMoreElements()) {
        ZipEntry zipentry = (ZipEntry) en.nextElement();
        if (!zipentry.isDirectory()) {
          processZipEntry(urlCL, zipentry, packageName, l, h, contextName);
          processZipEntry(zipentry, packageName, l, h, contextName);
        } else {
          // ZIP-Dir muss nicht bearbeitet werden
        }
      }
      zipfile.close();
    } catch (IOException ex) {
      log(Level.SEVERE, ex.getLocalizedMessage());
    }
  }
  private void processZipEntry(ClassLoader urlCL, ZipEntry zipentry, String packageName, JarScannerListener l, Handler h, String contextName) {
    log(Level.FINEST, zipentry.getName());
  @SuppressWarnings("unchecked")
  private void processZipEntry(ZipEntry zipentry, String packageName, JarScannerListener l, Handler h, String contextName) {
    finest(zipentry.getName());
    String zName = zipentry.getName();
    if (zName.toLowerCase().endsWith(".class")) {
      int pos = zName.indexOf(".class");
      String fullClassName = zName.substring(0, pos);
      log(Level.FINEST, "full class name: " + zName);
      finest("full class name: " + zName);
      String fullClassNameDots = fullClassName.replace('/', '.');
      log(Level.FINEST, "full class name dots: " + fullClassNameDots);
      finest("full class name dots: " + fullClassNameDots);
      String pkgName = getPackageName(fullClassNameDots);
      log(Level.FINEST, " -- package name: " + pkgName);
      finest(" -- package name: " + pkgName);
      if (null != urlCL && pkgName.toLowerCase().startsWith(packageName)) {
        Class c = null;
        try {
          c = urlCL.loadClass(fullClassNameDots);
          Class c = urlCL.loadClass(fullClassNameDots);
          if (c != null) {
            if (c.isAnnotationPresent(Actor.class)) {
              log(Level.FINER, " ---- ACTOR ---- " + fullClassNameDots);
              l.actorFound(c, h, contextName);
            if (c.isAnnotationPresent(annotation)) {
              finest(" ---- ACTOR ---- " + fullClassNameDots);
              l.annotationFound(c, h, contextName);
            } else {
              log(Level.FINER, "kein Actor " + fullClassNameDots);
              finest("kein Actor " + fullClassNameDots);
            }
          } else {
            log(Level.FINER, "class NOT loaded: " + zName);
            finest("class NOT loaded: " + zName);
          }
        } catch (ClassNotFoundException ex) {
          log(Level.FINER, " +++++ Class not found: " + ex.getMessage());
          finest(" +++++ Class not found: " + ex.getMessage());
        }
      }
    }
  }
  private String getPackageName(String fullClassName) {
    String packageName;
    int pos = fullClassName.lastIndexOf(".");
@@ -100,57 +128,69 @@
    }
    return packageName;
  }
  public ClassLoader getUrlClassLoader(Class c) {
    URL url;
    ClassLoader urlCL = null;
    ClassLoader cl = null;
    try {
      url = getPath(c).toURL();
      log(Level.FINER, "url: " + url.getPath());
      urlCL = new URLClassLoader(new URL[]{url});
    } catch (URISyntaxException ex) {
      log(Level.SEVERE, ex.getMessage());
      URL url = getPath(c).toURL();
      finer("url: " + url.getPath());
      cl = new URLClassLoader(new URL[]{url});
    } catch (MalformedURLException ex) {
      log(Level.SEVERE, ex.getMessage());
    } finally {
      return urlCL;
      return cl;
    }
  }
  public URI getPath(Class c) throws URISyntaxException {
    //Class c = this.getClass();
    String className = c.getName();
    finer("this name: " + className);
    int pos = className.indexOf(".class");
    if(pos > -1) {
      String classNameWoExt = className.substring(0, pos);
  public String getPathStr() {
    if (path != null) {
      return path.toString();
    } else {
      return "";
    }
    String classNameWoPkg = className.substring(className.lastIndexOf(".") + 1);
    finer("Class name: " + classNameWoPkg);
  }
  public boolean isJar() {
    return !getPathStr().toLowerCase().endsWith(".class");
  }
  private URI getPath(Class c) {
    String className = c.getName();
    finest("this name: " + className);
    String classNameWoPkg = c.getSimpleName();//className.substring(className.lastIndexOf(".") + 1);
    finest("Class name: " + classNameWoPkg);
    String classPath = c.getResource(classNameWoPkg + ".class").getPath();
    pos = classPath.indexOf("!");
    int pos = classPath.indexOf("!");
    String jarPath;
    if(pos > -1) {
    if (pos > -1) {
      jarPath = /*"jar:" + */ classPath.substring(0, pos);
    } else {
      jarPath = classPath;
    }
    finer("path: " + jarPath);
    return new URI(jarPath);
    finest("path: " + jarPath);
    try {
      return new URI(jarPath);
    } catch (URISyntaxException ex) {
      Logger.getLogger(JarScanner.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
      return null;
    }
  }
  private void finest(String msg) {
    log(Level.FINEST, msg);
  }
  private void finer(String msg) {
    log(Level.FINER, msg);
  }
  private void log(Level l, String msg) {
    Logger.getLogger(JarScanner.class.getName()).log(l, msg);
  }
  public interface JarScannerListener {
    public void actorFound(Class actorClass, Handler h, String contextName);
    public void annotationFound(Class foundClass, Handler h, String contextName);
  }
}