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

org.zodiac.script.engine.common.CommonScriptEngine Maven / Gradle / Ivy

package org.zodiac.script.engine.common;

import org.zodiac.script.engine.ExecuteResult;
import org.zodiac.script.engine.ListenerSupportEngine;
import org.zodiac.script.engine.ScriptListener;
import org.zodiac.sdk.toolkit.crypto.Md5;
import org.zodiac.sdk.toolkit.util.SystemClock;
import org.zodiac.sdk.toolkit.util.collection.CollUtil;
import org.zodiac.sdk.toolkit.util.lang.ArrayUtil;
import org.zodiac.sdk.toolkit.util.lang.ObjUtil;

import java.util.List;
import java.util.Map;

import javax.script.Bindings;
import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.script.SimpleScriptContext;

public abstract class CommonScriptEngine extends ListenerSupportEngine {

    /*编译器。*/
    protected Compilable compilable;
    /*脚本库。*/
    protected Map scriptBase = CollUtil.concurrentMap();

    protected Bindings utilBindings;

    protected List scriptListeners;

    protected CommonScriptEngine() {
        try {
            init();
        } catch (Exception e) {
            logger.warn("Init {} error", getScriptEngineName());
        }
    }

    @Override
    public boolean compiled(String id) {
        return scriptBase.containsKey(id);
    }

    @Override
    public boolean remove(String id) {
        return scriptBase.remove(id) != null;
    }

    @Override
    public void init(String... contents) throws Exception {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName(getScriptEngineName());
        compilable = (Compilable)engine;
        utilBindings = engine.createBindings();
        CompiledScript script;
        if (ArrayUtil.isNotEmptyArray(contents)) {
            for (String content : contents) {
                script = compilable.compile(content);
                script.eval(utilBindings);
            }
        }
        // scriptBase.clear();
    }

    @Override
    public org.zodiac.script.engine.ScriptContext getContext(String id) {
        return scriptBase.get(id);
    }

    @Override
    public boolean compile(String id, String code) throws Exception {
        if (logger.isDebugEnabled()) {
            logger.debug("Compile {} {} : {}", getScriptEngineName(), id, code);
        }
        if (compilable == null)
            init();
        CompiledScript compiledScript = compilable.compile(code);
        CommonScriptContext scriptContext = new CommonScriptContext(id, Md5.md5Hex(code), compiledScript);
        scriptBase.put(id, scriptContext);
        return true;
    }

    @Override
    public void addListener(ScriptListener scriptListener) {
        scriptListeners = ObjUtil.defaultIfNull(scriptListeners, CollUtil.linkedList());
        scriptListeners.add(scriptListener);
    }

    @Override
    public ExecuteResult execute(String id) {
        return execute(id, CollUtil.map());
    }

    @Override
    public ExecuteResult execute(String id, Map param) {
        long startTime = SystemClock.nowTimeMillis();
        if (logger.isDebugEnabled()) {
            logger.debug("Execute {} {} : {}", getScriptEngineName(), id);
        }
        ExecuteResult result = new ExecuteResult();
        CommonScriptContext scriptContext = scriptBase.get(id);
        try {
            if (scriptContext != null) {
                doListenerBefore(scriptContext);
                ScriptContext context = new SimpleScriptContext();
                context.setBindings(utilBindings, ScriptContext.GLOBAL_SCOPE);

                for (Map.Entry entry : param.entrySet()) {
                    context.setAttribute(entry.getKey(), entry.getValue(), ScriptContext.ENGINE_SCOPE);
                }
                result.setResult(scriptContext.getScript().eval(context)).setSuccess(true);
            } else {
                result.setSuccess(false).setMessage(String.format("script(%s): %s not found!", getScriptEngineName(), id));
            }
        } catch (ScriptException e) {
            result.setException(e);
        }
        result.setUseTime(SystemClock.nowTimeMillis() - startTime);
        doListenerAfter(scriptContext, result);
        return result;
    }

    @Override
    public void addGlobalVariable(Map vars) {
        utilBindings.putAll(vars);
    }

    protected class CommonScriptContext extends org.zodiac.script.engine.ScriptContext {
        private CompiledScript script;

        public CommonScriptContext(String id, String md5, CompiledScript script) {
            super(id, md5);
            this.script = script;
        }

        public CompiledScript getScript() {
            return script;
        }
    }

    public Bindings getUtilBindings() {
        return utilBindings;
    }

    public void setUtilBindings(Bindings utilBindings) {
        this.utilBindings = utilBindings;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy