From 2dcea49d917be2c0de0d83612cd73a18a60c9c40 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Thu, 11 Feb 2016 16:32:03 +0100 Subject: [PATCH] use nio Path --- .../testSrc/BuiltInWebServerTest.kt | 2 +- .../built-in-server/testSrc/TestManager.kt | 2 +- .../src/DirectoryBasedStorage.kt | 7 +- .../src/SchemeManagerFactoryImpl.kt | 9 +- .../src/SchemeManagerImpl.kt | 94 ++++++++-------- .../src/StateStorageManagerImpl.kt | 6 +- .../testSrc/ApplicationStoreTest.kt | 6 +- .../testSrc/DirectoryBasedStorageTest.kt | 4 +- .../testSrc/ModuleStoreRenameTest.kt | 2 +- .../testSrc/ModuleStoreTest.kt | 4 +- .../testSrc/ProjectStoreTest.kt | 4 +- .../testSrc/SchemeManagerTest.kt | 95 ++++++++-------- .../src/com/intellij/util/path.kt | 50 +++++++-- .../protocol-model-generator/src/FileSet.kt | 16 ++- .../testFramework/TemporaryDirectory.kt | 8 +- .../src/BaseRepositoryManager.kt | 104 ++++++++---------- plugins/settings-repository/src/IcsManager.kt | 23 ++-- .../src/ReadOnlySourcesManager.kt | 11 +- .../src/RepositoryService.kt | 11 +- .../src/copyAppSettingsToRepository.kt | 24 ++-- plugins/settings-repository/src/git/GitEx.kt | 12 +- .../src/git/GitRepositoryManager.kt | 46 ++++---- .../src/git/dirCacheEditor.kt | 5 +- .../src/keychain/FileCredentialsStore.kt | 32 +++++- .../src/settings/IcsSettings.kt | 18 ++- .../src/settings/readOnlySourcesEditor.kt | 12 +- .../testSrc/BareGitTest.kt | 6 +- .../testSrc/CredentialsTest.kt | 5 +- .../settings-repository/testSrc/GitTest.kt | 2 +- .../testSrc/IcsTestCase.kt | 4 +- .../settings-repository/testSrc/LoadTest.kt | 5 +- .../testSrc/OverwriteRemoteTest.kt | 7 +- 32 files changed, 333 insertions(+), 303 deletions(-) diff --git a/platform/built-in-server/testSrc/BuiltInWebServerTest.kt b/platform/built-in-server/testSrc/BuiltInWebServerTest.kt index 9b15e9c9a618..899d21dc4248 100644 --- a/platform/built-in-server/testSrc/BuiltInWebServerTest.kt +++ b/platform/built-in-server/testSrc/BuiltInWebServerTest.kt @@ -35,7 +35,7 @@ private class BuiltInWebServerTest : BuiltInServerTestCase() { private fun testIndex(vararg paths: String) { val project = BuiltInServerTestCase.projectRule.project - val newPath = tempDirManager.newPath(refreshVfs = false) + val newPath = tempDirManager.newPath() newPath.writeChild(manager.filePath!!, "hello") newPath.refreshVfs() diff --git a/platform/built-in-server/testSrc/TestManager.kt b/platform/built-in-server/testSrc/TestManager.kt index feaab3eb56ea..20339c80eded 100644 --- a/platform/built-in-server/testSrc/TestManager.kt +++ b/platform/built-in-server/testSrc/TestManager.kt @@ -49,7 +49,7 @@ internal class TestManager(val projectRule: ProjectRule, private val tempDirMana projectRule.project if (filePath!! == "_tmp_") { - val file = tempDirManager.newPath(".txt") + val file = tempDirManager.newPath(".txt", refreshVfs = true) if (!annotation!!.doNotCreate) { file.createFile() } diff --git a/platform/configuration-store-impl/src/DirectoryBasedStorage.kt b/platform/configuration-store-impl/src/DirectoryBasedStorage.kt index e4b2f3fb99a8..ec04f166a574 100644 --- a/platform/configuration-store-impl/src/DirectoryBasedStorage.kt +++ b/platform/configuration-store-impl/src/DirectoryBasedStorage.kt @@ -33,14 +33,15 @@ import com.intellij.util.LineSeparator import com.intellij.util.SmartList import com.intellij.util.SystemProperties import com.intellij.util.containers.SmartHashSet +import com.intellij.util.systemIndependentPath import gnu.trove.THashMap import org.jdom.Element -import java.io.File import java.io.FileNotFoundException import java.io.IOException import java.nio.ByteBuffer +import java.nio.file.Path -open class DirectoryBasedStorage(private val dir: File, +open class DirectoryBasedStorage(private val dir: Path, private val splitter: StateSplitter, private val pathMacroSubstitutor: TrackingPathMacroSubstitutor? = null) : StateStorageBase() { private @Volatile var virtualFile: VirtualFile? = null @@ -93,7 +94,7 @@ open class DirectoryBasedStorage(private val dir: File, private fun getVirtualFile(): VirtualFile? { var result = virtualFile if (result == null) { - result = LocalFileSystem.getInstance().findFileByIoFile(dir) + result = LocalFileSystem.getInstance().findFileByPath(dir.systemIndependentPath) virtualFile = result } return result diff --git a/platform/configuration-store-impl/src/SchemeManagerFactoryImpl.kt b/platform/configuration-store-impl/src/SchemeManagerFactoryImpl.kt index adc612723f3b..6508108e5882 100644 --- a/platform/configuration-store-impl/src/SchemeManagerFactoryImpl.kt +++ b/platform/configuration-store-impl/src/SchemeManagerFactoryImpl.kt @@ -27,7 +27,8 @@ import com.intellij.openapi.project.Project import com.intellij.util.SmartList import com.intellij.util.containers.ContainerUtil import com.intellij.util.lang.CompoundRuntimeException -import java.io.File +import java.nio.file.Path +import java.nio.file.Paths const val ROOT_CONFIG = "\$ROOT_CONFIG$" @@ -59,7 +60,7 @@ sealed class SchemeManagerFactoryBase : SchemesManagerFactory(), SettingsSavingC return originalPath } - abstract fun pathToFile(path: String, storageManager: StateStorageManager): File + abstract fun pathToFile(path: String, storageManager: StateStorageManager): Path fun process(processor: (SchemeManagerImpl) -> Unit) { for (manager in managers) { @@ -100,12 +101,12 @@ sealed class SchemeManagerFactoryBase : SchemesManagerFactory(), SettingsSavingC return path } - override fun pathToFile(path: String, storageManager: StateStorageManager) = File(storageManager.expandMacros("$ROOT_CONFIG/$path")) + override fun pathToFile(path: String, storageManager: StateStorageManager) = Paths.get(storageManager.expandMacros(ROOT_CONFIG), path) } private class ProjectSchemeManagerFactory(private val project: Project) : SchemeManagerFactoryBase() { override val componentManager = project - override fun pathToFile(path: String, storageManager: StateStorageManager) = File(project.basePath, if (ProjectUtil.isDirectoryBased(project)) "${Project.DIRECTORY_STORE_FOLDER}/$path" else ".$path") + override fun pathToFile(path: String, storageManager: StateStorageManager) = Paths.get(project.basePath, if (ProjectUtil.isDirectoryBased(project)) "${Project.DIRECTORY_STORE_FOLDER}/$path" else ".$path") } } \ No newline at end of file diff --git a/platform/configuration-store-impl/src/SchemeManagerImpl.kt b/platform/configuration-store-impl/src/SchemeManagerImpl.kt index f7679f1de56a..7c933590c7a5 100644 --- a/platform/configuration-store-impl/src/SchemeManagerImpl.kt +++ b/platform/configuration-store-impl/src/SchemeManagerImpl.kt @@ -35,28 +35,24 @@ import com.intellij.openapi.util.text.StringUtilRt import com.intellij.openapi.vfs.* import com.intellij.openapi.vfs.newvfs.NewVirtualFile import com.intellij.openapi.vfs.tracker.VirtualFileTracker -import com.intellij.util.PathUtil -import com.intellij.util.PathUtilRt -import com.intellij.util.SmartList -import com.intellij.util.ThrowableConvertor +import com.intellij.util.* import com.intellij.util.containers.ContainerUtil import com.intellij.util.io.URLUtil import com.intellij.util.text.UniqueNameGenerator import gnu.trove.THashMap import gnu.trove.THashSet import gnu.trove.TObjectObjectProcedure -import gnu.trove.TObjectProcedure import org.jdom.Document import org.jdom.Element -import java.io.File import java.io.IOException import java.io.InputStream +import java.nio.file.Path import java.util.* class SchemeManagerImpl(val fileSpec: String, private val processor: SchemeProcessor, private val provider: StreamProvider?, - private val ioDirectory: File, + private val ioDirectory: Path, val roamingType: RoamingType = RoamingType.DEFAULT, virtualFileTrackerDisposable: Disposable? = null, val presentableName: String? = null) : SchemesManager(), SafeWriteRequestor { @@ -104,7 +100,7 @@ class SchemeManagerImpl(val fileSpec: Stri private fun refreshVirtualDirectoryAndAddListener(virtualFileTrackerDisposable: Disposable?) { // store refreshes root directory, so, we don't need to use refreshAndFindFile - val directory = LocalFileSystem.getInstance().findFileByIoFile(ioDirectory) ?: return + val directory = LocalFileSystem.getInstance().findFileByPath(ioDirectory.systemIndependentPath) ?: return this.directory = directory directory.children @@ -118,7 +114,7 @@ class SchemeManagerImpl(val fileSpec: Stri } private fun addVfsListener(virtualFileTrackerDisposable: Disposable?) { - service().addTracker("${LocalFileSystem.PROTOCOL_PREFIX}${ioDirectory.absolutePath.replace(File.separatorChar, '/')}", object : VirtualFileAdapter() { + service().addTracker("${LocalFileSystem.PROTOCOL_PREFIX}${ioDirectory.toAbsolutePath().systemIndependentPath}", object : VirtualFileAdapter() { override fun contentsChanged(event: VirtualFileEvent) { if (event.requestor != null || !isMy(event)) { return @@ -268,17 +264,17 @@ class SchemeManagerImpl(val fileSpec: Stri } } else { - ioDirectory.listFiles({ parent, name -> canRead(name) })?.let { + ioDirectory.directoryStreamIfExists({ canRead(it.fileName.toString()) }) { for (file in it) { - if (file.isDirectory) { + if (file.isDirectory()) { continue } try { - loadScheme(file.name, file.inputStream(), true) + loadScheme(file.fileName.toString(), file.inputStream(), true) } catch (e: Throwable) { - LOG.error("Cannot read scheme ${file.path}", e) + LOG.error("Cannot read scheme $file", e) } } } @@ -467,16 +463,16 @@ class SchemeManagerImpl(val fileSpec: Stri } private fun removeDirectoryIfEmpty(errors: MutableList) { - ioDirectory.listFiles()?.let { + ioDirectory.directoryStreamIfExists { for (file in it) { - if (!file.isHidden) { - LOG.info("Directory ${ioDirectory.name} is not deleted: at least one file ${file.name} exists") - return + if (!file.isHidden()) { + LOG.info("Directory ${ioDirectory.fileName} is not deleted: at least one file ${file.fileName} exists") + return@removeDirectoryIfEmpty } } } - LOG.info("Remove schemes directory ${ioDirectory.name}") + LOG.info("Remove schemes directory ${ioDirectory.fileName}") directory = null var deleteUsingIo = !useVfs @@ -496,7 +492,7 @@ class SchemeManagerImpl(val fileSpec: Stri } if (deleteUsingIo) { - errors.catch { FileUtil.delete(ioDirectory) } + errors.catch { ioDirectory.deleteRecursively() } } } @@ -581,7 +577,7 @@ class SchemeManagerImpl(val fileSpec: Stri if (renamed) { externalInfo!!.scheduleDelete() } - FileUtil.writeToFile(File(ioDirectory, fileName), byteOut.internalBuffer, 0, byteOut.size()) + ioDirectory.resolve(fileName).write(byteOut.internalBuffer, 0, byteOut.size()) } } else { @@ -655,7 +651,7 @@ class SchemeManagerImpl(val fileSpec: Stri if (deleteUsingIo) { for (name in filesToDelete) { - errors.catch { FileUtil.delete(File(ioDirectory, name)) } + errors.catch { ioDirectory.resolve(name).delete() } } } @@ -665,13 +661,13 @@ class SchemeManagerImpl(val fileSpec: Stri private fun getDirectory(): VirtualFile? { var result = directory if (result == null) { - result = LocalFileSystem.getInstance().findFileByIoFile(ioDirectory) + result = LocalFileSystem.getInstance().findFileByPath(ioDirectory.systemIndependentPath) directory = result } return result } - override fun getRootDirectory() = ioDirectory + override fun getRootDirectory() = ioDirectory.toFile() override fun setSchemes(newSchemes: List, newCurrentScheme: T?, removeCondition: Condition?) { val oldCurrentScheme = currentScheme @@ -705,25 +701,23 @@ class SchemeManagerImpl(val fileSpec: Stri return } - schemeToInfo.retainEntries(object : TObjectObjectProcedure { - override fun execute(scheme: E, info: ExternalInfo): Boolean { - if (readOnlyExternalizableSchemes[scheme.name] == scheme) { - return true - } - - for (t in newSchemes) { - // by identity - if (t === scheme) { - if (filesToDelete.isNotEmpty()) { - filesToDelete.remove("${info.fileName}") - } - return true - } - } - - info.scheduleDelete() - return false + schemeToInfo.retainEntries(TObjectObjectProcedure { scheme, info -> + if (readOnlyExternalizableSchemes[scheme.name] == scheme) { + return@TObjectObjectProcedure true } + + for (t in newSchemes) { + // by identity + if (t === scheme) { + if (filesToDelete.isNotEmpty()) { + filesToDelete.remove("${info.fileName}") + } + return@TObjectObjectProcedure true + } + } + + info.scheduleDelete() + false }) } @@ -777,12 +771,10 @@ class SchemeManagerImpl(val fileSpec: Stri } override fun clearAllSchemes() { - schemeToInfo.forEachValue(object : TObjectProcedure { - override fun execute(info: ExternalInfo): Boolean { - info.scheduleDelete() - return true - } - }) + schemeToInfo.forEachValue { + it.scheduleDelete() + true + } currentScheme = null schemes.clear() @@ -895,11 +887,11 @@ private inline fun MutableList.catch(runnable: () -> Unit) { } } -fun createDir(ioDir: File, requestor: Any): VirtualFile { - ioDir.mkdirs() +fun createDir(ioDir: Path, requestor: Any): VirtualFile { + ioDir.createDirectories() val parentFile = ioDir.parent - val parentVirtualFile = (if (parentFile == null) null else VfsUtil.createDirectoryIfMissing(parentFile)) ?: throw IOException(ProjectBundle.message("project.configuration.save.file.not.found", parentFile)) - return getFile(ioDir.name, parentVirtualFile, requestor) + val parentVirtualFile = (if (parentFile == null) null else VfsUtil.createDirectoryIfMissing(parentFile.systemIndependentPath)) ?: throw IOException(ProjectBundle.message("project.configuration.save.file.not.found", parentFile)) + return getFile(ioDir.fileName.toString(), parentVirtualFile, requestor) } fun getFile(fileName: String, parent: VirtualFile, requestor: Any): VirtualFile { diff --git a/platform/configuration-store-impl/src/StateStorageManagerImpl.kt b/platform/configuration-store-impl/src/StateStorageManagerImpl.kt index 2d1af6710f58..aafb5ea8b1ee 100644 --- a/platform/configuration-store-impl/src/StateStorageManagerImpl.kt +++ b/platform/configuration-store-impl/src/StateStorageManagerImpl.kt @@ -36,6 +36,8 @@ import org.jdom.Element import org.jetbrains.annotations.TestOnly import java.io.File import java.io.IOException +import java.nio.file.Path +import java.nio.file.Paths import java.util.* import java.util.concurrent.locks.ReentrantLock import java.util.regex.Pattern @@ -195,7 +197,7 @@ open class StateStorageManagerImpl(private val rootTagName: String, val filePath = expandMacros(collapsedPath) @Suppress("DEPRECATION") if (stateSplitter != StateSplitter::class.java && stateSplitter != StateSplitterEx::class.java) { - val storage = MyDirectoryStorage(this, File(filePath), ReflectionUtil.newInstance(stateSplitter)) + val storage = MyDirectoryStorage(this, Paths.get(filePath), ReflectionUtil.newInstance(stateSplitter)) virtualFileTracker?.put(filePath, storage) return storage } @@ -212,7 +214,7 @@ open class StateStorageManagerImpl(private val rootTagName: String, return storage } - private class MyDirectoryStorage(override val storageManager: StateStorageManagerImpl, file: File, @Suppress("DEPRECATION") splitter: StateSplitter) : + private class MyDirectoryStorage(override val storageManager: StateStorageManagerImpl, file: Path, @Suppress("DEPRECATION") splitter: StateSplitter) : DirectoryBasedStorage(file, splitter, storageManager.pathMacroSubstitutor), StorageVirtualFileTracker.TrackedStorage private class MyFileStorage(override val storageManager: StateStorageManagerImpl, diff --git a/platform/configuration-store-impl/testSrc/ApplicationStoreTest.kt b/platform/configuration-store-impl/testSrc/ApplicationStoreTest.kt index 1687463a16e4..b41c71fc1eff 100644 --- a/platform/configuration-store-impl/testSrc/ApplicationStoreTest.kt +++ b/platform/configuration-store-impl/testSrc/ApplicationStoreTest.kt @@ -62,7 +62,7 @@ internal class ApplicationStoreTest { private var componentStore: MyComponentStore by Delegates.notNull() @Before fun setUp() { - testAppConfig = tempDirManager.newPath(refreshVfs = false) + testAppConfig = tempDirManager.newPath() componentStore = MyComponentStore(testAppConfig.systemIndependentPath) } @@ -220,7 +220,7 @@ internal class ApplicationStoreTest { @Test fun `don't save if only format is changed`() { val oldContent = "" val file = writeConfig("a.xml", oldContent) - val oldModificationTime = file.getLastModifiedTime() + val oldModificationTime = file.lastModified() testAppConfig.refreshVfs() val component = A() @@ -230,7 +230,7 @@ internal class ApplicationStoreTest { saveStore() assertThat(file).hasContent(oldContent) - assertThat(oldModificationTime).isEqualTo(file.getLastModifiedTime()) + assertThat(oldModificationTime).isEqualTo(file.lastModified()) component.options.bar = "2" component.options.foo = "1" diff --git a/platform/configuration-store-impl/testSrc/DirectoryBasedStorageTest.kt b/platform/configuration-store-impl/testSrc/DirectoryBasedStorageTest.kt index 2f7a2a7d7121..213d9ea14fa0 100644 --- a/platform/configuration-store-impl/testSrc/DirectoryBasedStorageTest.kt +++ b/platform/configuration-store-impl/testSrc/DirectoryBasedStorageTest.kt @@ -65,8 +65,8 @@ internal class DirectoryBasedStorageTest { @Rule fun getChain() = ruleChain @Test fun save() { - val dir = tempDirManager.newPath() - val storage = DirectoryBasedStorage(dir.toFile(), TestStateSplitter()) + val dir = tempDirManager.newPath(refreshVfs = true) + val storage = DirectoryBasedStorage(dir, TestStateSplitter()) val componentName = "test" diff --git a/platform/configuration-store-impl/testSrc/ModuleStoreRenameTest.kt b/platform/configuration-store-impl/testSrc/ModuleStoreRenameTest.kt index 4d5253ab917d..936a58786331 100644 --- a/platform/configuration-store-impl/testSrc/ModuleStoreRenameTest.kt +++ b/platform/configuration-store-impl/testSrc/ModuleStoreRenameTest.kt @@ -47,7 +47,7 @@ internal class ModuleStoreRenameTest { object : ExternalResource() { override fun before() { runInEdtAndWait { - module = projectRule.createModule(tempDirManager.newPath().resolve("m.iml")) + module = projectRule.createModule(tempDirManager.newPath(refreshVfs = true).resolve("m.iml")) } module.messageBus.connect().subscribe(ProjectTopics.MODULES, object : ModuleAdapter() { diff --git a/platform/configuration-store-impl/testSrc/ModuleStoreTest.kt b/platform/configuration-store-impl/testSrc/ModuleStoreTest.kt index 4c5a21681117..260f0855a09b 100644 --- a/platform/configuration-store-impl/testSrc/ModuleStoreTest.kt +++ b/platform/configuration-store-impl/testSrc/ModuleStoreTest.kt @@ -76,7 +76,7 @@ class ModuleStoreTest { @Test fun `must be empty if classpath storage`() { // we must not use VFS here, file must not be created - val moduleFile = tempDirManager.newPath("module").resolve("test.iml") + val moduleFile = tempDirManager.newPath("module", refreshVfs = true).resolve("test.iml") moduleFile.createModule().useAndDispose { ModuleRootModificationUtil.addContentRoot(this, moduleFile.parentSystemIndependentPath) saveStore() @@ -92,7 +92,7 @@ class ModuleStoreTest { @Test fun `one batch update session if several modules changed`() { val nameToCount = TObjectIntHashMap() - val root = tempDirManager.newPath() + val root = tempDirManager.newPath(refreshVfs = true) fun Module.addContentRoot() { val moduleName = name diff --git a/platform/configuration-store-impl/testSrc/ProjectStoreTest.kt b/platform/configuration-store-impl/testSrc/ProjectStoreTest.kt index 0ebf377a0136..97a159d2d749 100644 --- a/platform/configuration-store-impl/testSrc/ProjectStoreTest.kt +++ b/platform/configuration-store-impl/testSrc/ProjectStoreTest.kt @@ -27,11 +27,11 @@ import com.intellij.openapi.project.ex.ProjectEx import com.intellij.openapi.project.ex.ProjectManagerEx import com.intellij.openapi.project.impl.ProjectImpl import com.intellij.openapi.project.impl.ProjectManagerImpl -import com.intellij.openapi.util.io.systemIndependentPath import com.intellij.openapi.vfs.VirtualFile import com.intellij.testFramework.* import com.intellij.util.PathUtil import com.intellij.util.readText +import com.intellij.util.systemIndependentPath import org.assertj.core.api.Assertions.assertThat import org.intellij.lang.annotations.Language import org.junit.ClassRule @@ -52,7 +52,7 @@ private fun createOrLoadProject(tempDirManager: TemporaryDirectory, task: (Proje runInEdtAndWait { var filePath: String if (projectCreator == null) { - filePath = tempDirManager.newDirectory("test${if (directoryBased) "" else ProjectFileType.DOT_DEFAULT_EXTENSION}").systemIndependentPath + filePath = tempDirManager.newPath("test${if (directoryBased) "" else ProjectFileType.DOT_DEFAULT_EXTENSION}").systemIndependentPath } else { filePath = runWriteAction { projectCreator(tempDirManager.newVirtualDirectory()) } diff --git a/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt b/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt index 7532fa4bf183..e96c81ac3a66 100644 --- a/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt +++ b/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt @@ -18,13 +18,12 @@ package com.intellij.configurationStore import com.intellij.openapi.options.BaseSchemeProcessor import com.intellij.openapi.options.ExternalizableScheme import com.intellij.openapi.options.SchemesManagerFactory -import com.intellij.openapi.util.JDOMUtil import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.text.StringUtil import com.intellij.testFramework.PlatformTestUtil import com.intellij.testFramework.ProjectRule import com.intellij.testFramework.TemporaryDirectory -import com.intellij.util.SmartList +import com.intellij.util.* import com.intellij.util.lang.CompoundRuntimeException import com.intellij.util.xmlb.XmlSerializer import com.intellij.util.xmlb.annotations.Attribute @@ -40,6 +39,7 @@ import org.junit.ClassRule import org.junit.Rule import org.junit.Test import java.io.File +import java.nio.file.Path internal val FILE_SPEC = "REMOTE" @@ -55,8 +55,8 @@ internal class SchemeManagerTest { private val tempDirManager = TemporaryDirectory() @Rule fun getTemporaryFolder() = tempDirManager - private var localBaseDir: File? = null - private var remoteBaseDir: File? = null + private var localBaseDir: Path? = null + private var remoteBaseDir: Path? = null private fun getTestDataPath() = PlatformTestUtil.getCommunityPath().replace(File.separatorChar, '/') + "/platform/platform-tests/testData/options" @@ -112,14 +112,14 @@ internal class SchemeManagerTest { firstScheme!!.name = "first_renamed" manager.save() - checkSchemes(File(remoteBaseDir, "REMOTE"), "first_renamed->first_renamed;2->second", true) + checkSchemes(remoteBaseDir!!.resolve("REMOTE"), "first_renamed->first_renamed;2->second", true) checkSchemes(localBaseDir!!, "", false) firstScheme.name = "first_renamed2" manager.removeScheme(firstScheme) manager.save() - checkSchemes(File(remoteBaseDir, "REMOTE"), "2->second", true) + checkSchemes(remoteBaseDir!!.resolve("REMOTE"), "2->second", true) checkSchemes(localBaseDir!!, "", false) } @@ -142,16 +142,16 @@ internal class SchemeManagerTest { assertThat("first2").isEqualTo(scheme.name) } - fun TestScheme.save(file: File) { - FileUtil.writeToFile(file, serialize().toByteArray()) + fun TestScheme.save(file: Path) { + file.write(serialize().toByteArray()) } @Test fun `different extensions`() { - val dir = tempDirManager.newDirectory() + val dir = tempDirManager.newPath() val scheme = TestScheme("local", "true") - scheme.save(File(dir, "1.icls")) - TestScheme("local", "false").save(File(dir, "1.xml")) + scheme.save(dir.resolve("1.icls")) + TestScheme("local", "false").save(dir.resolve("1.xml")) val schemesManager = SchemeManagerImpl(FILE_SPEC, object: TestSchemesProcessor() { override fun isUpgradeNeeded() = true @@ -161,18 +161,18 @@ internal class SchemeManagerTest { schemesManager.loadSchemes() assertThat(schemesManager.allSchemes).containsOnly(scheme) - assertThat(File(dir, "1.icls")).isFile() - assertThat(File(dir, "1.xml")).isFile() + assertThat(dir.resolve("1.icls")).isRegularFile() + assertThat(dir.resolve("1.xml")).isRegularFile() scheme.data = "newTrue" schemesManager.save() - assertThat(File(dir, "1.icls")).isFile() - assertThat(File(dir, "1.xml")).doesNotExist() + assertThat(dir.resolve("1.icls")).isRegularFile() + assertThat(dir.resolve("1.xml")).doesNotExist() } @Test fun setSchemes() { - val dir = tempDirManager.newDirectory() + val dir = tempDirManager.newPath() val schemeManager = createSchemeManager(dir) schemeManager.loadSchemes() assertThat(schemeManager.allSchemes).isEmpty() @@ -183,12 +183,12 @@ internal class SchemeManagerTest { val schemes = schemeManager.allSchemes assertThat(schemes).containsOnly(scheme) - assertThat(File(dir, "s1.xml")).doesNotExist() + assertThat(dir.resolve("s1.xml")).doesNotExist() scheme.data = "newTrue" schemeManager.save() - assertThat(File(dir, "s1.xml")).isFile() + assertThat(dir.resolve("s1.xml")).isRegularFile() schemeManager.setSchemes(emptyList()) @@ -198,7 +198,7 @@ internal class SchemeManagerTest { } @Test fun `save only if scheme differs from bundled`() { - val dir = tempDirManager.newDirectory() + val dir = tempDirManager.newPath() var schemeManager = createSchemeManager(dir) val converter: (Element) -> TestScheme = { XmlSerializer.deserialize(it, TestScheme::class.java)!! } val bundledPath = "/bundledSchemes/default" @@ -219,7 +219,7 @@ internal class SchemeManagerTest { customScheme.data = "foo" schemeManager.save() - assertThat(File(dir, "default.xml")).isFile() + assertThat(dir.resolve("default.xml")).isRegularFile() schemeManager = createSchemeManager(dir) schemeManager.loadBundledScheme(bundledPath, this, converter) @@ -230,7 +230,7 @@ internal class SchemeManagerTest { } @Test fun `don't remove dir if no schemes but at least one non-hidden file exists`() { - val dir = tempDirManager.newDirectory() + val dir = tempDirManager.newPath() val schemeManager = createSchemeManager(dir) val scheme = TestScheme("s1") @@ -238,12 +238,12 @@ internal class SchemeManagerTest { schemeManager.save() - val schemeFile = File(dir, "s1.xml") - assertThat(schemeFile).isFile() + val schemeFile = dir.resolve("s1.xml") + assertThat(schemeFile).isRegularFile() schemeManager.setSchemes(emptyList()) - FileUtil.writeToFile(File(dir, "empty"), byteArrayOf()) + dir.resolve("empty").write(byteArrayOf()) schemeManager.save() @@ -252,11 +252,11 @@ internal class SchemeManagerTest { } @Test fun `remove empty directory only if some file was deleted`() { - val dir = tempDirManager.newDirectory() + val dir = tempDirManager.newPath() val schemeManager = createSchemeManager(dir) schemeManager.loadSchemes() - assertThat(dir.mkdirs()).isTrue() + dir.createDirectories() schemeManager.save() assertThat(dir).isDirectory() @@ -270,7 +270,7 @@ internal class SchemeManagerTest { } @Test fun rename() { - val dir = tempDirManager.newDirectory() + val dir = tempDirManager.newPath() val schemeManager = createSchemeManager(dir) schemeManager.loadSchemes() assertThat(schemeManager.allSchemes).isEmpty() @@ -281,19 +281,19 @@ internal class SchemeManagerTest { val schemes = schemeManager.allSchemes assertThat(schemes).containsOnly(scheme) - assertThat(File(dir, "s1.xml")).doesNotExist() + assertThat(dir.resolve("s1.xml")).doesNotExist() scheme.data = "newTrue" schemeManager.save() - assertThat(File(dir, "s1.xml")).isFile() + assertThat(dir.resolve("s1.xml")).isRegularFile() scheme.name = "s2" schemeManager.save() - assertThat(File(dir, "s1.xml")).doesNotExist() - assertThat(File(dir, "s2.xml")).isFile() + assertThat(dir.resolve("s1.xml")).doesNotExist() + assertThat(dir.resolve("s2.xml")).isRegularFile() } @Test fun `path must not contains ROOT_CONFIG macro`() { @@ -304,7 +304,7 @@ internal class SchemeManagerTest { assertThatThrownBy({SchemesManagerFactory.getInstance().create("foo\\bar", TestSchemesProcessor())}).hasMessage("Path must be system-independent, use forward slash instead of backslash") } - private fun createSchemeManager(dir: File) = SchemeManagerImpl(FILE_SPEC, TestSchemesProcessor(), null, dir) + private fun createSchemeManager(dir: Path) = SchemeManagerImpl(FILE_SPEC, TestSchemesProcessor(), null, dir) private fun createAndLoad(testData: String): SchemeManagerImpl { createTempFiles(testData) @@ -314,30 +314,30 @@ internal class SchemeManagerTest { private fun doLoadSaveTest(testData: String, expected: String, localExpected: String = "") { val schemesManager = createAndLoad(testData) schemesManager.save() - checkSchemes(File(remoteBaseDir, "REMOTE"), expected, true) + checkSchemes(remoteBaseDir!!.resolve("REMOTE"), expected, true) checkSchemes(localBaseDir!!, localExpected, false) } private fun checkSchemes(expected: String) { - checkSchemes(File(remoteBaseDir, "REMOTE"), expected, true) + checkSchemes(remoteBaseDir!!.resolve("REMOTE"), expected, true) checkSchemes(localBaseDir!!, "", false) } private fun createAndLoad(): SchemeManagerImpl { - val schemesManager = SchemeManagerImpl(FILE_SPEC, TestSchemesProcessor(), MockStreamProvider(remoteBaseDir!!), localBaseDir!!) + val schemesManager = SchemeManagerImpl(FILE_SPEC, TestSchemesProcessor(), MockStreamProvider(remoteBaseDir!!.toFile()), localBaseDir!!) schemesManager.loadSchemes() return schemesManager } private fun createTempFiles(testData: String) { - val temp = tempDirManager.newDirectory() - localBaseDir = File(temp, "__local") + val temp = tempDirManager.newPath() + localBaseDir = temp.resolve("__local") remoteBaseDir = temp - FileUtil.copyDir(File("${getTestDataPath()}/$testData"), File(temp, "REMOTE")) + FileUtil.copyDir(File("${getTestDataPath()}/$testData"), temp.resolve("REMOTE").toFile()) } } -private fun checkSchemes(baseDir: File, expected: String, ignoreDeleted: Boolean) { +private fun checkSchemes(baseDir: Path, expected: String, ignoreDeleted: Boolean) { val filesToScheme = StringUtil.split(expected, ";") val fileToSchemeMap = THashMap() for (fileToScheme in filesToScheme) { @@ -345,10 +345,9 @@ private fun checkSchemes(baseDir: File, expected: String, ignoreDeleted: Boolean fileToSchemeMap.put(fileToScheme.substring(0, index), fileToScheme.substring(index + 2)) } - val files = baseDir.listFiles() - if (files != null) { - for (file in files) { - val fileName = FileUtil.getNameWithoutExtension(file) + baseDir.directoryStreamIfExists { + for (file in it) { + val fileName = FileUtil.getNameWithoutExtension(file.fileName.toString()) if ("--deleted" == fileName && ignoreDeleted) { assertThat(fileToSchemeMap).containsKey(fileName) } @@ -356,14 +355,14 @@ private fun checkSchemes(baseDir: File, expected: String, ignoreDeleted: Boolean } for (file in fileToSchemeMap.keys) { - assertThat(File(baseDir, "$file.xml")).isFile() + assertThat(baseDir.resolve("$file.xml")).isRegularFile() } - if (files != null) { + baseDir.directoryStreamIfExists { val schemesProcessor = TestSchemesProcessor() - for (file in files) { - val scheme = schemesProcessor.readScheme(JDOMUtil.load(file), true)!! - assertThat(fileToSchemeMap.get(FileUtil.getNameWithoutExtension(file))).isEqualTo(scheme.name) + for (file in it) { + val scheme = schemesProcessor.readScheme(loadElement(file), true)!! + assertThat(fileToSchemeMap.get(FileUtil.getNameWithoutExtension(file.fileName.toString()))).isEqualTo(scheme.name) } } } diff --git a/platform/platform-impl/src/com/intellij/util/path.kt b/platform/platform-impl/src/com/intellij/util/path.kt index 4fa7049faaa8..1517c96c71a3 100644 --- a/platform/platform-impl/src/com/intellij/util/path.kt +++ b/platform/platform-impl/src/com/intellij/util/path.kt @@ -21,12 +21,8 @@ import com.intellij.openapi.vfs.VfsUtil import java.io.File import java.io.IOException import java.io.OutputStream -import java.nio.file.FileVisitResult -import java.nio.file.Files -import java.nio.file.Path -import java.nio.file.SimpleFileVisitor +import java.nio.file.* import java.nio.file.attribute.BasicFileAttributes -import java.nio.file.attribute.FileTime fun Path.exists() = Files.exists(this) @@ -74,7 +70,7 @@ fun Path.deleteRecursively(): Path = if (exists()) Files.walkFileTree(this, obje } }) else this -fun Path.getLastModifiedTime(): FileTime? = Files.getLastModifiedTime(this) +fun Path.lastModified() = Files.getLastModifiedTime(this) val Path.systemIndependentPath: String get() = toString().replace(File.separatorChar, '/') @@ -90,15 +86,33 @@ fun Path.writeChild(relativePath: String, data: ByteArray) = resolve(relativePat fun Path.writeChild(relativePath: String, data: String) = writeChild(relativePath, data.toByteArray()) -fun Path.write(data: ByteArray): Path { - parent?.createDirectories() - return Files.write(this, data) +fun Path.write(data: ByteArray, offset: Int = 0, length: Int = data.size): Path { + outputStream().use { it.write(data, offset, length) } + return this } +fun Path.size() = Files.size(this) + +fun Path.sizeOrNull(): Long { + val attributes: BasicFileAttributes + try { + attributes = Files.readAttributes(this, BasicFileAttributes::class.java) + } + catch (ignored: IOException) { + return -1 + } + + return attributes.size() +} + +fun Path.isHidden() = Files.isHidden(this) + fun Path.isDirectory() = Files.isDirectory(this) fun Path.isFile() = Files.isRegularFile(this) +fun Path.move(target: Path) = Files.move(this, target) + /** * Opposite to Java, parent directories will be created */ @@ -115,4 +129,22 @@ fun Path.refreshVfs() { VfsUtil.markDirtyAndRefresh(false, true, true, virtualFile) } } +} + +inline fun Path.directoryStreamIfExists(task: (stream: DirectoryStream) -> R): R? { + try { + Files.newDirectoryStream(this).use(task) + } + catch (ignored: NoSuchFileException) { + } + return null +} + +inline fun Path.directoryStreamIfExists(noinline filter: ((path: Path) -> Boolean), task: (stream: DirectoryStream) -> R): R? { + try { + Files.newDirectoryStream(this, { filter.invoke(it) }).use(task) + } + catch (ignored: NoSuchFileException) { + } + return null } \ No newline at end of file diff --git a/platform/script-debugger/protocol/protocol-model-generator/src/FileSet.kt b/platform/script-debugger/protocol/protocol-model-generator/src/FileSet.kt index a9c296f3b5ff..a79acfde0671 100644 --- a/platform/script-debugger/protocol/protocol-model-generator/src/FileSet.kt +++ b/platform/script-debugger/protocol/protocol-model-generator/src/FileSet.kt @@ -37,18 +37,16 @@ class FileSet(private val rootDir: Path) { } fun deleteOtherFiles() { - unusedFiles.forEach(object : TObjectProcedure { - override fun execute(path: Path): Boolean { - if (Files.deleteIfExists(path)) { - val parent = path.parent - Files.newDirectoryStream(parent).use { stream -> - if (!stream.iterator().hasNext()) { - Files.delete(parent) - } + unusedFiles.forEach(TObjectProcedure { it -> + if (Files.deleteIfExists(it)) { + val parent = it.parent + Files.newDirectoryStream(parent).use { stream -> + if (!stream.iterator().hasNext()) { + Files.delete(parent) } } - return true } + true }) } } diff --git a/platform/testFramework/src/com/intellij/testFramework/TemporaryDirectory.kt b/platform/testFramework/src/com/intellij/testFramework/TemporaryDirectory.kt index 7db92ae40f8a..c653d106a51c 100644 --- a/platform/testFramework/src/com/intellij/testFramework/TemporaryDirectory.kt +++ b/platform/testFramework/src/com/intellij/testFramework/TemporaryDirectory.kt @@ -25,7 +25,6 @@ import com.intellij.util.lang.CompoundRuntimeException import org.junit.rules.ExternalResource import org.junit.runner.Description import org.junit.runners.model.Statement -import java.io.File import java.io.IOException import java.nio.file.Path import java.nio.file.Paths @@ -55,12 +54,7 @@ class TemporaryDirectory : ExternalResource() { paths.clear() } - /** - * Directory is not created. - */ - fun newDirectory(directoryName: String? = null): File = generatePath(directoryName).toFile() - - fun newPath(directoryName: String? = null, refreshVfs: Boolean = true): Path { + fun newPath(directoryName: String? = null, refreshVfs: Boolean = false): Path { val path = generatePath(directoryName) if (refreshVfs) { path.refreshVfs() diff --git a/plugins/settings-repository/src/BaseRepositoryManager.kt b/plugins/settings-repository/src/BaseRepositoryManager.kt index af0b3adec660..8d8ca968ebe0 100644 --- a/plugins/settings-repository/src/BaseRepositoryManager.kt +++ b/plugins/settings-repository/src/BaseRepositoryManager.kt @@ -19,62 +19,53 @@ import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.invokeAndWaitIfNeed import com.intellij.openapi.diagnostic.debug import com.intellij.openapi.fileTypes.StdFileTypes -import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.vcs.merge.MergeDialogCustomizer import com.intellij.openapi.vcs.merge.MergeProvider2 import com.intellij.openapi.vcs.merge.MultipleFileMergeDialog import com.intellij.openapi.vfs.CharsetToolkit import com.intellij.openapi.vfs.VirtualFile import com.intellij.testFramework.LightVirtualFile -import com.intellij.util.PathUtilRt -import java.io.File -import java.io.FileInputStream +import com.intellij.util.* import java.io.InputStream import java.io.OutputStream +import java.nio.file.Path import java.util.concurrent.locks.ReentrantReadWriteLock import kotlin.concurrent.read import kotlin.concurrent.write -abstract class BaseRepositoryManager(protected val dir: File) : RepositoryManager { +abstract class BaseRepositoryManager(protected val dir: Path) : RepositoryManager { protected val lock: ReentrantReadWriteLock = ReentrantReadWriteLock() override fun processChildren(path: String, filter: (name: String) -> Boolean, processor: (name: String, inputStream: InputStream) -> Boolean) { - var files: Array? = null - lock.read { - files = File(dir, path).listFiles({ file, name -> filter(name) }) - } - - if (files == null || files!!.isEmpty()) { - return - } - - for (file in files!!) { - if (file.isDirectory || file.isHidden) { - continue; - } - - // we ignore empty files as well - delete if corrupted - if (file.length() == 0L) { - if (file.exists()) { - try { - LOG.warn("File $path is empty (length 0), will be removed") - delete(file, path) - } - catch (e: Exception) { - LOG.error(e) - } + dir.resolve(path).directoryStreamIfExists { + for (file in it) { + if (file.isDirectory() || file.isHidden()) { + continue; } - continue; - } - if (!processor(file.name, file.inputStream())) { - break; + // we ignore empty files as well - delete if corrupted + if (file.size() == 0L) { + if (file.exists()) { + try { + LOG.warn("File $path is empty (length 0), will be removed") + delete(file, path) + } + catch (e: Exception) { + LOG.error(e) + } + } + continue; + } + + if (!processor(file.fileName.toString(), file.inputStream())) { + break; + } } } } override fun deleteRepository() { - FileUtil.delete(dir) + dir.deleteRecursively() } protected open fun isPathIgnored(path: String): Boolean = false @@ -85,21 +76,22 @@ abstract class BaseRepositoryManager(protected val dir: File) : RepositoryManage return null } - var fileToDelete: File? = null + var fileToDelete: Path? = null lock.read { - val file = File(dir, path) - // we ignore empty files as well - delete if corrupted - if (file.length() == 0L) { - fileToDelete = file - } - else { - return FileInputStream(file) + val file = dir.resolve(path) + when (file.sizeOrNull()) { + -1L -> return null + 0L -> { + // we ignore empty files as well - delete if corrupted + fileToDelete = file + } + else -> return file.inputStream() } } try { lock.write { - if (fileToDelete!!.exists() && fileToDelete!!.length() == 0L) { + if (fileToDelete!!.sizeOrNull() == 0L) { LOG.warn("File $path is empty (length 0), will be removed") delete(fileToDelete!!, path) } @@ -121,9 +113,8 @@ abstract class BaseRepositoryManager(protected val dir: File) : RepositoryManage try { lock.write { - val file = File(dir, path) - FileUtil.writeToFile(file, content, 0, size) - + val file = dir.resolve(path) + file.write(content, 0, size) addToIndex(file, path, content, size) } } @@ -137,13 +128,13 @@ abstract class BaseRepositoryManager(protected val dir: File) : RepositoryManage /** * path relative to repository root */ - protected abstract fun addToIndex(file: File, path: String, content: ByteArray, size: Int) + protected abstract fun addToIndex(file: Path, path: String, content: ByteArray, size: Int) override fun delete(path: String) { LOG.debug { "Remove $path"} lock.write { - val file = File(dir, path) + val file = dir.resolve(path) // delete could be called for non-existent file if (file.exists()) { delete(file, path) @@ -151,25 +142,26 @@ abstract class BaseRepositoryManager(protected val dir: File) : RepositoryManage } } - private fun delete(file: File, path: String) { - val isFile = file.isFile + private fun delete(file: Path, path: String) { + val isFile = file.isFile() file.removeWithParentsIfEmpty(dir, isFile) deleteFromIndex(path, isFile) } protected abstract fun deleteFromIndex(path: String, isFile: Boolean) - override fun has(path: String) = lock.read { File(dir, path).exists() } + override fun has(path: String) = lock.read { dir.resolve(path).exists() } } -fun File.removeWithParentsIfEmpty(root: File, isFile: Boolean = true) { - FileUtil.delete(this) +fun Path.removeWithParentsIfEmpty(root: Path, isFile: Boolean = true) { + delete() if (isFile) { // remove empty directories - var parent = this.parentFile - while (parent != null && parent != root && parent.delete()) { - parent = parent.parentFile + var parent = this.parent + while (parent != null && parent != root) { + parent.delete() + parent = parent.parent } } } diff --git a/plugins/settings-repository/src/IcsManager.kt b/plugins/settings-repository/src/IcsManager.kt index 69208c6bfbe2..baf0837b34c7 100644 --- a/plugins/settings-repository/src/IcsManager.kt +++ b/plugins/settings-repository/src/IcsManager.kt @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -33,6 +33,8 @@ import com.intellij.openapi.util.AtomicNotNullLazyValue import com.intellij.openapi.util.io.FileUtil import com.intellij.util.SingleAlarm import com.intellij.util.SystemProperties +import com.intellij.util.exists +import com.intellij.util.move import org.jetbrains.keychain.CredentialsStore import org.jetbrains.keychain.FileCredentialsStore import org.jetbrains.keychain.OsXCredentialsStore @@ -40,11 +42,12 @@ import org.jetbrains.keychain.isOSXCredentialsStoreSupported import org.jetbrains.settingsRepository.git.GitRepositoryManager import org.jetbrains.settingsRepository.git.GitRepositoryService import org.jetbrains.settingsRepository.git.processChildren -import java.io.File import java.io.InputStream +import java.nio.file.Path +import java.nio.file.Paths import kotlin.properties.Delegates -val PLUGIN_NAME: String = "Settings Repository" +internal const val PLUGIN_NAME: String = "Settings Repository" internal val LOG: Logger = Logger.getInstance(IcsManager::class.java) @@ -52,7 +55,7 @@ val icsManager by lazy(LazyThreadSafetyMode.NONE) { ApplicationLoadListener.EP_NAME.findExtension(IcsApplicationLoadListener::class.java).icsManager } -class IcsManager(dir: File) { +class IcsManager(dir: Path) { val credentialsStore = object : AtomicNotNullLazyValue() { override fun compute(): CredentialsStore { if (isOSXCredentialsStoreSupported && SystemProperties.getBooleanProperty("ics.use.osx.keychain", true)) { @@ -63,14 +66,14 @@ class IcsManager(dir: File) { LOG.error(e) } } - return FileCredentialsStore(File(dir, ".git_auth")) + return FileCredentialsStore(dir.resolve(".git_auth")) } } - val settingsFile = File(dir, "config.json") + val settingsFile = dir.resolve("config.json") val settings: IcsSettings - val repositoryManager: RepositoryManager = GitRepositoryManager(credentialsStore, File(dir, "repository")) + val repositoryManager: RepositoryManager = GitRepositoryManager(credentialsStore, dir.resolve("repository")) init { try { @@ -226,14 +229,14 @@ class IcsApplicationLoadListener : ApplicationLoadListener { } val customPath = System.getProperty("ics.settingsRepository") - val pluginSystemDir = if (customPath == null) File(configPath, "settingsRepository") else File(FileUtil.expandUserHome(customPath)) + val pluginSystemDir = if (customPath == null) Paths.get(configPath, "settingsRepository") else Paths.get(FileUtil.expandUserHome(customPath)) icsManager = IcsManager(pluginSystemDir) if (!pluginSystemDir.exists()) { try { - val oldPluginDir = File(PathManager.getSystemPath(), "settingsRepository") + val oldPluginDir = Paths.get(PathManager.getSystemPath(), "settingsRepository") if (oldPluginDir.exists()) { - FileUtil.rename(oldPluginDir, pluginSystemDir) + oldPluginDir.move(pluginSystemDir) } } catch (e: Throwable) { diff --git a/plugins/settings-repository/src/ReadOnlySourcesManager.kt b/plugins/settings-repository/src/ReadOnlySourcesManager.kt index 2d7da366baf5..e0590395b714 100644 --- a/plugins/settings-repository/src/ReadOnlySourcesManager.kt +++ b/plugins/settings-repository/src/ReadOnlySourcesManager.kt @@ -16,12 +16,13 @@ package org.jetbrains.settingsRepository import com.intellij.util.SmartList +import com.intellij.util.exists import org.eclipse.jgit.lib.Repository import org.eclipse.jgit.storage.file.FileRepositoryBuilder import org.jetbrains.annotations.TestOnly -import java.io.File +import java.nio.file.Path -class ReadOnlySourcesManager(private val settings: IcsSettings, val rootDir: File) { +class ReadOnlySourcesManager(private val settings: IcsSettings, val rootDir: Path) { private var _repositories: List? = null val repositories: List @@ -36,9 +37,9 @@ class ReadOnlySourcesManager(private val settings: IcsSettings, val rootDir: Fil for (source in settings.readOnlySources) { try { val path = source.path ?: continue - val dir = File(rootDir, path) + val dir = rootDir.resolve(path) if (dir.exists()) { - r.add(FileRepositoryBuilder().setBare().setGitDir(dir).build()) + r.add(FileRepositoryBuilder().setBare().setGitDir(dir.toFile()).build()) } else { LOG.warn("Skip read-only source ${source.url} because dir doesn't exists") @@ -59,5 +60,5 @@ class ReadOnlySourcesManager(private val settings: IcsSettings, val rootDir: Fil _repositories = null } - @TestOnly fun sourceToDir(source: ReadonlySource) = File(rootDir, source.path!!) + @TestOnly fun sourceToDir(source: ReadonlySource) = rootDir.resolve(source.path!!) } \ No newline at end of file diff --git a/plugins/settings-repository/src/RepositoryService.kt b/plugins/settings-repository/src/RepositoryService.kt index 9dcbf7150bfc..17ab3f6f2be1 100644 --- a/plugins/settings-repository/src/RepositoryService.kt +++ b/plugins/settings-repository/src/RepositoryService.kt @@ -16,13 +16,16 @@ package org.jetbrains.settingsRepository import com.intellij.openapi.ui.Messages +import com.intellij.util.exists import com.intellij.util.io.URLUtil +import com.intellij.util.isDirectory import org.eclipse.jgit.lib.Constants import org.eclipse.jgit.transport.URIish import org.jetbrains.settingsRepository.git.createBareRepository import java.awt.Container -import java.io.File import java.io.IOException +import java.nio.file.Path +import java.nio.file.Paths interface RepositoryService { fun checkUrl(uriString: String, messageParent: Container? = null): Boolean { @@ -43,9 +46,9 @@ interface RepositoryService { fun checkFileRepo(url: String, messageParent: Container): Boolean { val suffix = "/${Constants.DOT_GIT}" - val file = File(if (url.endsWith(suffix)) url.substring(0, url.length - suffix.length) else url) + val file = Paths.get(if (url.endsWith(suffix)) url.substring(0, url.length - suffix.length) else url) if (file.exists()) { - if (!file.isDirectory) { + if (!file.isDirectory()) { //noinspection DialogTitleCapitalization Messages.showErrorDialog(messageParent, "Specified path is not a directory", "Specified Path is Invalid") return false @@ -75,5 +78,5 @@ interface RepositoryService { } // must be protected, kotlin bug - fun isValidRepository(file: File): Boolean + fun isValidRepository(file: Path): Boolean } \ No newline at end of file diff --git a/plugins/settings-repository/src/copyAppSettingsToRepository.kt b/plugins/settings-repository/src/copyAppSettingsToRepository.kt index 3791aafc381c..021d763a7079 100644 --- a/plugins/settings-repository/src/copyAppSettingsToRepository.kt +++ b/plugins/settings-repository/src/copyAppSettingsToRepository.kt @@ -23,6 +23,7 @@ import com.intellij.ide.actions.getExportableComponentsMap import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.components.RoamingType import com.intellij.openapi.components.stateStore +import com.intellij.util.directoryStreamIfExists import com.intellij.util.isFile import com.intellij.util.systemIndependentPath import java.nio.file.Files @@ -55,19 +56,16 @@ fun copyLocalConfig(storageManager: StateStorageManagerImpl = ApplicationManager } private fun saveDirectory(parent: Path, parentFileSpec: String, roamingType: RoamingType, streamProvider: IcsManager.IcsStreamProvider) { - if (!Files.isDirectory(parent)) { - return - } - - - for (file in Files.newDirectoryStream(parent)) { - val childFileSpec = "$parentFileSpec/${file.fileName}" - if (file.isFile()) { - val fileBytes = Files.readAllBytes(file) - streamProvider.doSave(childFileSpec, fileBytes, fileBytes.size, roamingType) - } - else { - saveDirectory(file, childFileSpec, roamingType, streamProvider) + parent.directoryStreamIfExists { + for (file in it) { + val childFileSpec = "$parentFileSpec/${file.fileName}" + if (file.isFile()) { + val fileBytes = Files.readAllBytes(file) + streamProvider.doSave(childFileSpec, fileBytes, fileBytes.size, roamingType) + } + else { + saveDirectory(file, childFileSpec, roamingType, streamProvider) + } } } } diff --git a/plugins/settings-repository/src/git/GitEx.kt b/plugins/settings-repository/src/git/GitEx.kt index 05a69f8860e1..1cf2be1881da 100644 --- a/plugins/settings-repository/src/git/GitEx.kt +++ b/plugins/settings-repository/src/git/GitEx.kt @@ -39,8 +39,8 @@ import org.eclipse.jgit.treewalk.filter.TreeFilter import org.jetbrains.keychain.CredentialsStore import org.jetbrains.settingsRepository.AuthenticationException import org.jetbrains.settingsRepository.LOG -import java.io.File import java.io.InputStream +import java.nio.file.Path fun wrapIfNeedAndReThrow(e: TransportException) { if (e is org.eclipse.jgit.errors.NoRemoteRepositoryException || e.status == TransportException.Status.CANNOT_RESOLVE_REPO) { @@ -91,14 +91,14 @@ fun Repository.disableAutoCrLf(): Repository { return this } -fun createBareRepository(dir: File): Repository { - val repository = FileRepositoryBuilder().setBare().setGitDir(dir).build() +fun createBareRepository(dir: Path): Repository { + val repository = FileRepositoryBuilder().setBare().setGitDir(dir.toFile()).build() repository.create(true) return repository } -fun createRepository(dir: File): Repository { - val repository = FileRepositoryBuilder().setWorkTree(dir).build() +fun createRepository(dir: Path): Repository { + val repository = FileRepositoryBuilder().setWorkTree(dir.toFile()).build() repository.create() return repository } @@ -165,7 +165,7 @@ fun Repository.computeIndexDiff(): IndexDiff { } } -fun cloneBare(uri: String, dir: File, credentialsStore: NotNullLazyValue? = null, progressMonitor: ProgressMonitor = NullProgressMonitor.INSTANCE): Repository { +fun cloneBare(uri: String, dir: Path, credentialsStore: NotNullLazyValue? = null, progressMonitor: ProgressMonitor = NullProgressMonitor.INSTANCE): Repository { val repository = createBareRepository(dir) val config = repository.setUpstream(uri) val remoteConfig = RemoteConfig(config, Constants.DEFAULT_REMOTE_NAME) diff --git a/plugins/settings-repository/src/git/GitRepositoryManager.kt b/plugins/settings-repository/src/git/GitRepositoryManager.kt index e76ab13f894b..978462fe4a5d 100644 --- a/plugins/settings-repository/src/git/GitRepositoryManager.kt +++ b/plugins/settings-repository/src/git/GitRepositoryManager.kt @@ -20,9 +20,8 @@ import com.intellij.openapi.progress.EmptyProgressIndicator import com.intellij.openapi.progress.ProgressIndicator import com.intellij.openapi.util.NotNullLazyValue import com.intellij.openapi.util.ShutDownTracker -import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.text.StringUtil -import com.intellij.util.SmartList +import com.intellij.util.* import org.eclipse.jgit.api.AddCommand import org.eclipse.jgit.api.errors.NoHeadException import org.eclipse.jgit.api.errors.UnmergedPathsException @@ -41,16 +40,17 @@ import org.jetbrains.jgit.dirCache.edit import org.jetbrains.keychain.CredentialsStore import org.jetbrains.settingsRepository.* import org.jetbrains.settingsRepository.RepositoryManager.Updater -import java.io.File import java.io.IOException +import java.nio.file.Files +import java.nio.file.Path import kotlin.concurrent.write -class GitRepositoryManager(private val credentialsStore: NotNullLazyValue, dir: File) : BaseRepositoryManager(dir) { +class GitRepositoryManager(private val credentialsStore: NotNullLazyValue, dir: Path) : BaseRepositoryManager(dir) { val repository: Repository get() { var r = _repository if (r == null) { - r = FileRepositoryBuilder().setWorkTree(dir).build() + r = FileRepositoryBuilder().setWorkTree(dir.toFile()).build() _repository = r if (ApplicationManager.getApplication()?.isUnitTestMode != true) { ShutDownTracker.getInstance().registerShutdownTask { _repository?.close() } @@ -103,7 +103,7 @@ class GitRepositoryManager(private val credentialsStore: NotNullLazyValue() for ((oldPath, newPath) in pairs) { - val old = File(dir, oldPath) + val old = dir.resolve(oldPath) if (!old.exists()) { continue } LOG.info("Rename $oldPath to $newPath") - - val files = old.listFiles() - if (files != null) { - val new = if (newPath == null) dir else File(dir, newPath) - for (file in files) { + old.directoryStreamIfExists { + val new = if (newPath == null) dir else dir.resolve(newPath) + for (file in it) { try { - if (file.isHidden) { - FileUtil.delete(file) + if (file.isHidden()) { + file.delete() } else { - file.renameTo(File(new, file.name)) + Files.move(file, new.resolve(file.fileName)) if (addCommand == null) { addCommand = AddCommand(repository) } - addCommand.addFilepattern(if (newPath == null) file.name else "$newPath/${file.name}") + addCommand!!.addFilepattern(if (newPath == null) file.fileName.toString() else "$newPath/${file.fileName}") } } catch (e: Throwable) { @@ -270,7 +268,7 @@ class GitRepositoryManager(private val credentialsStore: NotNullLazyValue(MyPrettyPrinter()).writeValueAsBytes(settings) if (serialized.size <= 2) { - FileUtil.delete(settingsFile) + settingsFile.delete() } else { - FileUtil.writeToFile(settingsFile, serialized) + settingsFile.write(serialized) } } -fun loadSettings(settingsFile: File): IcsSettings { +fun loadSettings(settingsFile: Path): IcsSettings { if (!settingsFile.exists()) { return IcsSettings() } - val settings = ObjectMapper().readValue(settingsFile, IcsSettings::class.java) + val settings = ObjectMapper().readValue(settingsFile.toFile(), IcsSettings::class.java) if (settings.commitDelay <= 0) { settings.commitDelay = DEFAULT_COMMIT_DELAY } diff --git a/plugins/settings-repository/src/settings/readOnlySourcesEditor.kt b/plugins/settings-repository/src/settings/readOnlySourcesEditor.kt index a340523b1f5a..875108a4f17d 100644 --- a/plugins/settings-repository/src/settings/readOnlySourcesEditor.kt +++ b/plugins/settings-repository/src/settings/readOnlySourcesEditor.kt @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -23,17 +23,17 @@ import com.intellij.openapi.progress.Task import com.intellij.openapi.ui.DialogBuilder import com.intellij.openapi.ui.TextBrowseFolderListener import com.intellij.openapi.ui.TextFieldWithBrowseButton -import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.text.StringUtil import com.intellij.ui.DocumentAdapter import com.intellij.util.Function import com.intellij.util.containers.ContainerUtil +import com.intellij.util.deleteRecursively +import com.intellij.util.exists import com.intellij.util.ui.FormBuilder import com.intellij.util.ui.table.TableModelEditor import gnu.trove.THashSet import org.jetbrains.settingsRepository.git.asProgressMonitor import org.jetbrains.settingsRepository.git.cloneBare -import java.io.File import javax.swing.JTextField import javax.swing.event.DocumentEvent @@ -130,7 +130,7 @@ internal fun createReadOnlySourcesEditor(): ConfigurableUi { indicator.checkCanceled() try { indicator.text2 = path - FileUtil.delete(File(root, path)) + root.resolve(path).deleteRecursively() } catch (e: Exception) { LOG.error(e) @@ -143,9 +143,9 @@ internal fun createReadOnlySourcesEditor(): ConfigurableUi { indicator.checkCanceled() try { indicator.text = "Cloning ${StringUtil.trimMiddle(source.url!!, 255)}" - val dir = File(root, source.path!!) + val dir = root.resolve(source.path!!) if (dir.exists()) { - FileUtil.delete(dir) + dir.deleteRecursively() } cloneBare(source.url!!, dir, icsManager.credentialsStore, indicator.asProgressMonitor()).close() } diff --git a/plugins/settings-repository/testSrc/BareGitTest.kt b/plugins/settings-repository/testSrc/BareGitTest.kt index 18aa6fc8e1cb..3d938cc2c14e 100644 --- a/plugins/settings-repository/testSrc/BareGitTest.kt +++ b/plugins/settings-repository/testSrc/BareGitTest.kt @@ -31,7 +31,7 @@ internal class BareGitTest { @Rule fun getTemporaryFolder() = tempDirManager @Test fun `remote doesn't have commits`() { - val repository = cloneBare(tempDirManager.createRepository("remote").workTree.absolutePath, tempDirManager.newDirectory("local")) + val repository = cloneBare(tempDirManager.createRepository("remote").workTree.absolutePath, tempDirManager.newPath("local")) assertThat(repository.read("\$ROOT_CONFIG$/keymaps/Mac OS X from RubyMine.xml")).isNull() } @@ -41,7 +41,7 @@ internal class BareGitTest { remoteRepository.add(filePath, SAMPLE_FILE_CONTENT) remoteRepository.commit("") - val repository = cloneBare(remoteRepository.workTree.absolutePath, tempDirManager.newDirectory()) + val repository = cloneBare(remoteRepository.workTree.absolutePath, tempDirManager.newPath()) assertThat(FileUtil.loadTextAndClose(repository.read(filePath)!!)).isEqualTo(SAMPLE_FILE_CONTENT) } @@ -52,7 +52,7 @@ internal class BareGitTest { remoteRepository.add(filePath, SAMPLE_FILE_CONTENT) remoteRepository.commit("") - val repository = cloneBare(remoteRepository.workTree.absolutePath, tempDirManager.newDirectory()) + val repository = cloneBare(remoteRepository.workTree.absolutePath, tempDirManager.newPath()) val data = THashMap() repository.processChildren("keymaps") {name, input -> diff --git a/plugins/settings-repository/testSrc/CredentialsTest.kt b/plugins/settings-repository/testSrc/CredentialsTest.kt index 194456ee0e9a..3b7041b8cd8a 100644 --- a/plugins/settings-repository/testSrc/CredentialsTest.kt +++ b/plugins/settings-repository/testSrc/CredentialsTest.kt @@ -18,12 +18,11 @@ class CredentialsTest { private var storeFile: File? = null private fun createProvider(credentialsStore: CredentialsStore): JGitCredentialsProvider { - return JGitCredentialsProvider(NotNullLazyValue.createConstantValue(credentialsStore), FileRepositoryBuilder().setBare().setGitDir(File("/tmp/fake")).build()) + return JGitCredentialsProvider(NotNullLazyValue.createConstantValue(credentialsStore), FileRepositoryBuilder().setBare().setGitDir(File("/tmp/fake")).build()) } private fun createFileStore(): FileCredentialsStore { - storeFile = FileUtil.generateRandomTemporaryPath() - return FileCredentialsStore(storeFile!!) + return FileCredentialsStore(FileUtil.generateRandomTemporaryPath().toPath()) } @After fun tearDown() { diff --git a/plugins/settings-repository/testSrc/GitTest.kt b/plugins/settings-repository/testSrc/GitTest.kt index 4dc4ab396f2d..a6f25f194b66 100644 --- a/plugins/settings-repository/testSrc/GitTest.kt +++ b/plugins/settings-repository/testSrc/GitTest.kt @@ -322,7 +322,7 @@ internal class GitTest : GitTestCase() { repositoryManager.setUpstream(remoteRepository.workTree.absolutePath) val store = ApplicationStoreImpl(ApplicationManager.getApplication()!!) - val localConfigPath = tempDirManager.newPath("local_config") + val localConfigPath = tempDirManager.newPath("local_config", refreshVfs = true) val lafData = """ diff --git a/plugins/settings-repository/testSrc/IcsTestCase.kt b/plugins/settings-repository/testSrc/IcsTestCase.kt index 34a83e419cb1..ef614ec565b8 100644 --- a/plugins/settings-repository/testSrc/IcsTestCase.kt +++ b/plugins/settings-repository/testSrc/IcsTestCase.kt @@ -53,7 +53,7 @@ abstract class IcsTestCase { get() = fsRule.fs val icsManager by lazy(LazyThreadSafetyMode.NONE) { - val icsManager = IcsManager(tempDirManager.newDirectory()) + val icsManager = IcsManager(tempDirManager.newPath()) icsManager.repositoryManager.createRepositoryIfNeed() icsManager.repositoryActive = true icsManager @@ -62,4 +62,4 @@ abstract class IcsTestCase { val provider by lazy(LazyThreadSafetyMode.NONE) { icsManager.ApplicationLevelProvider() } } -fun TemporaryDirectory.createRepository(directoryName: String? = null) = createGitRepository(newDirectory(directoryName)) +fun TemporaryDirectory.createRepository(directoryName: String? = null) = createGitRepository(newPath(directoryName)) diff --git a/plugins/settings-repository/testSrc/LoadTest.kt b/plugins/settings-repository/testSrc/LoadTest.kt index 85ebccd8c230..dee73511a9b0 100644 --- a/plugins/settings-repository/testSrc/LoadTest.kt +++ b/plugins/settings-repository/testSrc/LoadTest.kt @@ -28,7 +28,6 @@ import org.jetbrains.settingsRepository.git.cloneBare import org.jetbrains.settingsRepository.git.commit import org.junit.ClassRule import org.junit.Test -import java.io.File class LoadTest : IcsTestCase() { companion object { @@ -38,7 +37,7 @@ class LoadTest : IcsTestCase() { private val dirPath = "\$ROOT_CONFIG$/keymaps" - private fun createSchemeManager(dirPath: String) = SchemeManagerImpl(dirPath, TestSchemesProcessor(), provider, tempDirManager.newDirectory("schemes")) + private fun createSchemeManager(dirPath: String) = SchemeManagerImpl(dirPath, TestSchemesProcessor(), provider, tempDirManager.newPath("schemes")) @Test fun `load scheme`() { val localScheme = TestScheme("local") @@ -112,7 +111,7 @@ class LoadTest : IcsTestCase() { fun Repository.createAndRegisterReadOnlySource(): ReadonlySource { val source = ReadonlySource(workTree.absolutePath) - assertThat(cloneBare(source.url!!, File(icsManager.readOnlySourcesManager.rootDir, source.path!!)).objectDatabase.exists()).isTrue() + assertThat(cloneBare(source.url!!, icsManager.readOnlySourcesManager.rootDir.resolve(source.path!!)).objectDatabase.exists()).isTrue() icsManager.readOnlySourcesManager.setSources(listOf(source)) return source } diff --git a/plugins/settings-repository/testSrc/OverwriteRemoteTest.kt b/plugins/settings-repository/testSrc/OverwriteRemoteTest.kt index 94db204796d1..eb1f3bd200b2 100644 --- a/plugins/settings-repository/testSrc/OverwriteRemoteTest.kt +++ b/plugins/settings-repository/testSrc/OverwriteRemoteTest.kt @@ -1,11 +1,10 @@ package org.jetbrains.settingsRepository.test import com.intellij.testFramework.file -import com.intellij.util.isDirectory +import com.intellij.util.directoryStreamIfExists import com.intellij.util.readBytes import org.jetbrains.settingsRepository.SyncType import org.junit.Test -import java.nio.file.Files // empty means "no files, no HEAD, no commits" internal class OverwriteRemote : GitTestCase() { @@ -37,8 +36,8 @@ internal class OverwriteRemote : GitTestCase() { configureLocalRepository() val root = fs.getPath("/") - if (root.isDirectory()) { - for (path in Files.newDirectoryStream(root)) { + root.directoryStreamIfExists { + for (path in it) { provider.write(path.toString().substring(1), path.readBytes()) } repositoryManager.commit()