]> git.basschouten.com Git - openhab-addons.git/commitdiff
GraalJS now uses automation/js (#11719)
authorJonathan Gilbert <jpg@trillica.com>
Sun, 12 Dec 2021 22:06:37 +0000 (22:06 +0000)
committerGitHub <noreply@github.com>
Sun, 12 Dec 2021 22:06:37 +0000 (23:06 +0100)
* GraalJS now uses automation/js

Signed-off-by: Jonathan Gilbert <jpg@trillica.com>
bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/GraalJSScriptEngineFactory.java
bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java
bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/fs/watch/JSDependencyTracker.java [new file with mode: 0644]
bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/fs/watch/JSScriptFileWatcher.java [new file with mode: 0644]

index 14e9f783e8348684e9cbf94bf8a972051402b5ed..d6b98efeb73829ec98612241ee46e90af87569c2 100644 (file)
@@ -22,8 +22,6 @@ import javax.script.ScriptEngine;
 import org.openhab.core.automation.module.script.ScriptEngineFactory;
 import org.osgi.service.component.annotations.Component;
 
-import com.oracle.truffle.js.scriptengine.GraalJSEngineFactory;
-
 /**
  * An implementation of {@link ScriptEngineFactory} with customizations for GraalJS ScriptEngines.
  *
@@ -32,13 +30,24 @@ import com.oracle.truffle.js.scriptengine.GraalJSEngineFactory;
 @Component(service = ScriptEngineFactory.class)
 public final class GraalJSScriptEngineFactory implements ScriptEngineFactory {
 
+    public static final String MIME_TYPE = "application/javascript;version=ECMAScript-2021";
+
     @Override
     public List<String> getScriptTypes() {
         List<String> scriptTypes = new ArrayList<>();
-        GraalJSEngineFactory graalJSEngineFactory = new GraalJSEngineFactory();
 
-        scriptTypes.addAll(graalJSEngineFactory.getMimeTypes());
-        scriptTypes.addAll(graalJSEngineFactory.getExtensions());
+        /*
+         * Whilst we run in parallel with Nashorn, we use a custom mime-type to avoid
+         * disrupting Nashorn scripts. When Nashorn is removed, we take over the standard
+         * JS runtime.
+         */
+
+        // GraalJSEngineFactory graalJSEngineFactory = new GraalJSEngineFactory();
+        //
+        // scriptTypes.addAll(graalJSEngineFactory.getMimeTypes());
+        // scriptTypes.addAll(graalJSEngineFactory.getExtensions());
+
+        scriptTypes.add(MIME_TYPE);
 
         return Collections.unmodifiableList(scriptTypes);
     }
index 9f29b0d99d2c768072a1ec1e4ec6c725f3e91f72..6621d5d1a157833287d13d1522530374022aaeff 100644 (file)
  *
  * SPDX-License-Identifier: EPL-2.0
  */
-
 package org.openhab.automation.jsscripting.internal;
 
 import static org.openhab.core.automation.module.script.ScriptEngineFactory.*;
 
-import java.io.File;
 import java.io.IOException;
 import java.nio.channels.SeekableByteChannel;
 import java.nio.file.FileSystems;
@@ -33,8 +31,8 @@ import org.graalvm.polyglot.Context;
 import org.graalvm.polyglot.Engine;
 import org.openhab.automation.jsscripting.internal.fs.DelegatingFileSystem;
 import org.openhab.automation.jsscripting.internal.fs.PrefixedSeekableByteChannel;
+import org.openhab.automation.jsscripting.internal.fs.watch.JSDependencyTracker;
 import org.openhab.automation.jsscripting.internal.scriptengine.InvocationInterceptingScriptEngineWithInvocable;
-import org.openhab.core.OpenHAB;
 import org.openhab.core.automation.module.script.ScriptExtensionAccessor;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -51,8 +49,6 @@ public class OpenhabGraalJSScriptEngine extends InvocationInterceptingScriptEngi
     private static final Logger LOGGER = LoggerFactory.getLogger(OpenhabGraalJSScriptEngine.class);
 
     private static final String REQUIRE_WRAPPER_NAME = "__wraprequire__";
-    private static final String MODULE_DIR = String.join(File.separator, OpenHAB.getConfigFolder(), "automation", "lib",
-            "javascript", "personal");
 
     // these fields start as null because they are populated on first use
     private @NonNullByDefault({}) String engineIdentifier;
