package org.jpos.jposext.isomsgaction.service.support; import java.util.HashMap; import java.util.Map; import java.util.StringTokenizer; import org.jpos.iso.ISOException; import org.jpos.iso.ISOMsg; import bsh.BshClassManager; import bsh.EvalError; import bsh.Interpreter; import org.jpos.jposext.isomsgaction.service.IISOMsgAction; /** * BSH script execution action<BR/> * Messages array is made available in BSH through a "messages" variable.<BR/> * Context is also made available through a "context" variable.<BR/> * As the messages and context are fully exposed, one may take handle them carefully.<BR/> * * BSH script must provide a "entrypoint()" method. This entrypoint is the * method the action will call when processed. * * @author dgrandemange * */ public class ISOMsgActionBshScript extends ISOMsgAbstractAction implements IISOMsgAction { private static final String DEFAULT_MAIN_METHOD_MAIN = "entrypoint"; private static Map<String, String> mapScripts = new HashMap<String, String>(); private String bshScript; private String mainMethodName = DEFAULT_MAIN_METHOD_MAIN; private Interpreter bshInterpreter; private boolean evaluated = false; private String scriptId; private String includes; public ISOMsgActionBshScript() { super(); bshInterpreter = new Interpreter(); BshClassManager bcm = bshInterpreter.getClassManager(); bcm.setClassLoader(this.getClass().getClassLoader()); } /* (non-Javadoc) * @see org.jpos.jposext.isomsgaction.service.IISOMsgAction#process(org.jpos.iso.ISOMsg[], java.util.Map) */ public void process(ISOMsg[] msg, Map<String, Object> ctx) throws ISOException { if (null != bshScript) { try { if (null == scriptId) { bshInterpreter.set("messages", msg); bshInterpreter.set("context", ctx); if (!evaluated) { StringBuffer buf = new StringBuffer(); if (null != includes) { StringTokenizer tokenizer = new StringTokenizer( includes, ", "); while (tokenizer.hasMoreTokens()) { String token = tokenizer.nextToken(); if (!("".equals(token))) { String includeScript = mapScripts .get(token); if (null != includeScript) { buf.append(includeScript.trim()); buf.append("\n"); } else { throw new ISOException( String .format( "BSHScript '%s' : Referenced script '%s' does not exist.", this.scriptId, token)); } } } } buf.append(bshScript.trim()); bshInterpreter.eval(buf.toString()); evaluated = true; } bshInterpreter.eval(mainMethodName + "()"); } } catch (EvalError e) { throw new ISOException(e); } } } protected void registerScript() { if (null != scriptId) { synchronized (mapScripts) { mapScripts.put(scriptId, bshScript); } } } public String getBshScript() { return bshScript; } public void setBshScript(String bshScript) { this.bshScript = bshScript; registerScript(); } public String getMainMethodName() { return mainMethodName; } public void setMainMethodName(String mainMethodName) { this.mainMethodName = mainMethodName; } public String getScriptId() { return scriptId; } public void setScriptId(String scriptId) { this.scriptId = scriptId; registerScript(); } public String getIncludes() { return includes; } public void setIncludes(String includes) { this.includes = includes; } }