in src/main/org/apache/tools/ant/DirectoryScanner.java [1201:1294]
private void scandir(final File dir, final TokenizedPath path, final boolean fast,
String[] newFiles, final Deque<String> directoryNamesFollowed) {
String vpath = path.toString();
if (!vpath.isEmpty() && !vpath.endsWith(File.separator)) {
vpath += File.separator;
}
// avoid double scanning of directories, can only happen in fast mode
if (fast && hasBeenScanned(vpath)) {
return;
}
if (!followSymlinks) {
final ArrayList<String> noLinks = new ArrayList<>();
for (final String newFile : newFiles) {
final Path filePath;
if (dir == null) {
filePath = Paths.get(newFile);
} else {
filePath = Paths.get(dir.toPath().toString(), newFile);
}
if (Files.isSymbolicLink(filePath)) {
final String name = vpath + newFile;
final File file = new File(dir, newFile);
if (file.isDirectory()) {
dirsExcluded.addElement(name);
} else if (file.isFile()) {
filesExcluded.addElement(name);
}
accountForNotFollowedSymlink(name, file);
} else {
noLinks.add(newFile);
}
}
newFiles = noLinks.toArray(new String[0]);
} else {
directoryNamesFollowed.addFirst(dir.getName());
}
for (String newFile : newFiles) {
final String name = vpath + newFile;
final TokenizedPath newPath = new TokenizedPath(path, newFile);
final File file = new File(dir, newFile);
final String[] children;
// don't invoke file.list() if we know we never use the children
if (fast // slow scan scans everything anyway
&& file.isDirectory() // otherwise we need list() to know whether this is a directory
&& !scanDuringFastScan(newPath) // otherwise we'd invoke scandir
) {
children = new String[0];
} else {
children = file.list();
}
if (children == null || (children.length == 0 && file.isFile())) {
if (isIncluded(newPath)) {
accountForIncludedFile(newPath, file);
} else {
everythingIncluded = false;
filesNotIncluded.addElement(name);
}
} else if (file.isDirectory()) { // dir
if (followSymlinks
&& causesIllegalSymlinkLoop(newFile, dir, directoryNamesFollowed)) {
// will be caught and redirected to Ant's logging system
System.err.println("skipping symbolic link "
+ file.getAbsolutePath()
+ " -- too many levels of symbolic"
+ " links.");
notFollowedSymlinks.add(file.getAbsolutePath());
continue;
}
if (isIncluded(newPath)) {
accountForIncludedDir(newPath, file, fast, children,
directoryNamesFollowed);
} else {
everythingIncluded = false;
dirsNotIncluded.addElement(name);
if (fast && scanDuringFastScan(newPath)) {
scandir(file, newPath, fast, children, directoryNamesFollowed);
}
}
if (!fast) {
scandir(file, newPath, fast, children, directoryNamesFollowed);
}
}
}
if (followSymlinks) {
directoryNamesFollowed.removeFirst();
}
}