All Downloads are FREE. Search and download functionalities are using the official Maven repository.

wrp.jdk.nashorn.api.scripting.NashornScriptEngineUtil Maven / Gradle / Ivy

The newest version!
package wrp.jdk.nashorn.api.scripting;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bdware.doip.cluster.callback.AsyncJSResultCallback;
import org.bdware.doip.cluster.engine.DigestUtil;
import org.bdware.doip.cluster.engine.DoaClientUtil;
import org.bdware.doip.cluster.engine.DoipMessageUtil;
import org.bdware.doip.cluster.engine.IdentifierUtil;
import org.bdware.doip.cluster.entity.DDOEntity;
import org.bdware.doip.cluster.util.JSONTool;
import org.bdware.sc.util.JsonUtil;
import wrp.jdk.nashorn.internal.objects.Global;
import wrp.jdk.nashorn.internal.runtime.Context;
import wrp.jdk.nashorn.internal.runtime.ScriptFunction;
import wrp.jdk.nashorn.internal.runtime.ScriptRuntime;

import javax.script.Bindings;
import javax.script.ScriptException;
import java.net.URL;
import java.net.URLClassLoader;

public class NashornScriptEngineUtil {
    public NashornScriptEngine engine;
    public Bindings functionBindings;

    public IdentifierUtil doipClusterUtil;

    public NashornScriptEngineUtil(DDOEntity ddoInfo) {
        String[] args = new String[]{"--loader-per-compile=false", "-strict=false"};
        ClassLoader cl = new URLClassLoader(new URL[]{}, NashornScriptEngineFactory.class.getClassLoader());
        engine = (NashornScriptEngine)
                new NashornScriptEngineFactory()
                        .getScriptEngine(
                                args, // "--print-ast",
                                // "true",
                                // "-d=/Users/huaqiancai/Downloads/dumpedClz",
                                // "--trace-callsites=enterexit"
                                // "--log=methodhandles:all",
                                // fields:all,
                                // "--print-parse", "true" "--print-code",
                                // fields:finest
                                cl);
        functionBindings = engine.createBindings();
        doipClusterUtil = new IdentifierUtil(ddoInfo);
        functionBindings.put("IdentifierUtil", doipClusterUtil);
        functionBindings.put("DigestUtil", new DigestUtil());
        functionBindings.put("DoipMessageUtil", new DoipMessageUtil(this));
        functionBindings.put("DoaClient", new DoaClientUtil(ddoInfo.getDoaClient()));
        functionBindings.put("JsonUtil", new org.bdware.doip.cluster.engine.JsonUtil());

        try {
            registerAccessRuleFunctionsToEngineUtil(ddoInfo.getAccessRules());
        } catch (ScriptException e) {
            e.printStackTrace();
        }
    }

    public void registerAccessRuleFunctionsToEngineUtil(JsonObject bcoAccessRules) throws ScriptException {
        JsonElement functions = bcoAccessRules.get("functions");
        if (functions != null && !functions.isJsonNull() && functions.isJsonObject()) {
            JsonObject functionsObj = functions.getAsJsonObject();
            for (String funcName : functionsObj.keySet()) {
                String funcScript = functionsObj.get(funcName).getAsString();
                evalFunction(funcScript);
            }
        }
    }

    public void evalFunction(String funcScript) throws ScriptException {
        engine.eval(funcScript, functionBindings);
    }

    public  T invokeFunction(String funcName, Class t, JsonElement... args) throws ScriptException, NoSuchMethodException {
        assert args != null;
        int length = args.length;
        Object[] funcArgs = new Object[length];
        Object scriptRes = null;
        // synchronize(全局只有一个线程能走完54~60) -> 两个线程同时执行到Global的时候,前一个会被后面的替换掉,导致出现问题
        synchronized (NashornScriptEngineUtil.class) {
            Global previousGlobal = Context.getGlobal();
            Global newGlobal = ((ScriptObjectMirror) functionBindings).getHomeGlobal();
            boolean globalChanged = (previousGlobal != newGlobal);
            if (globalChanged)
                Context.setGlobal(newGlobal);
            try {
                for (int i = 0; i < length; i++) {
                    funcArgs[i] = JSONTool.convertJsonElementToMirror(args[i]);
                }

                scriptRes = engine.invokeMethod(functionBindings, funcName, funcArgs);
                scriptRes = JSONTool.convertMirrorToJson(scriptRes);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (globalChanged) Context.setGlobal(previousGlobal);
            }

        }
        String engineRes = JsonUtil.toJson(scriptRes);
        return JsonUtil.fromJson(engineRes, t);
    }

//    public  T invokeFunctionWithObject(String funcName, Class t, Object... args) throws ScriptException, NoSuchMethodException {
//        assert args != null;
//        Object scriptRes = null;
//        // synchronize(全局只有一个线程能走完54~60) -> 两个线程同时执行到Global的时候,前一个会被后面的替换掉,导致出现问题
//        synchronized (NashornScriptEngineUtil.class) {
//            Global previousGlobal = Context.getGlobal();
//            Context.setGlobal(((ScriptObjectMirror) functionBindings).getHomeGlobal());
//            scriptRes = engine.invokeMethod(functionBindings, funcName, args);
//            Context.setGlobal(previousGlobal);
//        }
//        return JsonUtil.fromJson((JsonElement) scriptRes, t);
//    }

