/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.ht.data.script;

import java.util.logging.Logger;

import javax.script.Invocable;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

/**
 *
 * @author Administrator
 */
public enum ScriptUtil {

    INSTANCE;
    private final Logger log = Logger.getLogger(ScriptUtil.class.getName());
    private ScriptEngine engine = null;
    private final String SCRIPT_NAME = "ECMAScript";

    private ScriptUtil() {
        ScriptEngineManager engineMgr = new ScriptEngineManager();
        engine = engineMgr.getEngineByName(SCRIPT_NAME);
        if (engine == null) {
            log.severe("Can not initialize ECMAScript engine!");
        }
    }

    public Invocable evalScript(String scripts) throws ScriptException {
        Object ret = engine.eval(scripts);
        if (ret != null) {
            log.warning("Following is returned by eval :");
            log.warning(ret.toString());
        }

        if (!(engine instanceof Invocable)) {
            log.severe("eval error");
            throw new ScriptException("Engine does not support Invocable interface!");
        }

        return (Invocable) engine;
    }

    public Object invokeFunction(String script, String name, Object[] args) throws ScriptException, NoSuchMethodException {
        // 设置全局变量
        for (int i = 0; i < args.length; i++) {
            engine.getContext().setAttribute("v".concat(Integer.toString(i + 1)), args[i], ScriptContext.ENGINE_SCOPE);
        }

        return this.evalScript(script).invokeFunction(name);
    }

//    /**
//     * 执行编译过的脚本
//     *
//     * @param script
//     * @param args
//     * @return
//     * @throws ScriptException
//     */
//    public Object evalExpression(CompiledScript script, Object[] args) throws ScriptException {
//        ScriptContext context = new SimpleScriptContext();
//        // 设置全局变量
//        for (int i = 0; i < args.length; i++) {
//            //engine.getContext().setAttribute("v".concat(Integer.toString(i + 1)),  args[i], ScriptContext.ENGINE_SCOPE);
//            context.setAttribute("v".concat(Integer.toString(i + 1)), args[i], ScriptContext.ENGINE_SCOPE);
//        }
//        return script.eval(context);
//    }

    public ScriptEngine getEngine() {
        return engine;
    }
}
