do not use VFS for application store

This commit is contained in:
Vladimir Krivosheev
2018-03-06 15:11:50 +01:00
parent 64edfe2fab
commit 4fa5151dc1
4 changed files with 55 additions and 70 deletions
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2015 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.
*/
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.configurationStore
import com.intellij.application.options.PathMacrosImpl
@@ -35,7 +21,8 @@ import org.jdom.Element
private class ApplicationPathMacroManager : BasePathMacroManager(null)
const val APP_CONFIG = "\$APP_CONFIG$"
private val FILE_STORAGE_DIR = "options"
private const val FILE_STORAGE_DIR = "options"
private const val DEFAULT_STORAGE_SPEC = "${PathManager.DEFAULT_OPTIONS_FILE_NAME}${FileStorageCoreUtil.DEFAULT_EXT}"
class ApplicationStoreImpl(private val application: Application, pathMacroManager: PathMacroManager? = null) : ComponentStoreImpl() {
override val storageManager = ApplicationStorageManager(application, pathMacroManager)
@@ -66,10 +53,6 @@ class ApplicationStoreImpl(private val application: Application, pathMacroManage
}
class ApplicationStorageManager(application: Application, pathMacroManager: PathMacroManager? = null) : StateStorageManagerImpl("application", pathMacroManager?.createTrackingSubstitutor(), application) {
companion object {
private val DEFAULT_STORAGE_SPEC = "${PathManager.DEFAULT_OPTIONS_FILE_NAME}${FileStorageCoreUtil.DEFAULT_EXT}"
}
override fun getOldStorageSpec(component: Any, componentName: String, operation: StateStorageOperation): String? {
return if (component is NamedJDOMExternalizable) {
@@ -85,6 +68,9 @@ class ApplicationStorageManager(application: Application, pathMacroManager: Path
override val isUseXmlProlog: Boolean
get() = false
override val isUseVfsForWrite: Boolean
get() = false
override fun providerDataStateChanged(storage: FileBasedStorage, element: Element?, type: DataStateChanged) {
// IDEA-144052 When "Settings repository" is enabled changes in 'Path Variables' aren't saved to default path.macros.xml file causing errors in build process
if (storage.fileSpec != "path.macros.xml") {
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2015 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.
*/
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.configurationStore
import com.intellij.notification.Notification
@@ -33,10 +19,9 @@ import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.util.ArrayUtil
import com.intellij.util.LineSeparator
import com.intellij.util.io.delete
import com.intellij.util.io.exists
import com.intellij.util.io.readChars
import com.intellij.util.io.systemIndependentPath
import com.intellij.util.io.writeSafe
import com.intellij.util.loadElement
import com.intellij.util.toBufferExposingByteArray
import org.jdom.Element
@@ -68,6 +53,7 @@ open class FileBasedStorage(file: Path,
}
protected open val isUseXmlProlog: Boolean = false
protected open val isUseVfsForWrite: Boolean = true
// we never set io file to null
fun setFile(virtualFile: VirtualFile?, ioFileIfChanged: Path?) {
@@ -87,17 +73,39 @@ open class FileBasedStorage(file: Path,
}
override fun saveLocally(element: Element?) {
if (storage.lineSeparator == null) {
storage.lineSeparator = if (storage.isUseXmlProlog) LineSeparator.LF else LineSeparator.getSystemLineSeparator()
var lineSeparator = storage.lineSeparator
if (lineSeparator == null) {
lineSeparator = if (storage.isUseXmlProlog) LineSeparator.getSystemLineSeparator() else LineSeparator.LF
storage.lineSeparator = lineSeparator
}
val virtualFile = storage.virtualFile
// only app level components do not use xml prolog
if (storage.roamingType == RoamingType.DISABLED && storage.isUseXmlProlog) {
if (element == null) {
}
}
val isUseVfs = storage.isUseVfsForWrite
val virtualFile = if (isUseVfs) storage.virtualFile else null
if (element == null) {
if (isUseVfs && virtualFile == null) {
LOG.warn("Cannot find virtual file $virtualFile")
}
deleteFile(storage.file, this, virtualFile)
storage.cachedVirtualFile = null
}
else if (!isUseVfs) {
val file = storage.file
LOG.debug { "Save $file" }
file.writeSafe { out ->
JDOMUtil.write(element, out, lineSeparator.separatorString)
}
}
else {
storage.cachedVirtualFile = writeFile(storage.file, this, virtualFile, element, if (storage.isUseXmlProlog) storage.lineSeparator!! else LineSeparator.LF, storage.isUseXmlProlog)
storage.cachedVirtualFile = writeFile(storage.file, this, virtualFile, element, lineSeparator, storage.isUseXmlProlog)
}
}
}
@@ -260,12 +268,10 @@ internal fun detectLineSeparators(chars: CharSequence, defaultSeparator: LineSep
private fun deleteFile(file: Path, requestor: Any, virtualFile: VirtualFile?) {
if (virtualFile == null) {
LOG.warn("Cannot find virtual file $file")
}
if (virtualFile == null) {
if (file.exists()) {
file.delete()
try {
Files.delete(file)
}
catch (ignored: NoSuchFileException) {
}
}
else if (virtualFile.exists()) {
@@ -282,4 +288,4 @@ internal fun deleteFile(requestor: Any, virtualFile: VirtualFile) {
runUndoTransparentWriteAction { virtualFile.delete(requestor) }
}
internal class ReadOnlyModificationException(val file: VirtualFile, val session: StateStorage.SaveSession?) : RuntimeException("File is read-only: "+file)
internal class ReadOnlyModificationException(val file: VirtualFile, val session: StateStorage.SaveSession?) : RuntimeException("File is read-only: $file")
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2015 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.
*/
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.configurationStore
import com.intellij.openapi.Disposable
@@ -74,11 +60,14 @@ open class StateStorageManagerImpl(private val rootTagName: String,
// access under storageLock
@Suppress("LeakingThis")
private var isUseVfsListener = if (componentManager == null) ThreeState.NO else ThreeState.UNSURE // unsure because depends on stream provider state
private var isUseVfsListener = if (componentManager == null || !isUseVfsForWrite) ThreeState.NO else ThreeState.UNSURE // unsure because depends on stream provider state
protected open val isUseXmlProlog: Boolean
get() = true
protected open val isUseVfsForWrite: Boolean
get() = true
companion object {
private fun createDefaultVirtualTracker(componentManager: ComponentManager?): StorageVirtualFileTracker? {
return when (componentManager) {
@@ -298,6 +287,9 @@ open class StateStorageManagerImpl(private val rootTagName: String,
override val isUseXmlProlog: Boolean
get() = rootElementName != null && storageManager.isUseXmlProlog
override val isUseVfsForWrite: Boolean
get() = storageManager.isUseVfsForWrite
override fun beforeElementSaved(element: Element) {
if (rootElementName != null) {
storageManager.beforeElementSaved(element)
@@ -1,6 +1,4 @@
/*
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
*/
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.util.io
import com.intellij.openapi.diagnostic.Logger
@@ -171,9 +169,9 @@ fun Path.writeSafe(outConsumer: (OutputStream) -> Unit): Path {
try {
Files.move(tempFile, this, StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING)
}
catch (e: IOException) {
catch (e: AtomicMoveNotSupportedException) {
LOG.warn(e)
FileUtil.rename(tempFile.toFile(), this.toFile())
Files.move(tempFile, this, StandardCopyOption.REPLACE_EXISTING)
}
return this
}
@@ -276,4 +274,7 @@ fun sanitizeFileName(name: String, replacement: String? = "_", isTruncate: Boole
}
return result.toString().truncateFileName()
}
}
val Path.isWritable: Boolean
get() = Files.isWritable(this)