mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
read artifacts and libraries data from both external and in-project sources
Problem is that both artifacts and libraries still don't use SchemeManager and so, we still need to use deprecated DirectoryBasedStorage
This commit is contained in:
+22
-10
@@ -1,6 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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 org.jetbrains.jps.model.serialization;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -123,15 +121,26 @@ public class JpsProjectLoader extends JpsLoaderBase {
|
||||
protected <E extends JpsElement> Element loadComponentData(@NotNull JpsElementExtensionSerializerBase<E> serializer, @NotNull Path configFile) {
|
||||
Path externalConfigDir = resolveExternalProjectConfig("project");
|
||||
Element data = super.loadComponentData(serializer, configFile);
|
||||
if (externalConfigDir != null && serializer.getComponentName().equals("CompilerConfiguration")) {
|
||||
Element externalData = JDomSerializationUtil.findComponent(loadRootElement(externalConfigDir.resolve(configFile.getFileName())), "External" + serializer.getComponentName());
|
||||
if (data == null) {
|
||||
return externalData;
|
||||
}
|
||||
else if (externalData != null) {
|
||||
return JDOMUtil.deepMerge(data, externalData);
|
||||
String componentName = serializer.getComponentName();
|
||||
if (externalConfigDir == null || !(componentName.equals("CompilerConfiguration"))) {
|
||||
return data;
|
||||
}
|
||||
|
||||
String prefixedComponentName = "External" + componentName;
|
||||
Element externalData = null;
|
||||
for (Element child : (JDOMUtil.getChildren(loadRootElement(externalConfigDir.resolve(configFile.getFileName()))))) {
|
||||
// be ready to handle both original name and prefixed
|
||||
if (child.getName().equals(prefixedComponentName) || child.getName().equals(componentName)) {
|
||||
externalData = child;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (data == null) {
|
||||
return externalData;
|
||||
}
|
||||
else if (externalData != null) {
|
||||
return JDOMUtil.deepMerge(data, externalData);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -201,6 +210,9 @@ public class JpsProjectLoader extends JpsLoaderBase {
|
||||
for (Path artifactFile : listXmlFiles(dir.resolve("artifacts"))) {
|
||||
loadArtifacts(loadRootElement(artifactFile));
|
||||
}
|
||||
if (externalConfigDir != null) {
|
||||
loadArtifacts(loadRootElement(externalConfigDir.resolve("artifacts.xml")));
|
||||
}
|
||||
artifactsTimingLog.run();
|
||||
|
||||
if (hasRunConfigurationSerializers()) {
|
||||
|
||||
@@ -25,15 +25,18 @@ import com.intellij.openapi.components.StateStorage.SaveSession
|
||||
import com.intellij.openapi.components.StateStorageChooserEx.Resolution
|
||||
import com.intellij.openapi.components.impl.ComponentManagerImpl
|
||||
import com.intellij.openapi.components.impl.stores.IComponentStore
|
||||
import com.intellij.openapi.components.impl.stores.SaveSessionAndFile
|
||||
import com.intellij.openapi.components.impl.stores.StoreUtil
|
||||
import com.intellij.openapi.components.impl.stores.UnknownMacroNotification
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.diagnostic.debug
|
||||
import com.intellij.openapi.progress.ProcessCanceledException
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.*
|
||||
import com.intellij.openapi.util.InvalidDataException
|
||||
import com.intellij.openapi.util.JDOMExternalizable
|
||||
import com.intellij.openapi.util.JDOMUtil
|
||||
import com.intellij.openapi.util.ModificationTracker
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess
|
||||
import com.intellij.project.isDirectoryBased
|
||||
import com.intellij.ui.AppUIUtil
|
||||
@@ -80,9 +83,7 @@ abstract class ComponentStoreImpl : IComponentStore {
|
||||
open val loadPolicy: StateLoadPolicy
|
||||
get() = StateLoadPolicy.LOAD
|
||||
|
||||
abstract val storageManager: StateStorageManager
|
||||
|
||||
override final fun getStateStorageManager() = storageManager
|
||||
override abstract val storageManager: StateStorageManager
|
||||
|
||||
override final fun initComponent(component: Any, isService: Boolean) {
|
||||
if (component is SettingsSavingComponent) {
|
||||
@@ -129,7 +130,7 @@ abstract class ComponentStoreImpl : IComponentStore {
|
||||
return componentName
|
||||
}
|
||||
|
||||
override fun save(readonlyFiles: MutableList<JBPair<StateStorage.SaveSession, VirtualFile>>) {
|
||||
override fun save(readonlyFiles: MutableList<SaveSessionAndFile>) {
|
||||
var errors: MutableList<Throwable>? = null
|
||||
|
||||
// component state uses scheme manager in an ipr project, so, we must save it before
|
||||
@@ -251,7 +252,7 @@ abstract class ComponentStoreImpl : IComponentStore {
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun doSave(saveSessions: List<SaveSession>, readonlyFiles: MutableList<JBPair<SaveSession, VirtualFile>> = arrayListOf(), prevErrors: MutableList<Throwable>? = null): MutableList<Throwable>? {
|
||||
protected open fun doSave(saveSessions: List<SaveSession>, readonlyFiles: MutableList<SaveSessionAndFile> = arrayListOf(), prevErrors: MutableList<Throwable>? = null): MutableList<Throwable>? {
|
||||
var errors = prevErrors
|
||||
for (session in saveSessions) {
|
||||
errors = executeSave(session, readonlyFiles, prevErrors)
|
||||
@@ -331,8 +332,8 @@ abstract class ComponentStoreImpl : IComponentStore {
|
||||
}
|
||||
|
||||
val storage = storageManager.getStateStorage(storageSpec)
|
||||
val stateGetter = if (isUseLoadedStateAsExisting(storage, name)) (storage as? StorageBaseEx<*>)?.createGetSession(component, name, stateClass) else null
|
||||
var state = if (stateGetter == null) storage.getState(component, name, stateClass, defaultState, reloadData) else stateGetter.getState(defaultState)
|
||||
val stateGetter = createStateGetter(isUseLoadedStateAsExisting(storage), storage, component, name, stateClass, reloadData = reloadData)
|
||||
var state = stateGetter.getState(defaultState)
|
||||
if (state == null) {
|
||||
if (changedStorages != null && changedStorages.contains(storage)) {
|
||||
// state will be null if file deleted
|
||||
@@ -348,7 +349,7 @@ abstract class ComponentStoreImpl : IComponentStore {
|
||||
component.loadState(state)
|
||||
}
|
||||
finally {
|
||||
stateGetter?.close()
|
||||
stateGetter.close()
|
||||
}
|
||||
return true
|
||||
}
|
||||
@@ -410,7 +411,7 @@ abstract class ComponentStoreImpl : IComponentStore {
|
||||
return storages.sortByDeprecated()
|
||||
}
|
||||
|
||||
final override fun isReloadPossible(componentNames: MutableSet<String>) = !componentNames.any { isNotReloadable(it) }
|
||||
final override fun isReloadPossible(componentNames: Set<String>) = !componentNames.any { isNotReloadable(it) }
|
||||
|
||||
private fun isNotReloadable(name: String): Boolean {
|
||||
val component = components.get(name)?.component ?: return false
|
||||
@@ -430,7 +431,7 @@ abstract class ComponentStoreImpl : IComponentStore {
|
||||
return notReloadableComponents ?: emptySet()
|
||||
}
|
||||
|
||||
override final fun reloadStates(componentNames: MutableSet<String>, messageBus: MessageBus) {
|
||||
override final fun reloadStates(componentNames: Set<String>, messageBus: MessageBus) {
|
||||
runBatchUpdate(messageBus) {
|
||||
reinitComponents(componentNames)
|
||||
}
|
||||
@@ -503,14 +504,14 @@ abstract class ComponentStoreImpl : IComponentStore {
|
||||
}
|
||||
}
|
||||
|
||||
internal fun executeSave(session: SaveSession, readonlyFiles: MutableList<JBPair<SaveSession, VirtualFile>>, previousErrors: MutableList<Throwable>?): MutableList<Throwable>? {
|
||||
internal fun executeSave(session: SaveSession, readonlyFiles: MutableList<SaveSessionAndFile>, previousErrors: MutableList<Throwable>?): MutableList<Throwable>? {
|
||||
var errors = previousErrors
|
||||
try {
|
||||
session.save()
|
||||
}
|
||||
catch (e: ReadOnlyModificationException) {
|
||||
LOG.warn(e)
|
||||
readonlyFiles.add(JBPair.create<SaveSession, VirtualFile>(e.session ?: session, e.file))
|
||||
readonlyFiles.add(SaveSessionAndFile(e.session ?: session, e.file))
|
||||
}
|
||||
catch (e: Exception) {
|
||||
if (errors == null) {
|
||||
@@ -544,7 +545,7 @@ internal fun Array<out Storage>.sortByDeprecated(): List<Storage> {
|
||||
}
|
||||
|
||||
private fun notifyUnknownMacros(store: IComponentStore, project: Project, componentName: String) {
|
||||
val substitutor = store.stateStorageManager.macroSubstitutor ?: return
|
||||
val substitutor = store.storageManager.macroSubstitutor ?: return
|
||||
|
||||
val immutableMacros = substitutor.getUnknownMacros(componentName)
|
||||
if (immutableMacros.isEmpty()) {
|
||||
|
||||
@@ -56,9 +56,12 @@ internal class DefaultProjectStoreImpl(override val project: ProjectImpl, privat
|
||||
service<DefaultProjectExportableAndSaveTrigger>().project = project
|
||||
}
|
||||
|
||||
private val storage by lazy { DefaultProjectStorage(Paths.get(ApplicationManager.getApplication().stateStore.stateStorageManager.expandMacros(FILE_SPEC)), FILE_SPEC, pathMacroManager) }
|
||||
private val storage by lazy { DefaultProjectStorage(Paths.get(ApplicationManager.getApplication().stateStore.storageManager.expandMacros(FILE_SPEC)), FILE_SPEC, pathMacroManager) }
|
||||
|
||||
override val storageManager = object : StateStorageManager {
|
||||
override val componentManager: ComponentManager?
|
||||
get() = null
|
||||
|
||||
override fun addStreamProvider(provider: StreamProvider, first: Boolean) {
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ abstract class DirectoryBasedStorageBase(@Suppress("DEPRECATION") protected val
|
||||
|
||||
protected abstract val virtualFile: VirtualFile?
|
||||
|
||||
override fun loadData() = StateMap.fromMap(DirectoryStorageUtil.loadFrom(virtualFile, pathMacroSubstitutor))
|
||||
override public fun loadData() = StateMap.fromMap(DirectoryStorageUtil.loadFrom(virtualFile, pathMacroSubstitutor))
|
||||
|
||||
override fun startExternalization(): StateStorage.ExternalizationSession? = null
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@ private fun exportInstalledPlugins(zipOut: MyZipOutputStream) {
|
||||
// onlyPaths - include only specified paths (relative to config dir, ends with "/" if directory)
|
||||
fun getExportableComponentsMap(onlyExisting: Boolean,
|
||||
computePresentableNames: Boolean,
|
||||
storageManager: StateStorageManager = ApplicationManager.getApplication().stateStore.stateStorageManager,
|
||||
storageManager: StateStorageManager = ApplicationManager.getApplication().stateStore.storageManager,
|
||||
onlyPaths: Set<String>? = null): Map<Path, List<ExportableItem>> {
|
||||
val result = LinkedHashMap<Path, MutableList<ExportableItem>>()
|
||||
@Suppress("DEPRECATION")
|
||||
|
||||
@@ -2,25 +2,18 @@ package com.intellij.configurationStore;
|
||||
|
||||
import com.intellij.openapi.components.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
@SuppressWarnings("ClassExplicitlyAnnotation")
|
||||
public final class FileStorageAnnotation implements Storage {
|
||||
private String path;
|
||||
public class FileStorageAnnotation implements Storage {
|
||||
protected final String path;
|
||||
|
||||
private boolean deprecated;
|
||||
private final Class<? extends StateStorage> storageClass;
|
||||
|
||||
public FileStorageAnnotation(@NotNull String path, boolean deprecated) {
|
||||
this(path, deprecated, StateStorage.class);
|
||||
}
|
||||
|
||||
public FileStorageAnnotation(@NotNull String path, boolean deprecated, @Nullable Class<? extends StateStorage> storageClass) {
|
||||
this.path = path;
|
||||
this.deprecated = deprecated;
|
||||
this.storageClass = storageClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -60,7 +53,7 @@ public final class FileStorageAnnotation implements Storage {
|
||||
|
||||
@Override
|
||||
public Class<? extends StateStorage> storageClass() {
|
||||
return storageClass;
|
||||
return StateStorage.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -36,7 +36,7 @@ private open class ModuleStoreImpl(module: Module, private val pathMacroManager:
|
||||
override fun <T> getStorageSpecs(component: PersistentStateComponent<T>, stateSpec: State, operation: StateStorageOperation): List<Storage> {
|
||||
val result = super.getStorageSpecs(component, stateSpec, operation)
|
||||
return StreamProviderFactory.EP_NAME.getExtensions(project).computeIfAny {
|
||||
LOG.runAndLogException { it.customizeStorageSpecs(component, storageManager.componentManager!!, stateSpec, result, operation) }
|
||||
LOG.runAndLogException { it.customizeStorageSpecs(component, storageManager, stateSpec, result, operation) }
|
||||
} ?: result
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.intellij.openapi.components.*
|
||||
import com.intellij.openapi.components.StateStorage.SaveSession
|
||||
import com.intellij.openapi.components.impl.stores.IComponentStore
|
||||
import com.intellij.openapi.components.impl.stores.IProjectStore
|
||||
import com.intellij.openapi.components.impl.stores.SaveSessionAndFile
|
||||
import com.intellij.openapi.diagnostic.runAndLogException
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.module.ModuleManager
|
||||
@@ -35,7 +36,6 @@ import com.intellij.openapi.project.ex.ProjectNameProvider
|
||||
import com.intellij.openapi.project.impl.ProjectImpl
|
||||
import com.intellij.openapi.project.impl.ProjectManagerImpl.UnableToSaveProjectNotification
|
||||
import com.intellij.openapi.project.impl.ProjectStoreClassProvider
|
||||
import com.intellij.openapi.util.Pair
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.openapi.util.io.FileUtilRt
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
@@ -200,7 +200,7 @@ internal abstract class ProjectStoreBase(override final val project: ProjectImpl
|
||||
else {
|
||||
result!!.sortWith(deprecatedComparator)
|
||||
StreamProviderFactory.EP_NAME.getExtensions(project).computeIfAny {
|
||||
LOG.runAndLogException { it.customizeStorageSpecs(component, project, stateSpec, result!!, operation) }
|
||||
LOG.runAndLogException { it.customizeStorageSpecs(component, storageManager, stateSpec, result!!, operation) }
|
||||
}?.let {
|
||||
// yes, DEPRECATED_PROJECT_FILE_STORAGE_ANNOTATION is not added in this case
|
||||
return it
|
||||
@@ -271,8 +271,8 @@ private open class ProjectStoreImpl(project: ProjectImpl, private val pathMacroM
|
||||
|
||||
override val storageManager = ProjectStateStorageManager(pathMacroManager.createTrackingSubstitutor(), project)
|
||||
|
||||
override fun setPath(filePath: String) {
|
||||
setPath(filePath, true, true)
|
||||
override fun setPath(path: String) {
|
||||
setPath(path, true, true)
|
||||
}
|
||||
|
||||
override fun getProjectName(): String {
|
||||
@@ -320,7 +320,7 @@ private open class ProjectStoreImpl(project: ProjectImpl, private val pathMacroM
|
||||
}
|
||||
}
|
||||
|
||||
override fun doSave(saveSessions: List<SaveSession>, readonlyFiles: MutableList<Pair<SaveSession, VirtualFile>>, prevErrors: MutableList<Throwable>?): MutableList<Throwable>? {
|
||||
override fun doSave(saveSessions: List<SaveSession>, readonlyFiles: MutableList<SaveSessionAndFile>, prevErrors: MutableList<Throwable>?): MutableList<Throwable>? {
|
||||
try {
|
||||
saveProjectName()
|
||||
}
|
||||
@@ -354,7 +354,7 @@ private open class ProjectStoreImpl(project: ProjectImpl, private val pathMacroM
|
||||
val oldList = readonlyFiles.toTypedArray()
|
||||
readonlyFiles.clear()
|
||||
for (entry in oldList) {
|
||||
errors = executeSave(entry.first, readonlyFiles, errors)
|
||||
errors = executeSave(entry.session, readonlyFiles, errors)
|
||||
}
|
||||
|
||||
CompoundRuntimeException.throwIfNotEmpty(errors)
|
||||
@@ -367,7 +367,7 @@ private open class ProjectStoreImpl(project: ProjectImpl, private val pathMacroM
|
||||
return errors
|
||||
}
|
||||
|
||||
protected open fun beforeSave(readonlyFiles: List<Pair<SaveSession, VirtualFile>>) {
|
||||
protected open fun beforeSave(readonlyFiles: MutableList<SaveSessionAndFile>) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -381,10 +381,10 @@ private fun dropUnableToSaveProjectNotification(project: Project, readOnlyFiles:
|
||||
}
|
||||
}
|
||||
|
||||
private fun getFilesList(readonlyFiles: List<Pair<SaveSession, VirtualFile>>) = Array(readonlyFiles.size) { readonlyFiles[it].second }
|
||||
private fun getFilesList(readonlyFiles: List<SaveSessionAndFile>) = Array(readonlyFiles.size) { readonlyFiles[it].file }
|
||||
|
||||
private class ProjectWithModulesStoreImpl(project: ProjectImpl, pathMacroManager: PathMacroManager) : ProjectStoreImpl(project, pathMacroManager) {
|
||||
override fun beforeSave(readonlyFiles: List<Pair<SaveSession, VirtualFile>>) {
|
||||
override fun beforeSave(readonlyFiles: MutableList<SaveSessionAndFile>) {
|
||||
super.beforeSave(readonlyFiles)
|
||||
|
||||
for (module in (ModuleManager.getInstance(project)?.modules ?: Module.EMPTY_ARRAY)) {
|
||||
|
||||
@@ -51,7 +51,7 @@ sealed class SchemeManagerFactoryBase : SchemeManagerFactory(), SettingsSavingCo
|
||||
val path = checkPath(directoryName)
|
||||
val manager = SchemeManagerImpl(path,
|
||||
processor,
|
||||
streamProvider ?: (componentManager?.stateStore?.stateStorageManager as? StateStorageManagerImpl)?.compoundStreamProvider,
|
||||
streamProvider ?: (componentManager?.stateStore?.storageManager as? StateStorageManagerImpl)?.compoundStreamProvider,
|
||||
directoryPath ?: pathToFile(path),
|
||||
roamingType,
|
||||
presentableName,
|
||||
@@ -122,7 +122,7 @@ sealed class SchemeManagerFactoryBase : SchemeManagerFactory(), SettingsSavingCo
|
||||
return path
|
||||
}
|
||||
|
||||
override fun pathToFile(path: String) = Paths.get(ApplicationManager.getApplication().stateStore.stateStorageManager.expandMacros(ROOT_CONFIG), path)!!
|
||||
override fun pathToFile(path: String) = Paths.get(ApplicationManager.getApplication().stateStore.storageManager.expandMacros(ROOT_CONFIG), path)!!
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
|
||||
@@ -51,7 +51,7 @@ private val MACRO_PATTERN = Pattern.compile("(\\$[^$]*\\$)")
|
||||
*/
|
||||
open class StateStorageManagerImpl(private val rootTagName: String,
|
||||
override final val macroSubstitutor: TrackingPathMacroSubstitutor? = null,
|
||||
val componentManager: ComponentManager? = null,
|
||||
override val componentManager: ComponentManager? = null,
|
||||
private val virtualFileTracker: StorageVirtualFileTracker? = StateStorageManagerImpl.createDefaultVirtualTracker(componentManager) ) : StateStorageManager {
|
||||
private val macros: MutableList<Macro> = ContainerUtil.createLockFreeCopyOnWriteList()
|
||||
private val storageLock = ReentrantReadWriteLock()
|
||||
@@ -73,6 +73,7 @@ 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
|
||||
|
||||
protected open val isUseXmlProlog: Boolean
|
||||
@@ -88,7 +89,7 @@ open class StateStorageManagerImpl(private val rootTagName: String,
|
||||
StorageVirtualFileTracker(componentManager.messageBus)
|
||||
}
|
||||
else -> {
|
||||
val tracker = (ApplicationManager.getApplication().stateStore.stateStorageManager as? StateStorageManagerImpl)?.virtualFileTracker ?: return null
|
||||
val tracker = (ApplicationManager.getApplication().stateStore.storageManager as? StateStorageManagerImpl)?.virtualFileTracker ?: return null
|
||||
Disposer.register(componentManager, Disposable {
|
||||
tracker.remove { it.storageManager.componentManager == componentManager }
|
||||
})
|
||||
@@ -144,12 +145,14 @@ open class StateStorageManagerImpl(private val rootTagName: String,
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("CAST_NEVER_SUCCEEDS")
|
||||
override final fun getStateStorage(storageSpec: Storage) = getOrCreateStorage(
|
||||
storageSpec.path,
|
||||
storageSpec.roamingType,
|
||||
storageSpec.storageClass.java,
|
||||
storageSpec.stateSplitter.java,
|
||||
storageSpec.exclusive
|
||||
storageSpec.exclusive,
|
||||
storageCreator = storageSpec as? StorageCreator
|
||||
)
|
||||
|
||||
protected open fun normalizeFileSpec(fileSpec: String): String {
|
||||
@@ -164,29 +167,24 @@ open class StateStorageManagerImpl(private val rootTagName: String,
|
||||
storageClass: Class<out StateStorage> = StateStorage::class.java,
|
||||
@Suppress("DEPRECATION") stateSplitter: Class<out StateSplitter> = StateSplitterEx::class.java,
|
||||
exclusive: Boolean = false,
|
||||
storageCustomizer: (StateStorage.() -> Unit)? = null): StateStorage {
|
||||
storageCustomizer: (StateStorage.() -> Unit)? = null,
|
||||
storageCreator: StorageCreator? = null): StateStorage {
|
||||
val normalizedCollapsedPath = normalizeFileSpec(collapsedPath)
|
||||
val key: String
|
||||
if (storageClass == StateStorage::class.java) {
|
||||
if (normalizedCollapsedPath.isEmpty()) {
|
||||
throw Exception("Normalized path is empty, raw path '$collapsedPath'")
|
||||
}
|
||||
key = normalizedCollapsedPath
|
||||
key = storageCreator?.key ?: normalizedCollapsedPath
|
||||
}
|
||||
else {
|
||||
val storageClassName = storageClass.name!!
|
||||
// we cannot change this ancient logic for now, so, detect this case manually
|
||||
if (storageClassName === "com.intellij.openapi.externalSystem.configurationStore.ExternalProjectStorage") {
|
||||
key = "$normalizedCollapsedPath@ExternalProjectStorage"
|
||||
}
|
||||
else {
|
||||
key = storageClassName
|
||||
}
|
||||
key = storageClass.name!!
|
||||
}
|
||||
|
||||
val storage = storageLock.read { storages.get(key) } ?: return storageLock.write {
|
||||
storages.getOrPut(key) {
|
||||
val storage = createStateStorage(storageClass, normalizedCollapsedPath, roamingType, stateSplitter, exclusive)
|
||||
@Suppress("IfThenToElvis")
|
||||
val storage = if (storageCreator == null) createStateStorage(storageClass, normalizedCollapsedPath, roamingType, stateSplitter, exclusive) else storageCreator.create(this)
|
||||
storageCustomizer?.let { storage.it() }
|
||||
storage
|
||||
}
|
||||
|
||||
@@ -17,12 +17,15 @@ package com.intellij.configurationStore
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.components.PersistentStateComponent
|
||||
import com.intellij.openapi.components.StateStorage
|
||||
import com.intellij.openapi.util.JDOMUtil
|
||||
import com.intellij.util.isEmpty
|
||||
import org.jdom.Element
|
||||
|
||||
abstract class StorageBaseEx<T : Any> : StateStorageBase<T>() {
|
||||
fun <S : Any> createGetSession(component: PersistentStateComponent<S>, componentName: String, stateClass: Class<S>, reload: Boolean = false) = StateGetter(component, componentName, getStorageData(reload), stateClass, this)
|
||||
fun <S : Any> createGetSession(component: PersistentStateComponent<S>, componentName: String, stateClass: Class<S>, reload: Boolean = false): StateGetter<S> {
|
||||
return StateGetterImpl(component, componentName, getStorageData(reload), stateClass, this)
|
||||
}
|
||||
|
||||
/**
|
||||
* serializedState is null if state equals to default (see XmlSerializer.serializeIfNotDefault)
|
||||
@@ -30,21 +33,42 @@ abstract class StorageBaseEx<T : Any> : StateStorageBase<T>() {
|
||||
abstract fun archiveState(storageData: T, componentName: String, serializedState: Element?)
|
||||
}
|
||||
|
||||
class StateGetter<S : Any, T : Any>(private val component: PersistentStateComponent<S>,
|
||||
private val componentName: String,
|
||||
private val storageData: T,
|
||||
private val stateClass: Class<S>,
|
||||
private val storage: StorageBaseEx<T>) {
|
||||
var serializedState: Element? = null
|
||||
fun <S : Any> createStateGetter(isUseLoadedStateAsExisting: Boolean, storage: StateStorage, component: PersistentStateComponent<S>, componentName: String, stateClass: Class<S>, reloadData: Boolean): StateGetter<S> {
|
||||
if (isUseLoadedStateAsExisting && storage is StorageBaseEx<*>) {
|
||||
return storage.createGetSession(component, componentName, stateClass, reloadData)
|
||||
}
|
||||
|
||||
fun getState(mergeInto: S? = null): S? {
|
||||
return object : StateGetter<S> {
|
||||
override fun getState(mergeInto: S?): S? {
|
||||
return storage.getState(component, componentName, stateClass, mergeInto, reloadData)
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface StateGetter<S : Any> {
|
||||
fun getState(mergeInto: S? = null): S?
|
||||
|
||||
fun close()
|
||||
}
|
||||
|
||||
private class StateGetterImpl<S : Any, T : Any>(private val component: PersistentStateComponent<S>,
|
||||
private val componentName: String,
|
||||
private val storageData: T,
|
||||
private val stateClass: Class<S>,
|
||||
private val storage: StorageBaseEx<T>) : StateGetter<S> {
|
||||
private var serializedState: Element? = null
|
||||
|
||||
override fun getState(mergeInto: S?): S? {
|
||||
LOG.assertTrue(serializedState == null)
|
||||
|
||||
serializedState = storage.getSerializedState(storageData, component, componentName, false)
|
||||
serializedState = storage.getSerializedState(storageData, component, componentName, archive = false)
|
||||
return storage.deserializeState(serializedState, stateClass, mergeInto)
|
||||
}
|
||||
|
||||
fun close() {
|
||||
override fun close() {
|
||||
if (serializedState == null) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ internal class ApplicationStoreTest {
|
||||
@Test fun `export settings`() {
|
||||
testAppConfig.refreshVfs()
|
||||
|
||||
val storageManager = ApplicationManager.getApplication().stateStore.stateStorageManager
|
||||
val storageManager = ApplicationManager.getApplication().stateStore.storageManager
|
||||
val optionsPath = storageManager.expandMacros(APP_CONFIG)
|
||||
val rootConfigPath = storageManager.expandMacros(ROOT_CONFIG)
|
||||
val map = getExportableComponentsMap(false, true, storageManager)
|
||||
|
||||
@@ -55,7 +55,7 @@ internal class DefaultProjectStoreTest {
|
||||
tempDirManager,
|
||||
WrapRule {
|
||||
val app = ApplicationManagerEx.getApplicationEx()
|
||||
val path = Paths.get(app.stateStore.stateStorageManager.expandMacros(APP_CONFIG))
|
||||
val path = Paths.get(app.stateStore.storageManager.expandMacros(APP_CONFIG))
|
||||
// dream about using in memory fs per test as ICS partially does and avoid such hacks
|
||||
path.refreshVfs()
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ class DoNotSaveDefaultsTest {
|
||||
}
|
||||
|
||||
val directoryTree = printDirectoryTree(Paths.get(
|
||||
componentManager.stateStore.stateStorageManager.expandMacros(APP_CONFIG)), setOf(
|
||||
componentManager.stateStore.storageManager.expandMacros(APP_CONFIG)), setOf(
|
||||
"path.macros.xml" /* todo EP to register (provide) macro dynamically */,
|
||||
"stubIndex.xml" /* low-level non-roamable stuff */,
|
||||
"usage.statistics.xml" /* SHOW_NOTIFICATION_ATTR in internal mode */,
|
||||
|
||||
@@ -30,7 +30,7 @@ import java.util.*
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
private val Module.storage: FileBasedStorage
|
||||
get() = (stateStore.stateStorageManager as StateStorageManagerImpl).getCachedFileStorages(listOf(StoragePathMacros.MODULE_FILE)).first()
|
||||
get() = (stateStore.storageManager as StateStorageManagerImpl).getCachedFileStorages(listOf(StoragePathMacros.MODULE_FILE)).first()
|
||||
|
||||
internal class ModuleStoreRenameTest {
|
||||
companion object {
|
||||
@@ -71,7 +71,7 @@ internal class ModuleStoreRenameTest {
|
||||
|
||||
// should be invoked after project tearDown
|
||||
override fun after() {
|
||||
(ApplicationManager.getApplication().stateStore.stateStorageManager as StateStorageManagerImpl).getVirtualFileTracker()!!.remove {
|
||||
(ApplicationManager.getApplication().stateStore.storageManager as StateStorageManagerImpl).getVirtualFileTracker()!!.remove {
|
||||
if (it.storageManager.componentManager == module) {
|
||||
throw AssertionError("Storage manager is not disposed, module $module, storage $it")
|
||||
}
|
||||
@@ -127,7 +127,7 @@ internal class ModuleStoreRenameTest {
|
||||
assertThat(newFile).isRegularFile
|
||||
|
||||
// ensure that macro value updated
|
||||
assertThat(module.stateStore.stateStorageManager.expandMacros(StoragePathMacros.MODULE_FILE)).isEqualTo(newFile.systemIndependentPath)
|
||||
assertThat(module.stateStore.storageManager.expandMacros(StoragePathMacros.MODULE_FILE)).isEqualTo(newFile.systemIndependentPath)
|
||||
|
||||
runInEdtAndWait {
|
||||
dependentModule.saveStore()
|
||||
|
||||
@@ -117,7 +117,7 @@ class ModuleStoreTest {
|
||||
}
|
||||
|
||||
fun Module.removeContentRoot() {
|
||||
val modulePath = stateStore.stateStorageManager.expandMacros(StoragePathMacros.MODULE_FILE)
|
||||
val modulePath = stateStore.storageManager.expandMacros(StoragePathMacros.MODULE_FILE)
|
||||
val moduleFile = Paths.get(modulePath)
|
||||
assertThat(moduleFile).isRegularFile
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ internal class ProjectStoreTest {
|
||||
assertThat(project.basePath).isEqualTo(PathUtil.getParentPath((PathUtil.getParentPath(project.projectFilePath!!))))
|
||||
|
||||
// test reload on external change
|
||||
val file = Paths.get(project.stateStore.stateStorageManager.expandMacros(PROJECT_FILE))
|
||||
val file = Paths.get(project.stateStore.storageManager.expandMacros(PROJECT_FILE))
|
||||
file.write(file.readText().replace("""<option name="value" value="foo" />""", """<option name="value" value="newValue" />"""))
|
||||
|
||||
project.baseDir.refresh(false, true)
|
||||
@@ -154,7 +154,7 @@ internal class ProjectStoreTest {
|
||||
testComponent.state!!.value = "foo"
|
||||
project.saveStore()
|
||||
|
||||
val file = Paths.get(project.stateStore.stateStorageManager.expandMacros(PROJECT_FILE))
|
||||
val file = Paths.get(project.stateStore.storageManager.expandMacros(PROJECT_FILE))
|
||||
assertThat(file).isRegularFile()
|
||||
// test exact string - xml prolog, line separators, indentation and so on must be exactly the same
|
||||
// todo get rid of default component states here
|
||||
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
// 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.openapi.externalSystem.configurationStore;
|
||||
|
||||
import com.intellij.configurationStore.DirectoryBasedStorage;
|
||||
import com.intellij.configurationStore.FileStorageAnnotation;
|
||||
import com.intellij.configurationStore.StateStorageManager;
|
||||
import com.intellij.configurationStore.StorageCreator;
|
||||
import com.intellij.openapi.components.ComponentManager;
|
||||
import com.intellij.openapi.components.State;
|
||||
import com.intellij.openapi.components.StateStorage;
|
||||
import com.intellij.openapi.components.StoragePathMacros;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class ExternalStorageSpec extends FileStorageAnnotation implements StorageCreator {
|
||||
private final State inProjectStateSpec;
|
||||
|
||||
public ExternalStorageSpec(@NotNull String path, @Nullable State inProjectStateSpec) {
|
||||
super(path, false);
|
||||
this.inProjectStateSpec = inProjectStateSpec;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public StateStorage create(@NotNull StateStorageManager storageManager) {
|
||||
ComponentManager componentManager = storageManager.getComponentManager();
|
||||
assert componentManager != null;
|
||||
if (path.equals(StoragePathMacros.MODULE_FILE)) {
|
||||
return new ExternalModuleStorage((Module)componentManager, storageManager);
|
||||
}
|
||||
|
||||
Project project = (Project)componentManager;
|
||||
if (inProjectStateSpec == null) {
|
||||
return new ExternalProjectStorage(path, project, storageManager);
|
||||
}
|
||||
else {
|
||||
return new ExternalProjectFilteringStorage(path, project, storageManager, inProjectStateSpec.name(), (DirectoryBasedStorage)storageManager.getStateStorage(inProjectStateSpec.storages()[0]));
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getKey() {
|
||||
return "external://" + path;
|
||||
}
|
||||
}
|
||||
+9
-2
@@ -25,7 +25,7 @@ internal class ExternalModuleStorage(private val module: Module, storageManager:
|
||||
internal open class ExternalProjectStorage @JvmOverloads constructor(fileSpec: String, project: Project, storageManager: StateStorageManager, rootElementName: String? = ProjectStateStorageManager.ROOT_TAG_NAME /* several components per file */) : XmlElementStorage(fileSpec, rootElementName, storageManager.macroSubstitutor, RoamingType.DISABLED) {
|
||||
protected val manager = StreamProviderFactory.EP_NAME.getExtensions(project).first { it is ExternalSystemStreamProviderFactory } as ExternalSystemStreamProviderFactory
|
||||
|
||||
override final fun loadLocalData() = manager.fileStorage.read(fileSpec)
|
||||
override fun loadLocalData() = manager.fileStorage.read(fileSpec)
|
||||
|
||||
override fun createSaveSession(states: StateMap) = object : XmlElementStorageSaveSession<ExternalProjectStorage>(states, this) {
|
||||
override fun saveLocally(element: Element?) {
|
||||
@@ -35,7 +35,14 @@ internal open class ExternalProjectStorage @JvmOverloads constructor(fileSpec: S
|
||||
}
|
||||
|
||||
// for libraries only for now - we use null rootElementName because the only component is expected (libraryTable)
|
||||
internal class ExternalProjectFilteringStorage(fileSpec: String, project: Project, storageManager: StateStorageManager) : ExternalProjectStorage(fileSpec, project, storageManager, null /* the only component per file */) {
|
||||
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 */) {
|
||||
override fun loadLocalData(): Element? {
|
||||
val externalData = super.loadLocalData()
|
||||
val internalData = inProjectStorage.getSerializedState(inProjectStorage.loadData(), null, componentName, true)
|
||||
return JDOMUtil.merge(externalData, internalData)
|
||||
}
|
||||
|
||||
override fun createSaveSession(states: StateMap) = object : XmlElementStorageSaveSession<ExternalProjectStorage>(states, this) {
|
||||
override fun saveLocally(element: Element?) {
|
||||
if (element == null || !element.children.any { it.isMarkedAsExternal() }) {
|
||||
|
||||
+30
-10
@@ -1,8 +1,8 @@
|
||||
// Copyright 2000-2017 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.openapi.externalSystem.configurationStore
|
||||
|
||||
import com.intellij.ProjectTopics
|
||||
import com.intellij.configurationStore.FileStorageAnnotation
|
||||
import com.intellij.configurationStore.StateStorageManager
|
||||
import com.intellij.configurationStore.StreamProviderFactory
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.components.*
|
||||
@@ -17,11 +17,14 @@ import com.intellij.openapi.project.isExternalStorageEnabled
|
||||
import com.intellij.openapi.roots.ProjectModelElement
|
||||
import com.intellij.openapi.startup.StartupManager
|
||||
import com.intellij.util.Function
|
||||
import gnu.trove.THashMap
|
||||
import org.jdom.Element
|
||||
import java.util.*
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock
|
||||
import kotlin.concurrent.read
|
||||
import kotlin.concurrent.write
|
||||
|
||||
private val EXTERNAL_MODULE_STORAGE_ANNOTATION = FileStorageAnnotation(StoragePathMacros.MODULE_FILE, false, ExternalModuleStorage::class.java)
|
||||
private val LOG = logger<ExternalSystemStreamProviderFactory>()
|
||||
|
||||
// todo handle module rename
|
||||
@@ -33,6 +36,9 @@ internal class ExternalSystemStreamProviderFactory(private val project: Project)
|
||||
|
||||
private val isReimportOnMissedExternalStorageScheduled = AtomicBoolean(false)
|
||||
|
||||
private val storageSpecLock = ReentrantReadWriteLock()
|
||||
private val storages = THashMap<String, Storage>()
|
||||
|
||||
init {
|
||||
// flush on save to be sure that data is saved (it is easy to reimport if corrupted (force exit, blue screen), but we need to avoid it if possible)
|
||||
ApplicationManager.getApplication().messageBus
|
||||
@@ -63,7 +69,8 @@ internal class ExternalSystemStreamProviderFactory(private val project: Project)
|
||||
})
|
||||
}
|
||||
|
||||
override fun customizeStorageSpecs(component: PersistentStateComponent<*>, componentManager: ComponentManager, stateSpec: State, storages: List<Storage>, operation: StateStorageOperation): List<Storage>? {
|
||||
override fun customizeStorageSpecs(component: PersistentStateComponent<*>, storageManager: StateStorageManager, stateSpec: State, storages: List<Storage>, operation: StateStorageOperation): List<Storage>? {
|
||||
val componentManager = storageManager.componentManager
|
||||
val project = componentManager as? Project ?: (componentManager as Module).project
|
||||
// we store isExternalStorageEnabled option in the project workspace file, so, for such components external storage is always disabled and not applicable
|
||||
if ((storages.size == 1 && storages.first().value == StoragePathMacros.WORKSPACE_FILE) || !project.isExternalStorageEnabled) {
|
||||
@@ -72,9 +79,15 @@ internal class ExternalSystemStreamProviderFactory(private val project: Project)
|
||||
|
||||
if (componentManager is Project) {
|
||||
val fileSpec = storages.firstOrNull()?.value
|
||||
if (fileSpec == "libraries") {
|
||||
if (fileSpec == "libraries" || fileSpec == "artifacts") {
|
||||
val externalStorageSpec = getOrCreateExternalStorageSpec("$fileSpec.xml", stateSpec)
|
||||
if (operation == StateStorageOperation.READ) {
|
||||
return listOf(externalStorageSpec)
|
||||
}
|
||||
|
||||
// write is separated, state is written to both storages and filtered by on serialization
|
||||
val result = ArrayList<Storage>(storages.size + 1)
|
||||
result.add(FileStorageAnnotation("$fileSpec.xml", false, ExternalProjectFilteringStorage::class.java))
|
||||
result.add(externalStorageSpec)
|
||||
result.addAll(storages)
|
||||
return result
|
||||
}
|
||||
@@ -94,13 +107,12 @@ internal class ExternalSystemStreamProviderFactory(private val project: Project)
|
||||
// so, we just add our storage as first and default storages in the end as fallback
|
||||
|
||||
// on write default storages also returned, because default FileBasedStorage will remove data if component has external source
|
||||
val annotation: FileStorageAnnotation
|
||||
val annotation: Storage
|
||||
if (componentManager is Project) {
|
||||
val fileSpec = storages.get(0).value
|
||||
annotation = FileStorageAnnotation(fileSpec, false, ExternalProjectStorage::class.java)
|
||||
annotation = getOrCreateExternalStorageSpec(storages.get(0).value)
|
||||
}
|
||||
else {
|
||||
annotation = EXTERNAL_MODULE_STORAGE_ANNOTATION
|
||||
annotation = getOrCreateExternalStorageSpec(StoragePathMacros.MODULE_FILE)
|
||||
}
|
||||
|
||||
if (stateSpec.externalStorageOnly) {
|
||||
@@ -113,6 +125,14 @@ internal class ExternalSystemStreamProviderFactory(private val project: Project)
|
||||
return result
|
||||
}
|
||||
|
||||
private fun getOrCreateExternalStorageSpec(fileSpec: String, inProjectStateSpec: State? = null): Storage {
|
||||
return storageSpecLock.read { storages.get(fileSpec) } ?: return storageSpecLock.write {
|
||||
storages.getOrPut(fileSpec) {
|
||||
ExternalStorageSpec(fileSpec, inProjectStateSpec)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun readModuleData(name: String): Element? {
|
||||
if (!moduleStorage.hasSomeData && isReimportOnMissedExternalStorageScheduled.compareAndSet(false, true) && !project.isInitialized) {
|
||||
StartupManager.getInstance(project).runWhenProjectIsInitialized {
|
||||
|
||||
@@ -128,7 +128,7 @@ public class ModuleImpl extends PlatformComponentManagerImpl implements ModuleEx
|
||||
public void rename(@NotNull String newName, boolean notifyStorage) {
|
||||
myName = newName;
|
||||
if (notifyStorage) {
|
||||
ServiceKt.getStateStore(this).getStateStorageManager()
|
||||
ServiceKt.getStateStore(this).getStorageManager()
|
||||
.rename(StoragePathMacros.MODULE_FILE, newName + ModuleFileType.DOT_DEFAULT_EXTENSION);
|
||||
}
|
||||
}
|
||||
@@ -136,7 +136,7 @@ public class ModuleImpl extends PlatformComponentManagerImpl implements ModuleEx
|
||||
@Override
|
||||
@NotNull
|
||||
public String getModuleFilePath() {
|
||||
return ServiceKt.getStateStore(this).getStateStorageManager().expandMacros(StoragePathMacros.MODULE_FILE);
|
||||
return ServiceKt.getStateStore(this).getStorageManager().expandMacros(StoragePathMacros.MODULE_FILE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -60,7 +60,7 @@ public final class ClasspathStorage extends StateStorageBase<Boolean> {
|
||||
ClasspathStorageProvider provider = getProvider(storageType);
|
||||
if (provider == null) {
|
||||
if (module.getUserData(ERROR_NOTIFIED_KEY) == null) {
|
||||
Notification n = new Notification(StorageUtilKt.getNOTIFICATION_GROUP_ID(), "Cannot load module '" + module.getName() + "'",
|
||||
Notification n = new Notification(StorageUtilKt.NOTIFICATION_GROUP_ID, "Cannot load module '" + module.getName() + "'",
|
||||
"Support for " + storageType + " format is not installed.", NotificationType.ERROR);
|
||||
n.notify(module.getProject());
|
||||
module.putUserData(ERROR_NOTIFIED_KEY, Boolean.TRUE);
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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.configurationStore
|
||||
|
||||
import com.intellij.notification.NotificationType
|
||||
@@ -30,7 +28,7 @@ import java.io.IOException
|
||||
import java.nio.file.Path
|
||||
import java.util.*
|
||||
|
||||
val NOTIFICATION_GROUP_ID = "Load Error"
|
||||
const val NOTIFICATION_GROUP_ID = "Load Error"
|
||||
|
||||
@TestOnly
|
||||
var DEBUG_LOG: String? = null
|
||||
@@ -107,7 +105,7 @@ private fun collect(componentManager: ComponentManager,
|
||||
unknownMacros: MutableSet<String>,
|
||||
substitutorToStore: MutableMap<TrackingPathMacroSubstitutor, IComponentStore>) {
|
||||
val store = componentManager.stateStore
|
||||
val substitutor = store.stateStorageManager.macroSubstitutor ?: return
|
||||
val substitutor = store.storageManager.macroSubstitutor ?: return
|
||||
|
||||
val macros = substitutor.getUnknownMacros(null)
|
||||
if (macros.isEmpty()) {
|
||||
|
||||
+10
-19
@@ -1,24 +1,7 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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.components.StateStorage
|
||||
import com.intellij.openapi.components.StateStorageOperation
|
||||
import com.intellij.openapi.components.Storage
|
||||
import com.intellij.openapi.components.TrackingPathMacroSubstitutor
|
||||
import com.intellij.openapi.components.*
|
||||
import com.intellij.util.messages.Topic
|
||||
|
||||
val STORAGE_TOPIC = Topic("STORAGE_LISTENER", StorageManagerListener::class.java, Topic.BroadcastDirection.TO_PARENT)
|
||||
@@ -27,6 +10,8 @@ interface StateStorageManager {
|
||||
val macroSubstitutor: TrackingPathMacroSubstitutor?
|
||||
get() = null
|
||||
|
||||
val componentManager: ComponentManager?
|
||||
|
||||
fun getStateStorage(storageSpec: Storage): StateStorage
|
||||
|
||||
fun addStreamProvider(provider: StreamProvider, first: Boolean = false)
|
||||
@@ -57,4 +42,10 @@ interface StateStorageManager {
|
||||
*/
|
||||
fun createSaveSessions(): List<StateStorage.SaveSession>
|
||||
}
|
||||
}
|
||||
|
||||
interface StorageCreator {
|
||||
val key: String
|
||||
|
||||
fun create(storageManager: StateStorageManager): StateStorage
|
||||
}
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2017 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.configurationStore
|
||||
|
||||
import com.intellij.openapi.components.*
|
||||
@@ -21,5 +21,5 @@ interface StreamProviderFactory {
|
||||
* `storages` are preprocessed by component store - not raw from state spec.
|
||||
* @return null if not applicable
|
||||
*/
|
||||
fun customizeStorageSpecs(component: PersistentStateComponent<*>, componentManager: ComponentManager, stateSpec: State, storages: List<Storage>, operation: StateStorageOperation): List<Storage>? = null
|
||||
fun customizeStorageSpecs(component: PersistentStateComponent<*>, storageManager: StateStorageManager, stateSpec: State, storages: List<Storage>, operation: StateStorageOperation): List<Storage>? = null
|
||||
}
|
||||
+5
-6
@@ -1,10 +1,9 @@
|
||||
// Copyright 2000-2017 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.openapi.components.impl.stores
|
||||
|
||||
import com.intellij.configurationStore.StateStorageManager
|
||||
import com.intellij.openapi.components.PersistentStateComponent
|
||||
import com.intellij.openapi.components.StateStorage
|
||||
import com.intellij.openapi.util.Pair
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.util.messages.MessageBus
|
||||
import org.jetbrains.annotations.SystemIndependent
|
||||
@@ -13,11 +12,9 @@ import org.jetbrains.annotations.TestOnly
|
||||
interface IComponentStore {
|
||||
val storageManager: StateStorageManager
|
||||
|
||||
val stateStorageManager: StateStorageManager
|
||||
|
||||
fun setPath(path: @SystemIndependent String)
|
||||
|
||||
fun initComponent(component: Any, service: Boolean)
|
||||
fun initComponent(component: Any, isService: Boolean)
|
||||
|
||||
fun initPersistencePlainComponent(component: Any, key: String)
|
||||
|
||||
@@ -29,8 +26,10 @@ interface IComponentStore {
|
||||
|
||||
class SaveCancelledException : RuntimeException()
|
||||
|
||||
fun save(readonlyFiles: List<Pair<StateStorage.SaveSession, VirtualFile>>)
|
||||
fun save(readonlyFiles: MutableList<SaveSessionAndFile>)
|
||||
|
||||
@TestOnly
|
||||
fun saveApplicationComponent(component: PersistentStateComponent<*>)
|
||||
}
|
||||
|
||||
data class SaveSessionAndFile(val session: StateStorage.SaveSession, val file: VirtualFile)
|
||||
|
||||
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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.project
|
||||
|
||||
import com.intellij.ide.highlighter.ProjectFileType
|
||||
@@ -56,5 +42,5 @@ fun isValidProjectPath(path: String, anyRegularFileIsValid: Boolean = false): Bo
|
||||
}
|
||||
|
||||
fun isEqualToProjectFileStorePath(project: Project, filePath: String, storePath: String): Boolean {
|
||||
return project.isDirectoryBased && filePath.equals(project.stateStore.stateStorageManager.expandMacros(storePath), !SystemInfo.isFileSystemCaseSensitive)
|
||||
return project.isDirectoryBased && filePath.equals(project.stateStore.storageManager.expandMacros(storePath), !SystemInfo.isFileSystemCaseSensitive)
|
||||
}
|
||||
@@ -1,16 +1,4 @@
|
||||
// Copyright 2000-2017 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.openapi.util;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -708,7 +696,15 @@ public class JDOMUtil {
|
||||
return element == null || element.getAttributes().size() == attributeCount && element.getContent().isEmpty();
|
||||
}
|
||||
|
||||
public static void merge(@NotNull Element to, @NotNull Element from) {
|
||||
@Nullable
|
||||
public static Element merge(@Nullable Element to, @Nullable Element from) {
|
||||
if (from == null) {
|
||||
return to;
|
||||
}
|
||||
if (to == null) {
|
||||
return from;
|
||||
}
|
||||
|
||||
for (Iterator<Element> iterator = from.getChildren().iterator(); iterator.hasNext(); ) {
|
||||
Element configuration = iterator.next();
|
||||
iterator.remove();
|
||||
@@ -719,6 +715,7 @@ public class JDOMUtil {
|
||||
iterator.remove();
|
||||
to.setAttribute(attribute);
|
||||
}
|
||||
return to;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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 org.jetbrains.settingsRepository;
|
||||
|
||||
import com.intellij.configurationStore.StateStorageManager;
|
||||
@@ -61,7 +47,7 @@ public class CommitToIcsDialog extends DialogWrapper {
|
||||
}
|
||||
|
||||
private void commitChanges(List<Change> changes) {
|
||||
StateStorageManager storageManager = ServiceKt.getStateStore(project).getStateStorageManager();
|
||||
StateStorageManager storageManager = ServiceKt.getStateStore(project).getStorageManager();
|
||||
TrackingPathMacroSubstitutor macroSubstitutor = storageManager.getMacroSubstitutor();
|
||||
assert macroSubstitutor != null;
|
||||
IcsManager icsManager = IcsManagerKt.getIcsManager();
|
||||
|
||||
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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 org.jetbrains.settingsRepository
|
||||
|
||||
import com.intellij.configurationStore.SchemeManagerFactoryBase
|
||||
@@ -146,7 +132,7 @@ class IcsManager @JvmOverloads constructor(dir: Path, val schemeManagerFactory:
|
||||
}
|
||||
|
||||
fun setApplicationLevelStreamProvider() {
|
||||
val storageManager = ApplicationManager.getApplication().stateStore.stateStorageManager
|
||||
val storageManager = ApplicationManager.getApplication().stateStore.storageManager
|
||||
// just to be sure
|
||||
storageManager.removeStreamProvider(ApplicationLevelProvider::class.java)
|
||||
storageManager.addStreamProvider(ApplicationLevelProvider(), first = true)
|
||||
@@ -155,7 +141,7 @@ class IcsManager @JvmOverloads constructor(dir: Path, val schemeManagerFactory:
|
||||
fun beforeApplicationLoaded(application: Application) {
|
||||
repositoryActive = repositoryManager.isRepositoryExists()
|
||||
|
||||
application.stateStore.stateStorageManager.addStreamProvider(ApplicationLevelProvider())
|
||||
application.stateStore.storageManager.addStreamProvider(ApplicationLevelProvider())
|
||||
|
||||
val messageBusConnection = application.messageBus.connect()
|
||||
messageBusConnection.subscribe(AppLifecycleListener.TOPIC, object : AppLifecycleListener {
|
||||
@@ -178,7 +164,7 @@ class IcsManager @JvmOverloads constructor(dir: Path, val schemeManagerFactory:
|
||||
})
|
||||
}
|
||||
|
||||
open inner class IcsStreamProvider(protected val projectId: String?) : StreamProvider {
|
||||
open inner class IcsStreamProvider(private val projectId: String?) : StreamProvider {
|
||||
override val enabled: Boolean
|
||||
get() = this@IcsManager.active
|
||||
|
||||
|
||||
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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 org.jetbrains.settingsRepository.actions
|
||||
|
||||
import com.intellij.configurationStore.StateStorageManagerImpl
|
||||
@@ -76,7 +62,7 @@ internal class ConfigureIcsAction : DumbAwareAction() {
|
||||
e.presentation.isEnabledAndVisible = true
|
||||
}
|
||||
else {
|
||||
e.presentation.isEnabledAndVisible = !(application.stateStore.stateStorageManager as StateStorageManagerImpl).compoundStreamProvider.enabled
|
||||
e.presentation.isEnabledAndVisible = !(application.stateStore.storageManager as StateStorageManagerImpl).compoundStreamProvider.enabled
|
||||
}
|
||||
e.presentation.icon = null
|
||||
}
|
||||
|
||||
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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 org.jetbrains.settingsRepository
|
||||
|
||||
import com.intellij.configurationStore.ROOT_CONFIG
|
||||
@@ -31,7 +17,7 @@ import java.nio.file.Files
|
||||
import java.nio.file.NoSuchFileException
|
||||
import java.nio.file.Path
|
||||
|
||||
fun copyLocalConfig(storageManager: StateStorageManagerImpl = ApplicationManager.getApplication()!!.stateStore.stateStorageManager as StateStorageManagerImpl) {
|
||||
fun copyLocalConfig(storageManager: StateStorageManagerImpl = ApplicationManager.getApplication()!!.stateStore.storageManager as StateStorageManagerImpl) {
|
||||
val streamProvider = storageManager.compoundStreamProvider.providers.first { it is IcsManager.IcsStreamProvider } as IcsManager.IcsStreamProvider
|
||||
|
||||
val fileToItems = getExportableComponentsMap(true, false, storageManager)
|
||||
|
||||
Reference in New Issue
Block a user