Reputation: 3050
I have a code like
private void processFiles() {
try {
Files.walk(Paths.get(Configurations.SOURCE_PATH))
.filter(new NoDestinationPathFilter()) //<--This one
.filter(new NoMetaFilesOrDirectories()) //<--and this too
.forEach(
path -> {
new FileProcessorFactory().getFileProcessor(
path).process(path);
});
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
As of now I have various other methods, which are same as the above one, with only difference in the filters. Some methods have additional filters, some have different or none.
Is it possible, that I create a collection of filters required for a condition and pass in dynamically. And all the filters in the collection are applied on the stream. I do not want to hard-code the list of filters being applied. I want to make it configuration based. How do I achieve that?
Upvotes: 1
Views: 509
Reputation: 3050
How about this?
private void processFiles(List<Predicate<Path>> filterList) {
Predicate<Path> compositeFilter=filterList.stream().reduce(w -> true, Predicate::and);
try {
Files.walk(Paths.get(Configurations.SOURCE_PATH))
.filter(compositeFilter)
.forEach(path -> {
new FileProcessorFactory().getFileProcessor(
path).process(path);
});
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
Upvotes: 1
Reputation: 121702
You can just use Files.find()
:
private void processFiles(final Path baseDir, final Consumer<? super Path> consumer,
final Collection<BiPredicate<Path, BasicFileAttributes>> filters)
throws IOException
{
final BiPredicate<Path, BasicFileAttributes> filter = filters.stream()
.reduce((t, u) -> true, BiPredicate::and);
try (
final Stream<Path> stream = Files.find(baseDir, Integer.MAX_VALUE, filter);
) {
stream.forEach(consumer);
}
}
Yes, this will mean converting your filters...
See also the javadoc of BiPredicate
and BasicFileAttributes
; in particular, BiPredicate
has a .and()
method which you will find useful in your situation.
Upvotes: 5