git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@439681 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -4,6 +4,8 @@ Changes from current Ant 1.7.0Beta1 version to current SVN version | |||
| Changes that could break older environments: | |||
| ------------------------------------------- | |||
| * <script> and <scriptdef> now set the current thread context. | |||
| Fixed bugs: | |||
| ----------- | |||
| @@ -14,6 +16,13 @@ Fixed bugs: | |||
| Other changes: | |||
| -------------- | |||
| * added setbeans attribute to <script> to allow <script>'s to be | |||
| run without referencing all references. | |||
| Bugzilla report 37688. | |||
| * added classpath attribute and nested element to <script> to allow | |||
| the language jars to be specified in the build script. | |||
| Bugzilla report 29676. | |||
| Changes from Ant 1.6.5 to Ant 1.7.0Beta1 | |||
| ======================================== | |||
| @@ -18,6 +18,7 @@ See <a href="../install.html#librarydependencies">Library Dependencies</a> for m | |||
| accessible from the script, using either their <code>name</code> or | |||
| <code>id</code> attributes (as long as their names are considered | |||
| valid Java identifiers, that is). | |||
| This is controlled by the "setbeans" attribute of the task. | |||
| The name "project" is a pre-defined reference to the Project, which can be | |||
| used instead of the project name. The name "self" is a pre-defined reference to the actual | |||
| <code><script></code>-Task instance.<br>From these objects you have access to the Ant Java API, see the | |||
| @@ -54,7 +55,50 @@ Groups@Google: "Rhino, enum.js, JavaAdapter?"</a> by Norris Boyd in the newsgrou | |||
| <td valign="top">The location of the script as a file, if not inline</td> | |||
| <td valign="top" align="center">No</td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">setbeans</td> | |||
| <td valign="top"> | |||
| This attribute controls whether to set variables for | |||
| all properties, references and targets in the running script. | |||
| If this attribute is false, only the the "project" and "self" variables are set. | |||
| If this attribute is true all the variables are set. The default value of this | |||
| attribute is "true". <em>Since Ant 1.7</em> | |||
| </td> | |||
| <td valign="top" align="center">No</td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">classpath</td> | |||
| <td valign="top"> | |||
| The classpath to pass into the script. <em>Since Ant 1.7</em> | |||
| </td> | |||
| <td align="center" valign="top">No</td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">classpathref</td> | |||
| <td valign="top">The classpath to use, given as a | |||
| <a href="../using.html#references">reference</a> to a path defined elsewhere. | |||
| <em>Since Ant 1.7</em></td> | |||
| <td align="center" valign="top">No</td> | |||
| </tr> | |||
| </table> | |||
| <h3>Parameters specified as nested elements</h3> | |||
| <h4>classpath</h4> | |||
| <p><em>Since Ant 1.7</em></p> | |||
| <p> | |||
| <code>Script</code>'s <code>classpath</code> attribute is a | |||
| <a href="../using.html#path">path-like structure</a> and can also be set via a nested | |||
| <code><classpath></code> element. | |||
| <p> | |||
| If a classpath is set, it will be used as the current thread context classloader, and | |||
| as the classloader given to the BSF manager. This means that it can be used to specify | |||
| the classpath containing the language implementation. This can be usefull if one wants | |||
| to keep ${user.home}/.ant/lib free of lots of scripting language specific jar files. | |||
| </p> | |||
| <p> | |||
| <b>NB:</b> This classpath cannot (currently) be used to specify the location of | |||
| the BSF jar file. | |||
| </p> | |||
| </p> | |||
| <h3>Examples</h3> | |||
| The following snippet shows use of five different languages: | |||
| <blockquote><pre> | |||
| @@ -85,6 +129,9 @@ print "message is %s" % message | |||
| Note that for the <i>jython</i> example, the script contents <b>must</b> | |||
| start on the first column. | |||
| </p> | |||
| <p> | |||
| Note also that for the <i>ruby</i> example, the names of the set variables are prefixed | |||
| by a '$'. | |||
| <p> | |||
| The following script shows a little more complicated jruby example: | |||
| </p> | |||
| @@ -103,6 +150,19 @@ print "message is %s" % message | |||
| xmlfiles = new java.io.File(".").listFiles().findAll{ it =~ "\.xml$"} | |||
| xmlfiles.sort().each { self.log(it.toString())} | |||
| </script> | |||
| </pre> | |||
| </blockquote> | |||
| <p> | |||
| The following example shows the use of classpath to specify the location | |||
| of the beanshell jar file. | |||
| </p> | |||
| <blockquote><pre> | |||
| <script language="beanshell" setbeans="true"> | |||
| <classpath> | |||
| <fileset dir="${user.home}/lang/beanshell" includes="*.jar" /> | |||
| </classpath> | |||
| System.out.println("Hello world"); | |||
| </script> | |||
| </pre> | |||
| </blockquote> | |||
| <p> | |||
| @@ -257,7 +317,7 @@ appropriate logging before and after invoking execute(). | |||
| <hr> | |||
| <p align="center">Copyright © 2000-2005 The Apache Software Foundation. All rights | |||
| <p align="center">Copyright © 2000-2006 The Apache Software Foundation. All rights | |||
| Reserved.</p> | |||
| </body> | |||
| @@ -21,6 +21,8 @@ import java.io.File; | |||
| import org.apache.tools.ant.BuildException; | |||
| import org.apache.tools.ant.Task; | |||
| import org.apache.tools.ant.util.ScriptRunner; | |||
| import org.apache.tools.ant.types.Path; | |||
| import org.apache.tools.ant.types.Reference; | |||
| /** | |||
| * Executes a script. | |||
| @@ -29,9 +31,11 @@ import org.apache.tools.ant.util.ScriptRunner; | |||
| */ | |||
| public class Script extends Task { | |||
| private String language; | |||
| private File src; | |||
| private String text; | |||
| private Path classpath; | |||
| private String language; | |||
| private File src; | |||
| private String text; | |||
| private boolean setBeans = true; | |||
| /** | |||
| * Do the work. | |||
| @@ -49,8 +53,14 @@ public class Script extends Task { | |||
| if (text != null) { | |||
| runner.addText(text); | |||
| } | |||
| runner.bindToComponent(this); | |||
| if (classpath != null) { | |||
| runner.setClasspath(classpath); | |||
| } | |||
| if (setBeans) { | |||
| runner.bindToComponent(this); | |||
| } else { | |||
| runner.bindToComponentMinimum(this); | |||
| } | |||
| runner.executeScript("ANT"); | |||
| } | |||
| @@ -81,4 +91,49 @@ public class Script extends Task { | |||
| public void addText(String text) { | |||
| this.text = text; | |||
| } | |||
| /** | |||
| * Set the classpath to be used when searching for classes and resources. | |||
| * | |||
| * @param classpath an Ant Path object containing the search path. | |||
| */ | |||
| public void setClasspath(Path classpath) { | |||
| createClasspath().append(classpath); | |||
| } | |||
| /** | |||
| * Classpath to be used when searching for classes and resources. | |||
| * | |||
| * @return an empty Path instance to be configured by Ant. | |||
| */ | |||
| public Path createClasspath() { | |||
| if (this.classpath == null) { | |||
| this.classpath = new Path(getProject()); | |||
| } | |||
| return this.classpath.createPath(); | |||
| } | |||
| /** | |||
| * Set the classpath by reference. | |||
| * | |||
| * @param r a Reference to a Path instance to be used as the classpath | |||
| * value. | |||
| */ | |||
| public void setClasspathRef(Reference r) { | |||
| createClasspath().setRefid(r); | |||
| } | |||
| /** | |||
| * Set the setbeans attribute. | |||
| * If this is true, <script> will create variables in the | |||
| * script instance for all | |||
| * properties, targets and references of the current project. | |||
| * It this is false, only the project and self variables will | |||
| * be set. | |||
| * The default is true. | |||
| * @param setBeans the value to set. | |||
| */ | |||
| public void setSetBeans(boolean setBeans) { | |||
| this.setBeans = setBeans; | |||
| } | |||
| } | |||
| @@ -20,8 +20,11 @@ package org.apache.tools.ant.util; | |||
| import java.io.File; | |||
| import java.io.FileInputStream; | |||
| import java.io.IOException; | |||
| import org.apache.bsf.BSFException; | |||
| import org.apache.bsf.BSFManager; | |||
| import org.apache.tools.ant.AntClassLoader; | |||
| import org.apache.tools.ant.BuildException; | |||
| import org.apache.tools.ant.ProjectComponent; | |||
| import org.apache.tools.ant.Project; | |||
| @@ -29,6 +32,7 @@ import org.apache.tools.ant.Project; | |||
| import java.util.Map; | |||
| import java.util.HashMap; | |||
| import java.util.Iterator; | |||
| import org.apache.tools.ant.types.Path; | |||
| /** | |||
| * This class is used to run BSF scripts | |||
| @@ -57,6 +61,11 @@ public class ScriptRunner { | |||
| /** Beans to be provided to the script */ | |||
| private Map beans = new HashMap(); | |||
| /** Classpath to be used when running the script. */ | |||
| private Path classpath = null; | |||
| /** Project this runner is used in */ | |||
| private Project project = null; | |||
| /** | |||
| * Add a list of named objects to the list to be exported to the script | |||
| @@ -111,8 +120,18 @@ public class ScriptRunner { | |||
| throw new BuildException("script language must be specified"); | |||
| } | |||
| ClassLoader origContextClassLoader = | |||
| Thread.currentThread().getContextClassLoader(); | |||
| ClassLoader scriptLoader = getClass().getClassLoader(); | |||
| if (classpath != null && project != null) { | |||
| AntClassLoader loader = project.createClassLoader(classpath); | |||
| loader.setParent(scriptLoader); | |||
| scriptLoader = loader; | |||
| } | |||
| try { | |||
| Thread.currentThread().setContextClassLoader(scriptLoader); | |||
| BSFManager manager = new BSFManager (); | |||
| manager.setClassLoader(scriptLoader); | |||
| for (Iterator i = beans.keySet().iterator(); i.hasNext();) { | |||
| String key = (String) i.next(); | |||
| @@ -141,6 +160,9 @@ public class ScriptRunner { | |||
| } | |||
| } | |||
| throw new BuildException(t); | |||
| } finally { | |||
| Thread.currentThread().setContextClassLoader( | |||
| origContextClassLoader); | |||
| } | |||
| } | |||
| @@ -162,6 +184,13 @@ public class ScriptRunner { | |||
| return language; | |||
| } | |||
| /** | |||
| * Set the class path to be used. | |||
| */ | |||
| public void setClasspath(Path classpath) { | |||
| this.classpath = classpath; | |||
| } | |||
| /** | |||
| * Load the script from an external file ; optional. | |||
| * | |||
| @@ -203,7 +232,7 @@ public class ScriptRunner { | |||
| * @param component to become <code>self</code> | |||
| */ | |||
| public void bindToComponent(ProjectComponent component) { | |||
| Project project = component.getProject(); | |||
| project = component.getProject(); | |||
| addBeans(project.getProperties()); | |||
| addBeans(project.getUserProperties()); | |||
| addBeans(project.getTargets()); | |||
| @@ -211,4 +240,15 @@ public class ScriptRunner { | |||
| addBean("project", project); | |||
| addBean("self", component); | |||
| } | |||
| /** | |||
| * Bind the runner to a project component. | |||
| * The project and self are the only beans set. | |||
| * @param component to become <code>self</code> | |||
| */ | |||
| public void bindToComponentMinimum(ProjectComponent component) { | |||
| project = component.getProject(); | |||
| addBean("project", project); | |||
| addBean("self", component); | |||
| } | |||
| } | |||