![JAR search and dependency download from the Maven repository](/logo.png)
com.gitee.beiding.template_excel.Js Maven / Gradle / Ivy
package com.gitee.beiding.template_excel;
import javax.script.*;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class Js {
private static class JsHolder {
private ScriptEngine engine;
private Bindings bindings;
}
private static List functions = new ArrayList<>();
private static List initializedFunctions;
private static ThreadLocal jsHolderThreadLocal = new ThreadLocal<>();
//创建定长的队列
private static BlockingQueue jsHolders = new ArrayBlockingQueue<>(Config.getCoreJsWorkerNumber());
//在每次执行完成之后使用该方法Js
static void recycle() {
JsHolder jsHolder = jsHolderThreadLocal.get();
if (jsHolder != null) {
jsHolders.offer(jsHolder);
jsHolderThreadLocal.remove();
}
}
private static JsHolder init() {
JsHolder jsHolder = jsHolderThreadLocal.get();
if (jsHolder == null) {
jsHolder = jsHolders.poll();
if (jsHolder == null) {
if (initializedFunctions == null) {
synchronized (Js.class) {
if (initializedFunctions == null) {
initializedFunctions = functions;
}
}
}
//放入线程占位
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
Bindings bindings = engine.getBindings(ScriptContext.GLOBAL_SCOPE);
jsHolder = new JsHolder();
jsHolder.engine = engine;
jsHolder.bindings = bindings;
jsHolderThreadLocal.set(jsHolder);
//初始化脚本
try {
set("console", new Console());
set("_java", new Java());
InputStream stream = Js.class.getClassLoader().getResource("init.js").openConnection().getInputStream();
String read = FileUtils.read(stream);
engine.eval(read);
for (String function : initializedFunctions) {
exe(function);
}
} catch (Exception e) {
throw new Error(e);
}
} else {
//绑定值
jsHolderThreadLocal.set(jsHolder);
}
}
return jsHolder;
}
//不能直接执行某些代码,防止引擎内部声明污染
static Object exe(String js) throws ScriptException {
try {
// System.out.println(js);
return init().engine.eval(js);
} catch (Exception e) {
throw e;
}
}
public static void defineCommand(String s) {
synchronized (Js.class) {
if (functions == null) {
throw new RuntimeException("请在Js使用前定义函数");
}
}
String d1 = s.trim();
if (!d1.startsWith("function")) {
throw new RuntimeException("指令定义无效,必须以function开头");
}
String d2 = d1.substring(8).trim();
System.out.println(d2);
if (!d2.startsWith("$")) {
throw new RuntimeException("指令名称必须以'$'开头");
}
functions.add(s);
}
public static Object call(String method, Object... p) {
try {
return ((Invocable) init().engine).invokeFunction(method, p);
} catch (ScriptException | NoSuchMethodException e) {
e.printStackTrace();
return null;
}
}
public static Object set(String k, Object v) {
return init().bindings.put(k, v);
}
public static Object put(String k, Object v) {
return init().bindings.put(k, v);
}
/**
* 由于引擎是线程隔离的,调用该方法定义的函数只对晚于调用该方法初始化的引擎才是有效的
*
* @param s 定义的函数
*/
//定义一个函数
public static void defineFunction(String s) {
synchronized (Js.class) {
if (functions == null) {
throw new RuntimeException("请在Js使用前定义函数");
}
}
String d1 = s.trim();
if (!d1.startsWith("function")) {
throw new RuntimeException("指令定义无效,必须以function开头");
}
String d2 = d1.trim();
if (d2.startsWith("$")) {
throw new RuntimeException("函数名称不能以'$'开头");
}
functions.add(FunctionUtils.handleCacheableFunction(s));
}
public static Object remove(String k) {
return init().bindings.remove(k);
}
public static Object get(String k) {
return init().bindings.get(k);
}
public static void putAll(Map all) {
init().bindings.putAll(all);
}
//提供控制台相关的功能
public static class Console {
public void log(String obj) {
System.out.println(call("objToString", obj));
}
public void log() {
System.out.println();
}
}
//提供缓存操作
private static class CacheTree {
private static class Node {
private Map
© 2015 - 2025 Weber Informatics LLC | Privacy Policy