On Mon, Mar 14, 2011 at 05:26:17PM +0100, Stefan Bodewig wrote:
> RAT creates a commons-io WildcardFileFilter from each exclude provided
> which behaves like Unix glob matchers (* and ? work like expected),
> except that they are applied to the children of a directory
> immediately. This means you can only match on the filename but not on
> its path.
Looking at the code, I don't think this behavior was intended. Here's the
ignored() method from Walker.java:
protected final boolean ignored(final File file) {
boolean result = false;
final String name = file.getName();
final File dir = file.getParentFile();
if (filter != null) {
result = !filter.accept(dir, name);
}
return result;
}
Since the filter is being supplied with both the dir and the filename, it sure
looks to me like the author wanted the filter to take both into account.
I believe the problem arose because of the commons-io WildcardFileFilter
interface.
WildcardFileFilter's accept(File, String) method is really weird. It takes a
directory, but doesn't do anything with it:
public boolean accept(File dir, String name) {
for (String wildcard : wildcards) {
if (FilenameUtils.wildcardMatch(name, wildcard, caseSensitivity)) {
return true;
}
}
return false;
}
I guess it couldn't behave any other way. If WildcardFileFilter wanted to pay
attention to the directory, it would have to break up the wildcard pattern
into one part for the filename and one part for the directory -- which I'm
pretty sure is impossible.
So, if RAT wants to work with WildcardFileFilter in such a way that it *does*
pay attention to the dir, it has to invoke accept(File) from the
java.io.FileFilter interface (which WildcardFileFilter implements in addition
to java.io.FilenameFilter). Here's how the ignored() method would have to
change:
protected final boolean ignored(final File file) {
boolean result = false;
- final String name = file.getName();
- final File dir = file.getParentFile();
if (filter != null) {
- result = !filter.accept(dir, name);
+ result = !filter.accept(file);
}
return result;
}
However, Walker's public API is built around FilenameFilter. It wouldn't be
easy to migrate to FileFilter.
java.io.FilenameFilter and monolithic path-matching patterns are just a bad
mix. Arguably, WildcardFileFilter shouldn't implement FilenameFilter, because
it produces such counter-intuitive behavior.
I don't think RAT's CLI is fixable to match paths without breaking backwards
compatibility.
Marvin Humphrey