diff --git a/cms-extensions/src/main/java/com/github/thmarx/cms/extensions/ExtensionManager.java b/cms-extensions/src/main/java/com/github/thmarx/cms/extensions/ExtensionManager.java index cfc3e861..45d56043 100644 --- a/cms-extensions/src/main/java/com/github/thmarx/cms/extensions/ExtensionManager.java +++ b/cms-extensions/src/main/java/com/github/thmarx/cms/extensions/ExtensionManager.java @@ -23,10 +23,10 @@ */ import com.github.thmarx.cms.api.ServerProperties; import com.github.thmarx.cms.api.db.DB; -import com.github.thmarx.cms.api.hooks.HookSystem; +import com.github.thmarx.cms.api.feature.features.HookSystemFeature; +import com.github.thmarx.cms.api.request.RequestContext; import com.github.thmarx.cms.extensions.request.RequestExtensions; import com.github.thmarx.cms.api.theme.Theme; -import com.github.thmarx.cms.extensions.ExtensionFileSystem; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; @@ -129,7 +129,7 @@ protected void loadExtensions(final Path extPath, final Consumer loader) .forEach(loader); } - public RequestExtensions newContext(Theme theme, final HookSystem hookSystem) throws IOException { + public RequestExtensions newContext(Theme theme, RequestContext requestContext) throws IOException { var context = Context.newBuilder() .allowAllAccess(true) .allowHostClassLookup(className -> true) @@ -155,15 +155,10 @@ public RequestExtensions newContext(Theme theme, final HookSystem hookSystem) th .engine(engine).build(); } - RequestExtensions holder = new RequestExtensions(context, themeContext); + RequestExtensions requestExtensions = new RequestExtensions(context, themeContext); final Value bindings = context.getBindings("js"); - bindings.putMember("extensions", holder); - bindings.putMember("fileSystem", db.getFileSystem()); - bindings.putMember("db", db); - bindings.putMember("theme", theme); - bindings.putMember("hooks", hookSystem); - bindings.putMember("ENV", serverProperties.env()); + setUpBinding(bindings, requestExtensions, theme, requestContext); var extPath = db.getFileSystem().resolve("extensions/"); if (Files.exists(extPath)) { @@ -173,12 +168,7 @@ public RequestExtensions newContext(Theme theme, final HookSystem hookSystem) th if (!theme.empty()) { final Value themeBindings = themeContext.getBindings("js"); - themeBindings.putMember("extensions", holder); - themeBindings.putMember("fileSystem", db.getFileSystem()); - themeBindings.putMember("db", db); - themeBindings.putMember("theme", theme); - themeBindings.putMember("hooks", hookSystem); - themeBindings.putMember("ENV", serverProperties.env()); + setUpBinding(themeBindings, requestExtensions, theme, requestContext); // theme_sources.forEach(themeContext::eval); var themeExtPath = parentTheme.extensionsPath(); @@ -188,7 +178,19 @@ public RequestExtensions newContext(Theme theme, final HookSystem hookSystem) th } } - return holder; + return requestExtensions; + } + + private void setUpBinding (Value bindings, + RequestExtensions requestExtensions, Theme theme, RequestContext requestContext) { + bindings.putMember("extensions", requestExtensions); + bindings.putMember("fileSystem", db.getFileSystem()); + bindings.putMember("db", db); + bindings.putMember("theme", theme); + // for backword compability +// bindings.putMember("hooks", requestContext.get(HookSystemFeature.class).hookSystem()); + bindings.putMember("requestContext", requestContext); + bindings.putMember("ENV", serverProperties.env()); } @Override diff --git a/cms-server/src/main/resources/com/github/thmarx/cms/extensions/system/charsets.mjs b/cms-extensions/src/main/resources/com/github/thmarx/cms/extensions/system/charsets.mjs similarity index 100% rename from cms-server/src/main/resources/com/github/thmarx/cms/extensions/system/charsets.mjs rename to cms-extensions/src/main/resources/com/github/thmarx/cms/extensions/system/charsets.mjs diff --git a/cms-extensions/src/main/resources/com/github/thmarx/cms/extensions/system/features.mjs b/cms-extensions/src/main/resources/com/github/thmarx/cms/extensions/system/features.mjs new file mode 100644 index 00000000..06231b4e --- /dev/null +++ b/cms-extensions/src/main/resources/com/github/thmarx/cms/extensions/system/features.mjs @@ -0,0 +1,20 @@ +export const AuthFeature = Java.type("com.github.thmarx.cms.api.feature.features.AuthFeature").class +export const ConfigurationFeature = Java.type("com.github.thmarx.cms.api.feature.features.ConfigurationFeature").class +export const ContentNodeMapperFeature = Java.type("com.github.thmarx.cms.api.feature.features.ContentNodeMapperFeature").class +export const ContentParserFeature = Java.type("com.github.thmarx.cms.api.feature.features.ContentParserFeature").class +export const ContentRenderFeature = Java.type("com.github.thmarx.cms.api.feature.features.ContentRenderFeature").class +export const CurrentNodeFeature = Java.type("com.github.thmarx.cms.api.feature.features.CurrentNodeFeature").class +export const CurrentTaxonomyFeature = Java.type("com.github.thmarx.cms.api.feature.features.CurrentTaxonomyFeature").class +export const DBFeature = Java.type("com.github.thmarx.cms.api.feature.features.DBFeature").class +export const EventBusFeature = Java.type("com.github.thmarx.cms.api.feature.features.EventBusFeature").class +export const HookSystemFeature = Java.type("com.github.thmarx.cms.api.feature.features.HookSystemFeature").class +export const InjectorFeature = Java.type("com.github.thmarx.cms.api.feature.features.InjectorFeature").class +export const IsDevModeFeature = Java.type("com.github.thmarx.cms.api.feature.features.IsDevModeFeature").class +export const IsPreviewFeature = Java.type("com.github.thmarx.cms.api.feature.features.IsPreviewFeature").class +export const MarkdownRendererFeature = Java.type("com.github.thmarx.cms.api.feature.features.MarkdownRendererFeature").class +export const ModuleManagerFeature = Java.type("com.github.thmarx.cms.api.feature.features.ModuleManagerFeature").class +export const RequestFeature = Java.type("com.github.thmarx.cms.api.feature.features.RequestFeature").class +export const ServerPropertiesFeature = Java.type("com.github.thmarx.cms.api.feature.features.ServerPropertiesFeature").class +export const SiteMediaServiceFeature = Java.type("com.github.thmarx.cms.api.feature.features.SiteMediaServiceFeature").class +export const SitePropertiesFeature = Java.type("com.github.thmarx.cms.api.feature.features.SitePropertiesFeature").class +export const ThemeFeature = Java.type("com.github.thmarx.cms.api.feature.features.ThemeFeature").class \ No newline at end of file diff --git a/cms-server/src/main/resources/com/github/thmarx/cms/extensions/system/files.mjs b/cms-extensions/src/main/resources/com/github/thmarx/cms/extensions/system/files.mjs similarity index 100% rename from cms-server/src/main/resources/com/github/thmarx/cms/extensions/system/files.mjs rename to cms-extensions/src/main/resources/com/github/thmarx/cms/extensions/system/files.mjs diff --git a/cms-server/src/main/resources/com/github/thmarx/cms/extensions/system/hooks.mjs b/cms-extensions/src/main/resources/com/github/thmarx/cms/extensions/system/hooks.mjs similarity index 57% rename from cms-server/src/main/resources/com/github/thmarx/cms/extensions/system/hooks.mjs rename to cms-extensions/src/main/resources/com/github/thmarx/cms/extensions/system/hooks.mjs index 1cdd1046..459be6f6 100644 --- a/cms-server/src/main/resources/com/github/thmarx/cms/extensions/system/hooks.mjs +++ b/cms-extensions/src/main/resources/com/github/thmarx/cms/extensions/system/hooks.mjs @@ -1,3 +1,7 @@ +import { HookSystemFeature } from 'system/features.mjs'; + +const hooks = requestContext.get(HookSystemFeature).hookSystem() + export const $hooks = { register : (name, fun, priority) => { if (priority) { diff --git a/cms-server/src/main/resources/com/github/thmarx/cms/extensions/system/http.mjs b/cms-extensions/src/main/resources/com/github/thmarx/cms/extensions/system/http.mjs similarity index 100% rename from cms-server/src/main/resources/com/github/thmarx/cms/extensions/system/http.mjs rename to cms-extensions/src/main/resources/com/github/thmarx/cms/extensions/system/http.mjs diff --git a/cms-server/src/main/resources/com/github/thmarx/cms/extensions/system/logging.mjs b/cms-extensions/src/main/resources/com/github/thmarx/cms/extensions/system/logging.mjs similarity index 100% rename from cms-server/src/main/resources/com/github/thmarx/cms/extensions/system/logging.mjs rename to cms-extensions/src/main/resources/com/github/thmarx/cms/extensions/system/logging.mjs diff --git a/cms-server/src/main/resources/com/github/thmarx/cms/extensions/system/query.mjs b/cms-extensions/src/main/resources/com/github/thmarx/cms/extensions/system/query.mjs similarity index 100% rename from cms-server/src/main/resources/com/github/thmarx/cms/extensions/system/query.mjs rename to cms-extensions/src/main/resources/com/github/thmarx/cms/extensions/system/query.mjs diff --git a/cms-server/src/main/resources/com/github/thmarx/cms/extensions/system/routes.mjs b/cms-extensions/src/main/resources/com/github/thmarx/cms/extensions/system/routes.mjs similarity index 100% rename from cms-server/src/main/resources/com/github/thmarx/cms/extensions/system/routes.mjs rename to cms-extensions/src/main/resources/com/github/thmarx/cms/extensions/system/routes.mjs diff --git a/cms-server/src/main/resources/com/github/thmarx/cms/extensions/system/shortcodes.mjs b/cms-extensions/src/main/resources/com/github/thmarx/cms/extensions/system/shortcodes.mjs similarity index 100% rename from cms-server/src/main/resources/com/github/thmarx/cms/extensions/system/shortcodes.mjs rename to cms-extensions/src/main/resources/com/github/thmarx/cms/extensions/system/shortcodes.mjs diff --git a/cms-server/src/main/resources/com/github/thmarx/cms/extensions/system/template.mjs b/cms-extensions/src/main/resources/com/github/thmarx/cms/extensions/system/template.mjs similarity index 100% rename from cms-server/src/main/resources/com/github/thmarx/cms/extensions/system/template.mjs rename to cms-extensions/src/main/resources/com/github/thmarx/cms/extensions/system/template.mjs diff --git a/cms-extensions/src/test/java/com/github/thmarx/cms/extensions/ExtensionManagerTest.java b/cms-extensions/src/test/java/com/github/thmarx/cms/extensions/ExtensionManagerTest.java new file mode 100644 index 00000000..75de3541 --- /dev/null +++ b/cms-extensions/src/test/java/com/github/thmarx/cms/extensions/ExtensionManagerTest.java @@ -0,0 +1,96 @@ +package com.github.thmarx.cms.extensions; + +/*- + * #%L + * cms-extensions + * %% + * Copyright (C) 2023 - 2024 Marx-Software + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +import com.github.thmarx.cms.api.ServerProperties; +import com.github.thmarx.cms.api.db.DB; +import com.github.thmarx.cms.api.feature.features.HookSystemFeature; +import com.github.thmarx.cms.api.hooks.HookSystem; +import com.github.thmarx.cms.api.request.RequestContext; +import com.github.thmarx.cms.api.theme.Theme; +import com.github.thmarx.cms.filesystem.FileSystem; +import java.io.IOException; +import java.nio.file.Path; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +/** + * + * @author t.marx + */ +@ExtendWith(MockitoExtension.class) +public class ExtensionManagerTest { + + @Mock + DB db; + @Mock + Theme theme; + @Mock + ServerProperties properties; + @Mock + FileSystem fileSystem; + + + ExtensionManager extensionManager; + + @BeforeEach + public void setup () throws Exception { + + Mockito.when(fileSystem.resolve("libs/")) + .thenReturn(Path.of("src/test/resources/site/libs")); + Mockito.when(fileSystem.resolve("extensions/")) + .thenReturn(Path.of("src/test/resources/site/extensions")); + Mockito.when(db.getFileSystem()).thenReturn(fileSystem); + Mockito.when(theme.extensionsPath()) + .thenReturn(Path.of("src/test/resources/theme/extensions")); + + extensionManager = new ExtensionManager(db, theme, properties); + extensionManager.init(); + } + + @AfterEach + public void shutdown () throws Exception { + extensionManager.close(); + } + + @Test + public void testSomeMethod() throws IOException { + + var requestContext = new RequestContext(); + final HookSystem hookSystem = new HookSystem(); + requestContext.add(HookSystemFeature.class, new HookSystemFeature(hookSystem)); + extensionManager.newContext(theme, requestContext); + + Assertions.assertThat(hookSystem.call("test").results()) + .hasSize(1) + .containsExactly("hallo") + ; + } + +} diff --git a/cms-extensions/src/test/resources/site/extensions/hook-test.js b/cms-extensions/src/test/resources/site/extensions/hook-test.js new file mode 100644 index 00000000..49b75784 --- /dev/null +++ b/cms-extensions/src/test/resources/site/extensions/hook-test.js @@ -0,0 +1,30 @@ +/*- + * #%L + * cms-extensions + * %% + * Copyright (C) 2023 - 2024 Marx-Software + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +import { $hooks } from 'system/hooks.mjs'; + +$hooks.register( + "test", + (context) => { + return 'hallo' + } +) diff --git a/cms-server/src/main/java/com/github/thmarx/cms/ipc/IPCServer.java b/cms-server/src/main/java/com/github/thmarx/cms/ipc/IPCServer.java index 2f292fbb..44b5a9db 100644 --- a/cms-server/src/main/java/com/github/thmarx/cms/ipc/IPCServer.java +++ b/cms-server/src/main/java/com/github/thmarx/cms/ipc/IPCServer.java @@ -48,7 +48,7 @@ public void run() { new IPCServerThread(serverSocket.accept(), eventConsumer, properties).start(); } } catch (IOException e) { - System.exit(-1); + throw new RuntimeException(e); } } diff --git a/cms-server/src/main/java/com/github/thmarx/cms/request/RequestContextFactory.java b/cms-server/src/main/java/com/github/thmarx/cms/request/RequestContextFactory.java index 4a317622..e3a4ea8f 100644 --- a/cms-server/src/main/java/com/github/thmarx/cms/request/RequestContextFactory.java +++ b/cms-server/src/main/java/com/github/thmarx/cms/request/RequestContextFactory.java @@ -89,39 +89,42 @@ public RequestContext create( var hookSystem = injector.getInstance(HookSystem.class); - RequestExtensions requestExtensions = extensionManager.newContext(theme, hookSystem); - - RenderContext renderContext = new RenderContext( - markdownRenderer, - createShortCodes(requestExtensions), - theme); - - var context = new RequestContext(); - context.add(InjectorFeature.class, new InjectorFeature(injector)); - context.add(HookSystemFeature.class, new HookSystemFeature(hookSystem)); - context.add(RequestFeature.class, new RequestFeature(uri, queryParameters)); - context.add(RequestExtensions.class, requestExtensions); - context.add(ThemeFeature.class, new ThemeFeature(theme)); - context.add(RenderContext.class, renderContext); - context.add(MarkdownRendererFeature.class, new MarkdownRendererFeature(renderContext.markdownRenderer())); - context.add(ContentParserFeature.class, new ContentParserFeature(injector.getInstance(ContentParser.class))); - context.add(ContentNodeMapperFeature.class, new ContentNodeMapperFeature(injector.getInstance(ContentNodeMapper.class))); + var requestContext = new RequestContext(); + requestContext.add(InjectorFeature.class, new InjectorFeature(injector)); + requestContext.add(HookSystemFeature.class, new HookSystemFeature(hookSystem)); + requestContext.add(RequestFeature.class, new RequestFeature(uri, queryParameters)); + requestContext.add(ThemeFeature.class, new ThemeFeature(theme)); + requestContext.add(ContentParserFeature.class, new ContentParserFeature(injector.getInstance(ContentParser.class))); + requestContext.add(ContentNodeMapperFeature.class, new ContentNodeMapperFeature(injector.getInstance(ContentNodeMapper.class))); if (ServerContext.IS_DEV) { - context.add(IsDevModeFeature.class, new IsDevModeFeature()); + requestContext.add(IsDevModeFeature.class, new IsDevModeFeature()); if (queryParameters.containsKey("preview")) { - context.add(IsPreviewFeature.class, new IsPreviewFeature()); + requestContext.add(IsPreviewFeature.class, new IsPreviewFeature()); } } - context.add(ConfigurationFeature.class, new ConfigurationFeature(injector.getInstance(Configuration.class))); - context.add(ServerPropertiesFeature.class, new ServerPropertiesFeature( + requestContext.add(ConfigurationFeature.class, new ConfigurationFeature(injector.getInstance(Configuration.class))); + requestContext.add(ServerPropertiesFeature.class, new ServerPropertiesFeature( injector.getInstance(Configuration.class) .get(ServerConfiguration.class).serverProperties() )); - context.add(SitePropertiesFeature.class, new SitePropertiesFeature(siteProperties)); - context.add(SiteMediaServiceFeature.class, new SiteMediaServiceFeature(siteMediaService)); + requestContext.add(SitePropertiesFeature.class, new SitePropertiesFeature(siteProperties)); + requestContext.add(SiteMediaServiceFeature.class, new SiteMediaServiceFeature(siteMediaService)); + + RequestExtensions requestExtensions = extensionManager.newContext(theme, requestContext); + + RenderContext renderContext = new RenderContext( + markdownRenderer, + createShortCodes(requestExtensions), + theme); + requestContext.add(RenderContext.class, renderContext); + requestContext.add(MarkdownRendererFeature.class, new MarkdownRendererFeature(renderContext.markdownRenderer())); + + + requestContext.add(RequestExtensions.class, requestExtensions); + - return context; + return requestContext; } private ShortCodes createShortCodes (RequestExtensions requestExtensions) { diff --git a/cms-server/src/main/resources/log4j2.xml b/cms-server/src/main/resources/log4j2.xml index 7419710f..8ac6feef 100644 --- a/cms-server/src/main/resources/log4j2.xml +++ b/cms-server/src/main/resources/log4j2.xml @@ -62,10 +62,10 @@ - + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 1d383734..1add8819 100644 --- a/pom.xml +++ b/pom.xml @@ -132,12 +132,12 @@ org.graalvm.polyglot polyglot - 24.0.0 + 24.0.1 org.graalvm.js js-language - 24.0.0 + 24.0.1 org.apache.logging.log4j