git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@533121 13f79535-47bb-0310-9956-ffa450edef68master
@@ -4,6 +4,11 @@ Changes from Ant 1.7.0 TO current SVN version | |||||
Changes that could break older environments: | Changes that could break older environments: | ||||
------------------------------------------- | ------------------------------------------- | ||||
* String resources only have properties single expanded. If you relied on | |||||
<string> resources being expanded more than once, it no longer happens. | |||||
Bugzilla report 42277. | |||||
Fixed bugs: | Fixed bugs: | ||||
----------- | ----------- | ||||
* Error in handling of some permissions, most notably the AllPermission on | * Error in handling of some permissions, most notably the AllPermission on | ||||
@@ -103,6 +108,11 @@ Other changes: | |||||
* JUnitVersionHelper.getTestCaseClassName is now public. Bugzilla 42231 | * JUnitVersionHelper.getTestCaseClassName is now public. Bugzilla 42231 | ||||
* <string> resource supports nested text. Bugzilla bug 42276 | |||||
* <scriptdef> now sources scripts from nested resources/resource collections. This lets you | |||||
define scripts in JARs, remote URLs, or any other supported resource. Bugzilla report 41597. | |||||
Changes from Ant 1.6.5 to Ant 1.7.0 | Changes from Ant 1.6.5 to Ant 1.7.0 | ||||
=================================== | =================================== | ||||
@@ -190,6 +190,13 @@ more information on writing scripts, please refer to the | |||||
<code>type="antlib:example.org:newtype"</code></td> | <code>type="antlib:example.org:newtype"</code></td> | ||||
<td valign="top" align="center">No</td> | <td valign="top" align="center">No</td> | ||||
</tr> | </tr> | ||||
<tr> | |||||
<td valign="top">any resource or resource collection</td> | |||||
<td valign="top">Since Ant1.7.1, this task can load scripts | |||||
from any resource supplied as a nested element. when </td> | |||||
<td valign="top" align="center">No</td> | |||||
</tr> | |||||
</table> | </table> | ||||
<h4>classpath</h4> | <h4>classpath</h4> | ||||
@@ -198,6 +205,7 @@ more information on writing scripts, please refer to the | |||||
for using this nested element. | for using this nested element. | ||||
</p> | </p> | ||||
<h3>Examples</h3> | <h3>Examples</h3> | ||||
<p> | <p> | ||||
@@ -23,6 +23,8 @@ import org.apache.tools.ant.Project; | |||||
import org.apache.tools.ant.MagicNames; | import org.apache.tools.ant.MagicNames; | ||||
import org.apache.tools.ant.BuildException; | import org.apache.tools.ant.BuildException; | ||||
import org.apache.tools.ant.ProjectHelper; | import org.apache.tools.ant.ProjectHelper; | ||||
import org.apache.tools.ant.types.Resource; | |||||
import org.apache.tools.ant.types.ResourceCollection; | |||||
import org.apache.tools.ant.taskdefs.DefBase; | import org.apache.tools.ant.taskdefs.DefBase; | ||||
import java.util.Map; | import java.util.Map; | ||||
@@ -250,25 +252,34 @@ public class ScriptDef extends DefBase { | |||||
} | } | ||||
// find the script repository - it is stored in the project | // find the script repository - it is stored in the project | ||||
Map scriptRepository = lookupScriptRepository(); | |||||
name = ProjectHelper.genComponentName(getURI(), name); | |||||
scriptRepository.put(name, this); | |||||
AntTypeDefinition def = new AntTypeDefinition(); | |||||
def.setName(name); | |||||
def.setClass(ScriptDefBase.class); | |||||
ComponentHelper.getComponentHelper( | |||||
getProject()).addDataTypeDefinition(def); | |||||
} | |||||
/** | |||||
* Find or create the script repository - it is stored in the project. | |||||
* This method is synchronized on the project under {@link MagicNames#SCRIPT_REPOSITORY} | |||||
* @return the current script repository registered as a refrence. | |||||
*/ | |||||
private Map lookupScriptRepository() { | |||||
Map scriptRepository = null; | Map scriptRepository = null; | ||||
Project p = getProject(); | Project p = getProject(); | ||||
synchronized (p) { | synchronized (p) { | ||||
scriptRepository = | scriptRepository = | ||||
(Map) p.getReference(MagicNames.SCRIPT_REPOSITORY); | |||||
(Map) p.getReference(MagicNames.SCRIPT_REPOSITORY); | |||||
if (scriptRepository == null) { | if (scriptRepository == null) { | ||||
scriptRepository = new HashMap(); | scriptRepository = new HashMap(); | ||||
p.addReference(MagicNames.SCRIPT_REPOSITORY, | p.addReference(MagicNames.SCRIPT_REPOSITORY, | ||||
scriptRepository); | |||||
scriptRepository); | |||||
} | } | ||||
} | } | ||||
name = ProjectHelper.genComponentName(getURI(), name); | |||||
scriptRepository.put(name, this); | |||||
AntTypeDefinition def = new AntTypeDefinition(); | |||||
def.setName(name); | |||||
def.setClass(ScriptDefBase.class); | |||||
ComponentHelper.getComponentHelper( | |||||
getProject()).addDataTypeDefinition(def); | |||||
return scriptRepository; | |||||
} | } | ||||
/** | /** | ||||
@@ -382,5 +393,14 @@ public class ScriptDef extends DefBase { | |||||
public void addText(String text) { | public void addText(String text) { | ||||
helper.addText(text); | helper.addText(text); | ||||
} | } | ||||
/** | |||||
* Add any source resource. | |||||
* @since Ant1.7.1 | |||||
* @param resource source of script | |||||
*/ | |||||
public void add(ResourceCollection resource) { | |||||
helper.add(resource); | |||||
} | |||||
} | } | ||||
@@ -21,10 +21,16 @@ import java.io.BufferedReader; | |||||
import java.io.File; | import java.io.File; | ||||
import java.io.FileReader; | import java.io.FileReader; | ||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.io.InputStream; | |||||
import java.io.Reader; | |||||
import java.io.FileNotFoundException; | |||||
import java.io.InputStreamReader; | |||||
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; | ||||
import org.apache.tools.ant.types.Resource; | |||||
import org.apache.tools.ant.types.ResourceCollection; | |||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.HashMap; | import java.util.HashMap; | ||||
@@ -186,27 +192,76 @@ public abstract class ScriptRunnerBase { | |||||
* @param file the file containing the script source. | * @param file the file containing the script source. | ||||
*/ | */ | ||||
public void setSrc(File file) { | public void setSrc(File file) { | ||||
String filename = file.getPath(); | |||||
if (!file.exists()) { | if (!file.exists()) { | ||||
throw new BuildException("file " + file.getPath() + " not found."); | |||||
throw new BuildException("file " + filename + " not found."); | |||||
} | } | ||||
try { | |||||
readSource(new FileReader(file), filename); | |||||
} catch (FileNotFoundException e) { | |||||
//this can only happen if the file got deleted a short moment ago | |||||
throw new BuildException("file " + filename + " not found."); | |||||
} | |||||
} | |||||
/** | |||||
* Read some source in from the given reader | |||||
* @param reader the reader; this is closed afterwards. | |||||
* @param name the name to use in error messages | |||||
*/ | |||||
private void readSource(Reader reader, String name) { | |||||
BufferedReader in = null; | BufferedReader in = null; | ||||
try { | try { | ||||
in = new BufferedReader(new FileReader(file)); | |||||
in = new BufferedReader(reader); | |||||
script += FileUtils.readFully(in); | script += FileUtils.readFully(in); | ||||
} catch (IOException ex) { | } catch (IOException ex) { | ||||
throw new BuildException(ex); | |||||
throw new BuildException("Failed to read "+ name,ex); | |||||
} finally { | } finally { | ||||
FileUtils.close(in); | FileUtils.close(in); | ||||
} | } | ||||
} | } | ||||
/** | |||||
* Add a resource to the source list. | |||||
* @since Ant 1.7.1 | |||||
* @param sourceResource the resource to load | |||||
* @throws BuildException if the resource cannot be read | |||||
*/ | |||||
public void loadResource(Resource sourceResource) { | |||||
String name = sourceResource.toLongString(); | |||||
InputStream in = null; | |||||
try { | |||||
in = sourceResource.getInputStream(); | |||||
} catch (IOException e) { | |||||
throw new BuildException("Failed to open "+name,e); | |||||
} catch (UnsupportedOperationException e) { | |||||
throw new BuildException("Failed to open " + name+ " -it is not readable",e); | |||||
} | |||||
readSource(new InputStreamReader(in), name); | |||||
} | |||||
/** | |||||
* Add all resources in a resource collection to the source list. | |||||
* @since Ant 1.7.1 | |||||
* @param collection the resource to load | |||||
* @throws BuildException if a resource cannot be read | |||||
*/ | |||||
public void loadResources(ResourceCollection collection) { | |||||
Iterator resources = collection.iterator(); | |||||
while (resources.hasNext()) { | |||||
Resource resource = (Resource) resources.next(); | |||||
loadResource(resource); | |||||
} | |||||
} | |||||
/** | /** | ||||
* Set the script text. | |||||
* Set the script text. Properties in the text are not expanded! | |||||
* | * | ||||
* @param text a component of the script text to be added. | * @param text a component of the script text to be added. | ||||
*/ | */ | ||||
public void addText(String text) { | public void addText(String text) { | ||||
this.script += text; | |||||
script += text; | |||||
} | } | ||||
/** | /** | ||||
@@ -21,6 +21,9 @@ import org.apache.tools.ant.ProjectComponent; | |||||
import org.apache.tools.ant.types.Path; | import org.apache.tools.ant.types.Path; | ||||
import java.io.File; | import java.io.File; | ||||
import org.apache.tools.ant.types.Reference; | import org.apache.tools.ant.types.Reference; | ||||
import org.apache.tools.ant.types.Resource; | |||||
import org.apache.tools.ant.types.ResourceCollection; | |||||
import org.apache.tools.ant.types.resources.Union; | |||||
/** | /** | ||||
@@ -36,6 +39,7 @@ public class ScriptRunnerHelper { | |||||
private boolean setBeans = true; | private boolean setBeans = true; | ||||
private ProjectComponent projectComponent; | private ProjectComponent projectComponent; | ||||
private ClassLoader scriptLoader = null; | private ClassLoader scriptLoader = null; | ||||
private Union resources=new Union(); | |||||
/** | /** | ||||
* Set the project component associated with this helper. | * Set the project component associated with this helper. | ||||
@@ -57,6 +61,9 @@ public class ScriptRunnerHelper { | |||||
if (text != null) { | if (text != null) { | ||||
runner.addText(text); | runner.addText(text); | ||||
} | } | ||||
if (resources !=null) { | |||||
runner.loadResources(resources); | |||||
} | |||||
if (setBeans) { | if (setBeans) { | ||||
runner.bindToComponent(projectComponent); | runner.bindToComponent(projectComponent); | ||||
} else { | } else { | ||||
@@ -188,4 +195,14 @@ public class ScriptRunnerHelper { | |||||
projectComponent.getProject()).createRunner( | projectComponent.getProject()).createRunner( | ||||
manager, language, generateClassLoader()); | manager, language, generateClassLoader()); | ||||
} | } | ||||
/** | |||||
* Add any source resource. | |||||
* | |||||
* @param resource source of script | |||||
* @since Ant1.7.1 | |||||
*/ | |||||
public void add(ResourceCollection resource) { | |||||
resources.add(resource); | |||||
} | |||||
} | } |
@@ -0,0 +1,99 @@ | |||||
<project default="test" xmlns:au="antlib:org.apache.ant.antunit"> | |||||
<description> | |||||
In which we test interesting aspects of scripting. | |||||
The targeted language is javascript; this lets us run without | |||||
additions on Java6+. | |||||
</description> | |||||
<target name="test"> | |||||
<au:antunit> | |||||
<fileset file="${ant.file}"/> | |||||
<au:plainlistener/> | |||||
</au:antunit> | |||||
</target> | |||||
<target name="tearDown"> | |||||
</target> | |||||
<property name="script.manager" value="auto" /> | |||||
<string id="script.code"> | |||||
self.log("Ant version =${ant.version}"); | |||||
project.setNewProperty("property","live"); | |||||
</string> | |||||
<presetdef name="js"> | |||||
<scriptdef language="javascript" name="scripttest" | |||||
manager="${script.manager}"> | |||||
<!-- optional property attribute--> | |||||
<attribute name="property" /> | |||||
</scriptdef> | |||||
</presetdef> | |||||
<property name="prop" | |||||
value='self.log("Ant version =${ant.version}");project.setNewProperty("property","live");' /> | |||||
<presetdef name="assertPropSet"> | |||||
<au:assertPropertyEquals name="property" value="live" /> | |||||
</presetdef> | |||||
<!--purely to test that everything works --> | |||||
<target name="testInline"> | |||||
<js > self.log("Hello");</js> | |||||
<scripttest/> | |||||
</target> | |||||
<target name="testStringResource"> | |||||
<js > | |||||
<string value='self.log("Ant version =${ant.version}");' /> | |||||
</js> | |||||
<scripttest/> | |||||
</target> | |||||
<target name="testStringResourceRef"> | |||||
<js > | |||||
<string refid="script.code" /> | |||||
</js> | |||||
<scripttest/> | |||||
<assertPropSet /> | |||||
</target> | |||||
<target name="testStringResourceInline"> | |||||
<js > | |||||
<string > | |||||
self.log("Ant version =${ant.version}"); | |||||
project.setNewProperty("property","live"); | |||||
</string> | |||||
</js> | |||||
<scripttest/> | |||||
<assertPropSet /> | |||||
</target> | |||||
<target name="testPropertyResource"> | |||||
<js> | |||||
<propertyresource name="prop" /> | |||||
</js> | |||||
<scripttest/> | |||||
<assertPropSet /> | |||||
</target> | |||||
<target name="testMixedResources"> | |||||
<js > | |||||
<string refid="script.code" /> | |||||
<propertyresource name="prop" /> | |||||
<string > | |||||
project.setNewProperty("property2","live"); | |||||
</string> | |||||
</js> | |||||
<scripttest/> | |||||
<assertPropSet name="property2" /> | |||||
</target> | |||||
</project> |