/* * Copyright 2004,2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.bsf.util; import java.beans.PropertyChangeEvent; import java.util.Vector; import org.apache.bsf.BSFDeclaredBean; import org.apache.bsf.BSFEngine; import org.apache.bsf.BSFException; import org.apache.bsf.BSFManager; /** * This is a base implementation of the BSFEngine interface which * engine implementations may choose to extend to get the basic * methods of the interface implemented. * <p> * * @author Sanjiva Weerawarana * @author Olivier Gruber (added original debugging support) */ public abstract class BSFEngineImpl implements BSFEngine { protected BSFManager mgr; // my manager protected String lang; // my language string protected Vector declaredBeans; // BSFDeclaredBeans protected String classPath; protected String tempDir; protected ClassLoader classLoader; /** * Default impl of apply - calls eval ignoring parameters and returns * the result. */ public Object apply(String source, int lineNo, int columnNo, Object funcBody, Vector paramNames, Vector arguments) throws BSFException { return eval(source, lineNo, columnNo, funcBody); } /** * Default impl of compileApply - calls compileExpr ignoring parameters. */ public void compileApply(String source, int lineNo, int columnNo, Object funcBody, Vector paramNames, Vector arguments, CodeBuffer cb) throws BSFException { compileExpr(source, lineNo, columnNo, funcBody, cb); } /** * Default impl of compileExpr - generates code that'll create a new * manager, evaluate the expression, and return the value. */ public void compileExpr(String source, int lineNo, int columnNo, Object expr, CodeBuffer cb) throws BSFException { ObjInfo bsfInfo = cb.getSymbol("bsf"); if (bsfInfo == null) { bsfInfo = new ObjInfo(BSFManager.class, "bsf"); cb.addFieldDeclaration("org.apache.bsf.BSFManager bsf = " + "new org.apache.bsf.BSFManager();"); cb.putSymbol("bsf", bsfInfo); } String evalString = bsfInfo.objName + ".eval(\"" + lang + "\", "; evalString += "request.getRequestURI(), " + lineNo + ", " + columnNo; evalString += "," + StringUtils.lineSeparator; evalString += StringUtils.getSafeString(expr.toString()) + ")"; ObjInfo oldRet = cb.getFinalServiceMethodStatement(); if (oldRet != null && oldRet.isExecutable()) { cb.addServiceMethodStatement(oldRet.objName + ";"); } cb.setFinalServiceMethodStatement(new ObjInfo(Object.class, evalString)); cb.addServiceMethodException("org.apache.bsf.BSFException"); } /** * Default impl of compileScript - generates code that'll create a new * manager, and execute the script. */ public void compileScript(String source, int lineNo, int columnNo, Object script, CodeBuffer cb) throws BSFException { ObjInfo bsfInfo = cb.getSymbol("bsf"); if (bsfInfo == null) { bsfInfo = new ObjInfo(BSFManager.class, "bsf"); cb.addFieldDeclaration("org.apache.bsf.BSFManager bsf = " + "new org.apache.bsf.BSFManager();"); cb.putSymbol("bsf", bsfInfo); } String execString = bsfInfo.objName + ".exec(\"" + lang + "\", "; execString += "request.getRequestURI(), " + lineNo + ", " + columnNo; execString += "," + StringUtils.lineSeparator; execString += StringUtils.getSafeString(script.toString()) + ")"; ObjInfo oldRet = cb.getFinalServiceMethodStatement(); if (oldRet != null && oldRet.isExecutable()) { cb.addServiceMethodStatement(oldRet.objName + ";"); } cb.setFinalServiceMethodStatement(new ObjInfo(void.class, execString)); cb.addServiceMethodException("org.apache.bsf.BSFException"); } public void declareBean(BSFDeclaredBean bean) throws BSFException { throw new BSFException(BSFException.REASON_UNSUPPORTED_FEATURE, "language " + lang + " does not support declareBean(...)."); } /** * Default impl of execute - calls eval and ignores the result. */ public void exec(String source, int lineNo, int columnNo, Object script) throws BSFException { eval(source, lineNo, columnNo, script); } /** * Default impl of interactive execution - calls eval and ignores the result. */ public void iexec(String source, int lineNo, int columnNo, Object script) throws BSFException { eval(source, lineNo, columnNo, script); } /** * initialize the engine; called right after construction by * the manager. Declared beans are simply kept in a vector and * that's it. Subclasses must do whatever they want with it. */ public void initialize(BSFManager mgr, String lang, Vector declaredBeans) throws BSFException { this.mgr = mgr; this.lang = lang; this.declaredBeans = declaredBeans; // initialize my properties from those of the manager. It'll send // propagate change events to me this.classPath = mgr.getClassPath(); this.tempDir = mgr.getTempDir(); this.classLoader = mgr.getClassLoader(); } /** * Receive property change events from the manager and update my fields * as needed. * * @param e PropertyChange event with the change data */ public void propertyChange(PropertyChangeEvent e) { String name = e.getPropertyName(); Object value = e.getNewValue(); if (name.equals("classPath")) { classPath = (String) value; } else if (name.equals("tempDir")) { tempDir = (String) value; } else if (name.equals("classLoader")) { classLoader = (ClassLoader) value; } } public void terminate() { mgr = null; declaredBeans = null; classLoader = null; } public void undeclareBean(BSFDeclaredBean bean) throws BSFException { throw new BSFException(BSFException.REASON_UNSUPPORTED_FEATURE, "language " + lang + " does not support undeclareBean(...)."); } }