    //    public  void invokeFunctionAsync(String funcName, RouteResultCallback rcb, JsonElement... args) throws ScriptException, NoSuchMethodException {
//        assert args != null;
//        int length = args.length;
//        Object[] funcArgs = new Object[length + 1];
//        // synchronize(全局只有一个线程能走完54~60) -> 两个线程同时执行到Global的时候,前一个会被后面的替换掉,导致出现问题
//        synchronized (NashornScriptEngineUtil.class) {
//            Global previousGlobal = Context.getGlobal();
//            Context.setGlobal(((ScriptObjectMirror) functionBindings).getHomeGlobal());
//            for (int i = 0; i < length; i++) {
//                funcArgs[i] = JSONTool.convertJsonElementToMirror(args[i]);
//            }
//            funcArgs[length] = rcb;
//            engine.invokeMethod(functionBindings, funcName, funcArgs);
//            Context.setGlobal(previousGlobal);
//        }
//    }
    static Logger LOGGER = LogManager.getLogger(NashornScriptEngineUtil.class);

    public  void invokeFunctionWithObjectAsync(String funcName, AsyncJSResultCallback rcb, Object... args) throws ScriptException, NoSuchMethodException {
        assert args != null;
        int length = args.length;
        Object[] funcArgs = new Object[length + 1];
        // synchronize(全局只有一个线程能走完54~60) -> 两个线程同时执行到Global的时候,前一个会被后面的替换掉,导致出现问题
        synchronized (NashornScriptEngineUtil.class) {
            Global previousGlobal = Context.getGlobal();
            Global newGlobal = ((ScriptObjectMirror) functionBindings).getHomeGlobal();
            boolean globalChanged = (previousGlobal != newGlobal);
            if (globalChanged)
                Context.setGlobal(newGlobal);
            try {
                System.arraycopy(args, 0, funcArgs, 0, args.length);
                funcArgs[length] = rcb;
                engine.invokeMethod(functionBindings, funcName, funcArgs);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (globalChanged)
                    Context.setGlobal(previousGlobal);
            }
        }
    }


//    public  T invokeFunction(ScriptFunction scriptFunction, Class t, JsonElement... params) {
//        synchronized (NashornScriptEngineUtil.class) {
//            Global previousGlobal = Context.getGlobal();
//            Global newGlobal = ((ScriptObjectMirror) functionBindings).getHomeGlobal();
//            boolean globalChanged = (previousGlobal != newGlobal);
//            if (globalChanged)
//                Context.setGlobal(((ScriptObjectMirror) functionBindings).getHomeGlobal());
//            Object[] funcArgs = new Object[params.length];
//            for (int i = 0; i < params.length; i++) {
//                funcArgs[i] = JSONTool.convertJsonElementToMirror(params[i]);
//            }
//            Object result = ScriptRuntime.apply(scriptFunction, ((ScriptObjectMirror) functionBindings).getHomeGlobal(), funcArgs);
//            result = JSONTool.convertMirrorToJson(result);
//            Context.setGlobal(previousGlobal);
//            String resultStr = JsonUtil.toJson(result);
//            return JsonUtil.fromJson(resultStr, t);
//        }
//    }

    public Object invokeFunctionWithObject(ScriptFunction scriptFunction, Object... params) {
        synchronized (NashornScriptEngineUtil.class) {
            Global previousGlobal = Context.getGlobal();
            Global newGlobal = ((ScriptObjectMirror) functionBindings).getHomeGlobal();
            boolean globalChanged = (previousGlobal != newGlobal);
            try {
                if (globalChanged)
                    Context.setGlobal(newGlobal);
                Object result = ScriptRuntime.apply(scriptFunction, ((ScriptObjectMirror) functionBindings).getHomeGlobal(), params);
                return result;
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            } finally {
                if (globalChanged && previousGlobal != null)
                    Context.setGlobal(previousGlobal);
            }
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy