blob: 15f6e6f4f3d3c237def7f89b894b3872960c5452 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.tools.ant.util.optional;
import org.apache.bsf.BSFException;
import org.apache.bsf.BSFManager;
import org.apache.bsf.BSFEngine;
import java.util.Iterator;
import java.util.Hashtable;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.util.ReflectUtil;
import org.apache.tools.ant.util.ScriptRunnerBase;
/**
* This class is used to run BSF scripts
*
*/
public class ScriptRunner extends ScriptRunnerBase {
// Register Groovy ourselves, since BSF did not
// natively support it in versions previous to 1.2.4.
static {
BSFManager.registerScriptingEngine(
"groovy",
"org.codehaus.groovy.bsf.GroovyEngine",
new String[] {"groovy", "gy"});
}
private BSFEngine engine;
private BSFManager manager;
/**
* Get the name of the manager prefix.
* @return "bsf"
*/
public String getManagerName() {
return "bsf";
}
/**
* Check if bsf supports the language.
* @return true if bsf can create an engine for this language.
*/
public boolean supportsLanguage() {
Hashtable table = (Hashtable) ReflectUtil.getField(
new BSFManager(), "registeredEngines");
String engineClassName = (String) table.get(getLanguage());
if (engineClassName == null) {
getProject().log(
"This is no BSF engine class for language '"
+ getLanguage() + "'",
Project.MSG_VERBOSE);
return false;
}
try {
getScriptClassLoader().loadClass(engineClassName);
return true;
} catch (Throwable ex) {
getProject().log(
"unable to create BSF engine class for language '"
+ getLanguage() + "'",
ex,
Project.MSG_VERBOSE);
return false;
}
}
/**
* Do the work.
*
* @param execName the name that will be passed to BSF for this script execution.
* @exception BuildException if something goes wrong executing the script.
*/
public void executeScript(String execName) throws BuildException {
checkLanguage();
ClassLoader origLoader = replaceContextLoader();
try {
BSFManager m = createManager();
declareBeans(m);
// execute the script
if (engine == null) {
m.exec(getLanguage(), execName, 0, 0, getScript());
} else {
engine.exec(execName, 0, 0, getScript());
}
} catch (BSFException be) {
throw getBuildException(be);
} finally {
restoreContextLoader(origLoader);
}
}
/**
* Evaluate the script.
*
* @param execName the name that will be passed to BSF for this script execution.
* @return the result of the evaluation
* @exception BuildException if something goes wrong executing the script.
*/
public Object evaluateScript(String execName) throws BuildException {
checkLanguage();
ClassLoader origLoader = replaceContextLoader();
try {
BSFManager m = createManager();
declareBeans(m);
// execute the script
if (engine == null) {
return m.eval(getLanguage(), execName, 0, 0, getScript());
}
return engine.eval(execName, 0, 0, getScript());
} catch (BSFException be) {
throw getBuildException(be);
} finally {
restoreContextLoader(origLoader);
}
}
/**
* Get/create a BuildException from a BSFException.
* @param be BSFException to convert.
* @return BuildException the converted exception.
*/
private BuildException getBuildException(BSFException be) {
Throwable t = be;
Throwable te = be.getTargetException();
if (te instanceof BuildException) {
return (BuildException) te;
}
return new BuildException(te == null ? t : te);
}
private void declareBeans(BSFManager m) throws BSFException {
for (Iterator i = getBeans().keySet().iterator(); i.hasNext();) {
String key = (String) i.next();
Object value = getBeans().get(key);
if (value != null) {
m.declareBean(key, value, value.getClass());
} else {
// BSF uses a hashtable to store values
// so cannot declareBean with a null value
// So need to remove any bean of this name as
// that bean should not be visible
m.undeclareBean(key);
}
}
}
private BSFManager createManager() throws BSFException {
if (manager != null) {
return manager;
}
BSFManager m = new BSFManager();
m.setClassLoader(getScriptClassLoader());
if (getKeepEngine()) {
BSFEngine e = manager.loadScriptingEngine(getLanguage());
this.manager = m;
this.engine = e;
}
return m;
}
}