GraalJS now uses automation/js (#11719)

* GraalJS now uses automation/js

Signed-off-by: Jonathan Gilbert <jpg@trillica.com>
This commit is contained in:
Jonathan Gilbert 2021-12-12 22:06:37 +00:00 committed by GitHub
parent 5d52435dea
commit 306c30eda1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 143 additions and 12 deletions

View 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);
}

View File

@ -10,12 +10,10 @@
*
* 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

View File

@ -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();
}
}

View File

@ -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);
}
});
}
}