reduce SchemeManagerImpl complexity — extract SchemeListManager

This commit is contained in:
Vladimir Krivosheev
2017-10-11 13:30:33 +02:00
parent 6a80d43fbd
commit fd43d4dfb6
7 changed files with 209 additions and 196 deletions
@@ -24,7 +24,10 @@ import com.intellij.openapi.components.impl.stores.FileStorageCoreUtil
import com.intellij.openapi.components.impl.stores.FileStorageCoreUtil.DEFAULT_EXT
import com.intellij.openapi.diagnostic.runAndLogException
import com.intellij.openapi.extensions.AbstractExtensionPointBean
import com.intellij.openapi.options.*
import com.intellij.openapi.options.ExternalizableScheme
import com.intellij.openapi.options.NonLazySchemeProcessor
import com.intellij.openapi.options.SchemeProcessor
import com.intellij.openapi.options.SchemeState
import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.openapi.util.Condition
import com.intellij.openapi.util.WriteExternalException
@@ -44,7 +47,6 @@ import com.intellij.util.*
import com.intellij.util.containers.ConcurrentList
import com.intellij.util.containers.ContainerUtil
import com.intellij.util.containers.catch
import com.intellij.util.containers.filterSmart
import com.intellij.util.io.*
import com.intellij.util.messages.MessageBus
import com.intellij.util.text.UniqueNameGenerator
@@ -57,34 +59,24 @@ import java.io.InputStream
import java.nio.file.Path
import java.util.*
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicReference
import java.util.function.Function
class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
private val processor: SchemeProcessor<T, MUTABLE_SCHEME>,
class SchemeManagerImpl<T : Any, MUTABLE_SCHEME : T>(val fileSpec: String,
processor: SchemeProcessor<T, MUTABLE_SCHEME>,
private val provider: StreamProvider?,
private val ioDirectory: Path,
val roamingType: RoamingType = RoamingType.DEFAULT,
val presentableName: String? = null,
private val schemeNameToFileName: SchemeNameToFileName = CURRENT_NAME_CONVERTER,
private val messageBus: MessageBus? = null) : SchemesManager<T>(), SafeWriteRequestor {
private val messageBus: MessageBus? = null) : SchemeManagerBase<T, MUTABLE_SCHEME>(processor), SafeWriteRequestor {
private val isOldSchemeNaming = schemeNameToFileName == OLD_NAME_CONVERTER
private val isLoadingSchemes = AtomicBoolean()
private val schemesRef = AtomicReference(ContainerUtil.createLockFreeCopyOnWriteList<T>() as ConcurrentList<T>)
private val schemeListManager = SchemeListManager(this)
private val schemes: ConcurrentList<T>
get() = schemesRef.get()
private val readOnlyExternalizableSchemes = ContainerUtil.newConcurrentMap<String, T>()
/**
* Schemes can be lazy loaded, so, client should be able to set current scheme by name, not only by instance.
*/
private @Volatile var currentPendingSchemeName: String? = null
private var currentScheme: T? = null
get() = schemeListManager.schemes
private var cachedVirtualDirectory: VirtualFile? = null
@@ -113,6 +105,9 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
}
}
override val allSchemeNames: Collection<String>
get() = schemes.let { if (it.isEmpty()) emptyList() else it.map { processor.getSchemeKey(it) } }
private inner class SchemeFileTracker : BulkFileListener {
private fun isMy(file: VirtualFile) = canRead(file.nameSequence)
@@ -217,9 +212,11 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
val newSchemes = SmartList<T>()
val readScheme = readSchemeFromFile(file, newSchemes)
if (readScheme != null) {
val existingScheme = findSchemeByName(readScheme.name)
if (existingScheme != null && readOnlyExternalizableSchemes.get(existingScheme.name) !== existingScheme) {
LOG.warn("Ignore incorrect VFS create scheme event: schema ${readScheme.name} is already exists")
val readSchemeKey = processor.getSchemeKey(readScheme)
val existingScheme = findSchemeByName(readSchemeKey)
@Suppress("SuspiciousEqualsCombination")
if (existingScheme != null && schemeListManager.readOnlyExternalizableSchemes.get(processor.getSchemeKey(existingScheme)) !== existingScheme) {
LOG.warn("Ignore incorrect VFS create scheme event: schema ${readSchemeKey} is already exists")
return
}
@@ -291,9 +288,10 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
attributeProvider, true)
val oldInfo = schemeToInfo.put(scheme, externalInfo)
LOG.assertTrue(oldInfo == null)
val oldScheme = readOnlyExternalizableSchemes.put(scheme.name, scheme)
val schemeKey = processor.getSchemeKey(scheme)
val oldScheme = schemeListManager.readOnlyExternalizableSchemes.put(schemeKey, scheme)
if (oldScheme != null) {
LOG.warn("Duplicated scheme ${scheme.name} - old: $oldScheme, new $scheme")
LOG.warn("Duplicated scheme ${schemeKey} - old: $oldScheme, new $scheme")
}
schemes.add(scheme)
}
@@ -307,17 +305,11 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
}
private fun getFileExtension(fileName: CharSequence, allowAny: Boolean): String {
return if (StringUtilRt.endsWithIgnoreCase(fileName, schemeExtension)) {
schemeExtension
}
else if (StringUtilRt.endsWithIgnoreCase(fileName, DEFAULT_EXT)) {
DEFAULT_EXT
}
else if (allowAny) {
PathUtil.getFileExtension(fileName.toString())!!
}
else {
throw IllegalStateException("Scheme file extension $fileName is unknown, must be filtered out")
return when {
StringUtilRt.endsWithIgnoreCase(fileName, schemeExtension) -> schemeExtension
StringUtilRt.endsWithIgnoreCase(fileName, DEFAULT_EXT) -> DEFAULT_EXT
allowAny -> PathUtil.getFileExtension(fileName.toString())!!
else -> throw IllegalStateException("Scheme file extension $fileName is unknown, must be filtered out")
}
}
@@ -335,7 +327,7 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
catchAndLog(name) {
val scheme = loadScheme(name, input, schemes, filesToDelete)
if (readOnly && scheme != null) {
readOnlyExternalizableSchemes.put(scheme.name, scheme)
schemeListManager.readOnlyExternalizableSchemes.put(processor.getSchemeKey(scheme), scheme)
}
}
true
@@ -356,7 +348,7 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
}
this.filesToDelete.addAll(filesToDelete)
replaceSchemeList(oldSchemes, schemes)
schemeListManager.replaceSchemeList(oldSchemes, schemes)
@Suppress("UNCHECKED_CAST")
for (i in newSchemesOffset until schemes.size) {
@@ -375,12 +367,6 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
}
}
private fun replaceSchemeList(oldList: ConcurrentList<T>, newList: List<T>) {
if (!schemesRef.compareAndSet(oldList, ContainerUtil.createLockFreeCopyOnWriteList(newList) as ConcurrentList<T>)) {
throw IllegalStateException("Scheme list was modified")
}
}
override fun reload() {
processor.beforeReloaded(this)
// we must not remove non-persistent (e.g. predefined) schemes, because we cannot load it (obviously)
@@ -398,7 +384,7 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
currentScheme?.let {
if (scheme === it) {
currentPendingSchemeName = it.name
currentPendingSchemeName = processor.getSchemeKey(it)
currentScheme = null
}
}
@@ -450,8 +436,8 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
return true
}
schemes.firstOrNull({ it.name == schemeName})?.let { existingScheme ->
if (readOnlyExternalizableSchemes.get(existingScheme.name) === existingScheme) {
schemes.firstOrNull({ processor.getSchemeKey(it) == schemeName})?.let { existingScheme ->
if (schemeListManager.readOnlyExternalizableSchemes.get(processor.getSchemeKey(existingScheme)) === existingScheme) {
// so, bundled scheme is shadowed
removeFirstScheme(schemes, scheduleDelete = false) { it === existingScheme }
return true
@@ -460,7 +446,7 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
removeFirstScheme(schemes) { it === existingScheme }
}
else {
if (schemeExtension != extension && schemeToInfo.get(existingScheme as Scheme)?.fileNameWithoutExtension == fileNameWithoutExtension) {
if (schemeExtension != extension && schemeToInfo.get(existingScheme)?.fileNameWithoutExtension == fileNameWithoutExtension) {
// 1.oldExt is loading after 1.newExt - we should delete 1.oldExt
filesToDelete.add(fileName)
}
@@ -508,12 +494,12 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
else {
val element = loadElement(input)
scheme = (processor as NonLazySchemeProcessor).readScheme(element, duringLoad) ?: return null
val schemeName = scheme!!.name
if (!checkExisting(schemeName)) {
val schemeKey = processor.getSchemeKey(scheme!!)
if (!checkExisting(schemeKey)) {
return null
}
schemeToInfo.put(scheme, createInfo(schemeName, element))
schemeToInfo.put(scheme, createInfo(schemeKey, element))
this.filesToDelete.remove(fileName)
}
@@ -638,7 +624,7 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
var fileNameWithoutExtension = currentFileNameWithoutExtension
if (fileNameWithoutExtension == null || isRenamed(scheme)) {
fileNameWithoutExtension = nameGenerator.generateUniqueName(schemeNameToFileName.schemeNameToFileName(scheme.name))
fileNameWithoutExtension = nameGenerator.generateUniqueName(schemeNameToFileName.schemeNameToFileName(processor.getSchemeKey(scheme)))
}
val newDigest = element!!.digest()
@@ -672,6 +658,7 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
}
// if another new scheme uses old name of this scheme, we must not delete it (as part of rename operation)
@Suppress("SuspiciousEqualsCombination")
val renamed = externalInfo != null && fileNameWithoutExtension !== currentFileNameWithoutExtension && currentFileNameWithoutExtension != null && nameGenerator.isUnique(currentFileNameWithoutExtension)
if (providerPath == null) {
if (useVfs) {
@@ -726,7 +713,7 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
externalInfo.setFileNameWithoutExtension(fileNameWithoutExtension, schemeExtension)
}
externalInfo.digest = newDigest
externalInfo.schemeName = scheme.name
externalInfo.schemeName = processor.getSchemeKey(scheme)
}
private fun isEqualToBundledScheme(externalInfo: ExternalInfo?, newDigest: ByteArray, scheme: MUTABLE_SCHEME): Boolean {
@@ -739,9 +726,9 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
return null
}
val bundledScheme = readOnlyExternalizableSchemes.get(scheme.name)
val bundledScheme = schemeListManager.readOnlyExternalizableSchemes.get(processor.getSchemeKey(scheme))
if (bundledScheme == null) {
if ((processor as? LazySchemeProcessor)?.isSchemeEqualToBundled(scheme) ?: false) {
if ((processor as? LazySchemeProcessor)?.isSchemeEqualToBundled(scheme) == true) {
externalInfo?.scheduleDelete()
return true
}
@@ -767,7 +754,7 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
private fun isRenamed(scheme: T): Boolean {
val info = schemeToInfo.get(scheme)
return info != null && scheme.name != info.schemeName
return info != null && processor.getSchemeKey(scheme) != info.schemeName
}
private fun deleteFiles(errors: MutableList<Throwable>, filesToDelete: MutableSet<String>) {
@@ -816,52 +803,19 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
return result
}
override fun getRootDirectory(): File = ioDirectory.toFile()
override val rootDirectory: File
get() = ioDirectory.toFile()
override fun setSchemes(newSchemes: List<T>, newCurrentScheme: T?, removeCondition: Condition<T>?) {
if (schemes.isNotEmpty()) {
if (removeCondition == null) {
schemes.clear()
}
else {
// we must not use remove or removeAll to avoid "equals" call
schemesRef.set(ContainerUtil.createConcurrentList(schemes.filterSmart { !removeCondition.value(it) }))
}
}
override fun setSchemes(newSchemes: List<T>, newCurrentScheme: T?, removeCondition: Condition<T>?) = schemeListManager.setSchemes(newSchemes, newCurrentScheme, removeCondition)
schemes.addAll(newSchemes)
val oldCurrentScheme = currentScheme
retainExternalInfo()
if (oldCurrentScheme != newCurrentScheme) {
val newScheme: T?
if (newCurrentScheme != null) {
currentScheme = newCurrentScheme
newScheme = newCurrentScheme
}
else if (oldCurrentScheme != null && !schemes.contains(oldCurrentScheme)) {
newScheme = schemes.firstOrNull()
currentScheme = newScheme
}
else {
newScheme = null
}
if (oldCurrentScheme != newScheme) {
processor.onCurrentSchemeSwitched(oldCurrentScheme, newScheme)
}
}
}
private fun retainExternalInfo() {
internal fun retainExternalInfo() {
if (schemeToInfo.isEmpty()) {
return
}
val iterator = schemeToInfo.entries.iterator()
l@ for ((scheme, info) in iterator) {
if (readOnlyExternalizableSchemes.get(scheme.name) == scheme) {
if (schemeListManager.readOnlyExternalizableSchemes.get(processor.getSchemeKey(scheme)) == scheme) {
continue
}
@@ -881,7 +835,7 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
var toReplace = -1
val schemes = schemes
for ((index, existing) in schemes.withIndex()) {
if (existing.name != scheme.name) {
if (processor.getSchemeKey(existing) != processor.getSchemeKey(scheme)) {
continue
}
@@ -892,7 +846,7 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
}
if (existing.javaClass != scheme.javaClass) {
LOG.warn("'${scheme.name}' ${existing.javaClass.simpleName} replaced with ${scheme.javaClass.simpleName}")
LOG.warn("'${processor.getSchemeKey(scheme)}' ${existing.javaClass.simpleName} replaced with ${scheme.javaClass.simpleName}")
}
if (replaceExisting && processor.isExternalizable(existing)) {
@@ -912,7 +866,7 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
}
}
else -> {
(scheme as ExternalizableScheme).renameScheme(UniqueNameGenerator.generateUniqueName(scheme.name, collectExistingNames(schemes)))
(scheme as ExternalizableScheme).renameScheme(UniqueNameGenerator.generateUniqueName(scheme.name, schemeListManager.collectExistingNames(schemes)))
schemes.add(scheme)
}
}
@@ -926,12 +880,6 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
processPendingCurrentSchemeName(scheme)
}
private fun collectExistingNames(schemes: Collection<T>): Collection<String> {
val result = THashSet<String>(schemes.size)
schemes.mapTo(result) { it.name }
return result
}
override fun clearAllSchemes() {
for (it in schemeToInfo.values) {
it.scheduleDelete()
@@ -942,43 +890,15 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
schemeToInfo.clear()
}
override fun getAllSchemes(): List<T> = Collections.unmodifiableList(schemes)
override val allSchemes: List<T>
get() = Collections.unmodifiableList(schemes)
override fun isEmpty() = schemes.isEmpty()
override val isEmpty: Boolean
get() = schemes.isEmpty()
override fun findSchemeByName(schemeName: String) = schemes.firstOrNull { it.name == schemeName }
override fun findSchemeByName(schemeName: String) = schemes.firstOrNull { processor.getSchemeKey(it) == schemeName }
override fun setCurrent(scheme: T?, notify: Boolean) {
currentPendingSchemeName = null
val oldCurrent = currentScheme
currentScheme = scheme
if (notify && oldCurrent !== scheme) {
processor.onCurrentSchemeSwitched(oldCurrent, scheme)
}
}
override fun setCurrentSchemeName(schemeName: String?, notify: Boolean) {
currentPendingSchemeName = schemeName
val scheme = if (schemeName == null) null else findSchemeByName(schemeName)
// don't set current scheme if no scheme by name - pending resolution (see currentSchemeName field comment)
if (scheme != null || schemeName == null) {
setCurrent(scheme, notify)
}
}
override fun getCurrentScheme() = currentScheme
override fun getCurrentSchemeName() = currentScheme?.name ?: currentPendingSchemeName
private fun processPendingCurrentSchemeName(newScheme: T) {
if (newScheme.name == currentPendingSchemeName) {
setCurrent(newScheme, false)
}
}
override fun removeScheme(schemeName: String) = removeFirstScheme(schemes) {it.name == schemeName}
override fun removeScheme(name: String) = removeFirstScheme(schemes) {processor.getSchemeKey(it) == name }
override fun removeScheme(scheme: T) = removeFirstScheme(schemes) { it == scheme } != null
@@ -1004,9 +924,7 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
return null
}
override fun getAllSchemeNames() = schemes.let { if (it.isEmpty()) emptyList() else it.map { it.name } }
override fun isMetadataEditable(scheme: T) = !readOnlyExternalizableSchemes.containsKey(scheme.name)
override fun isMetadataEditable(scheme: T) = !schemeListManager.readOnlyExternalizableSchemes.containsKey(processor.getSchemeKey(scheme))
override fun toString() = fileSpec
}
@@ -0,0 +1,66 @@
package com.intellij.configurationStore.schemeManager
import com.intellij.configurationStore.SchemeManagerImpl
import com.intellij.openapi.util.Condition
import com.intellij.util.containers.ConcurrentList
import com.intellij.util.containers.ContainerUtil
import com.intellij.util.containers.filterSmart
import gnu.trove.THashSet
import java.util.concurrent.atomic.AtomicReference
internal class SchemeListManager<T : Any>(private val schemeManager: SchemeManagerImpl<T, *>) {
val schemesRef = AtomicReference(ContainerUtil.createLockFreeCopyOnWriteList<T>() as ConcurrentList<T>)
val readOnlyExternalizableSchemes = ContainerUtil.newConcurrentMap<String, T>()
val schemes: ConcurrentList<T>
get() = schemesRef.get()
fun replaceSchemeList(oldList: ConcurrentList<T>, newList: List<T>) {
if (!schemesRef.compareAndSet(oldList, ContainerUtil.createLockFreeCopyOnWriteList(newList) as ConcurrentList<T>)) {
throw IllegalStateException("Scheme list was modified")
}
}
fun setSchemes(newSchemes: List<T>, newCurrentScheme: T?, removeCondition: Condition<T>?) {
if (schemes.isNotEmpty()) {
if (removeCondition == null) {
schemes.clear()
}
else {
// we must not use remove or removeAll to avoid "equals" call
schemesRef.set(ContainerUtil.createConcurrentList(schemes.filterSmart { !removeCondition.value(it) }))
}
}
schemes.addAll(newSchemes)
val oldCurrentScheme = schemeManager.currentScheme
schemeManager.retainExternalInfo()
if (oldCurrentScheme != newCurrentScheme) {
val newScheme: T?
if (newCurrentScheme != null) {
schemeManager.currentScheme = newCurrentScheme
newScheme = newCurrentScheme
}
else if (oldCurrentScheme != null && !schemes.contains(oldCurrentScheme)) {
newScheme = schemes.firstOrNull()
schemeManager.currentScheme = newScheme
}
else {
newScheme = null
}
if (oldCurrentScheme != newScheme) {
schemeManager.processor.onCurrentSchemeSwitched(oldCurrentScheme, newScheme)
}
}
}
fun collectExistingNames(schemes: Collection<T>): Collection<String> {
val result = THashSet<String>(schemes.size)
schemes.mapTo(result) { schemeManager.processor.getSchemeKey(it) }
return result
}
}
@@ -0,0 +1,49 @@
// 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.
package com.intellij.configurationStore.schemeManager
import com.intellij.openapi.options.SchemeProcessor
import com.intellij.openapi.options.SchemesManager
abstract class SchemeManagerBase<T : Any, in MUTABLE_SCHEME : T>(internal val processor: SchemeProcessor<T, MUTABLE_SCHEME>) : SchemesManager<T>() {
/**
* Schemes can be lazy loaded, so, client should be able to set current scheme by name, not only by instance.
*/
@Volatile
protected var currentPendingSchemeName: String? = null
override var currentScheme: T? = null
set(value) {
field = value
currentSchemeName = value?.let { processor.getSchemeKey(it) }
}
override var currentSchemeName: String?
get() = currentScheme?.let { processor.getSchemeKey(it) } ?: currentPendingSchemeName
set(schemeName) = setCurrentSchemeName(schemeName, true)
protected fun processPendingCurrentSchemeName(newScheme: T) {
if (processor.getSchemeKey(newScheme) == currentPendingSchemeName) {
setCurrent(newScheme, false)
}
}
override fun setCurrent(scheme: T?, notify: Boolean) {
currentPendingSchemeName = null
val oldCurrent = currentScheme
currentScheme = scheme
if (notify && oldCurrent !== scheme) {
processor.onCurrentSchemeSwitched(oldCurrent, scheme)
}
}
override fun setCurrentSchemeName(schemeName: String?, notify: Boolean) {
currentPendingSchemeName = schemeName
val scheme = schemeName?.let { findSchemeByName(it) }
// don't set current scheme if no scheme by name - pending resolution (see currentSchemeName field comment)
if (scheme != null || schemeName == null) {
setCurrent(scheme, notify)
}
}
}
@@ -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-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.
package com.intellij.configurationStore
import com.intellij.openapi.extensions.AbstractExtensionPointBean
@@ -33,7 +31,7 @@ val MODERN_NAME_CONVERTER = object : SchemeNameToFileName {
override fun schemeNameToFileName(name: String) = sanitizeFileName(name)
}
interface SchemeDataHolder<in T : Scheme> {
interface SchemeDataHolder<in T> {
/**
* You should call updateDigest() after read on init.
*/
@@ -56,7 +54,7 @@ interface SchemeExtensionProvider {
}
// applicable only for LazySchemeProcessor
interface SchemeContentChangedHandler<MUTABLE_SCHEME : Scheme> {
interface SchemeContentChangedHandler<MUTABLE_SCHEME> {
fun schemeContentChanged(scheme: MUTABLE_SCHEME, name: String, dataHolder: SchemeDataHolder<MUTABLE_SCHEME>)
}
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2016 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-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.
package com.intellij.openapi.options;
import org.jetbrains.annotations.NotNull;
@@ -23,10 +9,10 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class EmptySchemesManager extends SchemeManager {
public class EmptySchemesManager extends SchemeManager<Scheme> {
@Override
@NotNull
public Collection loadSchemes() {
public Collection<Scheme> loadSchemes() {
return Collections.emptySet();
}
@@ -40,7 +26,7 @@ public class EmptySchemesManager extends SchemeManager {
@Override
@NotNull
public List getAllSchemes() {
public List<Scheme> getAllSchemes() {
return Collections.emptyList();
}
@@ -49,8 +35,9 @@ public class EmptySchemesManager extends SchemeManager {
return null;
}
@Nullable
@Override
public Scheme getCurrentScheme() {
public String getCurrentSchemeName() {
return null;
}
@@ -61,16 +48,36 @@ public class EmptySchemesManager extends SchemeManager {
@Override
@NotNull
public Collection getAllSchemeNames() {
public Collection<String> getAllSchemeNames() {
return Collections.emptySet();
}
@NotNull
@Override
public File getRootDirectory() {
//noinspection ConstantConditions
return null;
}
@Override
public void setCurrentSchemeName(@Nullable String schemeName, boolean notify) {
}
@Override
public void setCurrent(@Nullable Scheme scheme, boolean notify) {
}
@Override
public void setCurrentSchemeName(@Nullable String s) {
}
@Nullable
@Override
public Scheme getCurrentScheme() {
return null;
}
@Override
public void setCurrentScheme(@Nullable Scheme scheme) {
}
}
@@ -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-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.
package com.intellij.openapi.options
import com.intellij.openapi.util.Condition
@@ -39,8 +25,7 @@ abstract class SchemeManager<T> {
open val isEmpty: Boolean
get() = allSchemes.isEmpty()
var currentScheme: T? = null
protected set
abstract var currentScheme: T?
/**
* If schemes are lazy loaded, you can use this method to postpone scheme selection (scheme will be found by name on first use)
@@ -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-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.
package com.intellij.openapi.options
import com.intellij.configurationStore.CURRENT_NAME_CONVERTER
@@ -25,7 +11,7 @@ import org.jdom.Parent
import java.nio.file.Path
@Deprecated("Please use SchemeManager")
abstract class SchemesManager<T : Scheme> : SchemeManager<T>()
abstract class SchemesManager<T> : SchemeManager<T>()
interface ExternalizableScheme : Scheme {
fun setName(value: String)
@@ -64,7 +50,11 @@ enum class SchemeState {
UNCHANGED, NON_PERSISTENT, POSSIBLY_CHANGED
}
abstract class SchemeProcessor<SCHEME : Scheme, MUTABLE_SCHEME: SCHEME> {
abstract class SchemeProcessor<SCHEME, in MUTABLE_SCHEME: SCHEME> {
open fun getSchemeKey(scheme: SCHEME): String {
return (scheme as Scheme).name
}
open fun isExternalizable(scheme: SCHEME) = scheme is ExternalizableScheme
/**