[davdeev] Symlink support reloaded

This commit is contained in:
Roman Shevchenko
2011-12-08 17:56:54 +01:00
parent 4396b9ac2e
commit 08e893528c
2 changed files with 60 additions and 12 deletions
@@ -15,9 +15,11 @@
*/
package com.intellij.openapi.vfs.newvfs.impl;
import com.intellij.openapi.util.AtomicNotNullLazyValue;
import com.intellij.openapi.util.NullableComputable;
import com.intellij.openapi.util.RecursionManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
import com.intellij.openapi.vfs.newvfs.NewVirtualFileSystem;
import com.intellij.openapi.vfs.newvfs.VfsImplUtil;
import org.jetbrains.annotations.NotNull;
@@ -25,28 +27,72 @@ import org.jetbrains.annotations.Nullable;
/**
* @author Dmitry Avdeev
* Date: 10/31/11
* @since 31.10.2011
*/
@SuppressWarnings("NonSynchronizedMethodOverridesSynchronizedMethod")
public class SymlinkDirectory extends VirtualDirectoryImpl {
private final AtomicNotNullLazyValue<VirtualDirectoryImpl> myTarget = new AtomicNotNullLazyValue<VirtualDirectoryImpl>() {
@NotNull
@Override
protected VirtualDirectoryImpl compute() {
final String path = getFileSystem().resolveSymLink(SymlinkDirectory.this);
VirtualFile file = null;
if (path != null) {
file = findFile(path, false);
}
if (file == SymlinkDirectory.this && file != null) {
final VirtualFile parent = file.getParent();
if (parent instanceof VirtualDirectoryImpl) {
((VirtualDirectoryImpl)parent).removeChild(file);
file = findFile(path, true);
}
}
return file instanceof VirtualDirectoryImpl ? (VirtualDirectoryImpl)file : new VirtualDirectoryImpl("foo", SymlinkDirectory.this, getFileSystem(), 0);
}
@Nullable
private final VirtualFile myTarget;
@Nullable
private VirtualFile findFile(final String path, final boolean refresh) {
return RecursionManager.doPreventingRecursion(SymlinkDirectory.this, false, new NullableComputable<VirtualFile>() {
@Override
public VirtualFile compute() {
return refresh ? VfsImplUtil.refreshAndFindFileByPath(getFileSystem(), path) : VfsImplUtil.findFileByPath(getFileSystem(), path);
}
});
}
};
public SymlinkDirectory(@NotNull String name, final VirtualDirectoryImpl parent, @NotNull final NewVirtualFileSystem fs, final int id) {
super(name, parent, fs, id);
final String path = fs.resolveSymLink(this);
}
myTarget = path == null ? null : RecursionManager.doPreventingRecursion("", false, new NullableComputable<VirtualFile>() {
@Override
public VirtualFile compute() {
return VfsImplUtil.findFileByPath(getFileSystem(), path);
}
});
@Override
public VirtualFileSystemEntry findChild(@NotNull String name) {
return myTarget.getValue().findChild(name);
}
@Override
public NewVirtualFile findChildIfCached(@NotNull String name) {
return myTarget.getValue().findChildIfCached(name);
}
@Override
public NewVirtualFile findChildById(int id) {
return myTarget.getValue().findChildById(id);
}
@Override
public NewVirtualFile findChildByIdIfCached(int id) {
return myTarget.getValue().findChildByIdIfCached(id);
}
@Override
public NewVirtualFile refreshAndFindChild(@NotNull String name) {
return myTarget.getValue().refreshAndFindChild(name);
}
@NotNull
@Override
public VirtualFile[] getChildren() {
return myTarget == null ? VirtualFile.EMPTY_ARRAY : myTarget.getChildren();
return myTarget.getValue().getChildren();
}
}
@@ -63,6 +63,8 @@ import java.util.*;
* @author max
*/
public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
private static final boolean ALT_SYMLINK_HANDLING = "true".equals(System.getProperty("idea.io.alt.symlink"));
private static final VirtualFileSystemEntry NULL_VIRTUAL_FILE = new VirtualFileImpl("*?;%NULL", null, -42);
private final NewVirtualFileSystem myFS;
@@ -165,7 +167,7 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
final VirtualFileSystemEntry child;
final NewVirtualFileSystem fs = getFileSystem();
if (PersistentFS.isDirectory(id)) {
child = /*PersistentFS.isSymLink(id) ? new SymlinkDirectory(name, this, fs, id) :*/ new VirtualDirectoryImpl(name, this, fs, id);
child = ALT_SYMLINK_HANDLING && PersistentFS.isSymLink(id) ? new SymlinkDirectory(name, this, fs, id) : new VirtualDirectoryImpl(name, this, fs, id);
}
else {
child = new VirtualFileImpl(name, this, id);