Ultrakompakter HTTP Server
ulrich
2024-12-03 cc007e5339f7ffc35cdd9b94ce3b712596a1494e
src/de/uhilger/neon/Scanner.java
@@ -35,8 +35,10 @@
import java.util.zip.ZipFile;
/**
 * Die Klasse Scanner enthaelt Methoden, um fuer eine Klasse zu bestimmen, in welcher JAR-Datei
 * sie liegt und diese JAR-Datei nach Klassen zu durchsuchen.
 * Die Klasse Scanner enthaelt Methoden, um fuer eine Klasse zu bestimmen, an welchem Ablageort sie
 * sich befindet und diesen Ort nach Klassen zu durchsuchen, die eine gegebene Annotation besitzen.
 *
 * Der Ort fur Klassen kann ein Java-Archiv (.jar) oder ein Ordner im Dateisystem sein.
 *
 * @author Ulrich Hilger
 * @version 0.1, 30.11.2024
@@ -50,8 +52,10 @@
  private final ClassLoader urlCL;
  /**
   * Einen Scanner erzeugen, der das Archiv, in dem sich eine gegebene Klasse befindet, nach
   * Klassen durchsucht, die eine bestimmte Annotation besitzen
   * Einen Scanner erzeugen, der den Ort, in dem sich eine gegebene Klasse befindet, nach Klassen
   * durchsucht, die eine bestimmte Annotation besitzen
   *
   * Der Ort fur Klassen kann ein Java-Archiv (.jar) oder ein Ordner im Dateisystem sein.
   *
   * @param c eine Klasse die sich im Archiv befindet, das durchsucht werden soll
   * @param annotation die Annotation, nach der gesucht wird
@@ -66,18 +70,28 @@
  public Class getAnnotation() {
    return annotation;
  }
  /**
   * Den Inhalt einer Jar-Datei nach Klassen durchsuchen, die die dem Konstruktor gegebene
   * Annotation besitzen.
   * Klassen suchen, die die dem Konstruktor gegebene Annotation besitzen.
   *
   * Anhand der im Konstruktor uebergebenen Klasse wird deren Ablageort ermittelt, entweder ein
   * Ordner im Dateisystem oder ein Java-Archiv (.jar). Dieser Ablageort wird dann nach annotierten
   * Klassen durchsucht. Gefundene Klassen werden dem Listener gemeldet.
   *
   * @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 ein Objekt, das 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
   * @param params Parameter, die an den Listener weitergereicht werden
   */
  public void processZipContent(String packageName, ScannerListener l, Handler h, String contextName) {
  public void process(ScannerListener l, String packageName, Object... params) {
    if (isJar()) {
      processZipContent(packageName, l, params);
    } else {
      processClasses(l, packageName, params);
    }
  }
  private void processZipContent(String packageName, ScannerListener l, Object... params) {
    try {
      ZipFile zipfile = new ZipFile(new File(path));
      Enumeration en = zipfile.entries();
@@ -85,7 +99,7 @@
      while (en.hasMoreElements()) {
        ZipEntry zipentry = (ZipEntry) en.nextElement();
        if (!zipentry.isDirectory()) {
          processZipEntry(zipentry, packageName, l, h, contextName);
          processZipEntry(zipentry, packageName, l, params);
        } else {
          // ZIP-Dir muss nicht bearbeitet werden
        }
@@ -94,9 +108,17 @@
      log(Level.SEVERE, ex.getLocalizedMessage());
    }
  }
  @SuppressWarnings("unchecked")
  private void processZipEntry(ZipEntry zipentry, String packageName, ScannerListener l, Handler h, String contextName) {
  /**
   * 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 ein Objekt, das verstaendigt wird, wenn eine annotierte Klasse gefunden wurde
   * @param params Parameter, die an den Listener weitergereicht werden
   */
  private void processZipEntry(ZipEntry zipentry, String packageName, ScannerListener l, Object... params) {
    finest(zipentry.getName());
    String zName = zipentry.getName();
    if (zName.toLowerCase().endsWith(".class")) {
@@ -113,7 +135,7 @@
          if (c != null) {
            if (c.isAnnotationPresent(annotation)) {
              finest(" ---- ACTOR ---- " + fullClassNameDots);
              l.annotationFound(c, h, contextName);
              l.annotationFound(c, params);
            } else {
              finest("kein Actor " + fullClassNameDots);
            }
@@ -126,30 +148,38 @@
      }
    }
  }
  public void processClasses(ScannerListener l, String packageName, Handler h, String contextName) {
      ClassLoader cl = getCl();
      InputStream stream = cl.getResourceAsStream(packageName.replaceAll("[.]", "/"));
      BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
      Iterator i = reader.lines().iterator();
      while (i.hasNext()) {
        String line = i.next().toString();
        if (line.endsWith(".class")) {
          try {
            Class actorClass = cl.loadClass(packageName + "."
                    + line.substring(0, line.lastIndexOf('.')));
            if (actorClass != null && actorClass.isAnnotationPresent(getAnnotation())) {
              //wire(h, actorClass, contextName);
              l.annotationFound(actorClass, h, contextName);
            }
          } catch (ClassNotFoundException ex) {
            // Klasse nicht gefunden. Muss das geloggt oder sonstwie behandel werden?
  /**
   * Einen Ordner mit Klassen durchsuchen
   *
   * @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 ein Objekt, das verstaendigt wird, wenn eine annotierte Klasse gefunden wurde
   * @param params Parameter, die an den Listener weitergereicht werden
   */
  private void processClasses(ScannerListener l, String packageName, Object... params) {
    ClassLoader cl = getCl();
    InputStream stream = cl.getResourceAsStream(packageName.replaceAll("[.]", "/"));
    BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
    Iterator i = reader.lines().iterator();
    while (i.hasNext()) {
      String line = i.next().toString();
      if (line.endsWith(".class")) {
        try {
          Class actorClass = cl.loadClass(packageName + "."
                  + line.substring(0, line.lastIndexOf('.')));
          if (actorClass != null && actorClass.isAnnotationPresent(getAnnotation())) {
            //wire(h, actorClass, contextName);
            l.annotationFound(actorClass, params);
          }
        } else {
          //wireActors(js, packageName + "." + line, h, contextName);
          processClasses(l, packageName + "." + line, h, contextName);
        } catch (ClassNotFoundException ex) {
          // Klasse nicht gefunden. Muss das geloggt oder sonstwie behandel werden?
        }
      } else {
        //wireActors(js, packageName + "." + line, h, contextName);
        processClasses(l, packageName + "." + line, params);
      }
    }
  }
  
  private String getPackageName(String fullClassName) {
@@ -227,8 +257,6 @@
  }
  public interface ScannerListener {
    public void annotationFound(Class foundClass, Handler h, String contextName);
    public void annotationFound(Class foundClass, Object... params);
  }
}
}