Browse Source

add setbeans and classpath to <script> task

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@439681 13f79535-47bb-0310-9956-ffa450edef68
master
Peter Reilly 19 years ago
parent
commit
9936be2698
4 changed files with 171 additions and 7 deletions
  1. +9
    -0
      WHATSNEW
  2. +61
    -1
      docs/manual/OptionalTasks/script.html
  3. +60
    -5
      src/main/org/apache/tools/ant/taskdefs/optional/Script.java
  4. +41
    -1
      src/main/org/apache/tools/ant/util/ScriptRunner.java

+ 9
- 0
WHATSNEW View File

@@ -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
========================================



+ 61
- 1
docs/manual/OptionalTasks/script.html View File

@@ -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>&lt;script&gt;</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>&lt;classpath&gt;</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())}
&lt;/script&gt;
</pre>
</blockquote>
<p>
The following example shows the use of classpath to specify the location
of the beanshell jar file.
</p>
<blockquote><pre>
&lt;script language="beanshell" setbeans="true"&gt;
&lt;classpath&gt;
&lt;fileset dir="${user.home}/lang/beanshell" includes="*.jar" /&gt;
&lt;/classpath&gt;
System.out.println("Hello world");
&lt;/script&gt;
</pre>
</blockquote>
<p>
@@ -257,7 +317,7 @@ appropriate logging before and after invoking execute().


<hr>
<p align="center">Copyright &copy; 2000-2005 The Apache Software Foundation. All rights
<p align="center">Copyright &copy; 2000-2006 The Apache Software Foundation. All rights
Reserved.</p>

</body>


+ 60
- 5
src/main/org/apache/tools/ant/taskdefs/optional/Script.java View File

@@ -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, &lt;script&gt; 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;
}
}

+ 41
- 1
src/main/org/apache/tools/ant/util/ScriptRunner.java View File

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

Loading…
Cancel
Save