IDEA-157763 Settings repository for IDE: initial

This commit is contained in:
Alexander Lobas
2016-08-10 16:58:56 +03:00
parent 14b940694c
commit fa7cd10e94
9 changed files with 109 additions and 10 deletions
@@ -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
@@ -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);
}
}
+11 -1
View File
@@ -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()