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