001: package com.canoo.webtest.boundary;
002:
003: /*
004: * Copyright 2003-2004 The Apache Software Foundation
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License");
007: * you may not use this file except in compliance with the License.
008: * You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: *
018: * This is a MODIFIED VERSION of ScriptRunner from Ant.
019: * Modifications Copyright (c) ASERT 2005.
020: * Modifications released under the Canoo WebTest license.
021: */
022: import org.apache.bsf.BSFException;
023: import org.apache.bsf.BSFManager;
024: import org.apache.commons.io.IOUtils;
025: import org.apache.tools.ant.BuildException;
026:
027: import java.io.File;
028: import java.io.FileInputStream;
029: import java.io.IOException;
030: import java.io.InputStream;
031: import java.util.HashMap;
032: import java.util.Iterator;
033: import java.util.Map;
034:
035: /**
036: * This class is used to run BSF scripts
037: */
038: public class ResetScriptRunner {
039: // Register Groovy ourselves, since BSF does not
040: // natively support it (yet).
041: // This "hack" can be removed once BSF has been
042: // modified to support Groovy or more dynamic
043: // registration.
044: static {
045: BSFManager.registerScriptingEngine("groovy",
046: "org.codehaus.groovy.bsf.GroovyEngine", new String[] {
047: "groovy", "gy" });
048: }
049:
050: /**
051: * Script language
052: */
053: private String fLanguage;
054:
055: /**
056: * Script content
057: */
058: private String fScript;
059:
060: /**
061: * Beans to be provided to the script
062: */
063: private Map fBeans = new HashMap();
064: private BSFManager fManager;
065:
066: {
067: reset();
068: }
069:
070: public void reset() {
071: fScript = "";
072: }
073:
074: /**
075: * Add a list of named objects to the list to be exported to the script
076: *
077: * @param dictionary a map of objects to be placed into the script context
078: * indexed by String names.
079: */
080: public void addBeans(final Map dictionary) {
081: for (Iterator i = dictionary.keySet().iterator(); i.hasNext();) {
082: final String key = (String) i.next();
083: try {
084: final Object val = dictionary.get(key);
085: addBean(key, val);
086: } catch (BuildException ex) {
087: // The key is in the dictionary but cannot be retrieved
088: // This is usually due to references that refer to tasks
089: // that have not been taskdefed in the current run.
090: // Ignore
091: }
092: }
093: }
094:
095: /**
096: * Add a single object into the script context.
097: *
098: * @param key the name in the context this object is to stored under.
099: * @param bean the object to be stored in the script context.
100: */
101: public void addBean(final String key, final Object bean) {
102: boolean isValid = key.length() > 0
103: && Character.isJavaIdentifierStart(key.charAt(0));
104:
105: for (int i = 1; isValid && i < key.length(); i++) {
106: isValid = Character.isJavaIdentifierPart(key.charAt(i));
107: }
108:
109: if (isValid) {
110: fBeans.put(key, bean);
111: }
112: }
113:
114: /**
115: * Do the work.
116: *
117: * @param execName the name that will be passed to BSF for this script
118: * execution.
119: * @throws BuildException if someting goes wrong exectuing the script.
120: */
121: public void executeScript(final String execName)
122: throws BuildException {
123: if (fLanguage == null) {
124: throw new BuildException(
125: "script language must be specified");
126: }
127: try {
128: if (fManager == null) {
129: fManager = prepareManager();
130: }
131: // execute the script
132: fManager.exec(fLanguage, execName, 0, 0, fScript);
133: } catch (BSFException be) {
134: throw createBuildException(be);
135: }
136: }
137:
138: /**
139: * Do the work.
140: *
141: * @param execName the name that will be passed to BSF for this script
142: * execution.
143: * @throws BuildException if someting goes wrong exectuing the script.
144: */
145: public String evalScript(final String execName)
146: throws BuildException {
147: if (fLanguage == null) {
148: throw new BuildException(
149: "script language must be specified");
150: }
151: try {
152: if (fManager == null) {
153: fManager = prepareManager();
154: }
155: // evaluate the expression
156: return fManager.eval(fLanguage, execName, 0, 0, fScript)
157: .toString();
158: } catch (BSFException be) {
159: throw createBuildException(be);
160: }
161: }
162:
163: private BSFManager prepareManager() throws BSFException {
164: final BSFManager manager = new BSFManager();
165: for (Iterator i = fBeans.keySet().iterator(); i.hasNext();) {
166: final String key = (String) i.next();
167: final Object value = fBeans.get(key);
168: if (value != null) {
169: manager.declareBean(key, value, value.getClass());
170: } else {
171: // BSF uses a hashtable to store values
172: // so cannot declareBean with a null value
173: // So need to remove any bean of this name as
174: // that bean should not be visible
175: manager.undeclareBean(key);
176: }
177: }
178: return manager;
179: }
180:
181: private static BuildException createBuildException(
182: final BSFException be) {
183: Throwable t = be;
184: final Throwable te = be.getTargetException();
185: if (te != null) {
186: if (te instanceof BuildException) {
187: return (BuildException) te;
188: } else {
189: t = te;
190: }
191: }
192: return new BuildException(t);
193: }
194:
195: /**
196: * Defines the language (required).
197: *
198: * @param lang the scripting language name for the script.
199: */
200: public void setLanguage(final String lang) {
201: this .fLanguage = lang;
202: }
203:
204: /**
205: * Get the script language
206: *
207: * @return the script language
208: */
209: public String getLanguage() {
210: return fLanguage;
211: }
212:
213: /**
214: * Load the script from an external file ; optional.
215: *
216: * @param file the file containing the script source.
217: */
218: public void setSrc(final File file) {
219: if (!file.exists()) {
220: throw new BuildException("file " + file.getPath()
221: + " not found.");
222: }
223: InputStream inputStream = null;
224: try {
225: inputStream = new FileInputStream(file);
226: fScript += IOUtils.toString(inputStream);
227: } catch (IOException e) {
228: throw new BuildException(e);
229: } finally {
230: IOUtils.closeQuietly(inputStream);
231: }
232: }
233:
234: /**
235: * Set the script text.
236: *
237: * @param text a component of the script text to be added.
238: */
239: public void addText(final String text) {
240: fScript += text;
241: }
242: }
|