IDEA-134915 (visit all non-recursive symlink targets)

This commit is contained in:
Roman Shevchenko
2015-02-27 16:23:31 +01:00
parent 12724a3c95
commit f5e2e1607b
2 changed files with 31 additions and 11 deletions
@@ -21,7 +21,8 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Set;
import java.util.List;
import java.util.Map;
/**
* @author Dmitry Avdeev
@@ -84,7 +85,7 @@ public abstract class VirtualFileVisitor<T> {
private boolean mySkipRoot = false;
private int myDepthLimit = -1;
private Set<VirtualFile> myVisitedTargets;
private Map<VirtualFile, List<VirtualFile>> myVisitedTargets;
private int myLevel = 0;
private Stack<T> myValueStack = null;
private T myValue = null;
@@ -102,7 +103,7 @@ public abstract class VirtualFileVisitor<T> {
}
}
if (myFollowSymLinks) {
myVisitedTargets = ContainerUtil.newHashSet();
myVisitedTargets = ContainerUtil.newHashMap();
}
}
@@ -184,11 +185,21 @@ public abstract class VirtualFileVisitor<T> {
}
VirtualFile target = file.getCanonicalFile();
if (!myVisitedTargets.add(target)) {
return false;
List<VirtualFile> links = myVisitedTargets.get(target);
if (links == null) {
myVisitedTargets.put(target, ContainerUtil.newSmartList(file));
return true;
}
return true;
boolean hasLoop = false;
for (VirtualFile link : links) {
if (VfsUtilCore.isAncestor(link, file, true)) {
hasLoop = true;
break;
}
}
links.add(file);
return !hasLoop;
}
final boolean depthLimitReached() {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -116,6 +116,16 @@ public class SymlinkHandlingTest extends SymlinkTestCase {
link2.getPath() + "/" + link1Home.getName() + "/" + link1.getName());
}
public void testVisitAllNonRecursiveLinks() throws Exception {
File target = createTestDir(myTempDir, "target");
File child = createTestDir(target, "child");
File link1 = createSymLink(target.getPath(), myTempDir.getPath() + "/link1");
File link2 = createSymLink(target.getPath(), myTempDir.getPath() + "/link2");
assertVisitedPaths(target.getPath(), child.getPath(),
link1.getPath(), link1.getPath() + "/child",
link2.getPath(), link2.getPath() + "/child");
}
public void testTargetIsWritable() throws Exception {
File targetFile = createTestFile(myTempDir, "target.txt");
File linkFile = createSymLink(targetFile.getPath(), myTempDir + "/link");
@@ -366,14 +376,13 @@ public class SymlinkHandlingTest extends SymlinkTestCase {
VirtualFile vDir = refreshAndFind(from);
assertNotNull(vDir);
Set<String> expectedSet = new HashSet<String>(expected.length + 1, 1);
ContainerUtil.addAll(expectedSet, vDir.getPath());
ContainerUtil.addAll(expectedSet, ContainerUtil.map(expected, new Function<String, String>() {
Set<String> expectedSet = ContainerUtil.map2Set(expected, new Function<String, String>() {
@Override
public String fun(String path) {
return FileUtil.toSystemIndependentName(path);
}
}));
});
expectedSet.add(vDir.getPath());
final Set<String> actualSet = new HashSet<String>();
VfsUtilCore.visitChildrenRecursively(vDir, new VirtualFileVisitor() {