Browse Source

Adding scripting support to selectors. No personal need for this right now, just rounding off what you can now do with mappers via filterchains

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@277368 13f79535-47bb-0310-9956-ffa450edef68
master
Steve Loughran 20 years ago
parent
commit
5fa7f18c21
9 changed files with 497 additions and 17 deletions
  1. +4
    -0
      build.xml
  2. +125
    -0
      docs/manual/CoreTypes/selectors.html
  3. +123
    -0
      src/etc/testcases/types/selectors/scriptselector.xml
  4. +1
    -7
      src/main/org/apache/tools/ant/taskdefs/optional/Script.java
  5. +1
    -0
      src/main/org/apache/tools/ant/types/defaults.properties
  6. +2
    -9
      src/main/org/apache/tools/ant/types/optional/ScriptFilter.java
  7. +161
    -0
      src/main/org/apache/tools/ant/types/optional/ScriptSelector.java
  8. +20
    -1
      src/main/org/apache/tools/ant/util/ScriptRunner.java
  9. +60
    -0
      src/testcases/org/apache/tools/ant/types/optional/ScriptSelectorTest.java

+ 4
- 0
build.xml View File

@@ -1537,6 +1537,10 @@
unless="bsf.present"/>
<exclude name="${optional.package}/BeanShellScriptTest.java"
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 -->
<exclude name="${ant.package}/AntClassLoaderDelegationTest.java"


+ 125
- 0
docs/manual/CoreTypes/selectors.html View File

@@ -927,7 +927,132 @@
</tr>
</table>

<a name="scriptselector"></a>
<h4>Script Selector</h4>

<p>
The <code>&lt;scriptselector&gt;</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>
&lt;scriptselector language=&quot;javascript&quot;&gt;
self.setSelected(true);
&lt;/scriptselector&gt;
</pre>
<p>
Selects every file.
</p>

<pre>
&lt;scriptselector language=&quot;javascript&quot;&gt;
self.setSelected((filename.length%2)==0);
&lt;/scriptselector&gt;
</pre>
Select files whose filename length is even.
<a name="selectcontainers"></a>
<h3>Selector Containers</h3>



+ 123
- 0
src/etc/testcases/types/selectors/scriptselector.xml View File

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

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

@@ -49,13 +49,7 @@ public class Script extends Task {
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");
}


+ 1
- 0
src/main/org/apache/tools/ant/types/defaults.properties View File

@@ -39,3 +39,4 @@ issigned=org.apache.tools.ant.taskdefs.condition.IsSigned
isfileselected=org.apache.tools.ant.taskdefs.condition.IsFileSelected
ispingable=org.apache.tools.ant.taskdefs.optional.condition.IsPingable
mavenrepository=org.apache.tools.ant.taskdefs.repository.MavenRepository
scriptselector=org.apache.tools.ant.types.optional.ScriptSelector

+ 2
- 9
src/main/org/apache/tools/ant/types/optional/ScriptFilter.java View File

@@ -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");
* you may not use this file except in compliance with the License.
@@ -60,14 +60,7 @@ public class ScriptFilter extends TokenFilter.ChainableReaderFilter {
return;
}
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);
}

/**


+ 161
- 0
src/main/org/apache/tools/ant/types/optional/ScriptSelector.java View File

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

}

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

@@ -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");
* 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.BSFManager;
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.HashMap;
import java.util.Iterator;
@@ -190,4 +193,20 @@ public class ScriptRunner {
public void addText(String 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);
}
}

+ 60
- 0
src/testcases/org/apache/tools/ant/types/optional/ScriptSelectorTest.java View File

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

}

Loading…
Cancel
Save