git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@277368 13f79535-47bb-0310-9956-ffa450edef68master
@@ -1537,6 +1537,10 @@ | |||||
unless="bsf.present"/> | unless="bsf.present"/> | ||||
<exclude name="${optional.package}/BeanShellScriptTest.java" | <exclude name="${optional.package}/BeanShellScriptTest.java" | ||||
unless="beanshell.present"/> | unless="beanshell.present"/> | ||||
<exclude name="${optional.type.package}/Script/*.java" | |||||
unless="bsf.present"/> | |||||
<exclude name="${optional.type.package}/Script/*.java" | |||||
unless="rhino.present"/> | |||||
<!-- fail if testcases can be loaded from the system classloader --> | <!-- fail if testcases can be loaded from the system classloader --> | ||||
<exclude name="${ant.package}/AntClassLoaderDelegationTest.java" | <exclude name="${ant.package}/AntClassLoaderDelegationTest.java" | ||||
@@ -927,7 +927,132 @@ | |||||
</tr> | </tr> | ||||
</table> | </table> | ||||
<a name="scriptselector"></a> | |||||
<h4>Script Selector</h4> | |||||
<p> | |||||
The <code><scriptselector></code> element enables you | |||||
to write a complex selection algorithm in any | |||||
<a href="http://jakarta.apache.org/bsf" target="_top">Apache BSF</a> | |||||
supported language.</p> | |||||
See the <a href="../OptionalTasks/script.html">Script</a> task for | |||||
an explanation of scripts and dependencies. | |||||
</p> | |||||
<p> | |||||
This selector was added in Apache Ant 1.7. | |||||
</p> | |||||
<table border="1" cellpadding="2" cellspacing="0"> | |||||
<tr> | |||||
<td valign="top"><b>Attribute</b></td> | |||||
<td valign="top"><b>Description</b></td> | |||||
<td align="center" valign="top"><b>Required</b></td> | |||||
</tr> | |||||
<tr> | |||||
<td valign="top">language</td> | |||||
<td valign="top">language of the script.</td> | |||||
<td valign="top" align="center">yes</td> | |||||
</tr> | |||||
<tr> | |||||
<td valign="top">src</td> | |||||
<td valign="top">filename of the script</td> | |||||
<td valign="top" align="center">no</td> | |||||
</tr> | |||||
</table> | |||||
<p> | |||||
If no <code>src</code> attribute is supplied, the script must be nested | |||||
inside the selector declaration. | |||||
</p> | |||||
<p>The embedded script is invoked for every test, with | |||||
the bean <code>self</code> | |||||
is bound to the selector. It has an attribute <code>selected</code> | |||||
must can be set using <code>setSelected(boolean)</code> to select that | |||||
file. | |||||
<p> | |||||
The following beans are configured for every script, alongside | |||||
the classic set of project, properties, and targets. | |||||
<table border="1" cellpadding="2" cellspacing="0"> | |||||
<tr> | |||||
<td valign="top"><b>Bean</b></td> | |||||
<td valign="top"><b>Description</b></td> | |||||
<td valign="top"><b>Type</b></td> | |||||
</tr> | |||||
<tr> | |||||
<td valign="top">self</td> | |||||
<td valign="top">selector instance</td> | |||||
<td valign="top">org.apache.tools.ant.types.optional</td> | |||||
</tr> | |||||
<tr> | |||||
<td valign="top">filename</td> | |||||
<td valign="top">filename of the selection</td> | |||||
<td valign="top" >String</td> | |||||
</tr> | |||||
<tr> | |||||
<td valign="top">file</td> | |||||
<td valign="top">file of the selection</td> | |||||
<td valign="top" >java.io.File</td> | |||||
</tr> | |||||
<tr> | |||||
<td valign="top">basedir</td> | |||||
<td valign="top">Fileset base directory</td> | |||||
<td valign="top" >java.io.File</td> | |||||
</tr> | |||||
</table> | |||||
<p> | |||||
The <code>self</code> bean maps to the selector, which has the following | |||||
attributes. Only the <code>selected</code> flag is writeable, the rest | |||||
are read only via their getter methods. | |||||
<table border="1" cellpadding="2" cellspacing="0"> | |||||
<tr> | |||||
<td valign="top"><b>Attribute</b></td> | |||||
<td valign="top"><b>Description</b></td> | |||||
<td align="center" valign="top"><b>Type</b></td> | |||||
</tr> | |||||
<tr> | |||||
<td valign="top">selected</td> | |||||
<td valign="top">writeable flag to select this file</td> | |||||
<td valign="top" align="center">boolean</td> | |||||
</tr> | |||||
<tr> | |||||
<td valign="top">filename</td> | |||||
<td valign="top">filename of the selection</td> | |||||
<td valign="top" >String</td> | |||||
</tr> | |||||
<tr> | |||||
<td valign="top">file</td> | |||||
<td valign="top">file of the selection</td> | |||||
<td valign="top" >java.io.File</td> | |||||
</tr> | |||||
<tr> | |||||
<td valign="top">basedir</td> | |||||
<td valign="top">Fileset base directory</td> | |||||
<td valign="top" >java.io.File</td> | |||||
</tr> | |||||
</table> | |||||
<p> | |||||
Example | |||||
</p> | |||||
<pre> | |||||
<scriptselector language="javascript"> | |||||
self.setSelected(true); | |||||
</scriptselector> | |||||
</pre> | |||||
<p> | |||||
Selects every file. | |||||
</p> | |||||
<pre> | |||||
<scriptselector language="javascript"> | |||||
self.setSelected((filename.length%2)==0); | |||||
</scriptselector> | |||||
</pre> | |||||
Select files whose filename length is even. | |||||
<a name="selectcontainers"></a> | <a name="selectcontainers"></a> | ||||
<h3>Selector Containers</h3> | <h3>Selector Containers</h3> | ||||
@@ -0,0 +1,123 @@ | |||||
<project name="scriptselector" default="def" basedir="."> | |||||
<property name="src.file" location="${ant.file}" /> | |||||
<macrodef name="testselected"> | |||||
<element name="selector" implicit="yes" optional="true"/> | |||||
<attribute name="message"/> | |||||
<sequential> | |||||
<fail message="@{message} failed: file was not selected"> | |||||
<condition> | |||||
<not> | |||||
<isfileselected file="{src.file}"> | |||||
<selector/> | |||||
</isfileselected> | |||||
</not> | |||||
</condition> | |||||
</fail> | |||||
</sequential> | |||||
</macrodef> | |||||
<macrodef name="testnoselected"> | |||||
<element name="selector" implicit="yes" optional="true"/> | |||||
<attribute name="message"/> | |||||
<sequential> | |||||
<fail message="@{message} failed: file was selected"> | |||||
<condition> | |||||
<isfileselected file="{src.file}"> | |||||
<selector/> | |||||
</isfileselected> | |||||
</condition> | |||||
</fail> | |||||
</sequential> | |||||
</macrodef> | |||||
<!-- this is here to test the macro is well coded --> | |||||
<target name="testNoSelector"> | |||||
<testselected message="testNoSelector" > | |||||
</testselected> | |||||
</target> | |||||
<target name="testNolanguage"> | |||||
<testselected message="testNolanguage" > | |||||
<selector> | |||||
<scriptselector > | |||||
self.setSelected(true); | |||||
</scriptselector> | |||||
</selector> | |||||
</testselected> | |||||
<scriptdef name="nolang"> | |||||
</scriptdef> | |||||
</target> | |||||
<target name="testSelectionSetByDefault"> | |||||
<testselected message="testSelectionSetByDefault" > | |||||
<selector> | |||||
<scriptselector language="javascript"> | |||||
</scriptselector> | |||||
</selector> | |||||
</testselected> | |||||
</target> | |||||
<target name="testSelectionSetWorks"> | |||||
<testselected message="testSelectionSetWorks" > | |||||
<selector> | |||||
<scriptselector language="javascript"> | |||||
self.setSelected(false); | |||||
self.setSelected(true); | |||||
</scriptselector> | |||||
</selector> | |||||
</testselected> | |||||
</target> | |||||
<target name="testSelectionClearWorks"> | |||||
<testnoselected message="testSelectionClearWorks"> | |||||
<selector> | |||||
<scriptselector language="javascript"> | |||||
self.setSelected(false); | |||||
</scriptselector> | |||||
</selector> | |||||
</testnoselected> | |||||
</target> | |||||
<target name="testFileAttribute"> | |||||
<testselected message="testFileAttribute" > | |||||
<selector> | |||||
<scriptselector language="javascript"> | |||||
self.setSelected(file.equals(self.getFile())); | |||||
</scriptselector> | |||||
</selector> | |||||
</testselected> | |||||
</target> | |||||
<target name="testFilenameAttribute"> | |||||
<testselected message="testFilenameAttribute" > | |||||
<selector> | |||||
<scriptselector language="javascript"> | |||||
self.setSelected(filename.equals(self.getFilename())); | |||||
</scriptselector> | |||||
</selector> | |||||
</testselected> | |||||
</target> | |||||
<target name="testBasedirAttribute"> | |||||
<testselected message="testBasedirAttribute" > | |||||
<selector> | |||||
<scriptselector language="javascript"> | |||||
self.setSelected(basedir.equals(self.getBasedir())); | |||||
</scriptselector> | |||||
</selector> | |||||
</testselected> | |||||
</target> | |||||
<target name="notestFilenameLength"> | |||||
<testselected message="notestFilenameLength" > | |||||
<selector> | |||||
<scriptselector language="javascript"> | |||||
self.setSelected((filename.length%2)==0); | |||||
</scriptselector> | |||||
</selector> | |||||
</testselected> | |||||
</target> | |||||
</project> |
@@ -49,13 +49,7 @@ public class Script extends Task { | |||||
runner.addText(text); | runner.addText(text); | ||||
} | } | ||||
runner.addBeans(getProject().getProperties()); | |||||
runner.addBeans(getProject().getUserProperties()); | |||||
runner.addBeans(getProject().getTargets()); | |||||
runner.addBeans(getProject().getReferences()); | |||||
runner.addBean("project", getProject()); | |||||
runner.addBean("self", this); | |||||
runner.bindToComponent(this); | |||||
runner.executeScript("ANT"); | runner.executeScript("ANT"); | ||||
} | } | ||||
@@ -39,3 +39,4 @@ issigned=org.apache.tools.ant.taskdefs.condition.IsSigned | |||||
isfileselected=org.apache.tools.ant.taskdefs.condition.IsFileSelected | isfileselected=org.apache.tools.ant.taskdefs.condition.IsFileSelected | ||||
ispingable=org.apache.tools.ant.taskdefs.optional.condition.IsPingable | ispingable=org.apache.tools.ant.taskdefs.optional.condition.IsPingable | ||||
mavenrepository=org.apache.tools.ant.taskdefs.repository.MavenRepository | mavenrepository=org.apache.tools.ant.taskdefs.repository.MavenRepository | ||||
scriptselector=org.apache.tools.ant.types.optional.ScriptSelector |
@@ -1,5 +1,5 @@ | |||||
/* | /* | ||||
* Copyright 2003-2004 The Apache Software Foundation | |||||
* Copyright 2003-2005 The Apache Software Foundation | |||||
* | * | ||||
* Licensed under the Apache License, Version 2.0 (the "License"); | * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
* you may not use this file except in compliance with the License. | * you may not use this file except in compliance with the License. | ||||
@@ -60,14 +60,7 @@ public class ScriptFilter extends TokenFilter.ChainableReaderFilter { | |||||
return; | return; | ||||
} | } | ||||
initialized = true; | initialized = true; | ||||
runner.addBeans(getProject().getProperties()); | |||||
runner.addBeans(getProject().getUserProperties()); | |||||
runner.addBeans(getProject().getTargets()); | |||||
runner.addBeans(getProject().getReferences()); | |||||
runner.addBean("project", getProject()); | |||||
runner.addBean("self", this); | |||||
runner.bindToComponent(this); | |||||
} | } | ||||
/** | /** | ||||
@@ -0,0 +1,161 @@ | |||||
/* | |||||
* Copyright 2005 The Apache Software Foundation | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* | |||||
*/ | |||||
package org.apache.tools.ant.types.optional; | |||||
import org.apache.tools.ant.types.selectors.BaseSelector; | |||||
import org.apache.tools.ant.util.ScriptRunner; | |||||
import org.apache.tools.ant.BuildException; | |||||
import java.io.File; | |||||
/** | |||||
* Selector that lets you run a script with selection logic inline | |||||
* @since Ant1.7 | |||||
*/ | |||||
public class ScriptSelector extends BaseSelector { | |||||
/** | |||||
* Has this object been initialized ? | |||||
*/ | |||||
private boolean initialized = false; | |||||
/** | |||||
* script runner | |||||
*/ | |||||
private ScriptRunner runner = new ScriptRunner(); | |||||
/** | |||||
* fields updated for every selection | |||||
*/ | |||||
private File basedir; | |||||
private String filename; | |||||
private File file; | |||||
/** | |||||
* selected flag | |||||
*/ | |||||
private boolean selected; | |||||
/** | |||||
* Defines the language (required). | |||||
* | |||||
* @param language the scripting language name for the script. | |||||
*/ | |||||
public void setLanguage(String language) { | |||||
runner.setLanguage(language); | |||||
} | |||||
/** | |||||
* Initialize on demand. | |||||
* | |||||
* @throws org.apache.tools.ant.BuildException | |||||
* if someting goes wrong | |||||
*/ | |||||
private void init() throws BuildException { | |||||
if (initialized) { | |||||
return; | |||||
} | |||||
initialized = true; | |||||
runner.bindToComponent(this); | |||||
} | |||||
/** | |||||
* Load the script from an external file ; optional. | |||||
* | |||||
* @param file the file containing the script source. | |||||
*/ | |||||
public void setSrc(File file) { | |||||
runner.setSrc(file); | |||||
} | |||||
/** | |||||
* The script text. | |||||
* | |||||
* @param text a component of the script text to be added. | |||||
*/ | |||||
public void addText(String text) { | |||||
runner.addText(text); | |||||
} | |||||
/** | |||||
* Method that each selector will implement to create their selection | |||||
* behaviour. If there is a problem with the setup of a selector, it can | |||||
* throw a BuildException to indicate the problem. | |||||
* | |||||
* @param basedir A java.io.File object for the base directory | |||||
* @param filename The name of the file to check | |||||
* @param file A File object for this filename | |||||
* | |||||
* @return whether the file should be selected or not | |||||
*/ | |||||
public boolean isSelected(File basedir, String filename, File file) { | |||||
init(); | |||||
setSelected(true); | |||||
this.file=file; | |||||
this.basedir=basedir; | |||||
this.filename=filename; | |||||
runner.addBean("basedir", basedir); | |||||
runner.addBean("filename", filename); | |||||
runner.addBean("file", file); | |||||
runner.executeScript("<ANT-Selector>"); | |||||
return isSelected(); | |||||
} | |||||
/** | |||||
* get the base directory | |||||
* @return | |||||
*/ | |||||
public File getBasedir() { | |||||
return basedir; | |||||
} | |||||
/** | |||||
* get the filename of the file | |||||
* @return | |||||
*/ | |||||
public String getFilename() { | |||||
return filename; | |||||
} | |||||
/** | |||||
* get the file that is currently to be tested | |||||
* @return | |||||
*/ | |||||
public File getFile() { | |||||
return file; | |||||
} | |||||
/** | |||||
* get state of selected flag | |||||
* @return | |||||
*/ | |||||
public boolean isSelected() { | |||||
return selected; | |||||
} | |||||
/** | |||||
* set the selected state | |||||
* Intended for script use, not as an Ant attribute | |||||
* @param selected | |||||
*/ | |||||
public void setSelected(boolean selected) { | |||||
this.selected = selected; | |||||
} | |||||
} |
@@ -1,5 +1,5 @@ | |||||
/* | /* | ||||
* Copyright 2003-2004 The Apache Software Foundation | |||||
* Copyright 2003-2005 The Apache Software Foundation | |||||
* | * | ||||
* Licensed under the Apache License, Version 2.0 (the "License"); | * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
* you may not use this file except in compliance with the License. | * you may not use this file except in compliance with the License. | ||||
@@ -22,6 +22,9 @@ 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.BuildException; | import org.apache.tools.ant.BuildException; | ||||
import org.apache.tools.ant.ProjectComponent; | |||||
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; | ||||
@@ -190,4 +193,20 @@ public class ScriptRunner { | |||||
public void addText(String text) { | public void addText(String text) { | ||||
this.script += text; | this.script += text; | ||||
} | } | ||||
/** | |||||
* Bind the runner to a project component. | |||||
* Properties, targets and references are all added as beans; | |||||
* project is bound to project, and self to the component. | |||||
* @param component to become <code>self</code> | |||||
*/ | |||||
public void bindToComponent(ProjectComponent component) { | |||||
Project project=component.getProject(); | |||||
addBeans(project.getProperties()); | |||||
addBeans(project.getUserProperties()); | |||||
addBeans(project.getTargets()); | |||||
addBeans(project.getReferences()); | |||||
addBean("project", project); | |||||
addBean("self", component); | |||||
} | |||||
} | } |
@@ -0,0 +1,60 @@ | |||||
/* | |||||
* Copyright 2005 The Apache Software Foundation | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* | |||||
*/ | |||||
package org.apache.tools.ant.types.optional; | |||||
import org.apache.tools.ant.BuildFileTest; | |||||
/** | |||||
* Test that scripting selection works. Needs scripting support to work | |||||
*/ | |||||
public class ScriptSelectorTest extends BuildFileTest { | |||||
public ScriptSelectorTest(String name) { | |||||
super(name); | |||||
} | |||||
public void setUp() { | |||||
configureProject("src/etc/testcases/types/selectors/scriptselector.xml"); | |||||
} | |||||
public void testNolanguage() { | |||||
expectBuildExceptionContaining("testNolanguage", | |||||
"Absence of language attribute not detected", | |||||
"script language must be specified"); | |||||
} | |||||
public void testSelectionSetByDefault() { | |||||
executeTarget("testSelectionSetByDefault"); | |||||
} | |||||
public void testSelectionSetWorks() { | |||||
executeTarget("testSelectionSetWorks"); | |||||
} | |||||
public void testSelectionClearWorks() { | |||||
executeTarget("testSelectionClearWorks"); | |||||
} | |||||
public void testFilenameAttribute() { | |||||
executeTarget("testFilenameAttribute"); | |||||
} | |||||
public void testFileAttribute() { | |||||
executeTarget("testFileAttribute"); | |||||
} | |||||
public void testBasedirAttribute() { | |||||
executeTarget("testBasedirAttribute"); | |||||
} | |||||
} |