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}