    001package com.hammurapi.common;
    002
    003import java.io.IOException;
    004import java.io.Reader;
    005import java.io.StringWriter;
    006
    007import javax.script.AbstractScriptEngine;
    008import javax.script.Bindings;
    009import javax.script.ScriptContext;
    010import javax.script.ScriptEngine;
    011import javax.script.ScriptEngineFactory;
    012import javax.script.ScriptEngineManager;
    013import javax.script.ScriptException;
    014import javax.script.SimpleBindings;
    015
    016import com.hammurapi.common.TokenExpander.TokenSource;
    017
    018public class TokenExpanderScriptEngine extends AbstractScriptEngine {
    019
    020        private ScriptEngineFactory factory;
    021        private ScriptEngine javaEngine;
    022
    023        public TokenExpanderScriptEngine() {
    024                this(null);
    025        }
    026
    027        public TokenExpanderScriptEngine(ScriptEngineFactory factory) {
    028                this.factory = factory;
    029                javaEngine = new ScriptEngineManager(TokenExpanderScriptEngine.class.getClassLoader()).getEngineByExtension("java");
    030
    031        }
    032
    033        public Object eval(String script, final ScriptContext scriptContext) throws ScriptException {
    034                TokenExpander te = new TokenExpander(new TokenSource() {
    035
    036                        @Override
    037                        public String getToken(String name) {
    038                                try {
    039                                        return evalToken(scriptContext, name);
    040                                } catch (ScriptException e) {
    041                                        throw new TokenExpansionException(e);
    042                                }
    043                        }
    044
    045                });
    046                return te.expand(script);
    047        }
    048
    049        protected String evalToken(ScriptContext scriptContext, String name) throws ScriptException {
    050                Object ret;
    051                if (javaEngine==null || name.indexOf('.')==-1) {
    052                        ret = scriptContext.getAttribute(name);
    053                } else {
    054                        ret = javaEngine.eval("return "+name+";", scriptContext);
    055                }
    056                return ret==null ? null : ret.toString();
    057        }
    058
    059        public Object eval(Reader reader, ScriptContext scriptContext) throws ScriptException {
    060                StringWriter sw = new StringWriter();
    061                char[] buf = new char[4096];
    062                int l;
    063                try {
    064                        while ((l=reader.read(buf))!=-1) {
    065                                sw.write(buf, 0, l);
    066                        }
    067                        sw.close();
    068                } catch (IOException e) {
    069                        throw new ScriptException(e);
    070                }
    071                return eval(sw.toString(), scriptContext);
    072        }
    073
    074        public Bindings createBindings() {
    075                return new SimpleBindings();
    076        }
    077
    078        public ScriptEngineFactory getFactory() {
    079                if (factory == null) {
    080                        factory = new TokenExpanderScriptEngineFactory();
    081                }
    082                return factory;
    083        }
    084
    085
    086}