diff --git a/lib/annotations/jdk/java/nio/file/annotations.xml b/lib/annotations/jdk/java/nio/file/annotations.xml
index 4fc7d46c809e..c2ec872789fd 100644
--- a/lib/annotations/jdk/java/nio/file/annotations.xml
+++ b/lib/annotations/jdk/java/nio/file/annotations.xml
@@ -2,10 +2,19 @@
-
+ -
+
+
+ -
+
+
-
-
+ -
+
+
\ 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 50bd63a3c070..0150bc6c4795 100644
--- a/platform/configuration-store-impl/src/SchemeManagerImpl.kt
+++ b/platform/configuration-store-impl/src/SchemeManagerImpl.kt
@@ -259,11 +259,9 @@ class SchemeManagerImpl(val fileSpec: Stri
if (provider != null && provider.enabled) {
provider.processChildren(fileSpec, roamingType, { canRead(it) }) { name, input, readOnly ->
catchAndLog(name) {
- input.use {
- val scheme = loadScheme(name, it, true)
- if (readOnly && scheme != null) {
- readOnlyExternalizableSchemes.put(scheme.name, scheme)
- }
+ val scheme = loadScheme(name, input, true)
+ if (readOnly && scheme != null) {
+ readOnlyExternalizableSchemes.put(scheme.name, scheme)
}
}
true
@@ -277,7 +275,7 @@ class SchemeManagerImpl(val fileSpec: Stri
}
catchAndLog(file.fileName.toString()) { filename ->
- file.inputStream()?.use { loadScheme(filename, it, true) }
+ file.inputStream().use { loadScheme(filename, it, true) }
}
}
}
diff --git a/platform/configuration-store-impl/src/StreamProvider.kt b/platform/configuration-store-impl/src/StreamProvider.kt
index 315947532141..9e7498560603 100644
--- a/platform/configuration-store-impl/src/StreamProvider.kt
+++ b/platform/configuration-store-impl/src/StreamProvider.kt
@@ -20,10 +20,10 @@ import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream
import java.io.InputStream
interface StreamProvider {
- open val enabled: Boolean
+ val enabled: Boolean
get() = true
- open fun isApplicable(fileSpec: String, roamingType: RoamingType = RoamingType.DEFAULT): Boolean = true
+ fun isApplicable(fileSpec: String, roamingType: RoamingType = RoamingType.DEFAULT): Boolean = true
/**
* @param fileSpec
@@ -34,9 +34,6 @@ interface StreamProvider {
fun read(fileSpec: String, roamingType: RoamingType = RoamingType.DEFAULT): InputStream?
- /**
- * You must close passed input stream.
- */
fun processChildren(path: String, roamingType: RoamingType, filter: (name: String) -> Boolean, processor: (name: String, input: InputStream, readOnly: Boolean) -> Boolean)
/**
diff --git a/platform/configuration-store-impl/testSrc/MockStreamProvider.kt b/platform/configuration-store-impl/testSrc/MockStreamProvider.kt
index 1385da123485..86e1b8a6ce29 100644
--- a/platform/configuration-store-impl/testSrc/MockStreamProvider.kt
+++ b/platform/configuration-store-impl/testSrc/MockStreamProvider.kt
@@ -1,53 +1,48 @@
package com.intellij.configurationStore
import com.intellij.openapi.components.RoamingType
-import com.intellij.openapi.util.io.FileUtil
-import com.intellij.util.SmartList
-import java.io.File
-import java.io.FileInputStream
+import com.intellij.util.*
import java.io.InputStream
+import java.nio.file.NoSuchFileException
+import java.nio.file.Path
-class MockStreamProvider(private val myBaseDir: File) : StreamProvider {
+class MockStreamProvider(private val dir: Path) : StreamProvider {
override fun write(fileSpec: String, content: ByteArray, size: Int, roamingType: RoamingType) {
- FileUtil.writeToFile(File(myBaseDir, fileSpec), content, 0, size)
+ dir.resolve(fileSpec).write(content, 0, size)
}
override fun read(fileSpec: String, roamingType: RoamingType): InputStream? {
- val file = File(myBaseDir, fileSpec)
- //noinspection IOResourceOpenedButNotSafelyClosed
- return if (file.exists()) FileInputStream(file) else null
+ val file = dir.resolve(fileSpec)
+ try {
+ return file.inputStream()
+ }
+ catch (e: NoSuchFileException) {
+ return null
+ }
}
- private fun listSubFiles(fileSpec: String, roamingType: RoamingType): Collection {
- if (roamingType !== RoamingType.DEFAULT) {
- return emptyList()
- }
-
- val files = File(myBaseDir, fileSpec).listFiles() ?: return emptyList()
- val names = SmartList()
- for (file in files) {
- names.add(file.name)
- }
- return names
- }
-
- /**
- * You must close passed input stream.
- */
override fun processChildren(path: String, roamingType: RoamingType, filter: (name: String) -> Boolean, processor: (name: String, input: InputStream, readOnly: Boolean) -> Boolean) {
- for (name in listSubFiles(path, roamingType)) {
- if (!filter(name)) {
- continue
- }
+ dir.resolve(path).directoryStreamIfExists({ filter(it.fileName.toString()) }) {
+ for (file in it) {
+ val attributes = file.basicAttributesIfExists()
+ if (attributes == null || attributes.isDirectory || file.isHidden()) {
+ continue
+ }
- val input = read("$path/$name", roamingType)
- if (input != null && !processor(name, input, false)) {
- break
+ // we ignore empty files as well - delete if corrupted
+ if (attributes.size() == 0L) {
+ file.delete()
+ continue
+ }
+
+ if (!file.inputStream().use { processor(file.fileName.toString(), it, false) }) {
+ break
+ }
}
}
}
override fun delete(fileSpec: String, roamingType: RoamingType) {
- FileUtil.delete(File(myBaseDir, fileSpec))
+ dir.resolve(fileSpec).delete()
}
}
diff --git a/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt b/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt
index e96c81ac3a66..0d09b11659f3 100644
--- a/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt
+++ b/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt
@@ -324,7 +324,7 @@ internal class SchemeManagerTest {
}
private fun createAndLoad(): SchemeManagerImpl {
- val schemesManager = SchemeManagerImpl(FILE_SPEC, TestSchemesProcessor(), MockStreamProvider(remoteBaseDir!!.toFile()), localBaseDir!!)
+ val schemesManager = SchemeManagerImpl(FILE_SPEC, TestSchemesProcessor(), MockStreamProvider(remoteBaseDir!!), localBaseDir!!)
schemesManager.loadSchemes()
return schemesManager
}
diff --git a/platform/platform-impl/src/com/intellij/util/path.kt b/platform/platform-impl/src/com/intellij/util/path.kt
index d4eabb06655a..7754685b073d 100644
--- a/platform/platform-impl/src/com/intellij/util/path.kt
+++ b/platform/platform-impl/src/com/intellij/util/path.kt
@@ -21,13 +21,15 @@ import com.intellij.openapi.vfs.VfsUtil
import org.jetbrains.io.readCharSequence
import java.io.File
import java.io.IOException
+import java.io.InputStream
import java.io.OutputStream
import java.nio.file.*
import java.nio.file.attribute.BasicFileAttributes
+import java.nio.file.attribute.FileTime
fun Path.exists() = Files.exists(this)
-fun Path.createDirectories() = Files.createDirectories(this)
+fun Path.createDirectories(): Path = Files.createDirectories(this)
/**
* Opposite to Java, parent directories will be created
@@ -37,7 +39,7 @@ fun Path.outputStream(): OutputStream {
return Files.newOutputStream(this)
}
-fun Path.inputStream() = Files.newInputStream(this)
+fun Path.inputStream(): InputStream = Files.newInputStream(this)
/**
* Opposite to Java, parent directories will be created
@@ -71,7 +73,7 @@ fun Path.deleteRecursively(): Path = if (exists()) Files.walkFileTree (this, obj
}
}) else this
-fun Path.lastModified() = Files.getLastModifiedTime(this)
+fun Path.lastModified(): FileTime = Files.getLastModifiedTime(this)
val Path.systemIndependentPath: String
get() = toString().replace(File.separatorChar, '/')
@@ -79,9 +81,9 @@ val Path.systemIndependentPath: String
val Path.parentSystemIndependentPath: String
get() = parent!!.toString().replace(File.separatorChar, '/')
-fun Path.readBytes() = Files.readAllBytes(this)
+fun Path.readBytes(): ByteArray = Files.readAllBytes(this)
-fun Path.readText() = readBytes().toString(Charsets.UTF_8)
+fun Path.readText(): String = readBytes().toString(Charsets.UTF_8)
fun Path.readChars() = inputStream().reader().readCharSequence(size().toInt())
@@ -103,25 +105,24 @@ fun Path.write(data: String): Path {
fun Path.size() = Files.size(this)
-fun Path.sizeOrNull(): Long {
- val attributes: BasicFileAttributes
+fun Path.basicAttributesIfExists(): BasicFileAttributes? {
try {
- attributes = Files.readAttributes(this, BasicFileAttributes::class.java)
+ return Files.readAttributes(this, BasicFileAttributes::class.java)
}
- catch (ignored: IOException) {
- return -1
+ catch (ignored: NoSuchFileException) {
+ return null
}
-
- return attributes.size()
}
+fun Path.sizeOrNull() = basicAttributesIfExists()?.size() ?: -1
+
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)
+fun Path.move(target: Path): Path = Files.move(this, target)
/**
* Opposite to Java, parent directories will be created
@@ -152,7 +153,7 @@ inline fun Path.directoryStreamIfExists(task: (stream: DirectoryStream
inline fun Path.directoryStreamIfExists(noinline filter: ((path: Path) -> Boolean), task: (stream: DirectoryStream) -> R): R? {
try {
- return Files.newDirectoryStream(this, { filter.invoke(it) }).use(task)
+ return Files.newDirectoryStream(this, filter).use(task)
}
catch (ignored: NoSuchFileException) {
}
diff --git a/plugins/settings-repository/src/BaseRepositoryManager.kt b/plugins/settings-repository/src/BaseRepositoryManager.kt
index 35029871070e..2ad42794a09f 100644
--- a/plugins/settings-repository/src/BaseRepositoryManager.kt
+++ b/plugins/settings-repository/src/BaseRepositoryManager.kt
@@ -26,9 +26,11 @@ import com.intellij.openapi.vfs.CharsetToolkit
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.testFramework.LightVirtualFile
import com.intellij.util.*
+import java.io.IOException
import java.io.InputStream
import java.io.OutputStream
import java.nio.file.Path
+import java.nio.file.attribute.BasicFileAttributes
import java.util.concurrent.locks.ReentrantReadWriteLock
import kotlin.concurrent.read
import kotlin.concurrent.write
@@ -37,28 +39,35 @@ abstract class BaseRepositoryManager(protected val dir: Path) : RepositoryManage
protected val lock: ReentrantReadWriteLock = ReentrantReadWriteLock()
override fun processChildren(path: String, filter: (name: String) -> Boolean, processor: (name: String, inputStream: InputStream) -> Boolean) {
- dir.resolve(path).directoryStreamIfExists {
+ dir.resolve(path).directoryStreamIfExists({ filter(it.fileName.toString()) }) {
for (file in it) {
- if (file.isDirectory() || file.isHidden()) {
- continue;
+ val attributes: BasicFileAttributes?
+ try {
+ attributes = file.basicAttributesIfExists()
+ }
+ catch (e: IOException) {
+ LOG.warn(e)
+ continue
+ }
+
+ if (attributes == null || attributes.isDirectory || file.isHidden()) {
+ continue
}
// 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)
- }
+ if (attributes.size() == 0L) {
+ try {
+ LOG.warn("File $path is empty (length 0), will be removed")
+ delete(file, path)
}
- continue;
+ catch (e: Exception) {
+ LOG.error(e)
+ }
+ continue
}
- if (!processor(file.fileName.toString(), file.inputStream())) {
- break;
+ if (!file.inputStream().use { processor(file.fileName.toString(), it) }) {
+ break
}
}
}
diff --git a/plugins/settings-repository/src/IcsManager.kt b/plugins/settings-repository/src/IcsManager.kt
index 568156f900d7..b866eee4aee6 100644
--- a/plugins/settings-repository/src/IcsManager.kt
+++ b/plugins/settings-repository/src/IcsManager.kt
@@ -70,7 +70,7 @@ class IcsManager(dir: Path) {
}
}
- val settingsFile = dir.resolve("config.json")
+ val settingsFile: Path = dir.resolve("config.json")
val settings: IcsSettings
val repositoryManager: RepositoryManager = GitRepositoryManager(credentialsStore, dir.resolve("repository"))
@@ -190,10 +190,10 @@ class IcsManager(dir: Path) {
// first of all we must load read-only schemes - scheme could be overridden if bundled or read-only, so, such schemes must be loaded first
for (repository in readOnlySourcesManager.repositories) {
- repository.processChildren(fullPath, filter, { name, input -> processor(name, input, true) })
+ repository.processChildren(fullPath, filter) { name, input -> processor(name, input, true) }
}
- repositoryManager.processChildren(fullPath, filter, { name, input -> processor(name, input, false) })
+ repositoryManager.processChildren(fullPath, filter) { name, input -> processor(name, input, false) }
}
override fun write(fileSpec: String, content: ByteArray, size: Int, roamingType: RoamingType) {
diff --git a/plugins/settings-repository/src/git/GitEx.kt b/plugins/settings-repository/src/git/GitEx.kt
index 1cf2be1881da..572154756f8f 100644
--- a/plugins/settings-repository/src/git/GitEx.kt
+++ b/plugins/settings-repository/src/git/GitEx.kt
@@ -97,7 +97,7 @@ fun createBareRepository(dir: Path): Repository {
return repository
}
-fun createRepository(dir: Path): Repository {
+fun createGitRepository(dir: Path): Repository {
val repository = FileRepositoryBuilder().setWorkTree(dir.toFile()).build()
repository.create()
return repository
@@ -250,8 +250,8 @@ fun Repository.processChildren(path: String, filter: ((name: String) -> Boolean)
continue
}
- if (!processor(fileName, objectLoader.openStream())) {
- break;
+ if (!objectLoader.openStream().use { processor(fileName, it) }) {
+ break
}
}
}
@@ -317,7 +317,7 @@ private class InputStreamWrapper(private val delegate: InputStream, private val
delegate.close()
}
finally {
- reader.close();
+ reader.close()
}
}
}
diff --git a/plugins/settings-repository/testSrc/IcsTestCase.kt b/plugins/settings-repository/testSrc/IcsTestCase.kt
index ef614ec565b8..fd53c86f356f 100644
--- a/plugins/settings-repository/testSrc/IcsTestCase.kt
+++ b/plugins/settings-repository/testSrc/IcsTestCase.kt
@@ -21,10 +21,10 @@ import org.eclipse.jgit.lib.Repository
import org.jetbrains.jgit.dirCache.AddLoadedFile
import org.jetbrains.jgit.dirCache.edit
import org.jetbrains.settingsRepository.IcsManager
+import org.jetbrains.settingsRepository.git.createGitRepository
import org.junit.Rule
import java.nio.file.FileSystem
import java.nio.file.Path
-import org.jetbrains.settingsRepository.git.createRepository as createGitRepository
fun Repository.add(path: String, data: String) = add(path, data.toByteArray())