001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018: package org.apache.tools.ant.util.optional;
019:
020: import org.apache.bsf.BSFException;
021: import org.apache.bsf.BSFManager;
022: import org.apache.bsf.BSFEngine;
023:
024: import java.util.Iterator;
025: import java.util.Hashtable;
026:
027: import org.apache.tools.ant.BuildException;
028: import org.apache.tools.ant.Project;
029:
030: import org.apache.tools.ant.util.ReflectUtil;
031: import org.apache.tools.ant.util.ScriptRunnerBase;
032:
033: /**
034: * This class is used to run BSF scripts
035: *
036: */
037: public class ScriptRunner extends ScriptRunnerBase {
038: // Register Groovy ourselves, since BSF did not
039: // natively support it in versions previous to 1.2.4.
040: static {
041: BSFManager.registerScriptingEngine("groovy",
042: "org.codehaus.groovy.bsf.GroovyEngine", new String[] {
043: "groovy", "gy" });
044: }
045:
046: private BSFEngine engine;
047: private BSFManager manager;
048:
049: /**
050: * Get the name of the manager prefix.
051: * @return "bsf"
052: */
053: public String getManagerName() {
054: return "bsf";
055: }
056:
057: /**
058: * Check if bsf supports the language.
059: * @return true if bsf can create an engine for this language.
060: */
061: public boolean supportsLanguage() {
062: Hashtable table = (Hashtable) ReflectUtil.getField(
063: new BSFManager(), "registeredEngines");
064: String engineClassName = (String) table.get(getLanguage());
065: if (engineClassName == null) {
066: getProject().log(
067: "This is no BSF engine class for language '"
068: + getLanguage() + "'", Project.MSG_VERBOSE);
069: return false;
070: }
071: try {
072: getScriptClassLoader().loadClass(engineClassName);
073: return true;
074: } catch (Throwable ex) {
075: getProject().log(
076: "unable to create BSF engine class for language '"
077: + getLanguage() + "'", ex,
078: Project.MSG_VERBOSE);
079: return false;
080: }
081: }
082:
083: /**
084: * Do the work.
085: *
086: * @param execName the name that will be passed to BSF for this script
087: * execution.
088: *
089: * @exception BuildException if someting goes wrong exectuing the script.
090: */
091: public void executeScript(String execName) throws BuildException {
092: checkLanguage();
093: ClassLoader origLoader = replaceContextLoader();
094: try {
095: BSFManager m = createManager();
096: declareBeans(m);
097: // execute the script
098: if (engine == null) {
099: m.exec(getLanguage(), execName, 0, 0, getScript());
100: } else {
101: engine.exec(execName, 0, 0, getScript());
102: }
103: } catch (BSFException be) {
104: throwBuildException(be);
105: } finally {
106: restoreContextLoader(origLoader);
107: }
108: }
109:
110: /**
111: * Do the work.
112: *
113: * @param execName the name that will be passed to BSF for this script
114: * execution.
115: * @return the result of the evalulation
116: * @exception BuildException if someting goes wrong exectuing the script.
117: */
118: public Object evaluateScript(String execName) throws BuildException {
119: checkLanguage();
120: ClassLoader origLoader = replaceContextLoader();
121: try {
122: BSFManager m = createManager();
123: declareBeans(m);
124: // execute the script
125: if (engine == null) {
126: return m.eval(getLanguage(), execName, 0, 0,
127: getScript());
128: } else {
129: return engine.eval(execName, 0, 0, getScript());
130: }
131: } catch (BSFException be) {
132: throwBuildException(be);
133: // NotReached
134: return null;
135: } finally {
136: restoreContextLoader(origLoader);
137: }
138: }
139:
140: /**
141: * Throw a buildException in place of a BSFException.
142: * @param be BSFException to convert.
143: * @throws BuildException the conveted exception.
144: */
145: private void throwBuildException(BSFException be) {
146: Throwable t = be;
147: Throwable te = be.getTargetException();
148: if (te != null) {
149: if (te instanceof BuildException) {
150: throw (BuildException) te;
151: } else {
152: t = te;
153: }
154: }
155: throw new BuildException(t);
156: }
157:
158: private void declareBeans(BSFManager m) throws BSFException {
159: for (Iterator i = getBeans().keySet().iterator(); i.hasNext();) {
160: String key = (String) i.next();
161: Object value = getBeans().get(key);
162: if (value != null) {
163: m.declareBean(key, value, value.getClass());
164: } else {
165: // BSF uses a hashtable to store values
166: // so cannot declareBean with a null value
167: // So need to remove any bean of this name as
168: // that bean should not be visible
169: m.undeclareBean(key);
170: }
171: }
172: }
173:
174: private BSFManager createManager() throws BSFException {
175: if (manager != null) {
176: return manager;
177: }
178: BSFManager m = new BSFManager();
179: m.setClassLoader(getScriptClassLoader());
180: if (getKeepEngine()) {
181: BSFEngine e = manager.loadScriptingEngine(getLanguage());
182: this.manager = m;
183: this.engine = e;
184: }
185: return m;
186: }
187: }
|