Selectors are a mechanism whereby the files that make up a fileset
can be selected based on criteria other than filename as provided
by the <include> and <exclude>
tags.
A selector is an element of PatternSet, and appears within it. FileSets contain a default PatternSet, so they can support selectors directly.
Different selectors have different attributes. Some selectors can
also contain other selectors, and these are called Selector
Containers. There is also a category of selectors that allow
user-defined extensions, called Extend Selectors.
[Note] I've altered PatternSet so that it is a Selector, and FileSet so that it is a subclass of PatternSet. This shouldn't affect anyone since the inheritance of DataType is still being followed, but it has the very nice feature that all static selectors can be defined in one place: SelectorContainer. It also makes intuitive sense to me that FileSet is a type of PatternSet, one that is applied to a specific directory. Others may disagree. Once a selector is defined in SelectorContainer, it is available for use in PatternSets, FileSets, AndSelectors, OrSelectors, NotSelectors, and any other selector that inherits from SelectorContainer.
Right now, PatternSet inherits from AndSelector. This was done in
the mistaken belief that the includes and excludes could be emulated with
<filenameselect> and <not><filenameselect></not>.
In fact, the structure is really more like
<and>
<or>
<filenameselect/> <!-- include -->
<filenameselect/> <!-- include -->
</or>
<not>
<filenameselect/> <!-- exclude -->
<filenameselect/> <!-- exclude -->
</not>
</and>
which isn't quite the same. I'll be creating an includes/excludes
selector container for PatternSet to inherit from.
Here is a list of the selectors implemented so far.
The <sizeselect> tag in a PatternSet will put
a limit on the files specified by the include tag, so that tags
which do not meet the size limits specified by the selector will not
end up being selected.
| Attribute | Description | Required |
| size | The size of the file which should be tested for. | Yes |
| units | The units that the size is expressed in. When using the standard single letter SI designations, such as "k","M", or "G", multiples of 1000 are used. If you want to use power of 2 units, use the IEC standard: "Ki" for 1024, "Mi" for 1048576, and so on. The default is no units, which means the size attributes expresses the exact number of bytes. | No |
| when | Indicates how to interpret the size, whether
the files to be selected should be larger, smaller, or equal to
that value. Acceptable values for this attribute are:
| No |
Here is an example of how to use the Size Selector:
<fileset dir="${jar.path}">
<patternset>
<include name="**/*.jar"/>
<sizeselect size="4" units="Ki" when="more"/>
</patternset>
</fileset>
Selects all JAR files that are larger than 4096 bytes.
The <dateselect> tag in a PatternSet will put
a limit on the files specified by the include tag, so that tags
whose last modified date does not meet the date limits specified
by the selector will not end up being selected.
| Attribute | Description | Required |
| datetime | Specifies the date and time to test for using a string of the format MM/DD/YYYY HH:MM AM_or_PM. | At least one of the two. |
| millis | The number of milliseconds since 1970 that should be tested for. It is usually much easier to use the datetime attribute. If neither datetime nor millis is specified, then the current date and time is used. | |
| when | Indicates how to interpret the date, whether
the files to be selected are those whose last modified times should
be before, after, or equal to the specified value. Acceptable
values for this attribute are:
| No |
Here is an example of how to use the Date Selector:
<fileset dir="${jar.path}" includes="**/*.jar">
<dateselect datetime="01/01/2001 12:00 AM" when="before"/>
</fileset>
Selects all JAR files which were last modified before midnight January 1, 2001.
Other selectors already written that need documenting: <filenameselect>, <extendselect> (along with details as to how to go about writing your own selectors with it), <and>, <or>, <not>, and <majority>
Since this is just a demonstration right now, there are only a few selectors to look at. However, I hope to have many more within a few weeks. These include:
negate="true")
contain lines that match a regular expression.
Want to define your own selectors? It's easy!
First, pick the type of selector that you want to define. There are three types, and a recipe for each one follows:
org.apache.tools.ant.types.selectors.ISelector.
You can either choose to implement all methods yourself from
scratch, or you can extend
org.apache.tools.ant.types.selectors.BaseSelector
instead, a convenience class that provides reasonable default
behaviour for many methods.public String checkForError(), which should
do the checking to make sure all fields have valid data and
return null if there are no errors,
or an error message if there are any. An error message will
result in a BuildException being thrown with that message.
public boolean isSelected(String filename, File file)
is the real purpose of the exercise. It returns true or false
depending on whether the given file should be selected from
the list or not.
toString().
org.apache.tools.ant.types.selectors.SelectorContainer.
Once it is in there, it will be available everywhere that static
selectors are appropriate.
org.apache.tools.ant.types.selectors.SelectorContainer.
This will ensure that your new
Container can access any new selectors that come along.
public boolean isSelected(String filename, File file)
method to do the right thing. Chances are you'll want to iterate
over the selectors under you, so use
getSelectorElements() to do that. You probably won't
need to rewrite checkForError(), since it does the right
thing most of the time.
selector.properties file,
or specify the class name in the selectordef element.
Make sure that you don't try to define the selectordef
from the extendselect you are trying to use
it from, since the elements aren't created until after the attributes
are assigned, and that will get you an error.org.apache.tools.ant.types.selectors.IExtendSelector.
The easiest way to do that is through the convenience base class
org.apache.tools.ant.types.selectors.BaseExtendSelector,
which provides all of the methods you could need. Just override the
ones you actually want to use (using any of the rest will cause
BuildExceptions) and you are away.
For your convenience, the beginning of a test file is available in the test directory under the selectors directory. Eventually this will have to be integrated into Ant's testing framework, but in the meantime it can provide a quick test to see if things work the way you expect them to.
And that's about all I've got to say about that.