@@ -70,8 +66,9 @@ public class OpenhabGraalJSScriptEngine extends InvocationInterceptingScriptEngi
                 Engine.newBuilder().allowExperimentalOptions(true).option("engine.WarnInterpreterOnly", "false")
                         .build(),
                 Context.newBuilder("js").allowExperimentalOptions(true).allowAllAccess(true)
-                        .option("js.commonjs-require-cwd", MODULE_DIR).option("js.nashorn-compat", "true") // to ease
-                                                                                                           // migration
+                        .option("js.commonjs-require-cwd", JSDependencyTracker.LIB_PATH)
+                        .option("js.nashorn-compat", "true") // to ease
+                        // migration
                         .option("js.ecmascript-version", "2021") // nashorn compat will enforce es5 compatibility, we
                                                                  // want ecma2021
                         .option("js.commonjs-require", "true") // enable CommonJS module support
diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/fs/watch/JSDependencyTracker.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/fs/watch/JSDependencyTracker.java
new file mode 100644 (file)
index 0000000..aed75a0
--- /dev/null
@@ -0,0 +1,60 @@
+/**
+ * Copyright (c) 2010-2021 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.automation.jsscripting.internal.fs.watch;
+
+import java.io.File;
+
+import org.openhab.core.OpenHAB;
+import org.openhab.core.automation.module.script.rulesupport.loader.DependencyTracker;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Tracks JS module dependencies
+ *
+ * @author Jonathan Gilbert - Initial contribution
+ */
+@Component(immediate = true, service = JSDependencyTracker.class)
+public class JSDependencyTracker extends DependencyTracker {
+
+    private final Logger logger = LoggerFactory.getLogger(JSDependencyTracker.class);
+
+    public static final String LIB_PATH = String.join(File.separator, OpenHAB.getConfigFolder(), "automation", "js",
+            "node_modules");
+
+    public JSDependencyTracker() {
+        super(LIB_PATH);
+    }
+
+    @Activate
+    public void activate() {
+        File directory = new File(LIB_PATH);
+        if (!directory.exists()) {
+            if (!directory.mkdirs()) {
+                logger.warn("Failed to create watched directory: {}", LIB_PATH);
+            }
+        } else if (directory.isFile()) {
+            logger.warn("Trying to watch directory {}, however it is a file", LIB_PATH);
+        }
+
+        super.activate();
+    }
+
+    @Deactivate
+    public void deactivate() {
+        super.deactivate();
+    }
+}
diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/fs/watch/JSScriptFileWatcher.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/fs/watch/JSScriptFileWatcher.java
new file mode 100644 (file)
index 0000000..39dca7f
--- /dev/null
@@ -0,0 +1,65 @@
+/**
+ * Copyright (c) 2010-2021 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.automation.jsscripting.internal.fs.watch;
+
+import java.io.File;
+import java.util.Optional;
+
+import org.openhab.automation.jsscripting.internal.GraalJSScriptEngineFactory;
+import org.openhab.core.automation.module.script.ScriptEngineManager;
+import org.openhab.core.automation.module.script.rulesupport.loader.ScriptFileReference;
+import org.openhab.core.automation.module.script.rulesupport.loader.ScriptFileWatcher;
+import org.openhab.core.service.ReadyService;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Reference;
+
+/**
+ * Monitors <openHAB-conf>/automation/js for Javascript files
+ *
+ * @author Jonathan Gilbert - Initial contribution
+ */
+@Component(immediate = true)
+public class JSScriptFileWatcher extends ScriptFileWatcher {
+    private static final String FILE_DIRECTORY = "automation" + File.separator + "js";
+
+    @Activate
+    public JSScriptFileWatcher(final @Reference ScriptEngineManager manager, final @Reference ReadyService readyService,
+            final @Reference JSDependencyTracker jsDependencyTracker) {
+        super(manager, jsDependencyTracker, readyService, FILE_DIRECTORY);
+    }
+
+    @Activate
+    @Override
+    public void activate() {
+        super.activate();
+    }
+
+    @Deactivate
+    @Override
+    public void deactivate() {
+        super.deactivate();
+    }
+
+    @Override
+    protected boolean createAndLoad(ScriptFileReference ref) {
+        return super.createAndLoad(new ScriptFileReference(ref.getScriptFileURL()) {
+            @Override
+            public Optional<String> getScriptType() {
+                assert super.getScriptType().get().equalsIgnoreCase("js");
+                return Optional.of(GraalJSScriptEngineFactory.MIME_TYPE);
+            }
+        });
+    }
+}