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}