Files
JStom/src/main/java/net/jstom/script/ScriptManager.java
2026-01-25 22:49:51 +00:00

105 lines
2.9 KiB
Java

package net.jstom.script;
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.HostAccess;
import org.graalvm.polyglot.Source;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class ScriptManager {
private final File scriptsDir;
private final Map<String, ScriptEnv> loadedScripts = new HashMap<>();
public ScriptManager(File scriptsDir) {
this.scriptsDir = scriptsDir;
}
public void load() {
if (!scriptsDir.exists()) {
scriptsDir.mkdirs();
}
File[] files = scriptsDir.listFiles((dir, name) -> name.endsWith(".js"));
if (files != null) {
for (File file : files) {
loadScript(file);
}
}
}
public void loadScript(File file) {
String fileName = file.getName();
unloadScript(fileName); // Ensure clean slate if reloading
System.out.println("[JStom] Loading script: " + fileName);
ScriptApi api = new ScriptApi();
Context context = Context.newBuilder("js")
.allowHostAccess(HostAccess.ALL)
.allowHostClassLookup(s -> true)
.allowIO(true)
.build();
context.getBindings("js").putMember("server", api);
try {
context.eval(Source.newBuilder("js", file).build());
loadedScripts.put(fileName, new ScriptEnv(context, api, file));
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
System.err.println("[JStom] Error executing script " + fileName);
e.printStackTrace();
// Cleanup if failed
api.cleanup();
context.close();
}
}
public void unloadScript(String fileName) {
ScriptEnv env = loadedScripts.remove(fileName);
if (env != null) {
env.api.cleanup();
env.context.close();
System.out.println("[JStom] Unloaded script: " + fileName);
}
}
public void unload() {
// Copy keys to avoid ConcurrentModificationException
for (String fileName : new java.util.ArrayList<>(loadedScripts.keySet())) {
unloadScript(fileName);
}
}
public void reload() {
unload();
load();
}
public void reload(String fileName) {
File file = new File(scriptsDir, fileName);
if (file.exists()) {
loadScript(file);
} else {
System.err.println("[JStom] File not found: " + fileName);
}
}
private static class ScriptEnv {
final Context context;
final ScriptApi api;
final File file;
public ScriptEnv(Context context, ScriptApi api, File file) {
this.context = context;
this.api = api;
this.file = file;
}
}
}