From 88772188aa05fbdaf4a99b9443d10c0b3e579554 Mon Sep 17 00:00:00 2001 From: Ilya Usanov Date: Thu, 17 Feb 2022 14:58:32 +0300 Subject: [PATCH] Fix nested files reload in case of missing attributes --- .../arc/browser/base/BaseArchiveFileSystem.kt | 5 ++--- .../arc/browser/base/BaseArchiveHandler.kt | 2 ++ .../base/nest/SupportsNestedArchives.kt | 4 ++-- .../base/sevenzip/SevenZipArchiveHandler.kt | 7 +++++++ .../idea/plugins/arc/browser/util/FSUtils.kt | 21 ++++++++++++++++--- 5 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/main/kotlin/com/github/b3er/idea/plugins/arc/browser/base/BaseArchiveFileSystem.kt b/src/main/kotlin/com/github/b3er/idea/plugins/arc/browser/base/BaseArchiveFileSystem.kt index ba9e7b0..72f860b 100644 --- a/src/main/kotlin/com/github/b3er/idea/plugins/arc/browser/base/BaseArchiveFileSystem.kt +++ b/src/main/kotlin/com/github/b3er/idea/plugins/arc/browser/base/BaseArchiveFileSystem.kt @@ -7,7 +7,6 @@ import com.intellij.openapi.fileTypes.FileTypeRegistry import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.text.StringUtil import com.intellij.openapi.vfs.VirtualFile -import com.intellij.openapi.vfs.impl.ArchiveHandler import com.intellij.openapi.vfs.newvfs.ArchiveFileSystem import com.intellij.openapi.vfs.newvfs.VfsImplUtil @@ -18,13 +17,13 @@ abstract class BaseArchiveFileSystem( abstract fun getHandlerForPath(localPath: String): BaseArchiveHandler<*> abstract fun isCorrectFileType(fileType: FileType): Boolean - override fun getHandler(entryFile: VirtualFile): ArchiveHandler { + override fun getHandler(entryFile: VirtualFile): BaseArchiveHandler<*> { return VfsImplUtil.getHandler(this, entryFile) { localPath -> getHandlerForPath(localPath) } } - override fun getHandlerForFile(file: VirtualFile): ArchiveHandler { + override fun getHandlerForFile(file: VirtualFile): BaseArchiveHandler<*> { return getHandler(file) } diff --git a/src/main/kotlin/com/github/b3er/idea/plugins/arc/browser/base/BaseArchiveHandler.kt b/src/main/kotlin/com/github/b3er/idea/plugins/arc/browser/base/BaseArchiveHandler.kt index 3fb8c84..f6d5c4c 100644 --- a/src/main/kotlin/com/github/b3er/idea/plugins/arc/browser/base/BaseArchiveHandler.kt +++ b/src/main/kotlin/com/github/b3er/idea/plugins/arc/browser/base/BaseArchiveHandler.kt @@ -14,6 +14,8 @@ abstract class BaseArchiveHandler(path: String) : ArchiveHandler(path) { var myFileLength: Long = DEFAULT_LENGTH abstract val accessorCache: FileAccessorCache, T> + abstract fun isSingleFileArchive(): Boolean + protected fun getFileHandle(): FileAccessorCache.Handle { val handle = accessorCache[this] val attributes = file.canonicalFile.let { diff --git a/src/main/kotlin/com/github/b3er/idea/plugins/arc/browser/base/nest/SupportsNestedArchives.kt b/src/main/kotlin/com/github/b3er/idea/plugins/arc/browser/base/nest/SupportsNestedArchives.kt index 30a7adf..3dee760 100644 --- a/src/main/kotlin/com/github/b3er/idea/plugins/arc/browser/base/nest/SupportsNestedArchives.kt +++ b/src/main/kotlin/com/github/b3er/idea/plugins/arc/browser/base/nest/SupportsNestedArchives.kt @@ -1,9 +1,9 @@ package com.github.b3er.idea.plugins.arc.browser.base.nest +import com.github.b3er.idea.plugins.arc.browser.base.BaseArchiveHandler import com.intellij.openapi.vfs.VirtualFile -import com.intellij.openapi.vfs.impl.ArchiveHandler interface SupportsNestedArchives { - fun getHandlerForFile(file: VirtualFile): ArchiveHandler + fun getHandlerForFile(file: VirtualFile): BaseArchiveHandler<*> } diff --git a/src/main/kotlin/com/github/b3er/idea/plugins/arc/browser/base/sevenzip/SevenZipArchiveHandler.kt b/src/main/kotlin/com/github/b3er/idea/plugins/arc/browser/base/sevenzip/SevenZipArchiveHandler.kt index 5a8cf7a..4ac0c49 100644 --- a/src/main/kotlin/com/github/b3er/idea/plugins/arc/browser/base/sevenzip/SevenZipArchiveHandler.kt +++ b/src/main/kotlin/com/github/b3er/idea/plugins/arc/browser/base/sevenzip/SevenZipArchiveHandler.kt @@ -70,6 +70,13 @@ class SevenZipArchiveHandler( } } + override fun isSingleFileArchive(): Boolean { + return getFileHandle().getAndUse { holder -> + holder.archive.isSingleFileArchive() + } + } + + private fun processEntry( map: Map, entry: ISimpleInArchiveItem, diff --git a/src/main/kotlin/com/github/b3er/idea/plugins/arc/browser/util/FSUtils.kt b/src/main/kotlin/com/github/b3er/idea/plugins/arc/browser/util/FSUtils.kt index a32b2b7..708a35a 100644 --- a/src/main/kotlin/com/github/b3er/idea/plugins/arc/browser/util/FSUtils.kt +++ b/src/main/kotlin/com/github/b3er/idea/plugins/arc/browser/util/FSUtils.kt @@ -5,7 +5,10 @@ import com.github.b3er.idea.plugins.arc.browser.base.nest.SupportsStreamForVirtu import com.github.b3er.idea.plugins.arc.browser.base.sevenzip.SevenZipInputStream import com.google.common.hash.Hashing import com.intellij.openapi.application.PathManager +import com.intellij.openapi.diagnostic.thisLogger +import com.intellij.openapi.util.io.FileSystemUtil import com.intellij.openapi.vfs.VirtualFile +import com.intellij.openapi.vfs.impl.ArchiveHandler import com.intellij.util.io.URLUtil import net.sf.sevenzipjbinding.ExtractOperationResult import org.apache.commons.lang.StringUtils @@ -32,15 +35,27 @@ object FSUtils { } } + private val logger = thisLogger() + + @Suppress("DEPRECATION", "UnstableApiUsage") fun copyFileToTemp(file: VirtualFile): File { val nestedFilesRoot = File(getPluginTempFolder(), NESTED_FILES_ROOT) if (!nestedFilesRoot.exists()) { nestedFilesRoot.mkdirs() } - @Suppress("DEPRECATION", "UnstableApiUsage") - val id = Hashing.md5() + val handler = (file.fileSystem as? SupportsNestedArchives)?.getHandlerForFile(file) + + val hasher = Hashing.md5() .newHasher() .putString(file.name, Charset.defaultCharset()) + + if (handler?.isSingleFileArchive() == true) { + val attributes = FileSystemUtil.getAttributes(handler.file.canonicalFile) + hasher.putLong(attributes?.lastModified ?: ArchiveHandler.DEFAULT_TIMESTAMP) + hasher.putLong(attributes?.length ?: ArchiveHandler.DEFAULT_LENGTH) + } + + val id = hasher .putLong(file.timeStamp) .putLong(file.length) .hash() @@ -52,7 +67,7 @@ object FSUtils { } val outFile = File(outFolder, file.name) - if (!outFile.exists() || outFile.length() != file.length) { + if (!outFile.exists()) { if (!tryToDirectCopyFile(file, outFile)) { val stream = file.inputStream file.inputStream.use {