blob: 4545a2be5c17670611156fbfd161acecbebdfe83 [file] [log] [blame]
/*
* Copyright 2012-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package com.facebook.buck.util;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileVisitOption;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.EnumSet;
/**
* Traverses all files in a directory. This class <em>will</em> follow symlinks.
*/
public abstract class DirectoryTraversal {
private final File root;
private final ImmutableSet<String> ignorePaths;
/** @param root must be a directory */
public DirectoryTraversal(File root, ImmutableSet<String> ignorePaths) {
this.root = Preconditions.checkNotNull(root);
this.ignorePaths = Preconditions.checkNotNull(ignorePaths);
}
public DirectoryTraversal(File root) {
this(root, ImmutableSet.<String>of());
}
public File getRoot() {
return root;
}
public final void traverse() throws IOException {
Preconditions.checkState(root.isDirectory(), "Must be a directory: %s", root);
final Path rootPath = root.toPath();
FileVisitor<Path> visitor = new FileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
if (ignorePaths.contains(rootPath.relativize(dir).toString())) {
return FileVisitResult.SKIP_SUBTREE;
} else {
return FileVisitResult.CONTINUE;
}
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
visit(file.toFile(), rootPath.relativize(file).toString());
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
return FileVisitResult.CONTINUE;
}
};
Files.walkFileTree(
rootPath, EnumSet.of(FileVisitOption.FOLLOW_LINKS), /* maxDepth */ Integer.MAX_VALUE,
visitor);
}
/**
* @param file an ordinary file (not a directory)
* @param relativePath a path such as "foo.txt" or "foo/bar.txt"
*/
public abstract void visit(File file, String relativePath) throws IOException;
public static void main(String[] args) throws IOException {
File directory = new File(args[0]);
new DirectoryTraversal(directory) {
@Override
public void visit(File file, String relativePath) {
System.out.println(relativePath);
}
}.traverse();
}
}