Skip to content

Commit

Permalink
[jsscripting] Support non unix file paths (openhab#11805)
Browse files Browse the repository at this point in the history
Lets try this again, Fixes openhab#11801

Signed-off-by: Dan Cunningham <[email protected]>
Signed-off-by: Andras Uhrin <[email protected]>
  • Loading branch information
digitaldan authored and andrasU committed Nov 12, 2022
1 parent 4d57848 commit 6a7636e
Showing 1 changed file with 28 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

import static org.openhab.core.automation.module.script.ScriptEngineFactory.*;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.channels.SeekableByteChannel;
Expand Down Expand Up @@ -66,7 +65,7 @@ public class OpenhabGraalJSScriptEngine extends InvocationInterceptingScriptEngi
private static final String GLOBAL_REQUIRE = "require(\"@jsscripting-globals\");";
private static final String REQUIRE_WRAPPER_NAME = "__wraprequire__";
// final CommonJS search path for our library
private static final Path LOCAL_NODE_PATH = Paths.get(File.separator + "node_modules");
private static final Path NODE_DIR = Paths.get("node_modules");

// these fields start as null because they are populated on first use
private @NonNullByDefault({}) String engineIdentifier;
Expand Down Expand Up @@ -116,10 +115,11 @@ public SeekableByteChannel newByteChannel(Path path, Set<? extends OpenOption> o
if (scriptDependencyListener != null) {
scriptDependencyListener.accept(path.toString());
}

if (path.toString().endsWith(".js")) {
SeekableByteChannel sbc = null;
if (path.startsWith(LOCAL_NODE_PATH)) {
InputStream is = getClass().getResourceAsStream(path.toString());
if (isRootNodePath(path)) {
InputStream is = getClass().getResourceAsStream(nodeFileToResource(path));
if (is == null) {
throw new IOException("Could not read " + path.toString());
}
Expand All @@ -137,8 +137,8 @@ public SeekableByteChannel newByteChannel(Path path, Set<? extends OpenOption> o
@Override
public void checkAccess(Path path, Set<? extends AccessMode> modes,
LinkOption... linkOptions) throws IOException {
if (path.startsWith(LOCAL_NODE_PATH)) {
if (getClass().getResource(path.toString()) == null) {
if (isRootNodePath(path)) {
if (getClass().getResource(nodeFileToResource(path)) == null) {
throw new NoSuchFileException(path.toString());
}
} else {
Expand All @@ -149,15 +149,15 @@ public void checkAccess(Path path, Set<? extends AccessMode> modes,
@Override
public Map<String, Object> readAttributes(Path path, String attributes,
LinkOption... options) throws IOException {
if (path.startsWith(LOCAL_NODE_PATH)) {
if (isRootNodePath(path)) {
return Collections.singletonMap("isRegularFile", true);
}
return super.readAttributes(path, attributes, options);
}

@Override
public Path toRealPath(Path path, LinkOption... linkOptions) throws IOException {
if (path.startsWith(LOCAL_NODE_PATH)) {
if (isRootNodePath(path)) {
return path;
}
return super.toRealPath(path, linkOptions);
Expand Down Expand Up @@ -210,4 +210,24 @@ protected void beforeInvocation() {
LOGGER.error("Could not inject global script", e);
}
}

/**
* Tests if this is a root node directory, `/node_modules`, `C:\node_modules`, etc...
*
* @param path
* @return
*/
private boolean isRootNodePath(Path path) {
return path.startsWith(path.getRoot().resolve(NODE_DIR));
}

/**
* Converts a root node path to a class resource path for loading local modules
*
* @param path
* @return
*/
private String nodeFileToResource(Path path) {
return "/" + NODE_DIR + "/" + path.getFileName();
}
}

0 comments on commit 6a7636e

Please sign in to comment.