Ultrakompakter HTTP Server
ulrich
2024-11-30 f4025a39226331d8c1c4686d2d1c73e080f9f4b3
src/de/uhilger/neon/Factory.java
@@ -23,6 +23,7 @@
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;
@@ -35,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;
@@ -42,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
@@ -59,7 +65,7 @@
 * @author Ulrich Hilger
 * @version 1, 6.2.2024
 */
public class Factory {
public class Factory implements JarScannerListener {
  public Factory() {
    listeners = new ArrayList<>();
@@ -89,16 +95,16 @@
    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
@@ -115,7 +121,7 @@
   * @throws InvocationTargetException
   * @throws IOException
   */
  public void runInstance(NeonDescriptor d, List<String> packageNames, List<DataProvider> sdp)
  public void runInstance(Class c, NeonDescriptor d, List<String> packageNames, List<DataProvider> sdp)
          throws ClassNotFoundException, NoSuchMethodException, InstantiationException, 
          IllegalAccessException, IllegalArgumentException, InvocationTargetException, IOException {
    List serverList = d.server;
@@ -128,7 +134,7 @@
      if(packageNames == null) {
        packageNames = d.actorPackages;
      }
      addContexts(d, server, sd.contexts, packageNames, sdp);
      addContexts(c, d, server, sd.contexts, packageNames, sdp);
      server.setExecutor(Executors.newFixedThreadPool(10));
      server.start();
@@ -156,7 +162,7 @@
    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 {
@@ -176,7 +182,7 @@
        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);
@@ -254,27 +260,39 @@
    }
  }
  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);
      }
    } catch (URISyntaxException ex) {
      Logger.getLogger(Factory.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
    }
  }
  
@@ -346,4 +364,11 @@
      l.instanceStarted();
    }
  }
  /* -------------- JarScannerListener Implementierung --------------- */
  @Override
  public void actorFound(Class actorClass, Handler h, String contextName) {
    wire(h, actorClass, contextName);
  }
}