From 692dc7be9791f131bfb253c13363b75bc41b8467 Mon Sep 17 00:00:00 2001 From: ulrich Date: Sun, 01 Dec 2024 16:56:40 +0000 Subject: [PATCH] JarScanner umbenannt, das Laden von Klassen ohne Jar ebenfalls auf Scanner umgestellt --- src/de/uhilger/neon/Factory.java | 45 ++++++---------------- src/de/uhilger/neon/Scanner.java | 60 ++++++++++++++++++++++++----- 2 files changed, 61 insertions(+), 44 deletions(-) diff --git a/src/de/uhilger/neon/Factory.java b/src/de/uhilger/neon/Factory.java index 48ceb6d..7cb2a86 100644 --- a/src/de/uhilger/neon/Factory.java +++ b/src/de/uhilger/neon/Factory.java @@ -23,7 +23,6 @@ import com.sun.net.httpserver.HttpContext; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; -import de.uhilger.neon.JarScanner.JarScannerListener; import de.uhilger.neon.entity.ContextDescriptor; import de.uhilger.neon.entity.NeonDescriptor; import de.uhilger.neon.entity.ServerDescriptor; @@ -48,6 +47,7 @@ import java.util.concurrent.Executors; import java.util.logging.Level; import java.util.logging.Logger; +import de.uhilger.neon.Scanner.ScannerListener; /** * Einen Neon-Server aus einer Beschreibungsdatei herstellen @@ -65,7 +65,7 @@ * @author Ulrich Hilger * @version 1, 6.2.2024 */ -public class Factory implements JarScannerListener { +public class Factory implements ScannerListener { public Factory() { listeners = new ArrayList<>(); @@ -138,8 +138,8 @@ if (packageNames == null) { packageNames = d.actorPackages; - } - addContexts(starter, d, server, sd.contexts, packageNames, sdp); + } + addContexts(new Scanner(starter, Actor.class), d, server, sd.contexts, packageNames, sdp); server.setExecutor(Executors.newFixedThreadPool(10)); server.start(); @@ -167,7 +167,7 @@ return auth; } - private void addContexts(Class c, NeonDescriptor d, HttpServer server, List contextList, List<String> packageNames, + private void addContexts(Scanner scn, NeonDescriptor d, HttpServer server, List contextList, List<String> packageNames, List<DataProvider> sdp) throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, IOException { @@ -187,8 +187,8 @@ ctxAttrs.putAll(cd.attributes); if (h instanceof Handler) { for (String packageName : packageNames) { - wireActors(c, - packageName, Actor.class, (Handler) h, + wireActors(scn, + packageName, (Handler) h, cd.attributes.get("contextName")); ctx.getAttributes().put("serverDataProviderList", sdp); } @@ -266,32 +266,11 @@ } @SuppressWarnings("unchecked") - private void wireActors(Class c, String packageName, Class annotation, Handler h, String contextName) { - JarScanner js = new JarScanner(c, annotation); - if (!js.isJar()) { - ClassLoader cl = c.getClassLoader(); - 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(annotation)) { - wire(h, actorClass, contextName); - } - } catch (ClassNotFoundException ex) { - // Klasse nicht gefunden. Muss das geloggt oder sonstwie behandel werden? - } - } else { - wireActors(c, packageName + "." + line, annotation, h, contextName); - } - } + private void wireActors(Scanner scn, String packageName, /*Class annotation, */Handler h, String contextName) { + if (!scn.isJar()) { + scn.processClasses(this, packageName, h, contextName); } else { - js.processZipContent(packageName, this, h, contextName); + scn.processZipContent(packageName, this, h, contextName); } } @@ -427,7 +406,7 @@ } } - /* -------------- JarScannerListener Implementierung --------------- */ + /* -------------- ScannerListener Implementierung --------------- */ @Override public void annotationFound(Class foundClass, Handler h, String contextName) { wire(h, foundClass, contextName); diff --git a/src/de/uhilger/neon/JarScanner.java b/src/de/uhilger/neon/Scanner.java similarity index 73% rename from src/de/uhilger/neon/JarScanner.java rename to src/de/uhilger/neon/Scanner.java index 23f8bd0..d328c83 100644 --- a/src/de/uhilger/neon/JarScanner.java +++ b/src/de/uhilger/neon/Scanner.java @@ -17,46 +17,55 @@ */ package de.uhilger.neon; +import java.io.BufferedReader; import java.io.File; import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.net.URLClassLoader; import java.util.Enumeration; +import java.util.Iterator; import java.util.logging.Level; import java.util.logging.Logger; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; /** - * Die Klasse JarScanner enthaelt Methoden, um fuer eine Klasse zu bestimmen, in welcher JAR-Datei + * 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. * * @author Ulrich Hilger * @version 0.1, 30.11.2024 */ -public final class JarScanner { +public final class Scanner { 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 + * Einen Scanner 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) { + public Scanner(Class c, Class annotation) { this.annotation = annotation; this.cls = c; this.urlCL = getUrlClassLoader(cls); this.path = getPath(c); - } + } + + public Class getAnnotation() { + return annotation; + } /** * Den Inhalt einer Jar-Datei nach Klassen durchsuchen, die die dem Konstruktor gegebene @@ -64,11 +73,11 @@ * * @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 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 */ - public void processZipContent(String packageName, JarScannerListener l, Handler h, String contextName) { + public void processZipContent(String packageName, ScannerListener l, Handler h, String contextName) { try { ZipFile zipfile = new ZipFile(new File(path)); Enumeration en = zipfile.entries(); @@ -87,7 +96,7 @@ } @SuppressWarnings("unchecked") - private void processZipEntry(ZipEntry zipentry, String packageName, JarScannerListener l, Handler h, String contextName) { + private void processZipEntry(ZipEntry zipentry, String packageName, ScannerListener l, Handler h, String contextName) { finest(zipentry.getName()); String zName = zipentry.getName(); if (zName.toLowerCase().endsWith(".class")) { @@ -118,6 +127,31 @@ } } + 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? + } + } else { + //wireActors(js, packageName + "." + line, h, contextName); + processClasses(l, packageName + "." + line, h, contextName); + } + } + } + private String getPackageName(String fullClassName) { String packageName; int pos = fullClassName.lastIndexOf("."); @@ -127,6 +161,10 @@ packageName = fullClassName; } return packageName; + } + + public ClassLoader getCl() { + return cls.getClassLoader(); } public ClassLoader getUrlClassLoader(Class c) { @@ -171,7 +209,7 @@ try { return new URI(jarPath); } catch (URISyntaxException ex) { - Logger.getLogger(JarScanner.class.getName()).log(Level.SEVERE, ex.getMessage(), ex); + Logger.getLogger(Scanner.class.getName()).log(Level.SEVERE, ex.getMessage(), ex); return null; } } @@ -185,10 +223,10 @@ } private void log(Level l, String msg) { - Logger.getLogger(JarScanner.class.getName()).log(l, msg); + Logger.getLogger(Scanner.class.getName()).log(l, msg); } - public interface JarScannerListener { + public interface ScannerListener { public void annotationFound(Class foundClass, Handler h, String contextName); } -- Gitblit v1.9.3