mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
* Copyright 2000-2012 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.
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.intellij.openapi.vfs.impl.jar;
|
||||
|
||||
import com.intellij.openapi.util.io.BufferExposingByteArrayInputStream;
|
||||
import com.intellij.openapi.util.io.FileAttributes;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
@@ -224,4 +225,12 @@ public class JarHandlerBase {
|
||||
|
||||
return getEntryInfo(fileOrDirectory) != null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public FileAttributes getAttributes(@NotNull final VirtualFile file) {
|
||||
synchronized (lock) {
|
||||
final ZipEntry entry = convertToEntry(file);
|
||||
return entry != null ? new FileAttributes(entry.isDirectory(), false, false, entry.getSize(), entry.getTime(), false) : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
* Copyright 2000-2012 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.
|
||||
@@ -113,9 +113,10 @@ public class JdkUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean checkForJdk(File file) {
|
||||
file = new File(file.getAbsolutePath() + File.separator + "bin");
|
||||
if (!file.exists()) return false;
|
||||
public static boolean checkForJdk(final File homePath) {
|
||||
File binPath = new File(homePath.getAbsolutePath() + File.separator + "bin");
|
||||
if (!binPath.exists()) return false;
|
||||
|
||||
FileFilter fileFilter = new FileFilter() {
|
||||
@SuppressWarnings({"HardCodedStringLiteral"})
|
||||
public boolean accept(File f) {
|
||||
@@ -124,21 +125,34 @@ public class JdkUtil {
|
||||
Comparing.strEqual(FileUtil.getNameWithoutExtension(f), "javah");
|
||||
}
|
||||
};
|
||||
File[] children = file.listFiles(fileFilter);
|
||||
return children != null && children.length >= 2;
|
||||
File[] children = binPath.listFiles(fileFilter);
|
||||
|
||||
return children != null && children.length >= 2 &&
|
||||
checkForRuntime(homePath.getAbsolutePath());
|
||||
}
|
||||
|
||||
public static boolean checkForJre(String file) {
|
||||
File ioFile = new File(new File(file.replace('/', File.separatorChar)).getAbsolutePath() + File.separator + "bin");
|
||||
if (!ioFile.exists()) return false;
|
||||
public static boolean checkForJre(String homePath) {
|
||||
homePath = new File(FileUtil.toSystemDependentName(homePath)).getAbsolutePath();
|
||||
File binPath = new File(homePath + File.separator + "bin");
|
||||
if (!binPath.exists()) return false;
|
||||
|
||||
FileFilter fileFilter = new FileFilter() {
|
||||
@SuppressWarnings({"HardCodedStringLiteral"})
|
||||
public boolean accept(File f) {
|
||||
return !f.isDirectory() && Comparing.strEqual(FileUtil.getNameWithoutExtension(f), "java");
|
||||
}
|
||||
};
|
||||
File[] children = ioFile.listFiles(fileFilter);
|
||||
return children != null && children.length >= 1;
|
||||
File[] children = binPath.listFiles(fileFilter);
|
||||
|
||||
return children != null && children.length >= 1 &&
|
||||
checkForRuntime(homePath);
|
||||
}
|
||||
|
||||
public static boolean checkForRuntime(final String homePath) {
|
||||
return new File(homePath + File.separator + "jre" + File.separator + "lib" + File.separator + "rt.jar").exists() ||
|
||||
new File(homePath + File.separator + "lib" + File.separator + "rt.jar").exists() ||
|
||||
new File(homePath + File.separator + ".." + File.separator + "Classes" + File.separator + "classes.jar").exists() ||
|
||||
new File(homePath + File.separator + "jre" + File.separator + "lib" + File.separator + "vm.jar").exists();
|
||||
}
|
||||
|
||||
public static GeneralCommandLine setupJVMCommandLine(final String exePath,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2012 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.
|
||||
@@ -13,10 +13,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @author max
|
||||
*/
|
||||
package com.intellij.openapi.vfs.newvfs;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
@@ -31,9 +27,13 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
* @author max
|
||||
*/
|
||||
public abstract class NewVirtualFile extends VirtualFile implements VirtualFileWithId {
|
||||
private volatile long myModificationStamp = LocalTimeCounter.currentTime();
|
||||
private final AtomicLong myModificationStamp = new AtomicLong(LocalTimeCounter.currentTime());
|
||||
|
||||
public boolean isValid() {
|
||||
ApplicationManager.getApplication().assertReadAccessAllowed();
|
||||
@@ -50,6 +50,9 @@ public abstract class NewVirtualFile extends VirtualFile implements VirtualFileW
|
||||
|
||||
public abstract NewVirtualFile getParent();
|
||||
|
||||
@Nullable
|
||||
public abstract NewVirtualFile getCanonicalFile();
|
||||
|
||||
@Nullable
|
||||
public abstract NewVirtualFile findChild(@NotNull @NonNls final String name);
|
||||
|
||||
@@ -75,11 +78,11 @@ public abstract class NewVirtualFile extends VirtualFile implements VirtualFileW
|
||||
}
|
||||
|
||||
public long getModificationStamp() {
|
||||
return myModificationStamp;
|
||||
return myModificationStamp.get();
|
||||
}
|
||||
|
||||
public void setModificationStamp(long modificationStamp) {
|
||||
myModificationStamp = modificationStamp;
|
||||
myModificationStamp.set(modificationStamp);
|
||||
}
|
||||
|
||||
public abstract void setWritable(boolean writable) throws IOException;
|
||||
|
||||
+15
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
* Copyright 2000-2012 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.
|
||||
@@ -14,11 +14,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @author max
|
||||
*/
|
||||
package com.intellij.openapi.vfs.newvfs;
|
||||
|
||||
import com.intellij.openapi.util.io.FileAttributes;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileListener;
|
||||
@@ -32,6 +30,9 @@ import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author max
|
||||
*/
|
||||
public abstract class NewVirtualFileSystem extends VirtualFileSystem implements FileSystemInterface, CachingVirtualFileSystem {
|
||||
private final Map<VirtualFileListener, VirtualFileListener> myListenerWrappers = new HashMap<VirtualFileListener, VirtualFileListener>();
|
||||
|
||||
@@ -150,4 +151,14 @@ public abstract class NewVirtualFileSystem extends VirtualFileSystem implements
|
||||
*/
|
||||
@FileUtil.FileBooleanAttributes
|
||||
public abstract int getBooleanAttributes(@NotNull final VirtualFile file, @FileUtil.FileBooleanAttributes int flags);
|
||||
|
||||
/**
|
||||
* Reads various file attributes in one shot (to reduce the number of native I/O calls).
|
||||
*
|
||||
* @param file file to get attributes of.
|
||||
* @return attributes of a given file, or <code>null</code> if the file doesn't exist.
|
||||
* @since 11.1
|
||||
*/
|
||||
@Nullable
|
||||
public abstract FileAttributes getAttributes(@NotNull VirtualFile file);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2012 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.
|
||||
@@ -14,13 +14,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @author max
|
||||
*/
|
||||
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.FileAttributes;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
@@ -40,6 +38,9 @@ import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author max
|
||||
*/
|
||||
public class TempFileSystem extends NewVirtualFileSystem {
|
||||
private final FSItem myRoot = new FSDir(null, "/");
|
||||
|
||||
@@ -375,4 +376,12 @@ public class TempFileSystem extends NewVirtualFileSystem {
|
||||
int regular = isDir == 0 ? FileUtil.BA_REGULAR : 0;
|
||||
return isDir | exists | regular;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileAttributes getAttributes(@NotNull final VirtualFile file) {
|
||||
final FSItem item = convert(file);
|
||||
if (item == null) return null;
|
||||
final long length = item instanceof FSFile ? ((FSFile)item).myContent.length : 0;
|
||||
return new FileAttributes(item.isDirectory(), false, false, length, item.myTimestamp, item.myWritable);
|
||||
}
|
||||
}
|
||||
|
||||
+17
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2012 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.
|
||||
@@ -21,6 +21,7 @@ import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.components.ApplicationComponent;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.io.FileAttributes;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.*;
|
||||
@@ -381,4 +382,19 @@ public class JarFileSystemImpl extends JarFileSystem implements ApplicationCompo
|
||||
}
|
||||
return exists | isDir | regular;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileAttributes getAttributes(@NotNull final VirtualFile file) {
|
||||
final JarHandler handler = getHandler(file);
|
||||
if (handler == null) return null;
|
||||
|
||||
if (file.getParent() == null) {
|
||||
final LocalFileSystem localFileSystem = LocalFileSystem.getInstance();
|
||||
final VirtualFile originalFile = localFileSystem.findFileByIoFile(handler.getOriginalFile());
|
||||
assert originalFile != null : file;
|
||||
return localFileSystem.getAttributes(originalFile);
|
||||
}
|
||||
|
||||
return handler.getAttributes(file);
|
||||
}
|
||||
}
|
||||
|
||||
+8
-37
@@ -22,6 +22,8 @@ import com.intellij.openapi.components.ApplicationComponent;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
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.vfs.JarFileSystem;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
@@ -45,17 +47,14 @@ import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
public final class LocalFileSystemImpl extends LocalFileSystemBase implements ApplicationComponent {
|
||||
|
||||
private final JBReentrantReadWriteLock LOCK = LockFactory.createReadWriteLock();
|
||||
final JBLock WRITE_LOCK = LOCK.writeLock();
|
||||
private final JBLock WRITE_LOCK = LOCK.writeLock();
|
||||
|
||||
private final List<WatchRequestImpl> myRootsToWatch = new ArrayList<WatchRequestImpl>();
|
||||
private WatchRequest[] myCachedNormalizedRequests = null;
|
||||
|
||||
private final FileWatcher myWatcher;
|
||||
|
||||
private final LocalFileSystemBase myNativeFileSystem;
|
||||
|
||||
private static class WatchRequestImpl implements WatchRequest {
|
||||
public final String myRootPath;
|
||||
|
||||
@@ -132,7 +131,6 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap
|
||||
if (myWatcher.isOperational()) {
|
||||
new StoreRefreshStatusThread().start();
|
||||
}
|
||||
myNativeFileSystem = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -471,12 +469,6 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap
|
||||
return false;
|
||||
}
|
||||
|
||||
@NonNls
|
||||
public String toString() {
|
||||
return "LocalFileSystem";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void refreshWithoutFileWatcher(final boolean asynchronous) {
|
||||
Runnable heavyRefresh = new Runnable() {
|
||||
@@ -499,33 +491,12 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists(@NotNull final VirtualFile fileOrDirectory) {
|
||||
if (myNativeFileSystem == null) return super.exists(fileOrDirectory);
|
||||
else return myNativeFileSystem.exists(fileOrDirectory);
|
||||
public FileAttributes getAttributes(@NotNull final VirtualFile file) {
|
||||
return FileSystemUtil.getAttributes(FileUtil.toSystemDependentName(file.getPath()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTimeStamp(@NotNull final VirtualFile file) {
|
||||
if (myNativeFileSystem == null) return super.getTimeStamp(file);
|
||||
else return myNativeFileSystem.getTimeStamp(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDirectory(@NotNull final VirtualFile file) {
|
||||
if (myNativeFileSystem == null) return super.isDirectory(file);
|
||||
else return myNativeFileSystem.isDirectory(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWritable(@NotNull final VirtualFile file) {
|
||||
if (myNativeFileSystem == null) return super.isWritable(file);
|
||||
else return myNativeFileSystem.isWritable(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String[] list(@NotNull final VirtualFile file) {
|
||||
if (myNativeFileSystem == null) return super.list(file);
|
||||
else return myNativeFileSystem.list(file);
|
||||
@NonNls
|
||||
public String toString() {
|
||||
return "LocalFileSystem";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
* Copyright 2000-2012 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.
|
||||
@@ -97,7 +97,7 @@ public class Win32Kernel {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private FileInfo doGetInfo(String path) {
|
||||
FileInfo doGetInfo(String path) {
|
||||
FileInfo info = myCache.get(path);
|
||||
if (info == null) {
|
||||
info = myKernel.getInfo(path.replace('/', '\\'));
|
||||
|
||||
+19
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
* Copyright 2000-2012 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.
|
||||
@@ -18,6 +18,8 @@ package com.intellij.openapi.vfs.impl.win32;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.io.FileAttributes;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.impl.local.LocalFileSystemBase;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
@@ -202,4 +204,20 @@ public class Win32LocalFileSystem extends LocalFileSystemBase {
|
||||
public int getBooleanAttributes(@NotNull VirtualFile file, int flags) {
|
||||
return myKernel.getBooleanAttributes(file.getPath(), flags);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileAttributes getAttributes(@NotNull final VirtualFile file) {
|
||||
final FileInfo fileInfo = myKernel.doGetInfo(FileUtil.toSystemDependentName(file.getPath()));
|
||||
if (fileInfo == null) return null;
|
||||
|
||||
final boolean isDirectory = isSet(fileInfo, Win32Kernel.FILE_ATTRIBUTE_DIRECTORY);
|
||||
final boolean isSymlink = isSet(fileInfo, Win32Kernel.FILE_ATTRIBUTE_REPARSE_POINT);
|
||||
final boolean isSpecial = isSet(fileInfo, Win32Kernel.FILE_ATTRIBUTE_DEVICE);
|
||||
final boolean isWritable = !isSet(fileInfo, Win32Kernel.FILE_ATTRIBUTE_READONLY);
|
||||
return new FileAttributes(isDirectory, isSymlink, isSpecial, fileInfo.length, fileInfo.timestamp, isWritable);
|
||||
}
|
||||
|
||||
private static boolean isSet(final FileInfo fileInfo, final int bit) {
|
||||
return (fileInfo.attributes & bit) == bit;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -499,10 +499,10 @@ public abstract class VirtualFileSystemEntry extends NewVirtualFile {
|
||||
}
|
||||
|
||||
@Override
|
||||
public VirtualFile getCanonicalFile() {
|
||||
public NewVirtualFile getCanonicalFile() {
|
||||
if (getFlagInt(HAS_SYMLINK_FLAG)) {
|
||||
final String path = getCanonicalPath();
|
||||
return path != null ? getFileSystem().findFileByPath(path) : null;
|
||||
return path != null ? (NewVirtualFile)getFileSystem().findFileByPath(path) : null;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2012 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.
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.intellij.mock;
|
||||
|
||||
import com.intellij.openapi.util.io.FileAttributes;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.LocalFileOperationsHandler;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
@@ -256,4 +257,9 @@ public class MockLocalFileSystem extends LocalFileSystem {
|
||||
public int getBooleanAttributes(@NotNull VirtualFile file, int flags) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileAttributes getAttributes(@NotNull VirtualFile file) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright 2000-2012 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.
|
||||
* 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 com.intellij.openapi.util.io;
|
||||
|
||||
import com.intellij.util.StringBuilderSpinAllocator;
|
||||
import org.intellij.lang.annotations.MagicConstant;
|
||||
|
||||
/**
|
||||
* @version 11.1
|
||||
* @see FileSystemUtil#getAttributes(String)
|
||||
*/
|
||||
@SuppressWarnings("OctalInteger")
|
||||
public final class FileAttributes {
|
||||
public static final int OWNER_READ = 0400;
|
||||
public static final int OWNER_WRITE = 0200;
|
||||
public static final int OWNER_EXECUTE = 0100;
|
||||
public static final int GROUP_READ = 0040;
|
||||
public static final int GROUP_WRITE = 0020;
|
||||
public static final int GROUP_EXECUTE = 0010;
|
||||
public static final int OTHERS_READ = 0004;
|
||||
public static final int OTHERS_WRITE = 0002;
|
||||
public static final int OTHERS_EXECUTE = 0001;
|
||||
|
||||
@MagicConstant(flags = {
|
||||
OWNER_READ, OWNER_WRITE, OWNER_EXECUTE, GROUP_READ, GROUP_WRITE, GROUP_EXECUTE, OTHERS_READ, OTHERS_WRITE, OTHERS_EXECUTE
|
||||
})
|
||||
public @interface Permissions { }
|
||||
|
||||
public final boolean isFile;
|
||||
public final boolean isDirectory;
|
||||
public final boolean isSymlink;
|
||||
public final boolean isSpecial;
|
||||
|
||||
/** In bytes, 0 for symlinks and special files. */
|
||||
public final long length;
|
||||
|
||||
/** In milliseconds (note that actual resolution may be less accurate). */
|
||||
public final long lastModified;
|
||||
|
||||
/** UNIX permission bits (for Windows only OWNER_WRITE matters and OWNER_READ/EXECUTE are always set), or -1 if not supported. */
|
||||
@Permissions
|
||||
public final int permissions;
|
||||
|
||||
// todo: hidden flag (?)
|
||||
|
||||
public FileAttributes(final boolean isDirectory,
|
||||
final boolean isSymlink,
|
||||
final boolean isSpecial,
|
||||
final long length,
|
||||
final long lastModified,
|
||||
final boolean writable) {
|
||||
this(isDirectory, isSymlink, isSpecial, length, lastModified, OWNER_READ | OWNER_EXECUTE | (writable ? OWNER_WRITE : 0));
|
||||
}
|
||||
|
||||
public FileAttributes(final boolean isDirectory,
|
||||
final boolean isSymlink,
|
||||
final boolean isSpecial,
|
||||
final long length,
|
||||
final long lastModified,
|
||||
@Permissions final int permissions) {
|
||||
this.isFile = !isDirectory && !isSymlink && !isSpecial;
|
||||
this.isDirectory = isDirectory;
|
||||
this.isSymlink = isSymlink;
|
||||
this.isSpecial = isSpecial;
|
||||
this.length = isSymlink || isSpecial ? 0 : length;
|
||||
this.lastModified = lastModified;
|
||||
this.permissions = permissions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
final FileAttributes that = (FileAttributes)o;
|
||||
|
||||
if (isDirectory != that.isDirectory) return false;
|
||||
if (isFile != that.isFile) return false;
|
||||
if (isSpecial != that.isSpecial) return false;
|
||||
if (isSymlink != that.isSymlink) return false;
|
||||
if (lastModified != that.lastModified) return false;
|
||||
if (permissions != that.permissions) return false;
|
||||
if (length != that.length) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = (isFile ? 1 : 0);
|
||||
result = 31 * result + (isDirectory ? 1 : 0);
|
||||
result = 31 * result + (isSymlink ? 1 : 0);
|
||||
result = 31 * result + (isSpecial ? 1 : 0);
|
||||
result = 31 * result + (int)(length ^ (length >>> 32));
|
||||
result = 31 * result + (int)(lastModified ^ (lastModified >>> 32));
|
||||
result = 31 * result + permissions;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = StringBuilderSpinAllocator.alloc();
|
||||
try {
|
||||
sb.append("[type:");
|
||||
if (isFile) sb.append('f');
|
||||
if (isDirectory) sb.append('d');
|
||||
if (isSymlink) sb.append('l');
|
||||
if (isSpecial) sb.append('!');
|
||||
|
||||
sb.append(" length:").append(length);
|
||||
|
||||
sb.append(" modified:").append(lastModified);
|
||||
|
||||
if (permissions != -1) {
|
||||
sb.append(" mode:").append(Integer.toOctalString(permissions));
|
||||
}
|
||||
|
||||
sb.append(']');
|
||||
return sb.toString();
|
||||
}
|
||||
finally {
|
||||
StringBuilderSpinAllocator.dispose(sb);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,61 +27,69 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
|
||||
// todo[r.sh] read attributes in one shot (IDEA 12)
|
||||
// todo[r.sh] use NIO2 API after migration to JDK 7
|
||||
/**
|
||||
* @version 11.1
|
||||
*/
|
||||
public class FileSystemUtil {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.util.io.FileSystemUtil");
|
||||
|
||||
@Nullable
|
||||
@NotNull
|
||||
private static final Mediator ourMediator;
|
||||
|
||||
static {
|
||||
Mediator mediator = null;
|
||||
if (SystemInfo.areSymLinksSupported) {
|
||||
if (SystemInfo.isJavaVersionAtLeast("1.7")) {
|
||||
try {
|
||||
mediator = new Jdk7MediatorImpl();
|
||||
mediator.isSymLink("/"); // quick test
|
||||
}
|
||||
catch (Throwable t) {
|
||||
if ("1.7.0-ea".equals(SystemInfo.JAVA_VERSION)) {
|
||||
LOG.warn(t);
|
||||
}
|
||||
else {
|
||||
LOG.error(t);
|
||||
}
|
||||
mediator = null;
|
||||
}
|
||||
|
||||
// todo: move IdeaWin32 interface to this package, add mediator
|
||||
|
||||
if (SystemInfo.isLinux || SystemInfo.isMac || SystemInfo.isSolaris || SystemInfo.isFreeBSD) {
|
||||
try {
|
||||
mediator = new JnaUnixMediatorImpl();
|
||||
mediator.getAttributes("/"); // quick test
|
||||
}
|
||||
if (mediator == null) {
|
||||
if (SystemInfo.isLinux || SystemInfo.isMac || SystemInfo.isSolaris || SystemInfo.isFreeBSD) {
|
||||
try {
|
||||
mediator = new JnaUnixMediatorImpl();
|
||||
mediator.isSymLink("/"); // quick test
|
||||
}
|
||||
catch (Throwable t) {
|
||||
LOG.error(t);
|
||||
mediator = null;
|
||||
}
|
||||
}
|
||||
catch (Throwable t) {
|
||||
LOG.error(t);
|
||||
mediator = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (mediator == null && SystemInfo.isJavaVersionAtLeast("1.7") && !"1.7.0-ea".equals(SystemInfo.JAVA_VERSION)) {
|
||||
try {
|
||||
mediator = new Jdk7MediatorImpl();
|
||||
mediator.getAttributes("/"); // quick test
|
||||
}
|
||||
catch (Throwable t) {
|
||||
LOG.error(t);
|
||||
mediator = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (mediator == null) {
|
||||
// todo: after introducing IdeaWin32 mediator, fail tests at this point, or issue a warning in production
|
||||
mediator = new StandardMediatorImpl();
|
||||
}
|
||||
|
||||
ourMediator = mediator;
|
||||
}
|
||||
|
||||
private FileSystemUtil() { }
|
||||
|
||||
public static boolean isSymLink(@NotNull final String path) {
|
||||
@Nullable
|
||||
public static FileAttributes getAttributes(@NotNull final String path) {
|
||||
try {
|
||||
return ourMediator != null && ourMediator.isSymLink(path);
|
||||
return ourMediator.getAttributes(path);
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.warn(e);
|
||||
return false;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isSymLink(@NotNull final String path) {
|
||||
final FileAttributes attributes = getAttributes(path);
|
||||
return attributes != null && attributes.isSymlink;
|
||||
}
|
||||
|
||||
public static boolean isSymLink(@NotNull final File file) {
|
||||
@@ -90,17 +98,15 @@ public class FileSystemUtil {
|
||||
|
||||
@Nullable
|
||||
public static String resolveSymLink(@NotNull final String path) {
|
||||
if (ourMediator != null) {
|
||||
try {
|
||||
final String realPath = ourMediator.resolveSymLink(path);
|
||||
if (realPath != null && new File(realPath).exists()) {
|
||||
return realPath;
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.warn(e);
|
||||
try {
|
||||
final String realPath = ourMediator.resolveSymLink(path);
|
||||
if (realPath != null && new File(realPath).exists()) {
|
||||
return realPath;
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.warn(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -110,15 +116,8 @@ public class FileSystemUtil {
|
||||
}
|
||||
|
||||
public static int getPermissions(@NotNull final String path) {
|
||||
if (SystemInfo.isUnix && ourMediator != null) {
|
||||
try {
|
||||
return ourMediator.getPermissions(path);
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.warn(e);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
final FileAttributes attributes = getAttributes(path);
|
||||
return attributes != null ? attributes.permissions : -1;
|
||||
}
|
||||
|
||||
public static int getPermissions(@NotNull final File file) {
|
||||
@@ -126,7 +125,7 @@ public class FileSystemUtil {
|
||||
}
|
||||
|
||||
public static void setPermissions(@NotNull final String path, final int permissions) {
|
||||
if (SystemInfo.isUnix && ourMediator != null) {
|
||||
if (SystemInfo.isUnix) {
|
||||
try {
|
||||
ourMediator.setPermissions(path, permissions);
|
||||
}
|
||||
@@ -141,16 +140,16 @@ public class FileSystemUtil {
|
||||
}
|
||||
|
||||
private interface Mediator {
|
||||
boolean isSymLink(@NotNull String path) throws Exception;
|
||||
@Nullable
|
||||
FileAttributes getAttributes(@NotNull String path) throws Exception;
|
||||
|
||||
@Nullable
|
||||
String resolveSymLink(@NotNull String path) throws Exception;
|
||||
|
||||
int getPermissions(@NotNull String path) throws Exception;
|
||||
|
||||
void setPermissions(@NotNull String path, int permissions) throws Exception;
|
||||
}
|
||||
|
||||
// todo[r.sh] remove reflection after migration to JDK 7
|
||||
@SuppressWarnings("OctalInteger")
|
||||
private static class Jdk7MediatorImpl implements Mediator {
|
||||
private final Object myDefaultFileSystem;
|
||||
@@ -158,8 +157,9 @@ public class FileSystemUtil {
|
||||
private final Method myIsSymbolicLink;
|
||||
private final Object myLinkOptions;
|
||||
private final Object myNoFollowLinkOptions;
|
||||
private final Method myGetAttribute;
|
||||
private final Method myReadAttributes;
|
||||
private final Method mySetAttribute;
|
||||
private final Method myToMillis;
|
||||
|
||||
private Jdk7MediatorImpl() throws Exception {
|
||||
myDefaultFileSystem = Class.forName("java.nio.file.FileSystems").getMethod("getDefault").invoke(null);
|
||||
@@ -168,7 +168,8 @@ public class FileSystemUtil {
|
||||
myGetPath.setAccessible(true);
|
||||
|
||||
final Class<?> pathClass = Class.forName("java.nio.file.Path");
|
||||
myIsSymbolicLink = Class.forName("java.nio.file.Files").getMethod("isSymbolicLink", pathClass);
|
||||
final Class<?> filesClass = Class.forName("java.nio.file.Files");
|
||||
myIsSymbolicLink = filesClass.getMethod("isSymbolicLink", pathClass);
|
||||
myIsSymbolicLink.setAccessible(true);
|
||||
|
||||
final Class<?> linkOptClass = Class.forName("java.nio.file.LinkOption");
|
||||
@@ -177,14 +178,35 @@ public class FileSystemUtil {
|
||||
Array.set(myNoFollowLinkOptions, 0, linkOptClass.getField("NOFOLLOW_LINKS").get(null));
|
||||
|
||||
final Class<?> linkOptArrClass = myLinkOptions.getClass();
|
||||
myGetAttribute = Class.forName("java.nio.file.Files").getMethod("getAttribute", pathClass, String.class, linkOptArrClass);
|
||||
mySetAttribute = Class.forName("java.nio.file.Files").getMethod("setAttribute", pathClass, String.class, Object.class, linkOptArrClass);
|
||||
myReadAttributes = filesClass.getMethod("readAttributes", pathClass, String.class, linkOptArrClass);
|
||||
myReadAttributes.setAccessible(true);
|
||||
mySetAttribute = filesClass.getMethod("setAttribute", pathClass, String.class, Object.class, linkOptArrClass);
|
||||
mySetAttribute.setAccessible(true);
|
||||
|
||||
final Class<?> fileTimeClass = Class.forName("java.nio.file.attribute.FileTime");
|
||||
myToMillis = fileTimeClass.getMethod("toMillis");
|
||||
myToMillis.setAccessible(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSymLink(@NotNull final String path) throws Exception {
|
||||
public FileAttributes getAttributes(@NotNull final String path) throws Exception {
|
||||
final Object pathObj = myGetPath.invoke(myDefaultFileSystem, path, ArrayUtil.EMPTY_STRING_ARRAY);
|
||||
return (Boolean)myIsSymbolicLink.invoke(null, pathObj);
|
||||
try {
|
||||
final Map attributes = (Map)myReadAttributes.invoke(null, pathObj, "posix:permissions,*", myNoFollowLinkOptions);
|
||||
return new FileAttributes((Boolean)attributes.get("isDirectory"),
|
||||
(Boolean)attributes.get("isSymbolicLink"),
|
||||
(Boolean)attributes.get("isOther"),
|
||||
(Long)attributes.get("size"),
|
||||
(Long)myToMillis.invoke(attributes.get("lastModifiedTime")),
|
||||
decodePermissions(attributes.get("permissions")));
|
||||
}
|
||||
catch (InvocationTargetException e) {
|
||||
final Throwable cause = e.getCause();
|
||||
if (cause != null && "java.nio.file.NoSuchFileException".equals(cause.getClass().getName())) {
|
||||
return null;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -196,38 +218,30 @@ public class FileSystemUtil {
|
||||
return toRealPath.invoke(pathObj, myLinkOptions).toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPermissions(@NotNull final String path) throws Exception {
|
||||
final Object pathObj = myGetPath.invoke(myDefaultFileSystem, path, ArrayUtil.EMPTY_STRING_ARRAY);
|
||||
final Object attribute = myGetAttribute.invoke(null, pathObj, POSIX_PERMISSIONS_ATTR, myNoFollowLinkOptions);
|
||||
return decodePermissions(attribute);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPermissions(@NotNull final String path, final int permissions) throws Exception {
|
||||
final Object pathObj = myGetPath.invoke(myDefaultFileSystem, path, ArrayUtil.EMPTY_STRING_ARRAY);
|
||||
final Object attribute = encodePermissions(permissions);
|
||||
if (attribute != null) {
|
||||
mySetAttribute.invoke(null, pathObj, POSIX_PERMISSIONS_ATTR, attribute, myLinkOptions);
|
||||
mySetAttribute.invoke(null, pathObj, "posix:permissions", attribute, myLinkOptions);
|
||||
}
|
||||
}
|
||||
|
||||
private static final String POSIX_PERMISSIONS_ATTR = "posix:permissions";
|
||||
|
||||
private static final Map<String, Integer> ATTRIBUTES_MAP;
|
||||
static {
|
||||
ATTRIBUTES_MAP = new HashMap<String, Integer>();
|
||||
ATTRIBUTES_MAP.put("OWNER_READ", 0400);
|
||||
ATTRIBUTES_MAP.put("OWNER_WRITE", 0200);
|
||||
ATTRIBUTES_MAP.put("OWNER_EXECUTE", 0100);
|
||||
ATTRIBUTES_MAP.put("GROUP_READ", 0040);
|
||||
ATTRIBUTES_MAP.put("GROUP_WRITE", 0020);
|
||||
ATTRIBUTES_MAP.put("GROUP_EXECUTE", 0010);
|
||||
ATTRIBUTES_MAP.put("OTHERS_READ", 0004);
|
||||
ATTRIBUTES_MAP.put("OTHERS_WRITE", 0002);
|
||||
ATTRIBUTES_MAP.put("OTHERS_EXECUTE", 0001);
|
||||
ATTRIBUTES_MAP.put("OWNER_READ", FileAttributes.OWNER_READ);
|
||||
ATTRIBUTES_MAP.put("OWNER_WRITE", FileAttributes.OWNER_WRITE);
|
||||
ATTRIBUTES_MAP.put("OWNER_EXECUTE", FileAttributes.OWNER_EXECUTE);
|
||||
ATTRIBUTES_MAP.put("GROUP_READ", FileAttributes.GROUP_READ);
|
||||
ATTRIBUTES_MAP.put("GROUP_WRITE", FileAttributes.GROUP_WRITE);
|
||||
ATTRIBUTES_MAP.put("GROUP_EXECUTE", FileAttributes.GROUP_EXECUTE);
|
||||
ATTRIBUTES_MAP.put("OTHERS_READ", FileAttributes.OTHERS_READ);
|
||||
ATTRIBUTES_MAP.put("OTHERS_WRITE", FileAttributes.OTHERS_WRITE);
|
||||
ATTRIBUTES_MAP.put("OTHERS_EXECUTE", FileAttributes.OTHERS_EXECUTE);
|
||||
}
|
||||
|
||||
@FileAttributes.Permissions
|
||||
private static int decodePermissions(final Object o) {
|
||||
if (!(o instanceof Collection)) return -1;
|
||||
|
||||
@@ -236,6 +250,7 @@ public class FileSystemUtil {
|
||||
final Integer bit = ATTRIBUTES_MAP.get(attr.toString());
|
||||
if (bit != null) value |= bit;
|
||||
}
|
||||
//noinspection MagicConstant
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -260,11 +275,14 @@ public class FileSystemUtil {
|
||||
}
|
||||
|
||||
// thanks to SVNKit for the idea
|
||||
@SuppressWarnings("OctalInteger")
|
||||
private static class JnaUnixMediatorImpl implements Mediator {
|
||||
@SuppressWarnings("OctalInteger")
|
||||
private interface LibC extends Library {
|
||||
// from stat(2)
|
||||
int S_MASK = 0177777;
|
||||
int S_IFLNK = 0120000;
|
||||
int S_IFLNK = 0120000; // symbolic link
|
||||
int S_IFREG = 0100000; // regular file
|
||||
int S_IFDIR = 0040000; // directory
|
||||
int PERM_MASK = 0777;
|
||||
|
||||
int lstat(String path, Pointer stat);
|
||||
@@ -274,34 +292,45 @@ public class FileSystemUtil {
|
||||
|
||||
private final LibC myLibC;
|
||||
private final Memory mySharedMem;
|
||||
private final int myOffset;
|
||||
private final int myModeOffset;
|
||||
private final int mySizeOffset;
|
||||
private final int myTimeOffset;
|
||||
|
||||
private JnaUnixMediatorImpl() throws Exception {
|
||||
myLibC = (LibC)Native.loadLibrary("c", LibC.class);
|
||||
mySharedMem = new Memory(512);
|
||||
myOffset = SystemInfo.isLinux ? (SystemInfo.is32Bit ? 16 : 24) :
|
||||
SystemInfo.isMac | SystemInfo.isFreeBSD ? 8 :
|
||||
SystemInfo.isSolaris ? (SystemInfo.is32Bit ? 20 : 16) :
|
||||
-1;
|
||||
if (myOffset < 0) throw new IllegalStateException("Unsupported OS: " + SystemInfo.OS_NAME);
|
||||
}
|
||||
|
||||
private synchronized int getMode(final String path) {
|
||||
mySharedMem.clear();
|
||||
final int res = SystemInfo.isLinux ? myLibC.__lxstat64(0, path, mySharedMem) : myLibC.lstat(path, mySharedMem);
|
||||
if (res == 0) {
|
||||
return (SystemInfo.isLinux ? mySharedMem.getInt(myOffset) : mySharedMem.getShort(myOffset)) & LibC.S_MASK;
|
||||
}
|
||||
else {
|
||||
LOG.debug("lstat(" + path + "): " + res);
|
||||
return -1;
|
||||
}
|
||||
myModeOffset = SystemInfo.isLinux ? (SystemInfo.is32Bit ? 16 : 24) :
|
||||
SystemInfo.isMac | SystemInfo.isFreeBSD ? 8 :
|
||||
SystemInfo.isSolaris ? (SystemInfo.is32Bit ? 20 : 16) :
|
||||
-1;
|
||||
mySizeOffset = SystemInfo.isLinux ? (SystemInfo.is32Bit ? 44 : 48) :
|
||||
SystemInfo.isMac | SystemInfo.isFreeBSD ? (SystemInfo.is32Bit ? 48 : 72) :
|
||||
SystemInfo.isSolaris ? (SystemInfo.is32Bit ? 48 : 40) :
|
||||
-1;
|
||||
myTimeOffset = SystemInfo.isLinux ? (SystemInfo.is32Bit ? 72 : 88) :
|
||||
SystemInfo.isMac | SystemInfo.isFreeBSD ? 40 :
|
||||
SystemInfo.isSolaris ? 64 :
|
||||
-1;
|
||||
if (myModeOffset < 0) throw new IllegalStateException("Unsupported OS: " + SystemInfo.OS_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSymLink(@NotNull final String path) throws Exception {
|
||||
final int mode = getMode(path);
|
||||
return mode != -1 && (mode & LibC.S_IFLNK) == LibC.S_IFLNK;
|
||||
public synchronized FileAttributes getAttributes(@NotNull final String path) throws Exception {
|
||||
mySharedMem.clear();
|
||||
final int res = SystemInfo.isLinux ? myLibC.__lxstat64(0, path, mySharedMem) : myLibC.lstat(path, mySharedMem);
|
||||
if (res == 0) {
|
||||
final int mode = (SystemInfo.isLinux ? mySharedMem.getInt(myModeOffset) : mySharedMem.getShort(myModeOffset)) & LibC.S_MASK;
|
||||
final boolean isDirectory = (mode & LibC.S_IFDIR) == LibC.S_IFDIR;
|
||||
final boolean isSymlink = (mode & LibC.S_IFLNK) == LibC.S_IFLNK;
|
||||
final boolean isSpecial = !isDirectory && !isSymlink && (mode & LibC.S_IFREG) == 0;
|
||||
final long size = mySharedMem.getLong(mySizeOffset);
|
||||
final long mTime1 = SystemInfo.is32Bit ? mySharedMem.getInt(myTimeOffset) : mySharedMem.getLong(myTimeOffset);
|
||||
final long mTime2 = SystemInfo.is32Bit ? mySharedMem.getInt(myTimeOffset + 4) : mySharedMem.getLong(myTimeOffset + 8);
|
||||
final long mTime = mTime1 * 1000 + mTime2 / 1000000;
|
||||
@FileAttributes.Permissions final int permissions = mode & LibC.PERM_MASK;
|
||||
return new FileAttributes(isDirectory, isSymlink, isSpecial, size, mTime, permissions);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -309,15 +338,68 @@ public class FileSystemUtil {
|
||||
return new File(path).getCanonicalPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPermissions(@NotNull final String path) throws Exception {
|
||||
final int mode = getMode(path);
|
||||
return mode != -1 ? mode & LibC.PERM_MASK : -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPermissions(@NotNull final String path, final int permissions) throws Exception {
|
||||
myLibC.chmod(path, permissions & LibC.PERM_MASK);
|
||||
}
|
||||
}
|
||||
|
||||
private static class StandardMediatorImpl implements Mediator {
|
||||
// from java.io.FileSystem
|
||||
private static final int BA_REGULAR = 0x02;
|
||||
private static final int BA_DIRECTORY = 0x04;
|
||||
|
||||
private final Object myFileSystem;
|
||||
private final Method myGetBooleanAttributes;
|
||||
|
||||
private StandardMediatorImpl() {
|
||||
Object fileSystem;
|
||||
Method getBooleanAttributes;
|
||||
try {
|
||||
final Class<?> fsClass = Class.forName("java.io.FileSystem");
|
||||
final Method getFileSystem = fsClass.getMethod("getFileSystem");
|
||||
getFileSystem.setAccessible(true);
|
||||
fileSystem = getFileSystem.invoke(null);
|
||||
getBooleanAttributes = fsClass.getDeclaredMethod("getBooleanAttributes", File.class);
|
||||
getBooleanAttributes.setAccessible(true);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
fileSystem = null;
|
||||
getBooleanAttributes = null;
|
||||
}
|
||||
myFileSystem = fileSystem;
|
||||
myGetBooleanAttributes = getBooleanAttributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileAttributes getAttributes(@NotNull final String path) throws Exception {
|
||||
final File file = new File(path);
|
||||
if (myFileSystem != null) {
|
||||
final int flags = (Integer)myGetBooleanAttributes.invoke(myFileSystem, file);
|
||||
if (flags != 0) {
|
||||
final boolean isDirectory = (flags & BA_DIRECTORY) != 0;
|
||||
final boolean isSpecial = (flags & (BA_REGULAR | BA_DIRECTORY)) == 0;
|
||||
return new FileAttributes(isDirectory, false, isSpecial, file.length(), file.lastModified(), file.canWrite());
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (file.exists()) {
|
||||
final boolean isDirectory = file.isDirectory();
|
||||
final boolean isSpecial = !isDirectory && !file.isFile();
|
||||
return new FileAttributes(isDirectory, false, isSpecial, file.length(), file.lastModified(), file.canWrite());
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String resolveSymLink(@NotNull final String path) throws Exception {
|
||||
return new File(path).getCanonicalPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPermissions(@NotNull final String path, final int permissions) throws Exception {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.lang.psi.dataFlow;
|
||||
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.CallEnvironment;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.CallInstruction;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.ControlFlowBuilderUtil;
|
||||
@@ -77,6 +78,7 @@ public class DFAEngine<E> {
|
||||
visited[instr.num()] = true;
|
||||
|
||||
while (!workList.isEmpty()) {
|
||||
ProgressManager.checkCanceled();
|
||||
final Instruction curr = workList.remove();
|
||||
final int num = curr.num();
|
||||
final E oldE = info.get(num);
|
||||
|
||||
Reference in New Issue
Block a user