configuration store: properly check for changes in storages with external part (IDEA-223363)

GitOrigin-RevId: 5269a493571f6ca60561c43b0b10f580e84323a2
This commit is contained in:
nik
2019-09-24 08:02:50 +00:00
committed by intellij-monorepo-bot
parent f95c597502
commit 46cf985f64
4 changed files with 20 additions and 3 deletions
@@ -1,6 +1,7 @@
// 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.roots.libraries;
import com.intellij.configurationStore.StoreReloadManager;
import com.intellij.jarRepository.RepositoryLibraryType;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.application.ex.PathManagerEx;
@@ -52,6 +53,7 @@ public class RepositoryLibrarySerializationTest extends ModuleRootManagerTestCas
@NotNull
private RepositoryLibraryProperties loadLibrary(String name) throws JDOMException, IOException {
LibraryTablesRegistrar.getInstance().getLibraryTable(myProject);
String libraryPath = "jps/model-serialization/testData/repositoryLibraries/.idea/libraries/" + name + ".xml";
File librarySource = PathManagerEx.findFileUnderCommunityHome(libraryPath);
@@ -59,6 +61,7 @@ public class RepositoryLibrarySerializationTest extends ModuleRootManagerTestCas
VirtualFile librariesVirtualFile = VfsUtil.createDirectoryIfMissing(myProject.getBaseDir(), ".idea/libraries");
VfsUtil.copy(this, LocalFileSystem.getInstance().refreshAndFindFileByIoFile(librarySource), librariesVirtualFile);
});
StoreReloadManager.getInstance().flushChangedProjectFileAlarm();
LibraryTable projectLibraryTable = LibraryTablesRegistrar.getInstance().getLibraryTable(myProject);
LibraryEx library = (LibraryEx)projectLibraryTable.getLibraryByName(name);
@@ -398,12 +398,12 @@ abstract class ComponentStoreImpl : IComponentStore {
val storage = storageManager.getStateStorage(storageSpec)
// if storage marked as changed, it means that analyzeExternalChangesAndUpdateIfNeeded was called for it and storage is already reloaded
val isReloadDataForStorage = if (reloadData == ThreeState.UNSURE) changedStorages!!.contains(storage) else reloadData.toBoolean()
val isReloadDataForStorage = if (reloadData == ThreeState.UNSURE) isStorageChanged(changedStorages!!, storage) else reloadData.toBoolean()
val stateGetter = doCreateStateGetter(isReloadDataForStorage, storage, info, name, stateClass)
var state = stateGetter.getState(defaultState)
if (state == null) {
if (changedStorages != null && changedStorages.contains(storage)) {
if (changedStorages != null && isStorageChanged(changedStorages, storage)) {
// state will be null if file deleted
// we must create empty (initial) state to reinit component
state = deserializeState(Element("state"), stateClass, null)!!
@@ -433,6 +433,9 @@ abstract class ComponentStoreImpl : IComponentStore {
return true
}
private fun isStorageChanged(changedStorages: Set<StateStorage>, storage: StateStorage) =
changedStorages.contains(storage) || storage is ExternalStorageWithInternalPart && changedStorages.contains(storage.internalStorage)
protected open fun doCreateStateGetter(reloadData: Boolean,
storage: StateStorage,
info: ComponentInfo,
@@ -4,6 +4,7 @@ package com.intellij.configurationStore
import com.intellij.openapi.components.PathMacroManager
import com.intellij.openapi.components.PathMacroSubstitutor
import com.intellij.openapi.components.RoamingType
import com.intellij.openapi.components.StateStorage
import com.intellij.openapi.components.impl.stores.FileStorageCoreUtil
import com.intellij.openapi.diagnostic.debug
import com.intellij.openapi.diagnostic.runAndLogException
@@ -21,6 +22,7 @@ import com.intellij.util.io.safeOutputStream
import gnu.trove.THashMap
import org.jdom.Attribute
import org.jdom.Element
import org.jetbrains.annotations.ApiStatus
import java.io.FileNotFoundException
import java.io.OutputStream
import java.io.Writer
@@ -439,4 +441,9 @@ internal fun createDataWriterForElement(element: Element, storageFilePathForDebu
}
}
}
}
@ApiStatus.Internal
interface ExternalStorageWithInternalPart {
val internalStorage: StateStorage
}
@@ -3,6 +3,7 @@ package com.intellij.openapi.externalSystem.configurationStore
import com.intellij.configurationStore.*
import com.intellij.openapi.components.RoamingType
import com.intellij.openapi.components.StateStorage
import com.intellij.openapi.components.StoragePathMacros
import com.intellij.openapi.module.Module
import com.intellij.openapi.project.Project
@@ -52,9 +53,12 @@ internal class ExternalProjectFilteringStorage(fileSpec: String,
project: Project,
storageManager: StateStorageManager,
private val componentName: String,
private val inProjectStorage: DirectoryBasedStorage) : ExternalProjectStorage(fileSpec, project, storageManager, rootElementName = null /* the only component per file */) {
private val inProjectStorage: DirectoryBasedStorage) : ExternalProjectStorage(fileSpec, project, storageManager, rootElementName = null /* the only component per file */), ExternalStorageWithInternalPart {
private val filter = DataWriterFilter.requireAttribute(SerializationConstants.EXTERNAL_SYSTEM_ID_ATTRIBUTE, DataWriterFilter.ElementLevel.FIRST)
override val internalStorage: StateStorage
get() = inProjectStorage
override fun loadLocalData(): Element? {
val externalData = super.loadLocalData()
val internalData = inProjectStorage.getSerializedState(inProjectStorage.loadData(), null, componentName, true)