|  |  | 
 |  |  |  */ | 
 |  |  | public class Factory implements ScannerListener { | 
 |  |  |  | 
 |  |  |   private Map<String, List<TempActor>> actorMap; | 
 |  |  |  | 
 |  |  |   public Factory() { | 
 |  |  |     listeners = new ArrayList<>(); | 
 |  |  |     actorMap = new HashMap<>(); | 
 |  |  |   } | 
 |  |  |  | 
 |  |  |   /** | 
 |  |  | 
 |  |  |  | 
 |  |  |     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()) { | 
 |  |  |       ServerDescriptor sd = serverIterator.next(); | 
 |  |  |     List<ServerDescriptor> serverList = d.server; | 
 |  |  |     for (ServerDescriptor sd : serverList) { | 
 |  |  |       HttpServer server = HttpServer.create(new InetSocketAddress(sd.port), 0); | 
 |  |  |       fireServerCreated(server); | 
 |  |  |  | 
 |  |  |       if (packageNames == null) { | 
 |  |  |         packageNames = d.actorPackages; | 
 |  |  |       }       | 
 |  |  |       addContexts(new Scanner(starter, Actor.class), d, server, sd.contexts, packageNames, sdp); | 
 |  |  |        | 
 |  |  |       Scanner scn = new Scanner(starter, Actor.class); | 
 |  |  |       for (String packageName : packageNames) { | 
 |  |  |         scn.process(this, packageName, new Object[]{}); | 
 |  |  |         // ctx.getAttributes().put("serverDataProviderList", sdp); | 
 |  |  |       } | 
 |  |  |        | 
 |  |  |       addContexts(d, server, sd.contexts, sdp); | 
 |  |  |  | 
 |  |  |       server.setExecutor(Executors.newFixedThreadPool(10)); | 
 |  |  |       server.start(); | 
 |  |  | 
 |  |  |     return auth; | 
 |  |  |   } | 
 |  |  |  | 
 |  |  |   private void addContexts(Scanner scn, NeonDescriptor d, HttpServer server, List contextList, List<String> packageNames, | 
 |  |  |   private void addContexts(NeonDescriptor d, HttpServer server, List<ContextDescriptor> contextList, | 
 |  |  |           List<DataProvider> sdp) | 
 |  |  |           throws ClassNotFoundException, NoSuchMethodException, InstantiationException, | 
 |  |  |           IllegalAccessException, IllegalArgumentException, InvocationTargetException, IOException { | 
 |  |  |     Map<String, HttpHandler> sharedHandlers = new HashMap(); | 
 |  |  |     Map<String, HttpHandler> sharedHandlers = new HashMap<>(); | 
 |  |  |     Iterator<ContextDescriptor> contextIterator = contextList.iterator(); | 
 |  |  |     Authenticator auth = null; | 
 |  |  |     while (contextIterator.hasNext()) { | 
 |  |  | 
 |  |  |         Map<String, Object> ctxAttrs = ctx.getAttributes(); | 
 |  |  |         /* | 
 |  |  |           Achtung: Wenn verschiedene Elemente dasselbe Attribut  | 
 |  |  |           deklarieren, ueberschreiben sie sich die Attribute gegenseitig. | 
 |  |  |           deklarieren, ueberschreiben sich die Attribute gegenseitig. | 
 |  |  |          */ | 
 |  |  |         ctxAttrs.putAll(cd.attributes); | 
 |  |  |         if (h instanceof Handler) { | 
 |  |  |           for (String packageName : packageNames) { | 
 |  |  |             scn.process(this, packageName, (Handler) h, cd.attributes.get("contextName")); | 
 |  |  |             ctx.getAttributes().put("serverDataProviderList", sdp); | 
 |  |  |           } | 
 |  |  |         ctxAttrs.put("serverDataProviderList", sdp); | 
 |  |  |         if (h instanceof Handler handler) { | 
 |  |  |           wire(handler, cd.attributes.get("contextName")); | 
 |  |  |         } | 
 |  |  |         if (cd.authenticator instanceof String) { | 
 |  |  |           if (!(auth instanceof Authenticator)) { | 
 |  |  | 
 |  |  |             ctx.getAttributes().putAll(d.authenticator.attributes); | 
 |  |  |             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; | 
 |  |  |             if (filterObj instanceof Filter filter) { | 
 |  |  |               ctx.getFilters().add(filter); | 
 |  |  |             } | 
 |  |  |           } | 
 |  |  | 
 |  |  |     Kontextpfades ausgefuehrt werden soll, muss die Action  | 
 |  |  |     als Route '/' angeben. | 
 |  |  |    */ | 
 |  |  |    | 
 |  |  |   /* | 
 |  |  |    Tradeoff: | 
 |  |  |       Es muss bei Initialisierung die Actor-Klasse ganz durchlaufen werden, um alle Methoden  | 
 |  |  |       zu finden, die eine Action-Annotation haben. Der Handler 'merkt' sich lediglich den Namen der  | 
 |  |  |       Actor-Klassen. Daher muessen bei jedem Aufruf eines Actors ueber den Handler abermals  | 
 |  |  |       alle Methoden dieses Actors durchsucht werden, um diejenige Methode zu finden, die mit  | 
 |  |  |       der zur Route des Requests passenden Action annotiert ist. | 
 |  |  |    | 
 |  |  |       Dieser Tradeoff bewirkt, dass nicht grosse Geflechte aus Klassen- und Methodenobjekten | 
 |  |  |       fuer die gesamten Actors einer Anwendung im Speicher gehalten werden muessen  | 
 |  |  |       sondern dynamisch zur Laufzeit instanziiert werden. | 
 |  |  |   */ | 
 |  |  |   | 
 |  |  |   /** | 
 |  |  |    * Actor-Klassen dem Handler hinzufuegen | 
 |  |  |    * | 
 |  |  |    * @param h Handler, dem der Actor hinzugefuegt wird, falls der Kontext uebereinstimmt | 
 |  |  |    * @param c hinzuzufuegende Actor-Klasse | 
 |  |  |    * @param contextName Name des Kontext, dem der Actor hinzugefuegt wird | 
 |  |  |    * @param contextName Name des Kontext, dem der Handler zugeordnet ist | 
 |  |  |    */ | 
 |  |  |   private void wire(Handler h, Class c, String contextName) { | 
 |  |  |     Method[] methods = c.getMethods(); | 
 |  |  |     for (Method method : methods) { | 
 |  |  |       Action action = method.getAnnotation(Action.class); | 
 |  |  |       if (action != null) { | 
 |  |  |         List actionHandlers = Arrays.asList(action.handler()); | 
 |  |  |         if (actionHandlers.contains(contextName)) { | 
 |  |  |           h.setActor(action.type(), action.route(), c.getName()); | 
 |  |  |         } | 
 |  |  |       } | 
 |  |  |   private void wire(Handler h, String contextName) { | 
 |  |  |     List<TempActor> actorList = actorMap.get(contextName); | 
 |  |  |     Iterator<TempActor> i = actorList.iterator(); | 
 |  |  |     while(i.hasNext()) { | 
 |  |  |       TempActor actor = i.next(); | 
 |  |  |       h.setActor(actor.getHttpMethod(), actor.getRoute(), actor.getActorClassName()); | 
 |  |  |     } | 
 |  |  |   } | 
 |  |  |  | 
 |  |  | 
 |  |  |   public void destroy() { | 
 |  |  |     this.listeners.clear(); | 
 |  |  |     this.listeners = null; | 
 |  |  |     this.actorMap.clear(); | 
 |  |  |     this.actorMap = null; | 
 |  |  |   } | 
 |  |  |  | 
 |  |  |   private void fireServerCreated(HttpServer server) { | 
 |  |  | 
 |  |  |   /* -------------- ScannerListener Implementierung --------------- */ | 
 |  |  |   @Override | 
 |  |  |   public void annotationFound(Class foundClass, Object[] params) { | 
 |  |  |     Handler h = null; | 
 |  |  |     String contextName = null; | 
 |  |  |     for(Object param : params) { | 
 |  |  |       if(param instanceof Handler) { | 
 |  |  |         h = (Handler) param; | 
 |  |  |       } else if(param instanceof String) { | 
 |  |  |         contextName = (String) param; | 
 |  |  |     Method[] methods = foundClass.getMethods(); | 
 |  |  |     for (Method method : methods) { | 
 |  |  |       Action action = method.getAnnotation(Action.class); | 
 |  |  |       if (action != null) { | 
 |  |  |         List<String> actionHandlers = Arrays.asList(action.handler()); | 
 |  |  |         for (String contextName : actionHandlers) { | 
 |  |  |            TempActor tempActor = new TempActor(); | 
 |  |  |            tempActor.setContextName(contextName); | 
 |  |  |            tempActor.setHttpMethod(action.type()); | 
 |  |  |            tempActor.setRoute(action.route()); | 
 |  |  |            tempActor.setActorClassName(foundClass.getName()); | 
 |  |  |             | 
 |  |  |            List<TempActor> actorList = actorMap.get(contextName); | 
 |  |  |            if(actorList == null) { | 
 |  |  |              actorList = new ArrayList<>(); | 
 |  |  |            } | 
 |  |  |            actorList.add(tempActor); | 
 |  |  |            actorMap.put(contextName, actorList); | 
 |  |  |       } | 
 |  |  |     } | 
 |  |  |     if(h == null || contextName == null) { | 
 |  |  |       Logger.getLogger(Factory.class.getName()).log(Level.FINER, "Handler oder contextName ist null"); | 
 |  |  |     } else { | 
 |  |  |       wire(h, foundClass, contextName); | 
 |  |  |     } | 
 |  |  |   } | 
 |  |  | } |