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: | Changes that could break older environments: | ||||
------------------------------------------- | ------------------------------------------- | ||||
* <script> and <scriptdef> now set the current thread context. | |||||
Fixed bugs: | Fixed bugs: | ||||
----------- | ----------- | ||||
@@ -14,6 +16,13 @@ Fixed bugs: | |||||
Other changes: | 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 | 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 | accessible from the script, using either their <code>name</code> or | ||||
<code>id</code> attributes (as long as their names are considered | <code>id</code> attributes (as long as their names are considered | ||||
valid Java identifiers, that is). | 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 | 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 | 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 | <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">The location of the script as a file, if not inline</td> | ||||
<td valign="top" align="center">No</td> | <td valign="top" align="center">No</td> | ||||
</tr> | </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> | </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> | <h3>Examples</h3> | ||||
The following snippet shows use of five different languages: | The following snippet shows use of five different languages: | ||||
<blockquote><pre> | <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> | Note that for the <i>jython</i> example, the script contents <b>must</b> | ||||
start on the first column. | start on the first column. | ||||
</p> | </p> | ||||
<p> | |||||
Note also that for the <i>ruby</i> example, the names of the set variables are prefixed | |||||
by a '$'. | |||||
<p> | <p> | ||||
The following script shows a little more complicated jruby example: | The following script shows a little more complicated jruby example: | ||||
</p> | </p> | ||||
@@ -103,6 +150,19 @@ print "message is %s" % message | |||||
xmlfiles = new java.io.File(".").listFiles().findAll{ it =~ "\.xml$"} | xmlfiles = new java.io.File(".").listFiles().findAll{ it =~ "\.xml$"} | ||||
xmlfiles.sort().each { self.log(it.toString())} | xmlfiles.sort().each { self.log(it.toString())} | ||||
</script> | </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> | </pre> | ||||
</blockquote> | </blockquote> | ||||
<p> | <p> | ||||
@@ -257,7 +317,7 @@ appropriate logging before and after invoking execute(). | |||||
<hr> | <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> | Reserved.</p> | ||||
</body> | </body> | ||||
@@ -21,6 +21,8 @@ import java.io.File; | |||||
import org.apache.tools.ant.BuildException; | import org.apache.tools.ant.BuildException; | ||||
import org.apache.tools.ant.Task; | import org.apache.tools.ant.Task; | ||||
import org.apache.tools.ant.util.ScriptRunner; | import org.apache.tools.ant.util.ScriptRunner; | ||||
import org.apache.tools.ant.types.Path; | |||||
import org.apache.tools.ant.types.Reference; | |||||
/** | /** | ||||
* Executes a script. | * Executes a script. | ||||
@@ -29,9 +31,11 @@ import org.apache.tools.ant.util.ScriptRunner; | |||||
*/ | */ | ||||
public class Script extends Task { | 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. | * Do the work. | ||||
@@ -49,8 +53,14 @@ public class Script extends Task { | |||||
if (text != null) { | if (text != null) { | ||||
runner.addText(text); | runner.addText(text); | ||||
} | } | ||||
runner.bindToComponent(this); | |||||
if (classpath != null) { | |||||
runner.setClasspath(classpath); | |||||
} | |||||
if (setBeans) { | |||||
runner.bindToComponent(this); | |||||
} else { | |||||
runner.bindToComponentMinimum(this); | |||||
} | |||||
runner.executeScript("ANT"); | runner.executeScript("ANT"); | ||||
} | } | ||||
@@ -81,4 +91,49 @@ public class Script extends Task { | |||||
public void addText(String text) { | public void addText(String text) { | ||||
this.text = 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.File; | ||||
import java.io.FileInputStream; | import java.io.FileInputStream; | ||||
import java.io.IOException; | import java.io.IOException; | ||||
import org.apache.bsf.BSFException; | import org.apache.bsf.BSFException; | ||||
import org.apache.bsf.BSFManager; | import org.apache.bsf.BSFManager; | ||||
import org.apache.tools.ant.AntClassLoader; | |||||
import org.apache.tools.ant.BuildException; | import org.apache.tools.ant.BuildException; | ||||
import org.apache.tools.ant.ProjectComponent; | import org.apache.tools.ant.ProjectComponent; | ||||
import org.apache.tools.ant.Project; | import org.apache.tools.ant.Project; | ||||
@@ -29,6 +32,7 @@ import org.apache.tools.ant.Project; | |||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.HashMap; | import java.util.HashMap; | ||||
import java.util.Iterator; | import java.util.Iterator; | ||||
import org.apache.tools.ant.types.Path; | |||||
/** | /** | ||||
* This class is used to run BSF scripts | * This class is used to run BSF scripts | ||||
@@ -57,6 +61,11 @@ public class ScriptRunner { | |||||
/** Beans to be provided to the script */ | /** Beans to be provided to the script */ | ||||
private Map beans = new HashMap(); | 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 | * 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"); | 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 { | try { | ||||
Thread.currentThread().setContextClassLoader(scriptLoader); | |||||
BSFManager manager = new BSFManager (); | BSFManager manager = new BSFManager (); | ||||
manager.setClassLoader(scriptLoader); | |||||
for (Iterator i = beans.keySet().iterator(); i.hasNext();) { | for (Iterator i = beans.keySet().iterator(); i.hasNext();) { | ||||
String key = (String) i.next(); | String key = (String) i.next(); | ||||
@@ -141,6 +160,9 @@ public class ScriptRunner { | |||||
} | } | ||||
} | } | ||||
throw new BuildException(t); | throw new BuildException(t); | ||||
} finally { | |||||
Thread.currentThread().setContextClassLoader( | |||||
origContextClassLoader); | |||||
} | } | ||||
} | } | ||||
@@ -162,6 +184,13 @@ public class ScriptRunner { | |||||
return language; | 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. | * Load the script from an external file ; optional. | ||||
* | * | ||||
@@ -203,7 +232,7 @@ public class ScriptRunner { | |||||
* @param component to become <code>self</code> | * @param component to become <code>self</code> | ||||
*/ | */ | ||||
public void bindToComponent(ProjectComponent component) { | public void bindToComponent(ProjectComponent component) { | ||||
Project project = component.getProject(); | |||||
project = component.getProject(); | |||||
addBeans(project.getProperties()); | addBeans(project.getProperties()); | ||||
addBeans(project.getUserProperties()); | addBeans(project.getUserProperties()); | ||||
addBeans(project.getTargets()); | addBeans(project.getTargets()); | ||||
@@ -211,4 +240,15 @@ public class ScriptRunner { | |||||
addBean("project", project); | addBean("project", project); | ||||
addBean("self", component); | 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); | |||||
} | |||||
} | } |