moved to FileUtil

This commit is contained in:
Alexey Kudravtsev
2012-03-06 12:44:50 +04:00
parent a67178d99d
commit ee56fc6c40
10 changed files with 161 additions and 133 deletions
@@ -19,11 +19,11 @@
*/
package com.intellij.openapi.vfs.newvfs;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileListener;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.VirtualFileSystem;
import org.intellij.lang.annotations.MagicConstant;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -45,10 +45,12 @@ public abstract class NewVirtualFileSystem extends VirtualFileSystem implements
return path;
}
@Override
public void refreshWithoutFileWatcher(final boolean asynchronous) {
refresh(asynchronous);
}
@Override
public boolean isReadOnly() {
return true;
}
@@ -70,6 +72,7 @@ public abstract class NewVirtualFileSystem extends VirtualFileSystem implements
protected abstract String extractRootPath(@NotNull String path);
@Override
public void addVirtualFileListener(@NotNull final VirtualFileListener listener) {
synchronized (myListenerWrappers) {
VirtualFileListener wrapper = new VirtualFileFilteringListener(listener, this);
@@ -78,6 +81,7 @@ public abstract class NewVirtualFileSystem extends VirtualFileSystem implements
}
}
@Override
public void removeVirtualFileListener(@NotNull final VirtualFileListener listener) {
synchronized (myListenerWrappers) {
final VirtualFileListener wrapper = myListenerWrappers.remove(listener);
@@ -89,12 +93,18 @@ public abstract class NewVirtualFileSystem extends VirtualFileSystem implements
public abstract int getRank();
@Override
public abstract VirtualFile copyFile(final Object requestor, @NotNull final VirtualFile file, @NotNull final VirtualFile newParent, @NotNull final String copyName) throws IOException;
@Override
@NotNull
public abstract VirtualFile createChildDirectory(final Object requestor, @NotNull final VirtualFile parent, @NotNull final String dir) throws IOException;
@Override
public abstract VirtualFile createChildFile(final Object requestor, @NotNull final VirtualFile parent, @NotNull final String file) throws IOException;
@Override
public abstract void deleteFile(final Object requestor, @NotNull final VirtualFile file) throws IOException;
@Override
public abstract void moveFile(final Object requestor, @NotNull final VirtualFile file, @NotNull final VirtualFile newParent) throws IOException;
@Override
public abstract void renameFile(final Object requestor, @NotNull final VirtualFile file, @NotNull final String newName) throws IOException;
public boolean markNewFilesAsDirty() {
@@ -105,14 +115,6 @@ public abstract class NewVirtualFileSystem extends VirtualFileSystem implements
return file.getName();
}
public static final int BA_EXISTS = 0x01;
public static final int BA_REGULAR = 0x02;
public static final int BA_DIRECTORY = 0x04;
public static final int BA_HIDDEN = 0x08;
@MagicConstant(flags = {BA_EXISTS, BA_REGULAR, BA_DIRECTORY, BA_HIDDEN})
public @interface FileBooleanAttributes {}
/**
* Queries the file about several attributes at once, and returns them ORed together.
* This method is typically faster than several methods calls querying corresponding file attributes one by one.
@@ -122,10 +124,10 @@ public abstract class NewVirtualFileSystem extends VirtualFileSystem implements
* Each attribute is an int constant from this class.
* Following attributes are defined:
* <ul>
* <li>{@link #BA_EXISTS} is set if {@link java.io.File#exists()} returns true</li>
* <li>{@link #BA_DIRECTORY} is set if {@link java.io.File#isDirectory()} returns true</li>
* <li>{@link #BA_HIDDEN} is set if {@link java.io.File#isHidden()} returns true</li>
* <li>{@link #BA_REGULAR} is set if {@link java.io.File#isFile()} returns true</li>
* <li>{@link com.intellij.openapi.util.io.FileUtil#BA_EXISTS} is set if {@link java.io.File#exists()} returns true</li>
* <li>{@link com.intellij.openapi.util.io.FileUtil#BA_DIRECTORY} is set if {@link java.io.File#isDirectory()} returns true</li>
* <li>{@link com.intellij.openapi.util.io.FileUtil#BA_HIDDEN} is set if {@link java.io.File#isHidden()} returns true</li>
* <li>{@link com.intellij.openapi.util.io.FileUtil#BA_REGULAR} is set if {@link java.io.File#isFile()} returns true</li>
* </ul>
* Attributes can be bitwise ORed together to query several file attributes at once.
* <code>-1</code> as an argument value will query all attributes.
@@ -146,6 +148,6 @@ public abstract class NewVirtualFileSystem extends VirtualFileSystem implements
* boolean isDirectory = (attributes & BA_DIRECTORY) != 0;
* }}</pre>
*/
@FileBooleanAttributes
public abstract int getBooleanAttributes(@NotNull final VirtualFile file, @FileBooleanAttributes int flags);
@FileUtil.FileBooleanAttributes
public abstract int getBooleanAttributes(@NotNull final VirtualFile file, @FileUtil.FileBooleanAttributes int flags);
}
@@ -21,6 +21,7 @@ package com.intellij.openapi.vfs.ex.temp;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.io.BufferExposingByteArrayInputStream;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.newvfs.ManagingFS;
@@ -369,9 +370,9 @@ public class TempFileSystem extends NewVirtualFileSystem {
@Override
public int getBooleanAttributes(@NotNull VirtualFile file, int flags) {
FSItem item = convert(file);
int isDir = item instanceof FSDir ? BA_DIRECTORY : 0;
int exists = item == null ? 0 : BA_EXISTS;
int regular = isDir == 0 ? BA_REGULAR : 0;
int isDir = item instanceof FSDir ? FileUtil.BA_DIRECTORY : 0;
int exists = item == null ? 0 : FileUtil.BA_EXISTS;
int regular = isDir == 0 ? FileUtil.BA_REGULAR : 0;
return isDir | exists | regular;
}
}
@@ -368,16 +368,16 @@ public class JarFileSystemImpl extends JarFileSystem implements ApplicationCompo
public int getBooleanAttributes(@NotNull VirtualFile file, int flags) {
int exists = 0;
JarHandler handler = getHandler(file);
if ((flags & BA_EXISTS) != 0) {
exists = handler.exists(file) ? BA_EXISTS : 0;
if ((flags & FileUtil.BA_EXISTS) != 0) {
exists = handler.exists(file) ? FileUtil.BA_EXISTS : 0;
}
int isDir = 0;
if ((flags & BA_DIRECTORY) != 0) {
isDir = handler.isDirectory(file) ? BA_DIRECTORY : 0;
if ((flags & FileUtil.BA_DIRECTORY) != 0) {
isDir = handler.isDirectory(file) ? FileUtil.BA_DIRECTORY : 0;
}
int regular = 0;
if ((flags & BA_REGULAR) != 0) {
regular = isDir == 0 ? BA_REGULAR : 0;
if ((flags & FileUtil.BA_REGULAR) != 0) {
regular = isDir == 0 ? FileUtil.BA_REGULAR : 0;
}
return exists | isDir | regular;
}
@@ -35,12 +35,10 @@ import com.intellij.util.Processor;
import com.intellij.util.ThrowableConsumer;
import com.intellij.util.io.SafeFileOutputStream;
import com.intellij.util.io.fs.IFile;
import org.intellij.lang.annotations.MagicConstant;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.*;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
@@ -137,44 +135,13 @@ public abstract class LocalFileSystemBase extends LocalFileSystem {
return new File(path);
}
private static final Method JAVA_IO_FILESYSTEM_GET_BOOLEAN_ATTRIBUTES_METHOD;
private static final Object/* java.io.FileSystem */ JAVA_IO_FILESYSTEM;
// copied from FileSystem
static {
Object fs;
Method getBooleanAttributes;
try {
Class<?> fsClass = Class.forName("java.io.FileSystem");
Method getFileSystem = fsClass.getMethod("getFileSystem");
getFileSystem.setAccessible(true);
fs = getFileSystem.invoke(null);
getBooleanAttributes = fsClass.getDeclaredMethod("getBooleanAttributes", File.class);
if (fs == null || getBooleanAttributes == null) {
fs = null;
getBooleanAttributes = null;
}
else {
getBooleanAttributes.setAccessible(true);
}
}
catch (Exception e) {
fs = null;
getBooleanAttributes = null;
}
JAVA_IO_FILESYSTEM = fs;
JAVA_IO_FILESYSTEM_GET_BOOLEAN_ATTRIBUTES_METHOD = getBooleanAttributes;
}
@NotNull
private static File convertToIOFileAndCheck(@NotNull final VirtualFile file) throws FileNotFoundException {
final File ioFile = convertToIOFile(file);
int intFlags = getBooleanAttributes(ioFile);
int intFlags = FileUtil.getBooleanAttributes(ioFile);
if (intFlags != -1) {
if ((intFlags & BA_EXISTS) != 0 && (intFlags & BA_REGULAR) == 0) {
if ((intFlags & FileUtil.BA_EXISTS) != 0 && (intFlags & FileUtil.BA_REGULAR) == 0) {
throw new FileNotFoundException("Not a file: " + ioFile);
}
return ioFile;
@@ -186,20 +153,6 @@ public abstract class LocalFileSystemBase extends LocalFileSystem {
return ioFile;
}
// todo[r.sh] use NIO2 API after migration to JDK 7
// returns -1 if could not get attributes
@MagicConstant(flags = {BA_EXISTS, BA_REGULAR, BA_DIRECTORY, BA_HIDDEN})
private static int getBooleanAttributes(@NotNull File f) {
if (JAVA_IO_FILESYSTEM_GET_BOOLEAN_ATTRIBUTES_METHOD != null) {
try {
Object flags = JAVA_IO_FILESYSTEM_GET_BOOLEAN_ATTRIBUTES_METHOD.invoke(JAVA_IO_FILESYSTEM, f);
return ((Integer)flags).intValue();
}
catch (Exception ignored) { }
}
return -1;
}
@Override
public boolean exists(@NotNull final VirtualFile fileOrDirectory) {
String path = fileOrDirectory.getPath();
@@ -246,9 +199,9 @@ public abstract class LocalFileSystemBase extends LocalFileSystem {
}
private static boolean isSpecialFile(@NotNull File ioFile) {
int flags = getBooleanAttributes(ioFile);
int flags = FileUtil.getBooleanAttributes(ioFile);
if (flags != -1) {
return (flags & (BA_REGULAR | BA_DIRECTORY | BA_EXISTS)) == (~BA_REGULAR & ~BA_DIRECTORY & BA_EXISTS);
return (flags & (FileUtil.BA_REGULAR | FileUtil.BA_DIRECTORY | FileUtil.BA_EXISTS)) == (~FileUtil.BA_REGULAR & ~FileUtil.BA_DIRECTORY & FileUtil.BA_EXISTS);
}
return !ioFile.isFile() && !ioFile.isDirectory() && ioFile.exists();
}
@@ -774,12 +727,12 @@ public abstract class LocalFileSystemBase extends LocalFileSystem {
@Override
public int getBooleanAttributes(@NotNull VirtualFile file, int flags) {
int attributes = getBooleanAttributes(convertToIOFile(file));
int attributes = FileUtil.getBooleanAttributes(convertToIOFile(file));
if (attributes != -1) return attributes & flags;
return ((flags & BA_EXISTS) != 0 && exists(file) ? BA_EXISTS : 0) |
((flags & BA_DIRECTORY) != 0 && isDirectory(file) ? BA_DIRECTORY : 0) |
((flags & BA_REGULAR) != 0 && !isSpecialFile(file) ? BA_REGULAR : 0) |
((flags & BA_HIDDEN) != 0 && convertToIOFile(file).isHidden() ? BA_HIDDEN : 0)
return ((flags & FileUtil.BA_EXISTS) != 0 && exists(file) ? FileUtil.BA_EXISTS : 0) |
((flags & FileUtil.BA_DIRECTORY) != 0 && isDirectory(file) ? FileUtil.BA_DIRECTORY : 0) |
((flags & FileUtil.BA_REGULAR) != 0 && !isSpecialFile(file) ? FileUtil.BA_REGULAR : 0) |
((flags & FileUtil.BA_HIDDEN) != 0 && convertToIOFile(file).isHidden() ? FileUtil.BA_HIDDEN : 0)
;
}
@@ -15,7 +15,7 @@
*/
package com.intellij.openapi.vfs.impl.win32;
import com.intellij.openapi.vfs.newvfs.NewVirtualFileSystem;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -109,21 +109,21 @@ public class Win32Kernel {
return info;
}
@NewVirtualFileSystem.FileBooleanAttributes
public int getBooleanAttributes(@NotNull String path, @NewVirtualFileSystem.FileBooleanAttributes int flags) {
@FileUtil.FileBooleanAttributes
public int getBooleanAttributes(@NotNull String path, @FileUtil.FileBooleanAttributes int flags) {
FileInfo info = doGetInfo(path);
int result = 0;
if ((flags & NewVirtualFileSystem.BA_EXISTS) != 0) {
result |= info == null ? 0 : NewVirtualFileSystem.BA_EXISTS;
if ((flags & FileUtil.BA_EXISTS) != 0) {
result |= info == null ? 0 : FileUtil.BA_EXISTS;
}
if ((flags & NewVirtualFileSystem.BA_DIRECTORY) != 0) {
result |= info == null || (info.attributes & FILE_ATTRIBUTE_DIRECTORY) == 0 ? 0 : NewVirtualFileSystem.BA_DIRECTORY;
if ((flags & FileUtil.BA_DIRECTORY) != 0) {
result |= info == null || (info.attributes & FILE_ATTRIBUTE_DIRECTORY) == 0 ? 0 : FileUtil.BA_DIRECTORY;
}
if ((flags & NewVirtualFileSystem.BA_REGULAR) != 0) {
result |= info == null || (info.attributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE | FILE_ATTRIBUTE_REPARSE_POINT)) != 0 ? 0 : NewVirtualFileSystem.BA_REGULAR;
if ((flags & FileUtil.BA_REGULAR) != 0) {
result |= info == null || (info.attributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE | FILE_ATTRIBUTE_REPARSE_POINT)) != 0 ? 0 : FileUtil.BA_REGULAR;
}
if ((flags & NewVirtualFileSystem.BA_HIDDEN) != 0) {
result |= info == null || (info.attributes & FILE_ATTRIBUTE_HIDDEN) == 0 ? 0 : NewVirtualFileSystem.BA_HIDDEN;
if ((flags & FileUtil.BA_HIDDEN) != 0) {
result |= info == null || (info.attributes & FILE_ATTRIBUTE_HIDDEN) == 0 ? 0 : FileUtil.BA_HIDDEN;
}
return result;
}
@@ -321,10 +321,10 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
private VirtualFileSystemEntry createAndFindChildWithEventFire(@NotNull String name) {
final NewVirtualFileSystem delegate = getFileSystem();
VirtualFile fake = new FakeVirtualFile(this, name);
int attributes = delegate.getBooleanAttributes(fake, NewVirtualFileSystem.BA_EXISTS | NewVirtualFileSystem.BA_DIRECTORY);
if ((attributes & NewVirtualFileSystem.BA_EXISTS) != 0) {
int attributes = delegate.getBooleanAttributes(fake, FileUtil.BA_EXISTS | FileUtil.BA_DIRECTORY);
if ((attributes & FileUtil.BA_EXISTS) != 0) {
final String realName = delegate.getCanonicallyCasedName(fake);
boolean isDir = (attributes & NewVirtualFileSystem.BA_DIRECTORY) != 0;
boolean isDir = (attributes & FileUtil.BA_DIRECTORY) != 0;
VFileCreateEvent event = new VFileCreateEvent(null, this, realName, isDir, true);
RefreshQueue.getInstance().processSingleEvent(event);
return findChild(realName);
@@ -145,7 +145,7 @@ public abstract class VirtualFileSystemEntry extends NewVirtualFile {
return pattern.regionMatches(ignoreCase, length, suffix, 0, suffix.length());
}
private Object rawName() {
protected Object rawName() {
return myName;
}
@@ -292,7 +292,7 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent {
final int parentId,
@NotNull VirtualFile file,
@NotNull NewVirtualFileSystem delegate,
@NewVirtualFileSystem.FileBooleanAttributes int attributes) {
@FileUtil.FileBooleanAttributes int attributes) {
String name = file.getName();
if (!name.isEmpty() && namesEqual(delegate, name, FSRecords.getName(id))) return false; // TODO: Handle root attributes change.
@@ -308,11 +308,11 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent {
FSRecords.setTimestamp(id, delegate.getTimeStamp(file));
boolean isDir = (attributes & NewVirtualFileSystem.BA_DIRECTORY) != 0;
boolean isDir = (attributes & FileUtil.BA_DIRECTORY) != 0;
FSRecords.setLength(id, isDir ? -1L : delegate.getLength(file));
boolean isSpecial = (attributes & (NewVirtualFileSystem.BA_REGULAR | NewVirtualFileSystem.BA_DIRECTORY | NewVirtualFileSystem.BA_EXISTS)) ==
NewVirtualFileSystem.BA_EXISTS;
boolean isSpecial = (attributes & (FileUtil.BA_REGULAR | FileUtil.BA_DIRECTORY | FileUtil.BA_EXISTS)) ==
FileUtil.BA_EXISTS;
FSRecords.setFlags(id, (isDir ? IS_DIRECTORY_FLAG : 0) |
(delegate.isWritable(file) ? 0 : IS_READ_ONLY) |
(delegate.isSymLink(file) ? IS_SYMLINK : 0) |
@@ -408,7 +408,7 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent {
VirtualFile fake = new FakeVirtualFile(parent, childName);
int attributes = delegate.getBooleanAttributes(fake, -1);
if ((attributes & NewVirtualFileSystem.BA_EXISTS) != 0) {
if ((attributes & FileUtil.BA_EXISTS) != 0) {
int child = createAndCopyRecord(delegate, fake, parentId, attributes);
FSRecords.updateList(parentId, ArrayUtil.append(children, child));
return child;
@@ -673,6 +673,7 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent {
}
};
@NotNull
private static List<? extends VFileEvent> validateEvents(@NotNull List<? extends VFileEvent> events) {
final List<EventWrapper> deletionEvents = Lists.newArrayList();
for (int i = 0, size = events.size(); i < size; i++) {
@@ -756,25 +757,22 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent {
};
}
else {
root = new VirtualDirectoryImpl(basePath, null, fs, rootId) {
@NotNull
@Override
public String getName() {
final String name = super.getName();
// TODO: HACK!!! Get to simpler solution.
if (getFileSystem() instanceof JarFileSystem) {
String jarName = name.substring(0, name.length() - JarFileSystem.JAR_SEPARATOR.length());
return jarName.substring(jarName.lastIndexOf('/') + 1);
}
return name;
}
};
if (fs instanceof JarFileSystem) {
// optimization: for jar roots do not store base path in the myName field, use local FS file's getPath()
String parentPath = basePath.substring(0, basePath.indexOf(JarFileSystem.JAR_SEPARATOR));
final VirtualFile parentLocalFile = LocalFileSystem.getInstance().findFileByPath(parentPath);
if (parentLocalFile == null) return null;
root = new JarRoot(fs, rootId, parentLocalFile);
}
else {
root = new VirtualDirectoryImpl(basePath, null, fs, rootId);
}
}
if (!fs.exists(root)) {
return null;
}
if (!fs.exists(root)) return null;
int attributes = NewVirtualFileSystem.BA_DIRECTORY | NewVirtualFileSystem.BA_EXISTS;
int attributes = FileUtil.BA_DIRECTORY | FileUtil.BA_EXISTS;
boolean newRoot = copyRecordFromDelegateFS(rootId, 0, root, fs, attributes);
if (!newRoot) {
if (fs.getTimeStamp(root) != FSRecords.getTimestamp(rootId)) {
@@ -964,7 +962,7 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent {
final NewVirtualFileSystem delegate = getDelegate(parent);
VirtualFile fake = new FakeVirtualFile(parent, name);
int attributes = delegate.getBooleanAttributes(fake, -1);
if ((attributes & NewVirtualFileSystem.BA_EXISTS) != 0) {
if ((attributes & FileUtil.BA_EXISTS) != 0) {
final int parentId = getFileId(parent);
int childId = createAndCopyRecord(delegate, fake, parentId, attributes);
appendIdToParentList(parentId, childId);
@@ -973,7 +971,7 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent {
}
}
private static int createAndCopyRecord(@NotNull NewVirtualFileSystem delegateSystem, @NotNull VirtualFile delegateFile, int parentId, @NewVirtualFileSystem.FileBooleanAttributes int attributes) {
private static int createAndCopyRecord(@NotNull NewVirtualFileSystem delegateSystem, @NotNull VirtualFile delegateFile, int parentId, @FileUtil.FileBooleanAttributes int attributes) {
int childId = FSRecords.createRecord();
copyRecordFromDelegateFS(childId, parentId, delegateFile, delegateSystem, attributes);
return childId;
@@ -1140,4 +1138,24 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent {
}
return delegate;
}
private static class JarRoot extends VirtualDirectoryImpl {
private final VirtualFile myParentLocalFile;
public JarRoot(@NotNull NewVirtualFileSystem fs, int rootId, @NotNull VirtualFile parentLocalFile) {
super("", null, fs, rootId);
myParentLocalFile = parentLocalFile;
}
@NotNull
@Override
public String getName() {
return myParentLocalFile.getName();
}
@Override
protected Object rawName() {
return myParentLocalFile.getPath() + JarFileSystem.JAR_SEPARATOR;
}
}
}
@@ -17,6 +17,7 @@ package com.intellij.openapi.vfs.newvfs.persistent;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.newvfs.ManagingFS;
@@ -32,8 +33,6 @@ import org.jetbrains.annotations.NotNull;
import java.util.*;
import static com.intellij.openapi.vfs.newvfs.NewVirtualFileSystem.*;
/**
* @author max
*/
@@ -53,14 +52,14 @@ public class RefreshWorker {
public void scan() {
final NewVirtualFile root = (NewVirtualFile)myRefreshRoot;
NewVirtualFileSystem delegate = root.getFileSystem();
final int rootAttributes = delegate.getBooleanAttributes(root, BA_EXISTS | BA_DIRECTORY);
final int rootAttributes = delegate.getBooleanAttributes(root, FileUtil.BA_EXISTS | FileUtil.BA_DIRECTORY);
if (root.isDirty() && (rootAttributes & BA_EXISTS) == 0) {
if (root.isDirty() && (rootAttributes & FileUtil.BA_EXISTS) == 0) {
scheduleDeletion(root);
root.markClean();
}
else {
if ((rootAttributes & BA_DIRECTORY) != 0) {
if ((rootAttributes & FileUtil.BA_DIRECTORY) != 0) {
delegate = PersistentFS.replaceWithNativeFS(delegate);
}
@@ -106,7 +105,7 @@ public class RefreshWorker {
else {
for (VirtualFile child : file.getCachedChildren()) {
final int childAttributes = delegate.getBooleanAttributes(child, -1);
if ((childAttributes & BA_EXISTS) != 0) {
if ((childAttributes & FileUtil.BA_EXISTS) != 0) {
scheduleChildRefresh(file, child, delegate, childAttributes);
}
else {
@@ -119,9 +118,9 @@ public class RefreshWorker {
if (name.isEmpty()) continue;
final VirtualFile fake = new FakeVirtualFile(file, name);
final int attributes = delegate.getBooleanAttributes(fake, BA_EXISTS | BA_DIRECTORY);
if ((attributes & BA_EXISTS) != 0) {
final boolean isDir = (attributes & BA_DIRECTORY) != 0;
final int attributes = delegate.getBooleanAttributes(fake, FileUtil.BA_EXISTS | FileUtil.BA_DIRECTORY);
if ((attributes & FileUtil.BA_EXISTS) != 0) {
final boolean isDir = (attributes & FileUtil.BA_DIRECTORY) != 0;
scheduleCreation(file, name, isDir);
}
}
@@ -150,20 +149,20 @@ public class RefreshWorker {
}
}
private static final int SPECIAL_MASK = BA_REGULAR | BA_DIRECTORY | BA_EXISTS;
private static final int SPECIAL_MASK = FileUtil.BA_REGULAR | FileUtil.BA_DIRECTORY | FileUtil.BA_EXISTS;
// todo[r.sh] compare link targets for files too
private void scheduleChildRefresh(@NotNull VirtualFileSystemEntry parent,
@NotNull VirtualFile child,
@NotNull NewVirtualFileSystem delegate,
@FileBooleanAttributes int childAttributes) {
@FileUtil.FileBooleanAttributes int childAttributes) {
final boolean currentIsDirectory = child.isDirectory();
final boolean currentIsSymlink = child.isSymLink();
final boolean currentIsSpecial = child.isSpecialFile();
final String currentLinkTarget = child instanceof SymlinkDirectory ? ((SymlinkDirectory)child).getTargetPath() : null;
final boolean upToDateIsDirectory = (childAttributes & BA_DIRECTORY) != 0;
final boolean upToDateIsDirectory = (childAttributes & FileUtil.BA_DIRECTORY) != 0;
final boolean upToDateIsSymlink = delegate.isSymLink(child);
final boolean upToDateIsSpecial = (childAttributes & SPECIAL_MASK) == BA_EXISTS;
final boolean upToDateIsSpecial = (childAttributes & SPECIAL_MASK) == FileUtil.BA_EXISTS;
final String upToDateLinkTarget = currentLinkTarget != null ? delegate.resolveSymLink(child) : null;
if (currentIsDirectory != upToDateIsDirectory ||
@@ -28,6 +28,7 @@ import com.intellij.util.SystemProperties;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.Stack;
import com.intellij.util.io.URLUtil;
import org.intellij.lang.annotations.MagicConstant;
import org.intellij.lang.annotations.RegExp;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -57,6 +58,8 @@ public class FileUtil {
private static final long CHANNELS_COPYING_LIMIT = 5L * MEGABYTE;
private static String ourCanonicalTempPathCache = null;
private static final int MAX_FILE_DELETE_ATTEMPTS = 10;
public static final Method JAVA_IO_FILESYSTEM_GET_BOOLEAN_ATTRIBUTES_METHOD;
public static final Object/* java.io.FileSystem */ JAVA_IO_FILESYSTEM;
@Nullable
public static String getRelativePath(File base, File file) {
@@ -613,7 +616,10 @@ public class FileUtil {
String parentDirPath = file.getParent();
if (parentDirPath != null) {
final File parentFile = new File(parentDirPath);
return parentFile.exists() && parentFile.isDirectory() || parentFile.mkdirs();
int attributes = getBooleanAttributes(file);
boolean ok = attributes != -1 && (attributes & (BA_EXISTS | BA_DIRECTORY)) == (BA_EXISTS | BA_DIRECTORY)
|| parentFile.exists() && parentFile.isDirectory();
return ok || parentFile.mkdirs();
}
}
return true;
@@ -1327,4 +1333,53 @@ public class FileUtil {
}
return firstLine.contains(marker);
}
// copied from FileSystem: they are package local there
public static final int BA_EXISTS = 0x01;
public static final int BA_REGULAR = 0x02;
public static final int BA_DIRECTORY = 0x04;
public static final int BA_HIDDEN = 0x08;
// todo[r.sh] use NIO2 API after migration to JDK 7
// returns -1 if could not get attributes
@MagicConstant(flags = {BA_EXISTS, BA_REGULAR, BA_DIRECTORY, BA_HIDDEN})
public static int getBooleanAttributes(@NotNull File f) {
if (JAVA_IO_FILESYSTEM_GET_BOOLEAN_ATTRIBUTES_METHOD != null) {
try {
Object flags = JAVA_IO_FILESYSTEM_GET_BOOLEAN_ATTRIBUTES_METHOD.invoke(JAVA_IO_FILESYSTEM, f);
return ((Integer)flags).intValue();
}
catch (Exception ignored) { }
}
return -1;
}
@MagicConstant(flags = {BA_EXISTS, BA_REGULAR, BA_DIRECTORY, BA_HIDDEN})
public @interface FileBooleanAttributes {}
static {
Object fs;
Method getBooleanAttributes;
try {
Class<?> fsClass = Class.forName("java.io.FileSystem");
Method getFileSystem = fsClass.getMethod("getFileSystem");
getFileSystem.setAccessible(true);
fs = getFileSystem.invoke(null);
getBooleanAttributes = fsClass.getDeclaredMethod("getBooleanAttributes", File.class);
if (fs == null || getBooleanAttributes == null) {
fs = null;
getBooleanAttributes = null;
}
else {
getBooleanAttributes.setAccessible(true);
}
}
catch (Exception e) {
fs = null;
getBooleanAttributes = null;
}
JAVA_IO_FILESYSTEM = fs;
JAVA_IO_FILESYSTEM_GET_BOOLEAN_ATTRIBUTES_METHOD = getBooleanAttributes;
}
}