JarScanner umbenannt, das Laden von Klassen ohne Jar ebenfalls auf Scanner umgestellt
1 files renamed
1 files modified
| | |
| | | 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; |
| | |
| | | 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 |
| | |
| | | * @author Ulrich Hilger |
| | | * @version 1, 6.2.2024 |
| | | */ |
| | | public class Factory implements JarScannerListener { |
| | | public class Factory implements ScannerListener { |
| | | |
| | | public Factory() { |
| | | listeners = new ArrayList<>(); |
| | |
| | | |
| | | 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(); |
| | |
| | | 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 { |
| | |
| | | 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); |
| | | } |
| | |
| | | } |
| | | |
| | | @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); |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | /* -------------- JarScannerListener Implementierung --------------- */ |
| | | /* -------------- ScannerListener Implementierung --------------- */ |
| | | @Override |
| | | public void annotationFound(Class foundClass, Handler h, String contextName) { |
| | | wire(h, foundClass, contextName); |
File was renamed from src/de/uhilger/neon/JarScanner.java |
| | |
| | | */ |
| | | 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 |
| | |
| | | * |
| | | * @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(); |
| | |
| | | } |
| | | |
| | | @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")) { |
| | |
| | | } |
| | | } |
| | | |
| | | 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("."); |
| | |
| | | packageName = fullClassName; |
| | | } |
| | | return packageName; |
| | | } |
| | | |
| | | public ClassLoader getCl() { |
| | | return cls.getClassLoader(); |
| | | } |
| | | |
| | | public ClassLoader getUrlClassLoader(Class c) { |
| | |
| | | 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; |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | 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); |
| | | } |