git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@278467 13f79535-47bb-0310-9956-ffa450edef68master
@@ -154,7 +154,7 @@ implementations are also usable as single-element | |||||
</tr> | </tr> | ||||
</table> | </table> | ||||
<p>The classpath along which to search for a Java resource | <p>The classpath along which to search for a Java resource | ||||
can also be specified by means of one or more nested | |||||
can also be specified by means of one or more nested | |||||
<code><a href="../using.html#path">classpath</a></code> elements. | <code><a href="../using.html#path">classpath</a></code> elements. | ||||
</p> | </p> | ||||
@@ -347,6 +347,8 @@ platforms. | |||||
- select resources selected by no nested resource selectors.</li> | - select resources selected by no nested resource selectors.</li> | ||||
<li><a href="#rsel.majority">majority</a> - select resources selected | <li><a href="#rsel.majority">majority</a> - select resources selected | ||||
by a majority of nested resource selectors.</li> | by a majority of nested resource selectors.</li> | ||||
<li><a href="selectors.html#modified">modified</a> - select resources which | |||||
content has changed.</li> | |||||
</ul> | </ul> | ||||
<h4><a name="rsel.name">name</a></h4> | <h4><a name="rsel.name">name</a></h4> | ||||
@@ -597,4 +599,4 @@ natural order, or by one or more nested resource comparators:</p> | |||||
Reserved.</p> | Reserved.</p> | ||||
</body> | </body> | ||||
</html> | |||||
</html> |
@@ -659,6 +659,12 @@ | |||||
The comparison, computing of the hashvalue and the store is done by implementation | The comparison, computing of the hashvalue and the store is done by implementation | ||||
of special interfaces. Therefore they may provide additional parameters.</p> | of special interfaces. Therefore they may provide additional parameters.</p> | ||||
<p>The <code><modified></code> selector can be used as ResourceSelector. | |||||
In that case it maps simple file resources to files and does its job. If the | |||||
resource is from another type, the <code><modified></code> selector tries | |||||
to (<b>attention!</b>) copy the content into a local file for computing the | |||||
hashvalue.</p> | |||||
<table border="1" cellpadding="2" cellspacing="0"> | <table border="1" cellpadding="2" cellspacing="0"> | ||||
<tr> | <tr> | ||||
<td valign="top"><b>Attribute</b></td> | <td valign="top"><b>Attribute</b></td> | ||||
@@ -729,6 +735,13 @@ | |||||
<td valign="top"> Should directories be selected? (boolean) </td> | <td valign="top"> Should directories be selected? (boolean) </td> | ||||
<td valign="top" align="center"> No, defaults to <i>true</i> </td> | <td valign="top" align="center"> No, defaults to <i>true</i> </td> | ||||
</tr> | </tr> | ||||
<tr> | |||||
<td valign="top"> selres </td> | |||||
<td valign="top"> Should Resources whithout an InputStream, and | |||||
therefore without checking, be selected? (boolean) </td> | |||||
<td valign="top" align="center"> No, defaults to <i>true</i>. Only relevant | |||||
when used as ResourceSelector. </td> | |||||
</tr> | |||||
<tr> | <tr> | ||||
<td valign="top"> delayupdate </td> | <td valign="top"> delayupdate </td> | ||||
<td valign="top"> If set to <i>true</i>, the storage of the cache will be delayed until the | <td valign="top"> If set to <i>true</i>, the storage of the cache will be delayed until the | ||||
@@ -932,7 +945,7 @@ | |||||
<h4>Script Selector</h4> | <h4>Script Selector</h4> | ||||
<p> | <p> | ||||
The <code><scriptselector></code> element enables you | |||||
The <code><scriptselector></code> element enables you | |||||
to write a complex selection algorithm in any | to write a complex selection algorithm in any | ||||
<a href="http://jakarta.apache.org/bsf" target="_top">Apache BSF</a> | <a href="http://jakarta.apache.org/bsf" target="_top">Apache BSF</a> | ||||
supported language.</p> | supported language.</p> | ||||
@@ -958,22 +971,22 @@ | |||||
<td valign="top">filename of the script</td> | <td valign="top">filename of the script</td> | ||||
<td valign="top" align="center">no</td> | <td valign="top" align="center">no</td> | ||||
</tr> | </tr> | ||||
</table> | |||||
</table> | |||||
<p> | <p> | ||||
If no <code>src</code> attribute is supplied, the script must be nested | If no <code>src</code> attribute is supplied, the script must be nested | ||||
inside the selector declaration. | |||||
inside the selector declaration. | |||||
</p> | </p> | ||||
<p>The embedded script is invoked for every test, with | <p>The embedded script is invoked for every test, with | ||||
the bean <code>self</code> | |||||
the bean <code>self</code> | |||||
is bound to the selector. It has an attribute <code>selected</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 | must can be set using <code>setSelected(boolean)</code> to select that | ||||
file. | file. | ||||
<p> | <p> | ||||
The following beans are configured for every script, alongside | The following beans are configured for every script, alongside | ||||
the classic set of project, properties, and targets. | the classic set of project, properties, and targets. | ||||
<table border="1" cellpadding="2" cellspacing="0"> | <table border="1" cellpadding="2" cellspacing="0"> | ||||
<tr> | <tr> | ||||
<td valign="top"><b>Bean</b></td> | <td valign="top"><b>Bean</b></td> | ||||
@@ -1000,13 +1013,13 @@ | |||||
<td valign="top">Fileset base directory</td> | <td valign="top">Fileset base directory</td> | ||||
<td valign="top" >java.io.File</td> | <td valign="top" >java.io.File</td> | ||||
</tr> | </tr> | ||||
</table> | |||||
</table> | |||||
<p> | <p> | ||||
The <code>self</code> bean maps to the selector, which has the following | The <code>self</code> bean maps to the selector, which has the following | ||||
attributes. Only the <code>selected</code> flag is writeable, the rest | |||||
attributes. Only the <code>selected</code> flag is writeable, the rest | |||||
are read only via their getter methods. | are read only via their getter methods. | ||||
<table border="1" cellpadding="2" cellspacing="0"> | <table border="1" cellpadding="2" cellspacing="0"> | ||||
<tr> | <tr> | ||||
<td valign="top"><b>Attribute</b></td> | <td valign="top"><b>Attribute</b></td> | ||||
@@ -1034,7 +1047,7 @@ | |||||
<td valign="top" >java.io.File</td> | <td valign="top" >java.io.File</td> | ||||
</tr> | </tr> | ||||
</table> | </table> | ||||
<p> | <p> | ||||
Example | Example | ||||
</p> | </p> | ||||
@@ -1053,7 +1066,7 @@ | |||||
</scriptselector> | </scriptselector> | ||||
</pre> | </pre> | ||||
Select files whose filename length is even. | Select files whose filename length is even. | ||||
<a name="selectcontainers"></a> | <a name="selectcontainers"></a> | ||||
<h3>Selector Containers</h3> | <h3>Selector Containers</h3> | ||||
@@ -1450,4 +1463,4 @@ Select files whose filename length is even. | |||||
</body> | </body> | ||||
</html> | |||||
</html> |
@@ -407,4 +407,12 @@ | |||||
<target name="all" | <target name="all" | ||||
depends="name,testexists,instanceof,testtype,testdate,testsize,logical" /> | depends="name,testexists,instanceof,testtype,testdate,testsize,logical" /> | ||||
<!-- | |||||
The tests for oata.types.selectors.ModifiedSelectorTest as | |||||
ResourceSelector are in its test-buildfile src\etc\testcases\types\selectors.xml. | |||||
--> | |||||
</project> | </project> |
@@ -261,4 +261,92 @@ | |||||
<property name="fs.full.value" refid="fs.full"/> | <property name="fs.full.value" refid="fs.full"/> | ||||
</target> | </target> | ||||
<target name="modifiedselectortest-ResourceSimple"> | |||||
<fail message="Didnt get the required numbers of Resources."> | |||||
<condition> | |||||
<not> | |||||
<resourcecount when="equal" count="3"> | |||||
<restrict> | |||||
<resources> | |||||
<file file="foo" /> | |||||
<resource name="foo" /> | |||||
<file file="foo" basedir="${basedir}" /> | |||||
</resources> | |||||
<modified selres="true" xmlns="antlib:org.apache.tools.ant.types.resources.selectors"/> | |||||
</restrict> | |||||
</resourcecount> | |||||
</not> | |||||
</condition> | |||||
</fail> | |||||
</target> | |||||
<target name="modifiedselectortest-ResourceSelresTrue"> | |||||
<fail message="Got the Resource, but should."> | |||||
<condition> | |||||
<not> | |||||
<resourcecount when="equal" count="1"> | |||||
<restrict> | |||||
<resources> | |||||
<resource name="notExisting" /> | |||||
</resources> | |||||
<modified selres="true" xmlns="antlib:org.apache.tools.ant.types.resources.selectors"/> | |||||
</restrict> | |||||
</resourcecount> | |||||
</not> | |||||
</condition> | |||||
</fail> | |||||
</target> | |||||
<target name="modifiedselectortest-ResourceSelresFalse"> | |||||
<fail message="Got the Resource, but should not."> | |||||
<condition> | |||||
<not> | |||||
<resourcecount when="equal" count="0"> | |||||
<restrict> | |||||
<resources> | |||||
<resource name="notExisting" /> | |||||
</resources> | |||||
<modified selres="false" xmlns="antlib:org.apache.tools.ant.types.resources.selectors"/> | |||||
</restrict> | |||||
</resourcecount> | |||||
</not> | |||||
</condition> | |||||
</fail> | |||||
</target> | |||||
<target name="modifiedselectortest-scenario-resourceSimple" depends="modifiedselectortest-scenario-prepare"> | |||||
<macrodef name="check"> | |||||
<attribute name="count"/> | |||||
<attribute name="message"/> | |||||
<sequential> | |||||
<fail message="@{message}"> | |||||
<condition> | |||||
<not> | |||||
<resourcecount when="equal" count="@{count}"> | |||||
<restrict> | |||||
<resources> | |||||
<fileset dir="${test.dir}/src"/> | |||||
</resources> | |||||
<modified selres="false" xmlns="antlib:org.apache.tools.ant.types.resources.selectors"/> | |||||
</restrict> | |||||
</resourcecount> | |||||
</not> | |||||
</condition> | |||||
</fail> | |||||
</sequential> | |||||
</macrodef> | |||||
<!-- select first time and create cachefile --> | |||||
<check count="14" message="Initial set of files not ok."/> | |||||
<!-- check second time: nothing should be selected --> | |||||
<check count="0" message="Selected files but shouldnt."/> | |||||
<!-- 'modify' the source files --> | |||||
<antcall target="modifiedselectortest-scenario-makeDirty"/> | |||||
<!-- copy third time: only the files with new CONTENT should be copied --> | |||||
<check count="2" message="Didnt select the 2 modified files."/> | |||||
</target> | |||||
</project> | </project> |
@@ -33,7 +33,11 @@ import org.apache.tools.ant.BuildEvent; | |||||
import org.apache.tools.ant.types.EnumeratedAttribute; | import org.apache.tools.ant.types.EnumeratedAttribute; | ||||
import org.apache.tools.ant.types.Parameter; | import org.apache.tools.ant.types.Parameter; | ||||
import org.apache.tools.ant.types.Path; | import org.apache.tools.ant.types.Path; | ||||
import org.apache.tools.ant.types.Resource; | |||||
import org.apache.tools.ant.types.resources.FileResource; | |||||
import org.apache.tools.ant.types.resources.selectors.ResourceSelector; | |||||
import org.apache.tools.ant.types.selectors.BaseExtendSelector; | import org.apache.tools.ant.types.selectors.BaseExtendSelector; | ||||
import org.apache.tools.ant.util.FileUtils; | |||||
/** | /** | ||||
@@ -228,10 +232,11 @@ import org.apache.tools.ant.types.selectors.BaseExtendSelector; | |||||
* a nested <i><param name="algorithm.provider" value="MyProvider"/></i>. | * a nested <i><param name="algorithm.provider" value="MyProvider"/></i>. | ||||
* | * | ||||
* | * | ||||
* @version 2004-07-12 | |||||
* @version 2005-07-19 | |||||
* @since Ant 1.6 | * @since Ant 1.6 | ||||
*/ | */ | ||||
public class ModifiedSelector extends BaseExtendSelector implements BuildListener { | |||||
public class ModifiedSelector extends BaseExtendSelector | |||||
implements BuildListener, ResourceSelector { | |||||
// ----- attributes ----- | // ----- attributes ----- | ||||
@@ -261,6 +266,12 @@ public class ModifiedSelector extends BaseExtendSelector implements BuildListene | |||||
/** Are directories selected? */ | /** Are directories selected? */ | ||||
private boolean selectDirectories = true; | private boolean selectDirectories = true; | ||||
/** | |||||
* Should Resources whithout an InputStream, and | |||||
* therefore without checking, be selected? | |||||
*/ | |||||
private boolean selectResourcesWithoutInputStream = true; | |||||
/** Delay the writing of the cache file */ | /** Delay the writing of the cache file */ | ||||
private boolean delayUpdate = true; | private boolean delayUpdate = true; | ||||
@@ -506,14 +517,73 @@ public class ModifiedSelector extends BaseExtendSelector implements BuildListene | |||||
// ----- the selection work ----- | // ----- the selection work ----- | ||||
/** | |||||
* Implementation of ResourceSelector.isSelected(). | |||||
* | |||||
* @param resource The resource to check | |||||
* @return whether the resource is selected | |||||
* @see org.apache.tools.ant.types.resources.selectors.ResourceSelector#isSelected(org.apache.tools.ant.types.Resource) | |||||
*/ | |||||
public boolean isSelected(Resource resource) { | |||||
if (resource.isFilesystemOnly()) { | |||||
// We have a 'resourced' file, so reconvert it and use | |||||
// the 'old' implementation. | |||||
FileResource fileResource = (FileResource) resource; | |||||
File file = fileResource.getFile(); | |||||
String filename = fileResource.getName(); | |||||
File basedir = fileResource.getBaseDir(); | |||||
return isSelected(basedir, filename, file); | |||||
} else { | |||||
try { | |||||
// How to handle non-file-Resources? I copy temporarily the | |||||
// resource to a file and use the file-implementation. | |||||
FileUtils fu = FileUtils.getFileUtils(); | |||||
File tmpFile = fu.createTempFile("modified-", ".tmp", null); | |||||
Resource tmpResource = new FileResource(tmpFile); | |||||
fu.copyResource(resource, tmpResource); | |||||
boolean isSelected = isSelected(tmpFile.getParentFile(), | |||||
tmpFile.getName(), | |||||
resource.toLongString()); | |||||
tmpFile.delete(); | |||||
return isSelected; | |||||
} catch (UnsupportedOperationException uoe) { | |||||
log("The resource '" | |||||
+ resource.getName() | |||||
+ "' does not provide an InputStream, so it is not checked. " | |||||
+ "Akkording to 'selres' attribute value it is " | |||||
+ ((selectResourcesWithoutInputStream) ? "" : " not") | |||||
+ "selected.", Project.MSG_INFO); | |||||
return selectResourcesWithoutInputStream; | |||||
} catch (Exception e) { | |||||
throw new BuildException(e); | |||||
} | |||||
} | |||||
} | |||||
/** | /** | ||||
* Implementation of BaseExtendSelector.isSelected(). | * Implementation of BaseExtendSelector.isSelected(). | ||||
* | |||||
* @param basedir as described in BaseExtendSelector | * @param basedir as described in BaseExtendSelector | ||||
* @param filename as described in BaseExtendSelector | * @param filename as described in BaseExtendSelector | ||||
* @param file as described in BaseExtendSelector | * @param file as described in BaseExtendSelector | ||||
* @return as described in BaseExtendSelector | * @return as described in BaseExtendSelector | ||||
*/ | */ | ||||
public boolean isSelected(File basedir, String filename, File file) { | public boolean isSelected(File basedir, String filename, File file) { | ||||
return isSelected(basedir, filename, file.getAbsolutePath()); | |||||
} | |||||
/** | |||||
* The business logic of this selector for use as ResourceSelector of | |||||
* FileSelector. | |||||
* | |||||
* @param basedir as described in BaseExtendSelector | |||||
* @param filename as described in BaseExtendSelector | |||||
* @param cacheKey the name for the key for storing the hashvalue | |||||
* @return | |||||
*/ | |||||
private boolean isSelected(File basedir, String filename, String cacheKey) { | |||||
validate(); | validate(); | ||||
File f = new File(basedir, filename); | File f = new File(basedir, filename); | ||||
@@ -524,7 +594,7 @@ public class ModifiedSelector extends BaseExtendSelector implements BuildListene | |||||
// Get the values and do the comparison | // Get the values and do the comparison | ||||
String cachedValue = String.valueOf(cache.get(f.getAbsolutePath())); | String cachedValue = String.valueOf(cache.get(f.getAbsolutePath())); | ||||
String newValue = algorithm.getValue(f); | |||||
String newValue = algorithm.getValue(f); | |||||
boolean rv = (comparator.compare(cachedValue, newValue) != 0); | boolean rv = (comparator.compare(cachedValue, newValue) != 0); | ||||
@@ -600,6 +670,15 @@ public class ModifiedSelector extends BaseExtendSelector implements BuildListene | |||||
} | } | ||||
/** | |||||
* Support for <i>selres</i> attribute. | |||||
* @param newValue the new value | |||||
*/ | |||||
public void setSelres(boolean newValue) { | |||||
this.selectResourcesWithoutInputStream = newValue; | |||||
} | |||||
/** | /** | ||||
* Getter for the modified count | * Getter for the modified count | ||||
* @return modified count | * @return modified count | ||||
@@ -964,4 +1043,5 @@ public class ModifiedSelector extends BaseExtendSelector implements BuildListene | |||||
return new String[] {"equal", "rule" }; | return new String[] {"equal", "rule" }; | ||||
} | } | ||||
} | } | ||||
} | } |
@@ -21,4 +21,6 @@ | |||||
classname="org.apache.tools.ant.types.resources.selectors.Size" /> | classname="org.apache.tools.ant.types.resources.selectors.Size" /> | ||||
<typedef name="date" | <typedef name="date" | ||||
classname="org.apache.tools.ant.types.resources.selectors.Date" /> | classname="org.apache.tools.ant.types.resources.selectors.Date" /> | ||||
<typedef name="modified" | |||||
classname="org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector" /> | |||||
</antlib> | </antlib> |
@@ -43,7 +43,7 @@ import org.apache.tools.ant.util.FileUtils; | |||||
/** | /** | ||||
* Unit tests for ModifiedSelector. | * Unit tests for ModifiedSelector. | ||||
* | * | ||||
* @version 2004-07-12 | |||||
* @version 2005-07-19 | |||||
* @since Ant 1.6 | * @since Ant 1.6 | ||||
*/ | */ | ||||
public class ModifiedSelectorTest extends BaseSelectorTest { | public class ModifiedSelectorTest extends BaseSelectorTest { | ||||