more robust code for zip handles when the files were changed (IDEA-148458)

This commit is contained in:
Maxim.Mossienko
2015-11-27 19:25:30 +01:00
parent 7d3ec630d9
commit 3ac5fda632
@@ -35,8 +35,8 @@ import java.util.zip.ZipFile;
public class ZipHandler extends ArchiveHandler {
private volatile String myCanonicalPathToZip = null;
private volatile long myFileStamp = DEFAULT_TIMESTAMP;
private volatile long myFileLength = DEFAULT_LENGTH;
private volatile long myFileStamp;
private volatile long myFileLength;
public ZipHandler(@NotNull String path) {
super(path);
@@ -45,8 +45,12 @@ public class ZipHandler extends ArchiveHandler {
private static final FileAccessorCache<ZipHandler, ZipFile> ourZipFileFileAccessorCache = new FileAccessorCache<ZipHandler, ZipFile>(20, 10) {
@Override
protected ZipFile createAccessor(ZipHandler key) throws IOException {
key.getFileStamp(); // cache file stamp and length
return new ZipFile(key.getCanonicalPathToZip());
final String canonicalPathToZip = key.getCanonicalPathToZip();
FileAttributes attributes = FileSystemUtil.getAttributes(canonicalPathToZip);
key.myFileStamp = attributes != null ? attributes.lastModified : DEFAULT_TIMESTAMP;
key.myFileLength = attributes != null ? attributes.length : DEFAULT_LENGTH;
return new ZipFile(canonicalPathToZip);
}
@Override
@@ -75,16 +79,6 @@ public class ZipHandler extends ArchiveHandler {
return value;
}
private long getFileStamp() {
long stamp = myFileStamp;
if (stamp == DEFAULT_TIMESTAMP) {
FileAttributes attributes = FileSystemUtil.getAttributes(getFileToUse());
myFileStamp = stamp = attributes != null ? attributes.lastModified : DEFAULT_TIMESTAMP;
myFileLength = attributes != null ? attributes.length : DEFAULT_LENGTH;
}
return stamp;
}
@NotNull
@Override
protected Map<String, EntryInfo> createEntriesMap() throws IOException {
@@ -114,17 +108,16 @@ public class ZipHandler extends ArchiveHandler {
if (getFile() == getFileToUse()) { // files are canonicalized
// IDEA-148458, http://bugs.java.com/view_bug.do?bug_id=4425695, JVM crashes on use of opened ZipFile after it was updated
// Reopen file if the file has been changed
FileAttributes attributes = FileSystemUtil.getAttributes(getFileToUse());
FileAttributes attributes = FileSystemUtil.getAttributes(getCanonicalPathToZip());
if (attributes == null) {
throw new FileNotFoundException(getCanonicalPathToZip());
}
if (attributes.lastModified == getFileStamp() && attributes.length == myFileLength) return handle;
if (attributes.lastModified == myFileStamp && attributes.length == myFileLength) return handle;
handle.release();
// Note that zip_util.c#ZIP_Get_From_Cache will allow us to have duplicated ZipFile instances without a problem
removeZipHandlerFromCache();
myFileStamp = DEFAULT_TIMESTAMP;
myFileLength = DEFAULT_LENGTH;
handle.release();
handle = ourZipFileFileAccessorCache.get(this);
}
@@ -163,7 +156,7 @@ public class ZipHandler extends ArchiveHandler {
if (".".equals(path.second)) {
return parentInfo;
}
info = store(map, parentInfo, path.second, isDirectory, entry.getSize(), getFileStamp(), entryName);
info = store(map, parentInfo, path.second, isDirectory, entry.getSize(), myFileStamp, entryName);
return info;
}