You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

ScriptRunner.java 6.5 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /*
  2. * Copyright 2003-2006 The Apache Software Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. *
  16. */
  17. package org.apache.tools.ant.util;
  18. import java.io.File;
  19. import java.io.FileInputStream;
  20. import java.io.IOException;
  21. import org.apache.bsf.BSFException;
  22. import org.apache.bsf.BSFManager;
  23. import org.apache.tools.ant.BuildException;
  24. import org.apache.tools.ant.ProjectComponent;
  25. import org.apache.tools.ant.Project;
  26. import java.util.Map;
  27. import java.util.HashMap;
  28. import java.util.Iterator;
  29. /**
  30. * This class is used to run BSF scripts
  31. *
  32. */
  33. public class ScriptRunner {
  34. // Register Groovy ourselves, since BSF does not
  35. // natively support it (yet).
  36. // This "hack" can be removed once BSF has been
  37. // modified to support Groovy or more dynamic
  38. // registration.
  39. static {
  40. BSFManager.registerScriptingEngine(
  41. "groovy",
  42. "org.codehaus.groovy.bsf.GroovyEngine",
  43. new String[] {"groovy", "gy"});
  44. }
  45. /** Script language */
  46. private String language;
  47. /** Script content */
  48. private String script = "";
  49. /** Beans to be provided to the script */
  50. private Map beans = new HashMap();
  51. /**
  52. * Add a list of named objects to the list to be exported to the script
  53. *
  54. * @param dictionary a map of objects to be placed into the script context
  55. * indexed by String names.
  56. */
  57. public void addBeans(Map dictionary) {
  58. for (Iterator i = dictionary.keySet().iterator(); i.hasNext();) {
  59. String key = (String) i.next();
  60. try {
  61. Object val = dictionary.get(key);
  62. addBean(key, val);
  63. } catch (BuildException ex) {
  64. // The key is in the dictionary but cannot be retrieved
  65. // This is usually due references that refer to tasks
  66. // that have not been taskdefed in the current run.
  67. // Ignore
  68. }
  69. }
  70. }
  71. /**
  72. * Add a single object into the script context.
  73. *
  74. * @param key the name in the context this object is to stored under.
  75. * @param bean the object to be stored in the script context.
  76. */
  77. public void addBean(String key, Object bean) {
  78. boolean isValid = key.length() > 0
  79. && Character.isJavaIdentifierStart(key.charAt(0));
  80. for (int i = 1; isValid && i < key.length(); i++) {
  81. isValid = Character.isJavaIdentifierPart(key.charAt(i));
  82. }
  83. if (isValid) {
  84. beans.put(key, bean);
  85. }
  86. }
  87. /**
  88. * Do the work.
  89. *
  90. * @param execName the name that will be passed to BSF for this script
  91. * execution.
  92. *
  93. * @exception BuildException if someting goes wrong exectuing the script.
  94. */
  95. public void executeScript(String execName) throws BuildException {
  96. if (language == null) {
  97. throw new BuildException("script language must be specified");
  98. }
  99. try {
  100. BSFManager manager = new BSFManager ();
  101. for (Iterator i = beans.keySet().iterator(); i.hasNext();) {
  102. String key = (String) i.next();
  103. Object value = beans.get(key);
  104. if (value != null) {
  105. manager.declareBean(key, value, value.getClass());
  106. } else {
  107. // BSF uses a hashtable to store values
  108. // so cannot declareBean with a null value
  109. // So need to remove any bean of this name as
  110. // that bean should not be visible
  111. manager.undeclareBean(key);
  112. }
  113. }
  114. // execute the script
  115. manager.exec(language, execName, 0, 0, script);
  116. } catch (BSFException be) {
  117. Throwable t = be;
  118. Throwable te = be.getTargetException();
  119. if (te != null) {
  120. if (te instanceof BuildException) {
  121. throw (BuildException) te;
  122. } else {
  123. t = te;
  124. }
  125. }
  126. throw new BuildException(t);
  127. }
  128. }
  129. /**
  130. * Defines the language (required).
  131. *
  132. * @param language the scripting language name for the script.
  133. */
  134. public void setLanguage(String language) {
  135. this.language = language;
  136. }
  137. /**
  138. * Get the script language
  139. *
  140. * @return the script language
  141. */
  142. public String getLanguage() {
  143. return language;
  144. }
  145. /**
  146. * Load the script from an external file ; optional.
  147. *
  148. * @param file the file containing the script source.
  149. */
  150. public void setSrc(File file) {
  151. if (!file.exists()) {
  152. throw new BuildException("file " + file.getPath() + " not found.");
  153. }
  154. int count = (int) file.length();
  155. byte[] data = new byte[count];
  156. FileInputStream inStream = null;
  157. try {
  158. inStream = new FileInputStream(file);
  159. inStream.read(data);
  160. } catch (IOException e) {
  161. throw new BuildException(e);
  162. } finally {
  163. FileUtils.close(inStream);
  164. }
  165. script += new String(data);
  166. }
  167. /**
  168. * Set the script text.
  169. *
  170. * @param text a component of the script text to be added.
  171. */
  172. public void addText(String text) {
  173. this.script += text;
  174. }
  175. /**
  176. * Bind the runner to a project component.
  177. * Properties, targets and references are all added as beans;
  178. * project is bound to project, and self to the component.
  179. * @param component to become <code>self</code>
  180. */
  181. public void bindToComponent(ProjectComponent component) {
  182. Project project = component.getProject();
  183. addBeans(project.getProperties());
  184. addBeans(project.getUserProperties());
  185. addBeans(project.getTargets());
  186. addBeans(project.getReferences());
  187. addBean("project", project);
  188. addBean("self", component);
  189. }
  190. }