From c103a86ecd93d30dccab63479ad527ec7cbf0ead Mon Sep 17 00:00:00 2001 From: ulrich Date: Sun, 01 Dec 2024 12:25:49 +0000 Subject: [PATCH] Einzelne Log-Aufrufe entfernt, Kommantere ergaenzt --- src/de/uhilger/neon/Factory.java | 174 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 files changed, 145 insertions(+), 29 deletions(-) diff --git a/src/de/uhilger/neon/Factory.java b/src/de/uhilger/neon/Factory.java index b6550ba..578ad4f 100644 --- a/src/de/uhilger/neon/Factory.java +++ b/src/de/uhilger/neon/Factory.java @@ -19,9 +19,11 @@ import com.google.gson.Gson; import com.sun.net.httpserver.Authenticator; +import com.sun.net.httpserver.Filter; 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; @@ -34,6 +36,9 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.InetSocketAddress; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -41,6 +46,8 @@ import java.util.List; import java.util.Map; import java.util.concurrent.Executors; +import java.util.logging.Level; +import java.util.logging.Logger; /** * Einen Neon-Server aus einer Beschreibungsdatei herstellen @@ -58,7 +65,7 @@ * @author Ulrich Hilger * @version 1, 6.2.2024 */ -public class Factory { +public class Factory implements JarScannerListener { public Factory() { listeners = new ArrayList<>(); @@ -88,20 +95,21 @@ return gson.fromJson(sb.toString(), NeonDescriptor.class); } - public void runInstance(NeonDescriptor d) + public void runInstance(Class c, NeonDescriptor d) throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, IOException { - this.runInstance(d, null, new ArrayList<>()); + this.runInstance(c, d, null, new ArrayList<>()); } - public void runInstance(NeonDescriptor d, List<String> packageNames) + public void runInstance(Class c, NeonDescriptor d, List<String> packageNames) throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, IOException { - this.runInstance(d, packageNames, new ArrayList<>()); + this.runInstance(c, d, packageNames, new ArrayList<>()); } /** * Einen Neon-Server gemaess einem Serverbeschreibungsobjekt herstellen und starten * + * @param starter die Klasse, mit der Neon durch Aufruf dieser Methode gestartet wird * @param d das Object mit der Serverbeschreibung * @param packageNames Namen der Packages, aus der rekursiv vorgefundene Actors eingebaut werden * sollen @@ -114,9 +122,12 @@ * @throws InvocationTargetException * @throws IOException */ - public void runInstance(NeonDescriptor d, List<String> packageNames, List<DataProvider> sdp) + public void runInstance(Class starter, NeonDescriptor d, List<String> packageNames, List<DataProvider> sdp) throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, IOException { + + Logger.getLogger(Factory.class.getName()).log(Level.FINER, System.getProperty("java.class.path")); + List serverList = d.server; Iterator<ServerDescriptor> serverIterator = serverList.iterator(); while (serverIterator.hasNext()) { @@ -127,7 +138,7 @@ if(packageNames == null) { packageNames = d.actorPackages; } - addContexts(d, server, sd.contexts, packageNames, sdp); + addContexts(starter, d, server, sd.contexts, packageNames, sdp); server.setExecutor(Executors.newFixedThreadPool(10)); server.start(); @@ -155,12 +166,13 @@ return auth; } - private void addContexts(NeonDescriptor d, HttpServer server, List contextList, List<String> packageNames, + private void addContexts(Class c, NeonDescriptor d, HttpServer server, List contextList, List<String> packageNames, List<DataProvider> sdp) throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, IOException { Map<String, HttpHandler> sharedHandlers = new HashMap(); Iterator<ContextDescriptor> contextIterator = contextList.iterator(); + Authenticator auth = null; while (contextIterator.hasNext()) { ContextDescriptor cd = contextIterator.next(); HttpHandler h = buildHandler(cd, sharedHandlers); @@ -174,17 +186,40 @@ ctxAttrs.putAll(cd.attributes); if (h instanceof Handler) { for (String packageName : packageNames) { - wireActors( + wireActors(c, packageName, Actor.class, (Handler) h, cd.attributes.get("contextName")); ctx.getAttributes().put("serverDataProviderList", sdp); } } - Authenticator auth = createAuthenticator(d); - if (auth instanceof Authenticator && cd.authenticator instanceof String) { + if(cd.authenticator instanceof String) { + if(!(auth instanceof Authenticator)) { + auth = createAuthenticator(d); + } + if(auth instanceof Authenticator) { ctx.setAuthenticator(auth); ctx.getAttributes().putAll(d.authenticator.attributes); - fireAuthenticatorCreated(ctx, auth); + fireAuthenticatorCreated(ctx, auth); // event umbenennen in etwas wie authAdded oder so + } + + } + + //Authenticator auth = createAuthenticator(d); + //if (auth instanceof Authenticator && cd.authenticator instanceof String) { + // ctx.setAuthenticator(auth); + // ctx.getAttributes().putAll(d.authenticator.attributes); + // fireAuthenticatorCreated(ctx, auth); + //} + if(cd.filter != null) { + for(String filterClassName : cd.filter) { + // + Object filterObj = Class.forName(filterClassName) + .getDeclaredConstructor().newInstance(); + if(filterObj instanceof Filter) { + Filter filter = (Filter) filterObj; + ctx.getFilters().add(filter); + } + } } fireHandlerCreated(ctx, h); fireContextCreated(ctx); @@ -229,29 +264,103 @@ } } - private void wireActors(String packageName, Class annotation, Handler h, String contextName) { - ClassLoader cl = ClassLoader.getSystemClassLoader(); - 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 = Class.forName(packageName + "." - + line.substring(0, line.lastIndexOf('.'))); - if (actorClass != null && actorClass.isAnnotationPresent(annotation)) { - wire(h, actorClass, contextName); + private void wireActors(Class c, String packageName, Class annotation, Handler h, String contextName) { + JarScanner js = new JarScanner(); + URI path; + try { + path = js.getPath(c); + if(path.toString().endsWith(".class")) { + 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); } - } catch (ClassNotFoundException ex) { - // Klasse nicht gefunden. Muss das geloggt oder sonstwie behandel werden? } } else { - wireActors(packageName + "." + line, annotation, h, contextName); + ClassLoader cl = js.getUrlClassLoader(c); + js.processZipContent(cl, new File(path), packageName, this, h, contextName); } + //listClasses(c, packageName); + } catch (URISyntaxException ex) { + Logger.getLogger(Factory.class.getName()).log(Level.SEVERE, ex.getMessage(), ex); } } + + /** + * Diese Testmethode zeigt, dass die Methode getResourceAsStream nicht funktioniert wie + * dokumentiert. + * + * 1. Sie liefert den Inhalt einer gegebenen Package mitsamt Unterpackages als + * Stream, wenn sie auf eine Packagestruktur angewendet wird, die unverpackt in einem + * Verzeichnis des Dateisystems liegt. + * + * 2. Sie liefert - faelschlicherweise - null bzw. einen leeren Stream, wenn die Packagestruktur + * in einem Jar verpackt ist. + * + * Saemtliche Versuche, ueber den ClassPath oder die Pfadangabe der Package das Verhalten zu + * aendern, gehen bislang fehl (z.B. / oder . als Separator, + * / oder . zu Beginn enthalten oder nicht, realative oder absolute packagepfadangabe). + * Es ist auch unerheblich, ob + * Class.getResourceAsStream oder Class.getClassLoader().getResourceAsStream verwendet wird. + * + * Unabhaengig davon, ob und wie letztlich im Fall 2. oben die Methode getResourceAsStream + * dazu zu bringen waere, eine Inhaltsliste fuer eine Package zu liefern ist allein die + * Tatsache, dass sich die Methode unterschiedlich verhaelt bereits ein + * schwerer Bug. + * + * @param c + * @param packageName + */ + private void listClasses(Class c, String packageName) { + Logger.getLogger(Factory.class.getName()).log(Level.FINER, "packageName: " + packageName); + //ClassLoader cl = c.getClassLoader(); + String newPackageName = packageName.replaceAll("[.]", "/"); + Logger.getLogger(Factory.class.getName()).log(Level.FINER, "newPackageName: " + newPackageName); + InputStream stream = c + .getResourceAsStream(newPackageName); + if(stream != null) { + BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); + Iterator i = reader.lines().iterator(); + Logger.getLogger(Factory.class.getName()).log(Level.FINER, Long.toString(reader.lines().count())); + while (i.hasNext()) { + String line = i.next().toString(); + Logger.getLogger(Factory.class.getName()).log(Level.FINER, "class to inspect: " + line); + if (line.endsWith(".class")) { + try { + Class actorClass = c.getClassLoader().loadClass(packageName + "." + + line.substring(0, line.lastIndexOf('.'))); + if (actorClass != null && actorClass.isAnnotationPresent(Actor.class)) { + Logger.getLogger(Factory.class.getName()).log(Level.FINER, "ACTOR"); + } else { + Logger.getLogger(Factory.class.getName()).log(Level.FINER, "no actor"); + } + } catch (ClassNotFoundException ex) { + Logger.getLogger(Factory.class.getName()).log(Level.FINER, "Klasse nicht gefunden"); + } + } else { + listClasses(c, packageName + "." + line); + } + } + } else { + Logger.getLogger(Factory.class.getName()).log(Level.FINER, "stream ist null"); + } + } + /* Eine Action-Annotation enthaelt gewoehnlich die Route, @@ -321,4 +430,11 @@ l.instanceStarted(); } } + + /* -------------- JarScannerListener Implementierung --------------- */ + + @Override + public void actorFound(Class actorClass, Handler h, String contextName) { + wire(h, actorClass, contextName); + } } -- Gitblit v1.9.3