Skip to content

Commit

Permalink
GraalJS now uses automation/js (openhab#11719)
Browse files Browse the repository at this point in the history
* GraalJS now uses automation/js

Signed-off-by: Jonathan Gilbert <[email protected]>
  • Loading branch information
jpg0 authored and andan67 committed Nov 5, 2022
1 parent 4ca5931 commit caae6b0
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@
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.
*
Expand All @@ -32,13 +30,24 @@
@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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -33,8 +31,8 @@
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;
Expand All @@ -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;
Expand All @@ -70,8 +66,9 @@ public OpenhabGraalJSScriptEngine() {
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
Expand Down
Original file line number Diff line number Diff line change
@@ -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();
}
}
Original file line number Diff line number Diff line change
@@ -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);
}
});
}
}

0 comments on commit caae6b0

Please sign in to comment.