/*
* SK's Minecraft Launcher
* Copyright (C) 2010-2014 Albert Pham <http://www.sk89q.com> and contributors
* Please see LICENSE.txt for license information.
*/
package com.skcraft.launcher.creator.controller.task;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.skcraft.launcher.util.MorePaths;
import lombok.Getter;
import lombok.Setter;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.Callable;
import static com.google.common.base.Preconditions.checkNotNull;
public class DirectoryWalker implements Callable<List<File>> {
@Getter private final File dir;
@Getter @Setter private FileFilter fileFilter = pathname -> true;
@Getter @Setter private boolean recursive;
public DirectoryWalker(File dir) {
checkNotNull(dir, "dir");
this.dir = dir;
}
@Override
public List<File> call() throws IOException {
if (!dir.isDirectory()) {
throw new IllegalArgumentException(dir.getAbsolutePath() + " is not a directory");
}
List<File> matched = Lists.newArrayList();
Set<String> seen = Sets.newHashSet();
Queue<File> queue = new LinkedList<>();
queue.add(dir);
File cur;
while ((cur = queue.poll()) != null) {
String canonical = cur.getCanonicalPath();
if (!seen.contains(canonical) && MorePaths.isSubDirectory(dir, cur)) {
File[] files = cur.listFiles();
if (files != null) {
for (File file : files) {
if (recursive && file.isDirectory()) {
queue.add(file);
}
if (fileFilter.accept(file)) {
matched.add(file);
}
}
}
}
}
return matched;
}
}