/*
* Copyright 2013-2016 consulo.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package consulo.compiler.server.fileSystem;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileAttributes;
import com.intellij.openapi.util.io.FileSystemUtil;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileOperationsHandler;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.local.CoreLocalVirtualFile;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collection;
import java.util.Collections;
import java.util.Locale;
import java.util.Set;
/**
* @author VISTALL
* @since 1:44/11.08.13
*/
public class CompilerServerLocalFileSystemImpl extends LocalFileSystem {
private static final FileAttributes FAKE_ROOT_ATTRIBUTES =
new FileAttributes(true, false, false, false, DEFAULT_LENGTH, DEFAULT_TIMESTAMP, false);
@Nullable
@Override
public VirtualFile findFileByIoFile(@NotNull File file) {
return file.exists() ? new CoreLocalVirtualFile(this, file) : null;
}
@Nullable
@Override
public VirtualFile refreshAndFindFileByIoFile(@NotNull File file) {
return findFileByIoFile(file);
}
@Override
public void refreshIoFiles(@NotNull Iterable<File> files) {
}
@Override
public void refreshIoFiles(@NotNull Iterable<File> files, boolean async, boolean recursive, @Nullable Runnable onFinish) {
}
@Override
public void refreshFiles(@NotNull Iterable<VirtualFile> files) {
}
@Override
public void refreshFiles(@NotNull Iterable<VirtualFile> files, boolean async, boolean recursive, @Nullable Runnable onFinish) {
}
@NotNull
@Override
public Set<WatchRequest> addRootsToWatch(@NotNull Collection<String> rootPaths, boolean watchRecursively) {
return Collections.emptySet();
}
@Override
public void removeWatchedRoots(@NotNull Collection<WatchRequest> watchRequests) {
}
@Override
public Set<WatchRequest> replaceWatchedRoots(@NotNull Collection<WatchRequest> watchRequests,
@Nullable Collection<String> recursiveRoots,
@Nullable Collection<String> flatRoots) {
return Collections.emptySet();
}
@Override
public void registerAuxiliaryFileOperationsHandler(@NotNull LocalFileOperationsHandler handler) {
}
@Override
public void unregisterAuxiliaryFileOperationsHandler(@NotNull LocalFileOperationsHandler handler) {
}
@Override
public boolean processCachedFilesInSubtree(@NotNull VirtualFile file, @NotNull Processor<VirtualFile> processor) {
throw new UnsupportedOperationException();
}
@Override
public boolean isCaseSensitive() {
return SystemInfo.isFileSystemCaseSensitive;
}
@Nullable
@Override
public VirtualFile findFileByPathIfCached(@NotNull @NonNls String path) {
throw new UnsupportedOperationException();
}
@NotNull
@Override
protected String extractRootPath(@NotNull String path) {
if (path.isEmpty()) {
try {
return extractRootPath(new File("").getCanonicalPath());
}
catch (IOException e) {
throw new RuntimeException(e);
}
}
if (SystemInfo.isWindows) {
if (path.length() >= 2 && path.charAt(1) == ':') {
// Drive letter
return path.substring(0, 2).toUpperCase(Locale.US);
}
if (path.startsWith("//") || path.startsWith("\\\\")) {
// UNC. Must skip exactly two path elements like [\\ServerName\ShareName]\pathOnShare\file.txt
// Root path is in square brackets here.
int slashCount = 0;
int idx;
for (idx = 2; idx < path.length() && slashCount < 2; idx++) {
final char c = path.charAt(idx);
if (c == '\\' || c == '/') {
slashCount++;
idx--;
}
}
return path.substring(0, idx);
}
return "";
}
return StringUtil.startsWithChar(path, '/') ? "/" : "";
}
@Override
public int getRank() {
return 0;
}
@Override
public VirtualFile copyFile(Object requestor, @NotNull VirtualFile file, @NotNull VirtualFile newParent, @NotNull String copyName)
throws IOException {
throw new UnsupportedOperationException();
}
@NotNull
@Override
public byte[] contentsToByteArray(@NotNull VirtualFile file) throws IOException {
throw new UnsupportedOperationException();
}
@NotNull
@Override
public InputStream getInputStream(@NotNull VirtualFile file) throws IOException {
return file.getInputStream();
}
@NotNull
@Override
public OutputStream getOutputStream(@NotNull VirtualFile file, Object requestor, long modStamp, long timeStamp) throws IOException {
throw new UnsupportedOperationException();
}
@Override
public long getLength(@NotNull VirtualFile file) {
return 0;
}
@Override
public boolean exists(@NotNull VirtualFile file) {
return file.exists();
}
@NotNull
@Override
public String[] list(@NotNull VirtualFile file) {
throw new UnsupportedOperationException();
}
@Override
public boolean isDirectory(@NotNull VirtualFile file) {
return file.isDirectory();
}
@Override
public long getTimeStamp(@NotNull VirtualFile file) {
return 0;
}
@Override
public void setTimeStamp(@NotNull VirtualFile file, long timeStamp) throws IOException {
}
@Override
public boolean isWritable(@NotNull VirtualFile file) {
return false;
}
@Override
public void setWritable(@NotNull VirtualFile file, boolean writableFlag) throws IOException {
throw new UnsupportedOperationException();
}
@NotNull
@Override
public VirtualFile createChildDirectory(Object requestor, @NotNull VirtualFile parent, @NotNull String dir) throws IOException {
File file = new File(parent.getPath(), dir);
FileUtil.createDirectory(file);
return findFileByIoFile(file);
}
@Override
public VirtualFile createChildFile(Object requestor, @NotNull VirtualFile parent, @NotNull String file) throws IOException {
throw new UnsupportedOperationException();
}
@Override
public void deleteFile(Object requestor, @NotNull VirtualFile file) throws IOException {
assert file instanceof CoreLocalVirtualFile;
FileUtil.delete(new File(file.getPath()));
}
@Override
public void moveFile(Object requestor, @NotNull VirtualFile file, @NotNull VirtualFile newParent) throws IOException {
throw new UnsupportedOperationException();
}
@Override
public void renameFile(Object requestor, @NotNull VirtualFile file, @NotNull String newName) throws IOException {
}
@Nullable
@Override
public FileAttributes getAttributes(@NotNull VirtualFile file) {
String path = normalize(file.getPath());
if (path == null) return null;
if (file.getParent() == null && path.startsWith("//")) {
return FAKE_ROOT_ATTRIBUTES; // fake Windows roots
}
return FileSystemUtil.getAttributes(FileUtil.toSystemDependentName(path));
}
@Override
@Nullable
protected String normalize(@NotNull String path) {
if (path.isEmpty()) {
try {
path = new File("").getCanonicalPath();
}
catch (IOException e) {
return path;
}
}
else if (SystemInfo.isWindows) {
if (path.charAt(0) == '/' && !path.startsWith("//")) {
path = path.substring(1); // hack over new File(path).toURI().toURL().getFile()
}
if (path.contains("~")) {
try {
path = new File(FileUtil.toSystemDependentName(path)).getCanonicalPath();
}
catch (IOException e) {
return null;
}
}
}
File file = new File(path);
if (!isAbsoluteFileOrDriveLetter(file)) {
path = file.getAbsolutePath();
}
return FileUtil.normalize(path);
}
private static boolean isAbsoluteFileOrDriveLetter(File file) {
String path = file.getPath();
if (SystemInfo.isWindows && path.length() == 2 && path.charAt(1) == ':') {
// just drive letter.
// return true, despite the fact that technically it's not an absolute path
return true;
}
return file.isAbsolute();
}
@NotNull
@Override
public String getProtocol() {
return PROTOCOL;
}
@Nullable
@Override
public VirtualFile findFileByPath(@NotNull @NonNls String path) {
return findFileByIoFile(new File(path));
}
@Override
public void refresh(boolean asynchronous) {
}
@Nullable
@Override
public VirtualFile refreshAndFindFileByPath(@NotNull String path) {
return findFileByPath(path);
}
}