diff --git a/.gitignore b/.gitignore
index c2f05ed3..80d70231 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,4 +20,6 @@ cms-server/modules/flexmark-module
cms-server/modules/markedjs-module
cms-server/modules/pebble-module
cms-server/modules/thymeleaf-module
-cms-server/modules/freemarker-module
\ No newline at end of file
+cms-server/modules/freemarker-module
+cms-server/modules/ui-module
+cms-server/modules/pug-module
\ No newline at end of file
diff --git a/cms-api/pom.xml b/cms-api/pom.xml
index 3af64b48..f1958b0b 100644
--- a/cms-api/pom.xml
+++ b/cms-api/pom.xml
@@ -23,6 +23,11 @@
org.eclipse.jetty
jetty-server
+
+ org.eclipse.jetty
+ jetty-http
+ ${jetty.version}
+
org.apache.logging.log4j
log4j-slf4j2-impl
diff --git a/cms-api/src/main/java/com/github/thmarx/cms/api/extensions/AbstractExtensionEndpoint.java b/cms-api/src/main/java/com/github/thmarx/cms/api/extensions/AbstractExtensionPoint.java
similarity index 93%
rename from cms-api/src/main/java/com/github/thmarx/cms/api/extensions/AbstractExtensionEndpoint.java
rename to cms-api/src/main/java/com/github/thmarx/cms/api/extensions/AbstractExtensionPoint.java
index 47b1b9f3..2d6645af 100644
--- a/cms-api/src/main/java/com/github/thmarx/cms/api/extensions/AbstractExtensionEndpoint.java
+++ b/cms-api/src/main/java/com/github/thmarx/cms/api/extensions/AbstractExtensionPoint.java
@@ -29,7 +29,7 @@
*
* @author t.marx
*/
-public abstract class AbstractExtensionEndpoint implements ExtensionPoint {
+public abstract class AbstractExtensionPoint implements ExtensionPoint {
@Getter
protected ModuleConfiguration moduleConfiguration;
@Getter
diff --git a/cms-api/src/main/java/com/github/thmarx/cms/api/extensions/HttpHandlerExtensionPoint.java b/cms-api/src/main/java/com/github/thmarx/cms/api/extensions/HttpHandlerExtensionPoint.java
index 7a84fcaf..e34e3f9f 100644
--- a/cms-api/src/main/java/com/github/thmarx/cms/api/extensions/HttpHandlerExtensionPoint.java
+++ b/cms-api/src/main/java/com/github/thmarx/cms/api/extensions/HttpHandlerExtensionPoint.java
@@ -27,7 +27,7 @@
* @author t.marx
*/
@Deprecated(since = "2.5.0")
-public abstract class HttpHandlerExtensionPoint extends AbstractExtensionEndpoint implements ExtensionHttpHandler {
+public abstract class HttpHandlerExtensionPoint extends AbstractExtensionPoint implements ExtensionHttpHandler {
abstract public boolean handles (String method, String uri);
diff --git a/cms-api/src/main/java/com/github/thmarx/cms/api/extensions/JettyHttpHandlerExtensionPoint.java b/cms-api/src/main/java/com/github/thmarx/cms/api/extensions/JettyHttpHandlerExtensionPoint.java
index 8426c3d3..4719326a 100644
--- a/cms-api/src/main/java/com/github/thmarx/cms/api/extensions/JettyHttpHandlerExtensionPoint.java
+++ b/cms-api/src/main/java/com/github/thmarx/cms/api/extensions/JettyHttpHandlerExtensionPoint.java
@@ -20,16 +20,10 @@
* #L%
*/
-import org.eclipse.jetty.server.Handler;
-
/**
*
* @author t.marx
*/
-public abstract class JettyHttpHandlerExtensionPoint extends AbstractExtensionEndpoint {
-
- abstract public String getContextPath();
-
- abstract public Handler getHandler();
-
+public abstract class JettyHttpHandlerExtensionPoint extends AbstractExtensionPoint {
+ abstract public Mapping getMapping();
}
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
new file mode 100644
index 00000000..7fbe4c69
--- /dev/null
+++ b/cms-api/src/main/java/com/github/thmarx/cms/api/extensions/Mapping.java
@@ -0,0 +1,54 @@
+package com.github.thmarx.cms.api.extensions;
+
+/*-
+ * #%L
+ * cms-api
+ * %%
+ * Copyright (C) 2023 Marx-Software
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #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;
+import org.eclipse.jetty.server.Handler;
+
+/**
+ *
+ * @author thmar
+ */
+public class Mapping {
+
+ private Map handlerMapping;
+
+ public Mapping () {
+ handlerMapping = new HashMap<>();
+ }
+
+ public void add (PathSpec pathSpec, Handler handler) {
+ handlerMapping.put(pathSpec, 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-api/src/main/java/com/github/thmarx/cms/api/extensions/MarkdownRendererProviderExtentionPoint.java b/cms-api/src/main/java/com/github/thmarx/cms/api/extensions/MarkdownRendererProviderExtentionPoint.java
index 6dbfdfcb..6c4a31d4 100644
--- a/cms-api/src/main/java/com/github/thmarx/cms/api/extensions/MarkdownRendererProviderExtentionPoint.java
+++ b/cms-api/src/main/java/com/github/thmarx/cms/api/extensions/MarkdownRendererProviderExtentionPoint.java
@@ -26,7 +26,7 @@
*
* @author t.marx
*/
-public abstract class MarkdownRendererProviderExtentionPoint extends AbstractExtensionEndpoint {
+public abstract class MarkdownRendererProviderExtentionPoint extends AbstractExtensionPoint {
public abstract String getName ();
public abstract MarkdownRenderer getRenderer ();
diff --git a/cms-api/src/main/java/com/github/thmarx/cms/api/extensions/TemplateEngineProviderExtentionPoint.java b/cms-api/src/main/java/com/github/thmarx/cms/api/extensions/TemplateEngineProviderExtentionPoint.java
index cd0eb0eb..f67c8d69 100644
--- a/cms-api/src/main/java/com/github/thmarx/cms/api/extensions/TemplateEngineProviderExtentionPoint.java
+++ b/cms-api/src/main/java/com/github/thmarx/cms/api/extensions/TemplateEngineProviderExtentionPoint.java
@@ -26,7 +26,7 @@
*
* @author t.marx
*/
-public abstract class TemplateEngineProviderExtentionPoint extends AbstractExtensionEndpoint {
+public abstract class TemplateEngineProviderExtentionPoint extends AbstractExtensionPoint {
public abstract String getName ();
public abstract TemplateEngine getTemplateEngine ();
diff --git a/cms-api/src/main/java/com/github/thmarx/cms/api/extensions/TemplateModelExtendingExtentionPoint.java b/cms-api/src/main/java/com/github/thmarx/cms/api/extensions/TemplateModelExtendingExtentionPoint.java
index 58f24c23..edb7e308 100644
--- a/cms-api/src/main/java/com/github/thmarx/cms/api/extensions/TemplateModelExtendingExtentionPoint.java
+++ b/cms-api/src/main/java/com/github/thmarx/cms/api/extensions/TemplateModelExtendingExtentionPoint.java
@@ -34,7 +34,7 @@
*
* @author thmar
*/
-public abstract class TemplateModelExtendingExtentionPoint extends AbstractExtensionEndpoint{
+public abstract class TemplateModelExtendingExtentionPoint extends AbstractExtensionPoint{
public abstract void extendModel (TemplateEngine.Model model);
diff --git a/cms-server/hosts/demo/content/.technical/test/example.md b/cms-server/hosts/demo/content/.technical/test/example.md
new file mode 100644
index 00000000..b06f805a
--- /dev/null
+++ b/cms-server/hosts/demo/content/.technical/test/example.md
@@ -0,0 +1,5 @@
+---
+title: Das ist der neue Titel
+---
+
+Das ist der ganz aktuelle Inhalt
\ No newline at end of file
diff --git a/cms-server/hosts/demo/test/ui-module/directory-create.http b/cms-server/hosts/demo/test/ui-module/directory-create.http
new file mode 100644
index 00000000..aec74852
--- /dev/null
+++ b/cms-server/hosts/demo/test/ui-module/directory-create.http
@@ -0,0 +1 @@
+POST http://localhost:1010/module/ui-module/file-system/create?path=.technical&filename=test&type=folder
\ No newline at end of file
diff --git a/cms-server/hosts/demo/test/ui-module/directory-delete.http b/cms-server/hosts/demo/test/ui-module/directory-delete.http
new file mode 100644
index 00000000..bbff6591
--- /dev/null
+++ b/cms-server/hosts/demo/test/ui-module/directory-delete.http
@@ -0,0 +1 @@
+DELETE http://localhost:1010/module/ui-module/file-system/delete?path=.technical/test
\ No newline at end of file
diff --git a/cms-server/hosts/demo/test/ui-module/file-create.http b/cms-server/hosts/demo/test/ui-module/file-create.http
new file mode 100644
index 00000000..f5f80a9d
--- /dev/null
+++ b/cms-server/hosts/demo/test/ui-module/file-create.http
@@ -0,0 +1,8 @@
+POST http://localhost:1010/module/ui-module/file-system/create?path=.technical/test&filename=example.md&type=file
+
+---
+title: Das ist der Titel
+---
+\# Neue Datei
+
+Das ist der Inhalt
\ No newline at end of file
diff --git a/cms-server/hosts/demo/test/ui-module/file-read.http b/cms-server/hosts/demo/test/ui-module/file-read.http
new file mode 100644
index 00000000..9f5b6f1c
--- /dev/null
+++ b/cms-server/hosts/demo/test/ui-module/file-read.http
@@ -0,0 +1 @@
+GET http://localhost:1010/module/ui-module/file-system/read?path=.technical/test/example.md
\ No newline at end of file
diff --git a/cms-server/hosts/demo/test/ui-module/file-write.http b/cms-server/hosts/demo/test/ui-module/file-write.http
new file mode 100644
index 00000000..4503696a
--- /dev/null
+++ b/cms-server/hosts/demo/test/ui-module/file-write.http
@@ -0,0 +1,8 @@
+PUT http://localhost:1010/module/ui-module/file-system/write?path=.technical/test/example.md
+
+---
+title: Das ist der neue Titel
+---
+# Neuerer Datei
+
+Das ist der ganz aktuelle Inhalt
\ No newline at end of file
diff --git a/cms-server/hosts/demo/test/ui-module/list-files.http b/cms-server/hosts/demo/test/ui-module/list-files.http
new file mode 100644
index 00000000..ed6bc16f
--- /dev/null
+++ b/cms-server/hosts/demo/test/ui-module/list-files.http
@@ -0,0 +1 @@
+GET http://localhost:1010/module/ui-module/file-system/list?path=.technical
\ No newline at end of file
diff --git a/cms-server/modules/example-module/libs/example-module-2.5.0-SNAPSHOT.jar b/cms-server/modules/example-module/libs/example-module-2.5.0-SNAPSHOT.jar
index 3d220e89..7a106dcd 100644
Binary files a/cms-server/modules/example-module/libs/example-module-2.5.0-SNAPSHOT.jar and b/cms-server/modules/example-module/libs/example-module-2.5.0-SNAPSHOT.jar differ
diff --git a/cms-server/modules/pug-module/libs/annotations-15.0.jar b/cms-server/modules/pug-module/libs/annotations-15.0.jar
deleted file mode 100644
index 3f838329..00000000
Binary files a/cms-server/modules/pug-module/libs/annotations-15.0.jar and /dev/null differ
diff --git a/cms-server/modules/pug-module/libs/caffeine-3.1.8.jar b/cms-server/modules/pug-module/libs/caffeine-3.1.8.jar
deleted file mode 100644
index e00640c2..00000000
Binary files a/cms-server/modules/pug-module/libs/caffeine-3.1.8.jar and /dev/null differ
diff --git a/cms-server/modules/pug-module/libs/checker-qual-3.37.0.jar b/cms-server/modules/pug-module/libs/checker-qual-3.37.0.jar
deleted file mode 100644
index b4f9db98..00000000
Binary files a/cms-server/modules/pug-module/libs/checker-qual-3.37.0.jar and /dev/null differ
diff --git a/cms-server/modules/pug-module/libs/chromeinspector-21.3.2.jar b/cms-server/modules/pug-module/libs/chromeinspector-21.3.2.jar
deleted file mode 100644
index ed6f4b3f..00000000
Binary files a/cms-server/modules/pug-module/libs/chromeinspector-21.3.2.jar and /dev/null differ
diff --git a/cms-server/modules/pug-module/libs/commons-collections4-4.4.jar b/cms-server/modules/pug-module/libs/commons-collections4-4.4.jar
deleted file mode 100644
index da06c3e4..00000000
Binary files a/cms-server/modules/pug-module/libs/commons-collections4-4.4.jar and /dev/null differ
diff --git a/cms-server/modules/pug-module/libs/commons-io-2.14.0.jar b/cms-server/modules/pug-module/libs/commons-io-2.14.0.jar
deleted file mode 100644
index 4273f322..00000000
Binary files a/cms-server/modules/pug-module/libs/commons-io-2.14.0.jar and /dev/null differ
diff --git a/cms-server/modules/pug-module/libs/commons-jexl3-3.2.1.jar b/cms-server/modules/pug-module/libs/commons-jexl3-3.2.1.jar
deleted file mode 100644
index 4a3b9269..00000000
Binary files a/cms-server/modules/pug-module/libs/commons-jexl3-3.2.1.jar and /dev/null differ
diff --git a/cms-server/modules/pug-module/libs/commons-lang3-3.13.0.jar b/cms-server/modules/pug-module/libs/commons-lang3-3.13.0.jar
deleted file mode 100644
index 891540f4..00000000
Binary files a/cms-server/modules/pug-module/libs/commons-lang3-3.13.0.jar and /dev/null differ
diff --git a/cms-server/modules/pug-module/libs/commons-logging-1.2.jar b/cms-server/modules/pug-module/libs/commons-logging-1.2.jar
deleted file mode 100644
index 93a3b9f6..00000000
Binary files a/cms-server/modules/pug-module/libs/commons-logging-1.2.jar and /dev/null differ
diff --git a/cms-server/modules/pug-module/libs/commons-text-1.10.0.jar b/cms-server/modules/pug-module/libs/commons-text-1.10.0.jar
deleted file mode 100644
index beada027..00000000
Binary files a/cms-server/modules/pug-module/libs/commons-text-1.10.0.jar and /dev/null differ
diff --git a/cms-server/modules/pug-module/libs/compiler-21.3.2.jar b/cms-server/modules/pug-module/libs/compiler-21.3.2.jar
deleted file mode 100644
index 3733db0b..00000000
Binary files a/cms-server/modules/pug-module/libs/compiler-21.3.2.jar and /dev/null differ
diff --git a/cms-server/modules/pug-module/libs/concurrentlinkedhashmap-lru-1.4.2.jar b/cms-server/modules/pug-module/libs/concurrentlinkedhashmap-lru-1.4.2.jar
deleted file mode 100644
index 6b483d59..00000000
Binary files a/cms-server/modules/pug-module/libs/concurrentlinkedhashmap-lru-1.4.2.jar and /dev/null differ
diff --git a/cms-server/modules/pug-module/libs/error_prone_annotations-2.21.1.jar b/cms-server/modules/pug-module/libs/error_prone_annotations-2.21.1.jar
deleted file mode 100644
index 00f26ae1..00000000
Binary files a/cms-server/modules/pug-module/libs/error_prone_annotations-2.21.1.jar and /dev/null differ
diff --git a/cms-server/modules/pug-module/libs/flexmark-0.62.2.jar b/cms-server/modules/pug-module/libs/flexmark-0.62.2.jar
deleted file mode 100644
index 948349ac..00000000
Binary files a/cms-server/modules/pug-module/libs/flexmark-0.62.2.jar and /dev/null differ
diff --git a/cms-server/modules/pug-module/libs/flexmark-util-ast-0.62.2.jar b/cms-server/modules/pug-module/libs/flexmark-util-ast-0.62.2.jar
deleted file mode 100644
index f0e1d44d..00000000
Binary files a/cms-server/modules/pug-module/libs/flexmark-util-ast-0.62.2.jar and /dev/null differ
diff --git a/cms-server/modules/pug-module/libs/flexmark-util-builder-0.62.2.jar b/cms-server/modules/pug-module/libs/flexmark-util-builder-0.62.2.jar
deleted file mode 100644
index d1409f8c..00000000
Binary files a/cms-server/modules/pug-module/libs/flexmark-util-builder-0.62.2.jar and /dev/null differ
diff --git a/cms-server/modules/pug-module/libs/flexmark-util-collection-0.62.2.jar b/cms-server/modules/pug-module/libs/flexmark-util-collection-0.62.2.jar
deleted file mode 100644
index 34860df8..00000000
Binary files a/cms-server/modules/pug-module/libs/flexmark-util-collection-0.62.2.jar and /dev/null differ
diff --git a/cms-server/modules/pug-module/libs/flexmark-util-data-0.62.2.jar b/cms-server/modules/pug-module/libs/flexmark-util-data-0.62.2.jar
deleted file mode 100644
index 78fc5030..00000000
Binary files a/cms-server/modules/pug-module/libs/flexmark-util-data-0.62.2.jar and /dev/null differ
diff --git a/cms-server/modules/pug-module/libs/flexmark-util-dependency-0.62.2.jar b/cms-server/modules/pug-module/libs/flexmark-util-dependency-0.62.2.jar
deleted file mode 100644
index 559ca267..00000000
Binary files a/cms-server/modules/pug-module/libs/flexmark-util-dependency-0.62.2.jar and /dev/null differ
diff --git a/cms-server/modules/pug-module/libs/flexmark-util-format-0.62.2.jar b/cms-server/modules/pug-module/libs/flexmark-util-format-0.62.2.jar
deleted file mode 100644
index 325df939..00000000
Binary files a/cms-server/modules/pug-module/libs/flexmark-util-format-0.62.2.jar and /dev/null differ
diff --git a/cms-server/modules/pug-module/libs/flexmark-util-html-0.62.2.jar b/cms-server/modules/pug-module/libs/flexmark-util-html-0.62.2.jar
deleted file mode 100644
index d09c241d..00000000
Binary files a/cms-server/modules/pug-module/libs/flexmark-util-html-0.62.2.jar and /dev/null differ
diff --git a/cms-server/modules/pug-module/libs/flexmark-util-misc-0.62.2.jar b/cms-server/modules/pug-module/libs/flexmark-util-misc-0.62.2.jar
deleted file mode 100644
index eece2d76..00000000
Binary files a/cms-server/modules/pug-module/libs/flexmark-util-misc-0.62.2.jar and /dev/null differ
diff --git a/cms-server/modules/pug-module/libs/flexmark-util-sequence-0.62.2.jar b/cms-server/modules/pug-module/libs/flexmark-util-sequence-0.62.2.jar
deleted file mode 100644
index 590be166..00000000
Binary files a/cms-server/modules/pug-module/libs/flexmark-util-sequence-0.62.2.jar and /dev/null differ
diff --git a/cms-server/modules/pug-module/libs/flexmark-util-visitor-0.62.2.jar b/cms-server/modules/pug-module/libs/flexmark-util-visitor-0.62.2.jar
deleted file mode 100644
index efc2552e..00000000
Binary files a/cms-server/modules/pug-module/libs/flexmark-util-visitor-0.62.2.jar and /dev/null differ
diff --git a/cms-server/modules/pug-module/libs/graal-sdk-21.3.2.jar b/cms-server/modules/pug-module/libs/graal-sdk-21.3.2.jar
deleted file mode 100644
index a502d11d..00000000
Binary files a/cms-server/modules/pug-module/libs/graal-sdk-21.3.2.jar and /dev/null differ
diff --git a/cms-server/modules/pug-module/libs/gson-2.10.1.jar b/cms-server/modules/pug-module/libs/gson-2.10.1.jar
deleted file mode 100644
index a88c5bd9..00000000
Binary files a/cms-server/modules/pug-module/libs/gson-2.10.1.jar and /dev/null differ
diff --git a/cms-server/modules/pug-module/libs/icu4j-70.1.jar b/cms-server/modules/pug-module/libs/icu4j-70.1.jar
deleted file mode 100644
index 9f074737..00000000
Binary files a/cms-server/modules/pug-module/libs/icu4j-70.1.jar and /dev/null differ
diff --git a/cms-server/modules/pug-module/libs/js-21.3.2.jar b/cms-server/modules/pug-module/libs/js-21.3.2.jar
deleted file mode 100644
index 4c342002..00000000
Binary files a/cms-server/modules/pug-module/libs/js-21.3.2.jar and /dev/null differ
diff --git a/cms-server/modules/pug-module/libs/js-scriptengine-21.3.2.jar b/cms-server/modules/pug-module/libs/js-scriptengine-21.3.2.jar
deleted file mode 100644
index cc7681f7..00000000
Binary files a/cms-server/modules/pug-module/libs/js-scriptengine-21.3.2.jar and /dev/null differ
diff --git a/cms-server/modules/pug-module/libs/profiler-21.3.2.jar b/cms-server/modules/pug-module/libs/profiler-21.3.2.jar
deleted file mode 100644
index 1476e837..00000000
Binary files a/cms-server/modules/pug-module/libs/profiler-21.3.2.jar and /dev/null differ
diff --git a/cms-server/modules/pug-module/libs/pug-module-2.5.0-SNAPSHOT.jar b/cms-server/modules/pug-module/libs/pug-module-2.5.0-SNAPSHOT.jar
deleted file mode 100644
index 16dca7d3..00000000
Binary files a/cms-server/modules/pug-module/libs/pug-module-2.5.0-SNAPSHOT.jar and /dev/null differ
diff --git a/cms-server/modules/pug-module/libs/pug4j-2.1.0.jar b/cms-server/modules/pug-module/libs/pug4j-2.1.0.jar
deleted file mode 100644
index b864acfa..00000000
Binary files a/cms-server/modules/pug-module/libs/pug4j-2.1.0.jar and /dev/null differ
diff --git a/cms-server/modules/pug-module/libs/regex-21.3.2.jar b/cms-server/modules/pug-module/libs/regex-21.3.2.jar
deleted file mode 100644
index 1227e5f3..00000000
Binary files a/cms-server/modules/pug-module/libs/regex-21.3.2.jar and /dev/null differ
diff --git a/cms-server/modules/pug-module/libs/truffle-api-21.3.2.jar b/cms-server/modules/pug-module/libs/truffle-api-21.3.2.jar
deleted file mode 100644
index 1f4a5f4c..00000000
Binary files a/cms-server/modules/pug-module/libs/truffle-api-21.3.2.jar and /dev/null differ
diff --git a/cms-server/modules/pug-module/module.properties b/cms-server/modules/pug-module/module.properties
deleted file mode 100644
index 8f3b401e..00000000
--- a/cms-server/modules/pug-module/module.properties
+++ /dev/null
@@ -1,4 +0,0 @@
-id=pug-module
-name=pug module
-version=2.5.0-SNAPSHOT
-priority=HIGH
\ No newline at end of file
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..a864b6c2 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,12 +73,12 @@ public class VHost {
@Getter
private final EventBus eventBus;
- protected SiteProperties properties;
-
+ protected SiteProperties siteProperties;
+
protected ModuleManager moduleManager;
protected final ServerProperties serverProperties;
-
+
public VHost(final Path hostBase, final ServerProperties serverProperties) {
this.eventBus = new DefaultEventBus();
this.fileSystem = new FileSystem(hostBase, eventBus);
@@ -97,46 +97,48 @@ public void shutdown() {
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(),
+ var classLoader = new ModuleAPIClassLoader(ClassLoader.getSystemClassLoader(),
List.of(
- "org.slf4j",
+ "org.slf4j",
"com.github.thmarx.cms",
"org.apache.logging",
"org.graalvm.polyglot",
"org.graalvm.js",
- "org.eclipse.jetty"
- ));
- this.moduleManager = ModuleManagerImpl.create(
- modules.toFile(),
- fileSystem.resolve("modules_data").toFile(),
- new CMSModuleContext(properties, serverProperties, fileSystem, eventBus),
+ "org.eclipse.jetty",
+ "jakarta.servlet"
+ ));
+ this.moduleManager = ModuleManagerImpl.create(modules.toFile(),
+ fileSystem.resolve("modules_data").toFile(),
+ new CMSModuleContext(siteProperties, serverProperties, fileSystem, eventBus),
classLoader
);
- properties.activeModules().forEach(module_id -> {
- try {
- log.debug("activate module {}", module_id);
- moduleManager.activateModule(module_id);
- } catch (IOException ex) {
- log.error(null, ex);
- }
- });
-
+ siteProperties.activeModules().stream()
+ .filter(module_id -> moduleManager.getModuleIds().contains(module_id))
+ .forEach(module_id -> {
+ try {
+ log.debug("activate module {}", module_id);
+ moduleManager.activateModule(module_id);
+ } catch (IOException ex) {
+ log.error(null, ex);
+ }
+ });
+
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);
- moduleManager.deactivateModule(module_id);
- } catch (IOException ex) {
- log.error(null, ex);
- }
- });
-
- hostname = properties.hostname();
+ try {
+ log.debug("deactivate module {}", module_id);
+ moduleManager.deactivateModule(module_id);
+ } catch (IOException ex) {
+ log.error(null, ex);
+ }
+ });
+
+ hostname = siteProperties.hostname();
contentBase = fileSystem.resolve("content/");
assetBase = fileSystem.resolve("assets/");
@@ -149,7 +151,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,11 +165,11 @@ 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();
-
+
if (extOpt.isPresent()) {
return extOpt.get().getTemplateEngine();
} else {
@@ -176,11 +178,11 @@ 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();
-
+
if (extOpt.isPresent()) {
return extOpt.get().getRenderer();
} else {
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 006f46e8..6b674573 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
@@ -19,26 +19,17 @@
* limitations under the License.
* #L%
*/
-
import com.github.thmarx.cms.api.ServerProperties;
-import com.github.thmarx.cms.api.extensions.JettyHttpHandlerExtensionPoint;
import com.github.thmarx.cms.server.jetty.handler.JettyDefaultHandler;
-import com.github.thmarx.cms.server.jetty.handler.JettyModuleHandler;
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 java.util.concurrent.atomic.AtomicReference;
-import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.jetty.http.pathmap.PathSpec;
-import org.eclipse.jetty.http.pathmap.ServletPathSpec;
import org.eclipse.jetty.server.Handler;
-import org.eclipse.jetty.server.HandlerContainer;
-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;
@@ -60,7 +51,7 @@ public Handler httpHandler() {
var defaultHandler = new JettyDefaultHandler(contentResolver, extensionManager, (context) -> {
return resolveMarkdownRenderer(context);
});
-
+
log.debug("create assets handler for {}", assetBase.toString());
ResourceHandler assetsHandler = new ResourceHandler();
assetsHandler.setDirAllowed(false);
@@ -70,55 +61,38 @@ public Handler httpHandler() {
} else {
assetsHandler.setCacheControl("max-age=" + TimeUnit.HOURS.toSeconds(24));
}
-
+
ResourceHandler faviconHandler = new ResourceHandler();
faviconHandler.setDirAllowed(false);
faviconHandler.setBaseResource(new FileFolderPathResource(assetBase.resolve("favicon.ico")));
-
+
PathMappingsHandler pathMappingsHandler = new PathMappingsHandler();
pathMappingsHandler.addMapping(PathSpec.from("/"), defaultHandler);
pathMappingsHandler.addMapping(PathSpec.from("/assets/*"), assetsHandler);
- pathMappingsHandler.addMapping(PathSpec.from("/favicon.ico"), faviconHandler);
-
+ pathMappingsHandler.addMapping(PathSpec.from("/favicon.ico"), faviconHandler);
+
ContextHandler defaultContextHandler = new ContextHandler(pathMappingsHandler, "/");
- defaultContextHandler.setVirtualHosts(List.of(properties.hostname()));
-
-
-// var moduleHandler = new JettyModuleHandler(moduleManager);
-// ContextHandler moduleContextHandler = new ContextHandler(moduleHandler, "/module");
+ defaultContextHandler.setVirtualHosts(List.of(siteProperties.hostname()));
+
+ 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");
-
+
ContextHandlerCollection contextCollection = new ContextHandlerCollection(
defaultContextHandler,
-// moduleContextHandler,
- extensionContextHandler,
- modulesContextHandler()
+ moduleContextHandler,
+ extensionContextHandler
);
-
-
+
GzipHandler gzipHandler = new GzipHandler(contextCollection);
gzipHandler.setMinGzipSize(1024);
gzipHandler.addIncludedMimeTypes("text/plain");
- gzipHandler.addIncludedMimeTypes("text/html");
+ gzipHandler.addIncludedMimeTypes("text/html");
gzipHandler.addIncludedMimeTypes("text/css");
gzipHandler.addIncludedMimeTypes("application/javascript");
return gzipHandler;
}
-
- private ContextHandler modulesContextHandler () {
- List contextHandlers = new ArrayList<>();
- moduleManager.extensions(JettyHttpHandlerExtensionPoint.class).forEach((extension) -> {
- contextHandlers.add(new ContextHandler(
- extension.getHandler(), "/module/" + extension.getContextPath()
- ));
- });
- ContextHandler modulesContextHandler = new ContextHandler(
- new ContextHandlerCollection(contextHandlers.toArray(ContextHandler[]::new)),
- "/module"
- );
-
- return modulesContextHandler;
- }
}
diff --git a/cms-server/src/main/java/com/github/thmarx/cms/server/jetty/handler/JettyModuleHandler.java b/cms-server/src/main/java/com/github/thmarx/cms/server/jetty/handler/JettyModuleHandler.java
index fb76f84d..4fd36f11 100644
--- a/cms-server/src/main/java/com/github/thmarx/cms/server/jetty/handler/JettyModuleHandler.java
+++ b/cms-server/src/main/java/com/github/thmarx/cms/server/jetty/handler/JettyModuleHandler.java
@@ -37,6 +37,7 @@
*/
@RequiredArgsConstructor
@Slf4j
+@Deprecated
public class JettyModuleHandler extends Handler.Abstract {
private final ModuleManager moduleManager;
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
new file mode 100644
index 00000000..e5ed494e
--- /dev/null
+++ b/cms-server/src/main/java/com/github/thmarx/cms/server/jetty/handler/JettyModuleMappingHandler.java
@@ -0,0 +1,131 @@
+package com.github.thmarx.cms.server.jetty.handler;
+
+/*-
+ * #%L
+ * cms-server
+ * %%
+ * Copyright (C) 2023 Marx-Software
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * 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;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.util.Callback;
+
+/**
+ *
+ * @author t.marx
+ */
+@RequiredArgsConstructor
+@Slf4j
+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.getMapping()));
+ }
+ });
+ }
+
+ @Override
+ public boolean handle(Request request, Response response, Callback callback) throws Exception {
+ try {
+ String moduleId = getModuleID(request);
+
+ var module = moduleManager.module(moduleId);
+
+ if (!moduleMappgings.containsKey(moduleId)) {
+ Response.writeError(request, response, callback, 404);
+ return false;
+ }
+
+ var uri = getModuleUri(request);
+ Optional findFirst = moduleMappgings.get(moduleId).stream().filter(mapping -> mapping.getMatchingHandler(uri).isPresent()).findFirst();
+
+ if (findFirst.isPresent()) {
+ var mapping = findFirst.get();
+ var handler = mapping.getMatchingHandler(uri).get();
+ if (!handler.isStarted()) {
+ handler.start();
+ }
+ return handler.handle(request, response, callback);
+ }
+
+ Response.writeError(request, response, callback, 404);
+ return false;
+ } catch (Exception e) {
+ log.error(null, e);
+ callback.failed(e);
+ return false;
+ }
+
+ }
+
+ private String getModuleUri(Request request) {
+ var modulePath = getModulePath(request);
+ if (modulePath.contains("/")) {
+ return modulePath.substring(modulePath.indexOf("/"));
+ }
+ return modulePath;
+ }
+
+ private String getModuleID(Request request) {
+ var modulePath = getModulePath(request);
+ if (modulePath.contains("/")) {
+ return modulePath.split("/")[0];
+ }
+ return modulePath;
+ }
+
+ private String getModulePath(Request request) {
+ var path = request.getHttpURI().getPath();
+ var contextPath = request.getContext().getContextPath();
+ path = path.replace(contextPath, "");
+
+ if (path.startsWith("/")) {
+ path = path.substring(1);
+ }
+
+ return path;
+ }
+
+ @Override
+ public List getHandlers() {
+ return moduleMappgings.values().stream().map(mapper -> mapper.getHandlers())
+ .flatMap(List::stream)
+ .toList();
+ }
+
+}
diff --git a/modules/example-module/src/main/java/com/github/thmarx/cms/modules/example/ExampleJettyHttpHandlerExtension.java b/modules/example-module/src/main/java/com/github/thmarx/cms/modules/example/ExampleJettyHttpHandlerExtension.java
index 608d22ca..e18d71f7 100644
--- a/modules/example-module/src/main/java/com/github/thmarx/cms/modules/example/ExampleJettyHttpHandlerExtension.java
+++ b/modules/example-module/src/main/java/com/github/thmarx/cms/modules/example/ExampleJettyHttpHandlerExtension.java
@@ -21,6 +21,7 @@
*/
import com.github.thmarx.cms.api.extensions.JettyHttpHandlerExtensionPoint;
+import com.github.thmarx.cms.api.extensions.Mapping;
import com.github.thmarx.modules.api.annotation.Extension;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
@@ -29,8 +30,6 @@
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.PathMappingsHandler;
import org.eclipse.jetty.util.Callback;
/**
@@ -41,17 +40,12 @@
public class ExampleJettyHttpHandlerExtension extends JettyHttpHandlerExtensionPoint {
@Override
- public String getContextPath() {
- return "example";
- }
-
- @Override
- public Handler getHandler() {
- PathMappingsHandler pathMappingsHandler = new PathMappingsHandler();
- pathMappingsHandler.addMapping(PathSpec.from("/world"), new ExampleHandler("Hello world!"));
- pathMappingsHandler.addMapping(PathSpec.from("/people"), new ExampleHandler("Hello people!"));
+ public Mapping getMapping() {
+ Mapping mapping = new Mapping();
+ mapping.add(PathSpec.from("/world"), new ExampleHandler("Hello world!"));
+ mapping.add(PathSpec.from("/people"), new ExampleHandler("Hello people!"));
- return pathMappingsHandler;
+ return mapping;
}
@RequiredArgsConstructor
diff --git a/pom.xml b/pom.xml
index 42f2d39a..8907af5a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -12,6 +12,7 @@
com.github.thmarx.cms.Startup
yyyy-MM-dd HH:mm
1.2
+ 12.0.3
cms-api
@@ -55,7 +56,7 @@
org.eclipse.jetty
jetty-server
- 12.0.2
+ ${jetty.version}
org.projectlombok