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); | |||
} | |||
} |