GraalJS now uses automation/js (#11719)
* GraalJS now uses automation/js Signed-off-by: Jonathan Gilbert <jpg@trillica.com>
This commit is contained in:
@@ -22,8 +22,6 @@ import javax.script.ScriptEngine;
|
|||||||
import org.openhab.core.automation.module.script.ScriptEngineFactory;
|
import org.openhab.core.automation.module.script.ScriptEngineFactory;
|
||||||
import org.osgi.service.component.annotations.Component;
|
import org.osgi.service.component.annotations.Component;
|
||||||
|
|
||||||
import com.oracle.truffle.js.scriptengine.GraalJSEngineFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An implementation of {@link ScriptEngineFactory} with customizations for GraalJS ScriptEngines.
|
* 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)
|
@Component(service = ScriptEngineFactory.class)
|
||||||
public final class GraalJSScriptEngineFactory implements ScriptEngineFactory {
|
public final class GraalJSScriptEngineFactory implements ScriptEngineFactory {
|
||||||
|
|
||||||
|
public static final String MIME_TYPE = "application/javascript;version=ECMAScript-2021";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getScriptTypes() {
|
public List<String> getScriptTypes() {
|
||||||
List<String> scriptTypes = new ArrayList<>();
|
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);
|
return Collections.unmodifiableList(scriptTypes);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,12 +10,10 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.openhab.automation.jsscripting.internal;
|
package org.openhab.automation.jsscripting.internal;
|
||||||
|
|
||||||
import static org.openhab.core.automation.module.script.ScriptEngineFactory.*;
|
import static org.openhab.core.automation.module.script.ScriptEngineFactory.*;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.channels.SeekableByteChannel;
|
import java.nio.channels.SeekableByteChannel;
|
||||||
import java.nio.file.FileSystems;
|
import java.nio.file.FileSystems;
|
||||||
@@ -33,8 +31,8 @@ import org.graalvm.polyglot.Context;
|
|||||||
import org.graalvm.polyglot.Engine;
|
import org.graalvm.polyglot.Engine;
|
||||||
import org.openhab.automation.jsscripting.internal.fs.DelegatingFileSystem;
|
import org.openhab.automation.jsscripting.internal.fs.DelegatingFileSystem;
|
||||||
import org.openhab.automation.jsscripting.internal.fs.PrefixedSeekableByteChannel;
|
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.automation.jsscripting.internal.scriptengine.InvocationInterceptingScriptEngineWithInvocable;
|
||||||
import org.openhab.core.OpenHAB;
|
|
||||||
import org.openhab.core.automation.module.script.ScriptExtensionAccessor;
|
import org.openhab.core.automation.module.script.ScriptExtensionAccessor;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
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 Logger LOGGER = LoggerFactory.getLogger(OpenhabGraalJSScriptEngine.class);
|
||||||
|
|
||||||
private static final String REQUIRE_WRAPPER_NAME = "__wraprequire__";
|
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
|
// these fields start as null because they are populated on first use
|
||||||
private @NonNullByDefault({}) String engineIdentifier;
|
private @NonNullByDefault({}) String engineIdentifier;
|
||||||
@@ -70,7 +66,8 @@ public class OpenhabGraalJSScriptEngine extends InvocationInterceptingScriptEngi
|
|||||||
Engine.newBuilder().allowExperimentalOptions(true).option("engine.WarnInterpreterOnly", "false")
|
Engine.newBuilder().allowExperimentalOptions(true).option("engine.WarnInterpreterOnly", "false")
|
||||||
.build(),
|
.build(),
|
||||||
Context.newBuilder("js").allowExperimentalOptions(true).allowAllAccess(true)
|
Context.newBuilder("js").allowExperimentalOptions(true).allowAllAccess(true)
|
||||||
.option("js.commonjs-require-cwd", MODULE_DIR).option("js.nashorn-compat", "true") // to ease
|
.option("js.commonjs-require-cwd", JSDependencyTracker.LIB_PATH)
|
||||||
|
.option("js.nashorn-compat", "true") // to ease
|
||||||
// migration
|
// migration
|
||||||
.option("js.ecmascript-version", "2021") // nashorn compat will enforce es5 compatibility, we
|
.option("js.ecmascript-version", "2021") // nashorn compat will enforce es5 compatibility, we
|
||||||
// want ecma2021
|
// want ecma2021
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user