mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-157763 Settings repository for IDE: initial
This commit is contained in:
@@ -282,7 +282,7 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
|
||||
val oldSchemes = schemes
|
||||
val schemes = oldSchemes.toMutableList()
|
||||
val newSchemesOffset = schemes.size
|
||||
if (provider != null && provider.enabled) {
|
||||
if (provider != null && provider.isApplicable(fileSpec, roamingType)) {
|
||||
provider.processChildren(fileSpec, roamingType, { canRead(it) }) { name, input, readOnly ->
|
||||
catchAndLog(name) {
|
||||
val scheme = loadScheme(name, input, schemes, filesToDelete)
|
||||
@@ -500,7 +500,7 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
|
||||
private val T.fileName: String?
|
||||
get() = schemeToInfo.get(this)?.fileNameWithoutExtension
|
||||
|
||||
private fun canRead(name: CharSequence) = (updateExtension && name.endsWith(DEFAULT_EXT, true) || name.endsWith(schemeExtension, true)) && (processor !is LazySchemeProcessor || processor.isSchemeFile(name))
|
||||
fun canRead(name: CharSequence) = (updateExtension && name.endsWith(DEFAULT_EXT, true) || name.endsWith(schemeExtension, true)) && (processor !is LazySchemeProcessor || processor.isSchemeFile(name))
|
||||
|
||||
private fun readSchemeFromFile(file: VirtualFile, schemes: MutableList<T> = this.schemes): MUTABLE_SCHEME? {
|
||||
val fileName = file.name
|
||||
|
||||
@@ -54,9 +54,14 @@ open class StateStorageManagerImpl(private val rootTagName: String,
|
||||
private val virtualFileTracker: StorageVirtualFileTracker? = StateStorageManagerImpl.createDefaultVirtualTracker(componentManager) ) : StateStorageManager {
|
||||
private val macros: MutableList<Macro> = ContainerUtil.createLockFreeCopyOnWriteList()
|
||||
private val storageLock = ReentrantReadWriteLock()
|
||||
private val storages = THashMap<String, StateStorage>()
|
||||
val storages = THashMap<String, StateStorage>()
|
||||
|
||||
var streamProvider: StreamProvider? = null
|
||||
private val streamWrapper = StreamProviderWrapper()
|
||||
var streamProvider: StreamProvider?
|
||||
get() = streamWrapper
|
||||
set (value) {
|
||||
streamWrapper.setStreamProvider(value)
|
||||
}
|
||||
|
||||
// access under storageLock
|
||||
private var isUseVfsListener = if (componentManager == null) ThreeState.NO else ThreeState.UNSURE // unsure because depends on stream provider state
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.intellij.configurationStore
|
||||
|
||||
import com.intellij.openapi.components.RoamingType
|
||||
import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import java.io.InputStream
|
||||
|
||||
interface StreamProvider {
|
||||
@@ -42,6 +43,7 @@ interface StreamProvider {
|
||||
fun delete(fileSpec: String, roamingType: RoamingType = RoamingType.DEFAULT)
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
fun StreamProvider.write(path: String, content: String) {
|
||||
write(path, content.toByteArray())
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ abstract class XmlElementStorage protected constructor(protected val fileSpec: S
|
||||
roamingType: RoamingType? = RoamingType.DEFAULT,
|
||||
provider: StreamProvider? = null) : StorageBaseEx<StateMap>() {
|
||||
val roamingType: RoamingType = roamingType ?: RoamingType.DEFAULT
|
||||
private val provider: StreamProvider? = if (provider == null || roamingType == RoamingType.DISABLED || !provider.isApplicable(fileSpec, this.roamingType)) null else provider
|
||||
private val provider: StreamProvider? = if (provider == null || roamingType == RoamingType.DISABLED) null else provider
|
||||
|
||||
protected abstract fun loadLocalData(): Element?
|
||||
|
||||
@@ -48,7 +48,7 @@ abstract class XmlElementStorage protected constructor(protected val fileSpec: S
|
||||
override fun loadData(): StateMap {
|
||||
val element: Element?
|
||||
// we don't use local data if has stream provider
|
||||
if (provider != null && provider.enabled) {
|
||||
if (provider != null && provider.isApplicable(fileSpec, roamingType)) {
|
||||
try {
|
||||
element = loadDataFromProvider()
|
||||
dataLoadedFromProvider(element)
|
||||
@@ -130,7 +130,7 @@ abstract class XmlElementStorage protected constructor(protected val fileSpec: S
|
||||
}
|
||||
|
||||
val provider = storage.provider
|
||||
if (provider != null && provider.enabled) {
|
||||
if (provider != null && provider.isApplicable(storage.fileSpec, storage.roamingType)) {
|
||||
if (element == null) {
|
||||
provider.delete(storage.fileSpec, storage.roamingType)
|
||||
}
|
||||
@@ -163,13 +163,17 @@ abstract class XmlElementStorage protected constructor(protected val fileSpec: S
|
||||
}
|
||||
|
||||
fun updatedFromStreamProvider(changedComponentNames: MutableSet<String>, deleted: Boolean) {
|
||||
updatedFrom(changedComponentNames, deleted, true)
|
||||
}
|
||||
|
||||
fun updatedFrom(changedComponentNames: MutableSet<String>, deleted: Boolean, streamProvider: Boolean) {
|
||||
if (roamingType == RoamingType.DISABLED) {
|
||||
// storage roaming was changed to DISABLED, but settings repository has old state
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
val newElement = if (deleted) null else loadDataFromProvider()
|
||||
val newElement = if (deleted) null else if (streamProvider) loadDataFromProvider() else loadLocalData()
|
||||
val states = storageDataRef.get()
|
||||
if (newElement == null) {
|
||||
// if data was loaded, mark as changed all loaded components
|
||||
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
package com.intellij.configurationStore;
|
||||
|
||||
import com.intellij.openapi.components.RoamingType;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import kotlin.jvm.functions.Function3;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* @author Alexander Lobas
|
||||
*/
|
||||
public class StreamProviderWrapper implements StreamProvider {
|
||||
private StreamProvider myStreamProvider;
|
||||
|
||||
@Nullable
|
||||
public static StreamProvider getOriginalProvider(@Nullable StreamProvider provider) {
|
||||
if (provider instanceof StreamProviderWrapper) {
|
||||
return ((StreamProviderWrapper)provider).myStreamProvider;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setStreamProvider(@Nullable StreamProvider streamProvider) {
|
||||
myStreamProvider = streamProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getEnabled() {
|
||||
return myStreamProvider != null && myStreamProvider.getEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(@NotNull String fileSpec, @NotNull RoamingType roamingType) {
|
||||
return getEnabled() && myStreamProvider.isApplicable(fileSpec, roamingType);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public InputStream read(@NotNull String fileSpec, @NotNull RoamingType roamingType) {
|
||||
return myStreamProvider.read(fileSpec, roamingType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processChildren(@NotNull String path,
|
||||
@NotNull RoamingType roamingType,
|
||||
@NotNull Function1<? super String, Boolean> filter,
|
||||
@NotNull Function3<? super String, ? super InputStream, ? super Boolean, Boolean> processor) {
|
||||
myStreamProvider.processChildren(path, roamingType, filter, processor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(@NotNull String fileSpec, @NotNull byte[] content, int size, @NotNull RoamingType roamingType) {
|
||||
myStreamProvider.write(fileSpec, content, size, roamingType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(@NotNull String fileSpec, @NotNull RoamingType roamingType) {
|
||||
myStreamProvider.delete(fileSpec, roamingType);
|
||||
}
|
||||
}
|
||||
@@ -152,10 +152,18 @@ class IcsManager(dir: Path) {
|
||||
}
|
||||
}
|
||||
|
||||
fun newStreamProvider() {
|
||||
val application = ApplicationManager.getApplication()
|
||||
(application.stateStore.stateStorageManager as StateStorageManagerImpl).streamProvider = ApplicationLevelProvider()
|
||||
}
|
||||
|
||||
fun beforeApplicationLoaded(application: Application) {
|
||||
repositoryActive = repositoryManager.isRepositoryExists()
|
||||
|
||||
(application.stateStore.stateStorageManager as StateStorageManagerImpl).streamProvider = ApplicationLevelProvider()
|
||||
val storage = application.stateStore.stateStorageManager as StateStorageManagerImpl
|
||||
if (storage.streamProvider == null || !storage.streamProvider!!.enabled) {
|
||||
storage.streamProvider = ApplicationLevelProvider()
|
||||
}
|
||||
|
||||
autoSyncManager.registerListeners(application)
|
||||
|
||||
@@ -179,6 +187,8 @@ class IcsManager(dir: Path) {
|
||||
override val enabled: Boolean
|
||||
get() = repositoryActive
|
||||
|
||||
override fun isApplicable(fileSpec: String, roamingType: RoamingType): Boolean = enabled
|
||||
|
||||
override fun processChildren(path: String, roamingType: RoamingType, filter: (name: String) -> Boolean, processor: (name: String, input: InputStream, readOnly: Boolean) -> Boolean) {
|
||||
val fullPath = toRepositoryPath(path, roamingType, null)
|
||||
|
||||
|
||||
@@ -15,9 +15,12 @@
|
||||
*/
|
||||
package org.jetbrains.settingsRepository.actions
|
||||
|
||||
import com.intellij.configurationStore.StateStorageManagerImpl
|
||||
import com.intellij.notification.NotificationGroup
|
||||
import com.intellij.notification.NotificationType
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.components.stateStore
|
||||
import com.intellij.openapi.project.DumbAwareAction
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.settingsRepository.*
|
||||
@@ -60,6 +63,14 @@ internal class ConfigureIcsAction : DumbAwareAction() {
|
||||
}
|
||||
|
||||
override fun update(e: AnActionEvent) {
|
||||
if (icsManager.repositoryActive) {
|
||||
e.presentation.isEnabledAndVisible = true
|
||||
}
|
||||
else {
|
||||
val application = ApplicationManager.getApplication()
|
||||
val provider = (application.stateStore.stateStorageManager as StateStorageManagerImpl).streamProvider
|
||||
e.presentation.isEnabledAndVisible = provider == null || !provider.enabled
|
||||
}
|
||||
e.presentation.icon = null
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ package org.jetbrains.settingsRepository
|
||||
|
||||
import com.intellij.configurationStore.ROOT_CONFIG
|
||||
import com.intellij.configurationStore.StateStorageManagerImpl
|
||||
import com.intellij.configurationStore.StreamProviderWrapper
|
||||
import com.intellij.configurationStore.removeMacroIfStartsWith
|
||||
import com.intellij.ide.actions.ExportableItem
|
||||
import com.intellij.ide.actions.getExportableComponentsMap
|
||||
@@ -33,7 +34,7 @@ import java.nio.file.NoSuchFileException
|
||||
import java.nio.file.Path
|
||||
|
||||
fun copyLocalConfig(storageManager: StateStorageManagerImpl = ApplicationManager.getApplication()!!.stateStore.stateStorageManager as StateStorageManagerImpl) {
|
||||
val streamProvider = storageManager.streamProvider!! as IcsManager.IcsStreamProvider
|
||||
val streamProvider = StreamProviderWrapper.getOriginalProvider(storageManager.streamProvider)!! as IcsManager.IcsStreamProvider
|
||||
|
||||
val fileToComponents = getExportableComponentsMap(true, false, storageManager)
|
||||
fileToComponents.keys.forEachGuaranteed { file ->
|
||||
|
||||
@@ -81,6 +81,10 @@ fun createMergeActions(project: Project?, urlTextField: TextFieldWithBrowseButto
|
||||
}
|
||||
upstreamSet = true
|
||||
|
||||
if (repositoryWillBeCreated) {
|
||||
icsManager.newStreamProvider()
|
||||
}
|
||||
|
||||
if (repositoryWillBeCreated && syncType != SyncType.OVERWRITE_LOCAL) {
|
||||
ApplicationManager.getApplication().saveSettings()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user