blob: 2cd8fb403b674ad4c6b69e7420de844655034a3a [file] [log] [blame]
package org.jetbrains.io;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.concurrent.TimeUnit;
public final class LocalFileFinder {
// if java.io.File.exists() takes more time than this timeout we assume that this is network drive and do not ping it any more
private static final int FILE_EXISTS_MAX_TIMEOUT_MILLIS = 10;
private static final Cache<Character, Boolean> myWindowsDrivesMap = CacheBuilder.newBuilder().expireAfterWrite(5, TimeUnit.MINUTES).build();
private LocalFileFinder() {
}
@Nullable
/**
Behavior is not predictable and result is not guaranteed:
1) result of check cached, but cache entry invalidated on timeout (5 min after write), not on actual change of drive status.
2) even if drive exists, it could be not used due to 10 ms threshold.
Method is not generic and is not suitable for all.
*/
public static VirtualFile findFile(@NotNull String path) {
if (windowsDriveExists(path)) {
return LocalFileSystem.getInstance().findFileByPath(path);
}
return null;
}
public static boolean windowsDriveExists(@NotNull String path) {
if (!SystemInfo.isWindows) return true;
if (path.length() > 2 && Character.isLetter(path.charAt(0)) && path.charAt(1) == ':') {
final char driveLetter = Character.toUpperCase(path.charAt(0));
final Boolean driveExists = myWindowsDrivesMap.getIfPresent(driveLetter);
if (driveExists != null) {
return driveExists;
}
else {
final long t0 = System.currentTimeMillis();
boolean exists = new File(driveLetter + ":" + File.separator).exists();
if (System.currentTimeMillis() - t0 > FILE_EXISTS_MAX_TIMEOUT_MILLIS) {
exists = false; // may be a slow network drive
}
myWindowsDrivesMap.put(driveLetter, exists);
return exists;
}
}
return false;
}
}