From 9158a5134b8a2ad05406e6b451a3bd0136d80d98 Mon Sep 17 00:00:00 2001 From: Thorsten Marx Date: Sat, 4 Nov 2023 07:21:19 +0100 Subject: [PATCH] working example of resourcehandler inside of module --- .../thmarx/cms/api/extensions/Mapping.java | 10 +-- .../com/github/thmarx/cms/server/VHost.java | 21 +++--- .../thmarx/cms/server/jetty/JettyServer.java | 2 +- .../thmarx/cms/server/jetty/JettyVHost.java | 14 ++-- .../handler/JettyModuleMappingHandler.java | 67 +++++++++++-------- .../ui/http/UIJettyHttpHandlerExtension.java | 23 +++---- .../assets/{ => ui-module/assets}/index.html | 0 7 files changed, 72 insertions(+), 65 deletions(-) rename modules/ui-module/src/main/resources/com/github/thmarx/cms/modules/ui/assets/{ => ui-module/assets}/index.html (100%) diff --git a/cms-api/src/main/java/com/github/thmarx/cms/api/extensions/Mapping.java b/cms-api/src/main/java/com/github/thmarx/cms/api/extensions/Mapping.java index fdeb4cd7..7fbe4c69 100644 --- a/cms-api/src/main/java/com/github/thmarx/cms/api/extensions/Mapping.java +++ b/cms-api/src/main/java/com/github/thmarx/cms/api/extensions/Mapping.java @@ -1,7 +1,3 @@ -/* - * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license - * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template - */ package com.github.thmarx.cms.api.extensions; /*- @@ -24,7 +20,9 @@ * #L% */ +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Optional; import org.eclipse.jetty.http.pathmap.PathSpec; @@ -49,4 +47,8 @@ public void add (PathSpec pathSpec, Handler handler) { public Optional getMatchingHandler (String uri) { return handlerMapping.entrySet().stream().filter(entry -> entry.getKey().matches(uri)).map(entry -> entry.getValue()).findFirst(); } + + public List getHandlers () { + return new ArrayList<>(handlerMapping.values()); + } } diff --git a/cms-server/src/main/java/com/github/thmarx/cms/server/VHost.java b/cms-server/src/main/java/com/github/thmarx/cms/server/VHost.java index d594c57b..ec979130 100644 --- a/cms-server/src/main/java/com/github/thmarx/cms/server/VHost.java +++ b/cms-server/src/main/java/com/github/thmarx/cms/server/VHost.java @@ -73,7 +73,7 @@ public class VHost { @Getter private final EventBus eventBus; - protected SiteProperties properties; + protected SiteProperties siteProperties; protected ModuleManager moduleManager; @@ -99,7 +99,7 @@ public void init(Path modules) throws IOException { fileSystem.init(); var props = fileSystem.resolve("site.yaml"); - properties = PropertiesLoader.hostProperties(props); + siteProperties = PropertiesLoader.hostProperties(props); var classLoader = new ModuleAPIClassLoader(ClassLoader.getSystemClassLoader(), List.of( @@ -110,13 +110,12 @@ public void init(Path modules) throws IOException { "org.graalvm.js", "org.eclipse.jetty" )); - this.moduleManager = ModuleManagerImpl.create( - modules.toFile(), + this.moduleManager = ModuleManagerImpl.create(modules.toFile(), fileSystem.resolve("modules_data").toFile(), - new CMSModuleContext(properties, serverProperties, fileSystem, eventBus), + new CMSModuleContext(siteProperties, serverProperties, fileSystem, eventBus), classLoader ); - properties.activeModules().forEach(module_id -> { + siteProperties.activeModules().forEach(module_id -> { try { log.debug("activate module {}", module_id); moduleManager.activateModule(module_id); @@ -126,7 +125,7 @@ public void init(Path modules) throws IOException { }); moduleManager.getModuleIds().stream() - .filter(id -> !properties.activeModules().contains(id)) + .filter(id -> !siteProperties.activeModules().contains(id)) .forEach((module_id) -> { try { log.debug("deactivate module {}", module_id); @@ -136,7 +135,7 @@ public void init(Path modules) throws IOException { } }); - hostname = properties.hostname(); + hostname = siteProperties.hostname(); contentBase = fileSystem.resolve("content/"); assetBase = fileSystem.resolve("assets/"); @@ -149,7 +148,7 @@ public void init(Path modules) throws IOException { templateEngine = resolveTemplateEngine(); - contentRenderer = new ContentRenderer(contentParser, templateEngine, fileSystem, properties, moduleManager); + contentRenderer = new ContentRenderer(contentParser, templateEngine, fileSystem, siteProperties, moduleManager); contentResolver = new ContentResolver(contentBase, contentRenderer, fileSystem); eventBus.register(ContentChangedEvent.class, (EventListener) (ContentChangedEvent event) -> { @@ -163,7 +162,7 @@ public void init(Path modules) throws IOException { } protected TemplateEngine resolveTemplateEngine() { - var engine = this.properties.templateEngine(); + var engine = this.siteProperties.templateEngine(); List extensions = moduleManager.extensions(TemplateEngineProviderExtentionPoint.class); Optional extOpt = extensions.stream().filter((ext) -> ext.getName().equals(engine)).findFirst(); @@ -176,7 +175,7 @@ protected TemplateEngine resolveTemplateEngine() { } protected MarkdownRenderer resolveMarkdownRenderer(final Context context) { - var engine = this.properties.markdownEngine(); + var engine = this.siteProperties.markdownEngine(); List extensions = moduleManager.extensions(MarkdownRendererProviderExtentionPoint.class); Optional extOpt = extensions.stream().filter((ext) -> ext.getName().equals(engine)).findFirst(); diff --git a/cms-server/src/main/java/com/github/thmarx/cms/server/jetty/JettyServer.java b/cms-server/src/main/java/com/github/thmarx/cms/server/jetty/JettyServer.java index 918bbad0..1bdf2fd7 100644 --- a/cms-server/src/main/java/com/github/thmarx/cms/server/jetty/JettyServer.java +++ b/cms-server/src/main/java/com/github/thmarx/cms/server/jetty/JettyServer.java @@ -63,7 +63,7 @@ public void startup() throws IOException { host.init(Path.of("modules")); vhosts.add(host); } catch (IOException ex) { - ex.printStackTrace(); + log.error(null, ex); } } }); diff --git a/cms-server/src/main/java/com/github/thmarx/cms/server/jetty/JettyVHost.java b/cms-server/src/main/java/com/github/thmarx/cms/server/jetty/JettyVHost.java index 186dae36..3fc23e4d 100644 --- a/cms-server/src/main/java/com/github/thmarx/cms/server/jetty/JettyVHost.java +++ b/cms-server/src/main/java/com/github/thmarx/cms/server/jetty/JettyVHost.java @@ -21,28 +21,22 @@ */ import com.github.thmarx.cms.api.ServerProperties; -import com.github.thmarx.cms.api.extensions.JettyHttpHandlerExtensionPoint; -import com.github.thmarx.cms.api.extensions.Mapping; +import com.github.thmarx.cms.api.SiteProperties; import com.github.thmarx.cms.server.jetty.handler.JettyDefaultHandler; import com.github.thmarx.cms.server.jetty.handler.JettyExtensionHandler; import com.github.thmarx.cms.server.VHost; import com.github.thmarx.cms.server.jetty.handler.JettyModuleMappingHandler; import java.nio.file.Path; -import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; -import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.eclipse.jetty.http.pathmap.PathSpec; import org.eclipse.jetty.server.Handler; -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.Response; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.handler.ContextHandlerCollection; import org.eclipse.jetty.server.handler.PathMappingsHandler; import org.eclipse.jetty.server.handler.ResourceHandler; import org.eclipse.jetty.server.handler.gzip.GzipHandler; -import org.eclipse.jetty.util.Callback; /** * @@ -51,6 +45,7 @@ @Slf4j public class JettyVHost extends VHost { + public JettyVHost(Path hostBase, ServerProperties serverProperties) { super(hostBase, serverProperties); } @@ -80,10 +75,11 @@ public Handler httpHandler() { pathMappingsHandler.addMapping(PathSpec.from("/favicon.ico"), faviconHandler); ContextHandler defaultContextHandler = new ContextHandler(pathMappingsHandler, "/"); - defaultContextHandler.setVirtualHosts(List.of(properties.hostname())); + defaultContextHandler.setVirtualHosts(List.of(siteProperties.hostname())); - var moduleHandler = new JettyModuleMappingHandler(moduleManager); + var moduleHandler = new JettyModuleMappingHandler(moduleManager, siteProperties); + moduleHandler.init(); ContextHandler moduleContextHandler = new ContextHandler(moduleHandler, "/module"); var extensionHandler = new JettyExtensionHandler(extensionManager); ContextHandler extensionContextHandler = new ContextHandler(extensionHandler, "/extension"); diff --git a/cms-server/src/main/java/com/github/thmarx/cms/server/jetty/handler/JettyModuleMappingHandler.java b/cms-server/src/main/java/com/github/thmarx/cms/server/jetty/handler/JettyModuleMappingHandler.java index fe16bb7a..bbeb3383 100644 --- a/cms-server/src/main/java/com/github/thmarx/cms/server/jetty/handler/JettyModuleMappingHandler.java +++ b/cms-server/src/main/java/com/github/thmarx/cms/server/jetty/handler/JettyModuleMappingHandler.java @@ -19,8 +19,14 @@ * limitations under the License. * #L% */ +import com.github.thmarx.cms.api.SiteProperties; import com.github.thmarx.cms.api.extensions.JettyHttpHandlerExtensionPoint; +import com.github.thmarx.cms.api.extensions.Mapping; +import com.github.thmarx.modules.api.Module; import com.github.thmarx.modules.api.ModuleManager; +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Multimap; +import java.util.List; import java.util.Optional; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -35,9 +41,23 @@ */ @RequiredArgsConstructor @Slf4j -public class JettyModuleMappingHandler extends Handler.Abstract { +public class JettyModuleMappingHandler extends Handler.AbstractContainer { private final ModuleManager moduleManager; + private final SiteProperties siteProperties; + + private final Multimap moduleMappgings = ArrayListMultimap.create(); + + public void init () { + siteProperties.activeModules().forEach((var moduleid) -> { + final Module module = moduleManager + .module(moduleid); + if (module.provides(JettyHttpHandlerExtensionPoint.class)) { + List extensions = module.extensions(JettyHttpHandlerExtensionPoint.class); + extensions.forEach(ext -> moduleMappgings.put(moduleid, ext.getHandler())); + } + }); + } @Override public boolean handle(Request request, Response response, Callback callback) throws Exception { @@ -45,39 +65,25 @@ public boolean handle(Request request, Response response, Callback callback) thr String moduleId = getModuleID(request); var module = moduleManager.module(moduleId); - - if (module == null || !module.provides(JettyHttpHandlerExtensionPoint.class)) { - response.setStatus(404); - callback.succeeded(); + + if (!moduleMappgings.containsKey(moduleId)) { + Response.writeError(request, response, callback, 404); return false; } - - var extensions = module.extensions(JettyHttpHandlerExtensionPoint.class); + var uri = getModuleUri(request); - - Optional findFirst = extensions.stream().filter(ext -> ext.getHandler().getMatchingHandler(uri).isPresent()).findFirst(); + Optional findFirst = moduleMappgings.get(moduleId).stream().filter(mapping -> mapping.getMatchingHandler(uri).isPresent()).findFirst(); if (findFirst.isPresent()) { - var mapping = findFirst.get().getHandler(); - Optional matchingHandler = mapping.getMatchingHandler(uri); - if (matchingHandler.isPresent()) { - - var ext = matchingHandler.get(); - var classLoader = Thread.currentThread().getContextClassLoader(); - try { - Thread.currentThread().setContextClassLoader(ext.getClass().getClassLoader()); - setServer(getServer()); - ext.start(); - return ext.handle(request, response, callback); - - } finally { - Thread.currentThread().setContextClassLoader(classLoader); - } - + var mapping = findFirst.get(); + var handler = mapping.getMatchingHandler(uri).get(); + if (!handler.isStarted()) { + handler.start(); } + return handler.handle(request, response, callback); } - response.setStatus(404); - callback.succeeded(); + + Response.writeError(request, response, callback, 404); return false; } catch (Exception e) { log.error(null, e); @@ -115,4 +121,11 @@ private String getModulePath(Request request) { return path; } + @Override + public List getHandlers() { + return moduleMappgings.values().stream().map(mapper -> mapper.getHandlers()) + .flatMap(List::stream) + .toList(); + } + } diff --git a/modules/ui-module/src/main/java/com/github/thmarx/cms/modules/ui/http/UIJettyHttpHandlerExtension.java b/modules/ui-module/src/main/java/com/github/thmarx/cms/modules/ui/http/UIJettyHttpHandlerExtension.java index 69263ac5..750f6f5f 100644 --- a/modules/ui-module/src/main/java/com/github/thmarx/cms/modules/ui/http/UIJettyHttpHandlerExtension.java +++ b/modules/ui-module/src/main/java/com/github/thmarx/cms/modules/ui/http/UIJettyHttpHandlerExtension.java @@ -23,10 +23,7 @@ import com.github.thmarx.cms.api.extensions.Mapping; import com.github.thmarx.modules.api.annotation.Extension; import java.net.URI; -import java.net.URISyntaxException; import java.net.URL; -import java.util.logging.Level; -import java.util.logging.Logger; import lombok.extern.slf4j.Slf4j; import org.eclipse.jetty.http.pathmap.PathSpec; @@ -50,26 +47,26 @@ public String getContextPath() { public Mapping getHandler() { Mapping mapping = new Mapping(); - var classLoader = Thread.currentThread().getContextClassLoader(); +// var classLoader = Thread.currentThread().getContextClassLoader(); try { - Thread.currentThread().setContextClassLoader(UIJettyHttpHandlerExtension.class.getClassLoader()); + //Thread.currentThread().setContextClassLoader(UIJettyHttpHandlerExtension.class.getClassLoader()); ResourceHandler resourceHandler = new ResourceHandler(); resourceHandler.setDirAllowed(false); - resourceHandler.setBaseResource( - ResourceFactory.of(resourceHandler) - .newClassLoaderResource("com/github/thmarx/cms/modules/ui/assets/", false) - ); -// URL resource = UIJettyHttpHandlerExtension.class.getResource("/com/github/thmarx/cms/modules/ui/assets/"); -// var fileURI = resource.toURI().toString().replace("jar:", ""); -// resourceHandler.setBaseResource(ResourceFactory.of(resourceHandler).newJarFileResource(URI.create(fileURI))); +// resourceHandler.setBaseResource( +// ResourceFactory.of(resourceHandler) +// .newClassLoaderResource("com/github/thmarx/cms/modules/ui/assets/", false) +// ); + URL resource = UIJettyHttpHandlerExtension.class.getResource("/com/github/thmarx/cms/modules/ui/assets"); + var fileURI = resource.toURI().toString().replace("jar:", ""); + resourceHandler.setBaseResource(ResourceFactory.of(resourceHandler).newJarFileResource(URI.create(fileURI))); mapping.add(PathSpec.from("/assets/*"), resourceHandler); } catch (Exception ex) { log.error(null, ex); } finally { - Thread.currentThread().setContextClassLoader(classLoader); +// Thread.currentThread().setContextClassLoader(classLoader); } return mapping; diff --git a/modules/ui-module/src/main/resources/com/github/thmarx/cms/modules/ui/assets/index.html b/modules/ui-module/src/main/resources/com/github/thmarx/cms/modules/ui/assets/ui-module/assets/index.html similarity index 100% rename from modules/ui-module/src/main/resources/com/github/thmarx/cms/modules/ui/assets/index.html rename to modules/ui-module/src/main/resources/com/github/thmarx/cms/modules/ui/assets/ui-module/assets/index.html