mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
read-only sources must works without configured ICS repo — StreamProvider API
This commit is contained in:
@@ -278,16 +278,15 @@ 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.isApplicable(fileSpec, roamingType)) {
|
||||
provider.processChildren(fileSpec, roamingType, { canRead(it) }) { name, input, readOnly ->
|
||||
catchAndLog(name) {
|
||||
val scheme = loadScheme(name, input, schemes, filesToDelete)
|
||||
if (readOnly && scheme != null) {
|
||||
readOnlyExternalizableSchemes.put(scheme.name, scheme)
|
||||
}
|
||||
if (provider != null && provider.processChildren(fileSpec, roamingType, { canRead(it) }) { name, input, readOnly ->
|
||||
catchAndLog(name) {
|
||||
val scheme = loadScheme(name, input, schemes, filesToDelete)
|
||||
if (readOnly && scheme != null) {
|
||||
readOnlyExternalizableSchemes.put(scheme.name, scheme)
|
||||
}
|
||||
true
|
||||
}
|
||||
true
|
||||
}) {
|
||||
}
|
||||
else {
|
||||
ioDirectory.directoryStreamIfExists({ canRead(it.fileName.toString()) }) {
|
||||
@@ -717,14 +716,13 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
|
||||
}
|
||||
|
||||
private fun deleteFiles(errors: MutableList<Throwable>, filesToDelete: MutableSet<String>) {
|
||||
if (provider != null && provider.enabled) {
|
||||
if (provider != null) {
|
||||
val iterator = filesToDelete.iterator()
|
||||
for (name in iterator) {
|
||||
errors.catch {
|
||||
val spec = "$fileSpec/$name"
|
||||
if (provider.isApplicable(spec, roamingType)) {
|
||||
if (provider.delete(spec, roamingType)) {
|
||||
iterator.remove()
|
||||
provider.delete(spec, roamingType)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,28 +10,25 @@ class StreamProviderWrapper : StreamProvider {
|
||||
override val enabled: Boolean
|
||||
get() = streamProvider.let { it != null && it.enabled }
|
||||
|
||||
override fun isApplicable(fileSpec: String, roamingType: RoamingType): Boolean {
|
||||
return enabled && streamProvider!!.isApplicable(fileSpec, roamingType)
|
||||
}
|
||||
override fun isApplicable(fileSpec: String, roamingType: RoamingType) = streamProvider?.isApplicable(fileSpec, roamingType) ?: false
|
||||
|
||||
override fun <R> read(fileSpec: String, roamingType: RoamingType, consumer: (InputStream?) -> R): R {
|
||||
return streamProvider!!.read(fileSpec, roamingType, consumer)
|
||||
}
|
||||
override fun read(fileSpec: String, roamingType: RoamingType, consumer: (InputStream?) -> Unit) = streamProvider?.read(fileSpec, roamingType, consumer) ?: false
|
||||
|
||||
override fun processChildren(path: String,
|
||||
roamingType: RoamingType,
|
||||
filter: Function1<String, Boolean>,
|
||||
processor: Function3<String, InputStream, Boolean, Boolean>) {
|
||||
streamProvider!!.processChildren(path, roamingType, filter, processor)
|
||||
processor: Function3<String, InputStream, Boolean, Boolean>): Boolean {
|
||||
return streamProvider?.let {
|
||||
it.processChildren(path, roamingType, filter, processor)
|
||||
true
|
||||
} ?: false
|
||||
}
|
||||
|
||||
override fun write(fileSpec: String, content: ByteArray, size: Int, roamingType: RoamingType) {
|
||||
streamProvider!!.write(fileSpec, content, size, roamingType)
|
||||
}
|
||||
|
||||
override fun delete(fileSpec: String, roamingType: RoamingType) {
|
||||
streamProvider!!.delete(fileSpec, roamingType)
|
||||
}
|
||||
override fun delete(fileSpec: String, roamingType: RoamingType) = streamProvider?.delete(fileSpec, roamingType) ?: false
|
||||
}
|
||||
|
||||
fun StreamProvider?.getOriginalProvider() = if (this is StreamProviderWrapper) streamProvider else null
|
||||
@@ -47,25 +47,25 @@ abstract class XmlElementStorage protected constructor(val fileSpec: String,
|
||||
|
||||
override fun hasState(storageData: StateMap, componentName: String) = storageData.hasState(componentName)
|
||||
|
||||
override fun loadData(): StateMap {
|
||||
val element: Element?
|
||||
// we don't use local data if has stream provider
|
||||
if (provider != null && provider.isApplicable(fileSpec, roamingType)) {
|
||||
element = LOG.catchAndLog {
|
||||
loadDataFromProvider().apply { dataLoadedFromProvider(this) }
|
||||
override fun loadData() = loadElement()?.let { loadState(it) } ?: StateMap.EMPTY
|
||||
|
||||
private fun loadElement(useStreamProvider: Boolean = true): Element? {
|
||||
var element: Element? = null
|
||||
LOG.catchAndLog {
|
||||
if (!useStreamProvider || !(provider?.read(fileSpec, roamingType) {
|
||||
it?.let {
|
||||
element = loadElement(it)
|
||||
}
|
||||
} ?: false)) {
|
||||
element = loadLocalData()
|
||||
}
|
||||
}
|
||||
else {
|
||||
element = loadLocalData()
|
||||
}
|
||||
return element?.let { loadState(element) } ?: StateMap.EMPTY
|
||||
return element
|
||||
}
|
||||
|
||||
protected open fun dataLoadedFromProvider(element: Element?) {
|
||||
}
|
||||
|
||||
private fun loadDataFromProvider(): Element? = provider!!.read(fileSpec, roamingType) { it?.let(::loadElement) }
|
||||
|
||||
private fun loadState(element: Element): StateMap {
|
||||
beforeElementLoaded(element)
|
||||
return StateMap.fromMap(FileStorageCoreUtil.load(element, pathMacroSubstitutor, true))
|
||||
@@ -127,15 +127,15 @@ abstract class XmlElementStorage protected constructor(val fileSpec: String,
|
||||
}
|
||||
|
||||
val provider = storage.provider
|
||||
if (provider != null && provider.isApplicable(storage.fileSpec, storage.roamingType)) {
|
||||
if (element == null) {
|
||||
provider.delete(storage.fileSpec, storage.roamingType)
|
||||
}
|
||||
else {
|
||||
// we should use standard line-separator (\n) - stream provider can share file content on any OS
|
||||
provider.write(storage.fileSpec, element.toBufferExposingByteArray(), storage.roamingType)
|
||||
if (element == null) {
|
||||
if (provider == null || !provider.delete(storage.fileSpec, storage.roamingType)) {
|
||||
saveLocally(null)
|
||||
}
|
||||
}
|
||||
else if (provider != null && provider.isApplicable(storage.fileSpec, storage.roamingType)) {
|
||||
// we should use standard line-separator (\n) - stream provider can share file content on any OS
|
||||
provider.write(storage.fileSpec, element.toBufferExposingByteArray(), storage.roamingType)
|
||||
}
|
||||
else {
|
||||
saveLocally(element)
|
||||
}
|
||||
@@ -163,14 +163,14 @@ abstract class XmlElementStorage protected constructor(val fileSpec: String,
|
||||
updatedFrom(changedComponentNames, deleted, true)
|
||||
}
|
||||
|
||||
fun updatedFrom(changedComponentNames: MutableSet<String>, deleted: Boolean, streamProvider: Boolean) {
|
||||
fun updatedFrom(changedComponentNames: MutableSet<String>, deleted: Boolean, useStreamProvider: Boolean) {
|
||||
if (roamingType == RoamingType.DISABLED) {
|
||||
// storage roaming was changed to DISABLED, but settings repository has old state
|
||||
return
|
||||
}
|
||||
|
||||
LOG.catchAndLog {
|
||||
val newElement = if (deleted) null else if (streamProvider) loadDataFromProvider() else loadLocalData()
|
||||
val newElement = if (deleted) null else loadElement(useStreamProvider)
|
||||
val states = storageDataRef.get()
|
||||
if (newElement == null) {
|
||||
// if data was loaded, mark as changed all loaded components
|
||||
|
||||
@@ -323,7 +323,8 @@ internal class ApplicationStoreTest {
|
||||
private fun writeConfig(fileName: String, @Language("XML") data: String) = testAppConfig.writeChild(fileName, data)
|
||||
|
||||
private class MyStreamProvider : StreamProvider {
|
||||
override fun processChildren(path: String, roamingType: RoamingType, filter: (String) -> Boolean, processor: (String, InputStream, Boolean) -> Boolean) {
|
||||
override fun processChildren(path: String, roamingType: RoamingType, filter: (String) -> Boolean, processor: (String, InputStream, Boolean) -> Boolean): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
val data: MutableMap<RoamingType, MutableMap<String, String>> = THashMap()
|
||||
@@ -341,13 +342,15 @@ internal class ApplicationStoreTest {
|
||||
return map
|
||||
}
|
||||
|
||||
override fun <R> read(fileSpec: String, roamingType: RoamingType, consumer: (InputStream?) -> R): R {
|
||||
override fun read(fileSpec: String, roamingType: RoamingType, consumer: (InputStream?) -> Unit): Boolean {
|
||||
val data = getMap(roamingType).get(fileSpec)
|
||||
return data?.let { ByteArrayInputStream(it.toByteArray()) }.let(consumer)
|
||||
data?.let { ByteArrayInputStream(it.toByteArray()) }.let(consumer)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun delete(fileSpec: String, roamingType: RoamingType) {
|
||||
data[roamingType]?.remove(fileSpec)
|
||||
override fun delete(fileSpec: String, roamingType: RoamingType): Boolean {
|
||||
data.get(roamingType)?.remove(fileSpec)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,17 +11,18 @@ class MockStreamProvider(private val dir: Path) : StreamProvider {
|
||||
dir.resolve(fileSpec).write(content, 0, size)
|
||||
}
|
||||
|
||||
override fun <R> read(fileSpec: String, roamingType: RoamingType, consumer: (InputStream?) -> R): R {
|
||||
override fun read(fileSpec: String, roamingType: RoamingType, consumer: (InputStream?) -> Unit): Boolean {
|
||||
val file = dir.resolve(fileSpec)
|
||||
try {
|
||||
return file.inputStream().use(consumer)
|
||||
file.inputStream().use(consumer)
|
||||
}
|
||||
catch (e: NoSuchFileException) {
|
||||
return consumer(null)
|
||||
consumer(null)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun processChildren(path: String, roamingType: RoamingType, filter: (name: String) -> Boolean, processor: (name: String, input: InputStream, readOnly: Boolean) -> Boolean) {
|
||||
override fun processChildren(path: String, roamingType: RoamingType, filter: (name: String) -> Boolean, processor: (name: String, input: InputStream, readOnly: Boolean) -> Boolean): Boolean {
|
||||
dir.resolve(path).directoryStreamIfExists({ filter(it.fileName.toString()) }) {
|
||||
for (file in it) {
|
||||
val attributes = file.basicAttributesIfExists()
|
||||
@@ -40,9 +41,12 @@ class MockStreamProvider(private val dir: Path) : StreamProvider {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun delete(fileSpec: String, roamingType: RoamingType) {
|
||||
override fun delete(fileSpec: String, roamingType: RoamingType): Boolean {
|
||||
dir.resolve(fileSpec).delete()
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,9 +26,7 @@ import javax.swing.ButtonGroup
|
||||
import javax.swing.JLabel
|
||||
|
||||
class LayoutBuilder(val `$`: LayoutBuilderImpl, val buttonGroup: ButtonGroup? = null) {
|
||||
inline fun row(label: String, init: Row.() -> Unit) {
|
||||
row(label = Label(label), init = init)
|
||||
}
|
||||
inline fun row(label: String, init: Row.() -> Unit) = row(label = Label(label), init = init)
|
||||
|
||||
inline fun row(label: JLabel? = null, separated: Boolean = false, init: Row.() -> Unit): Row {
|
||||
val row = `$`.newRow(label, buttonGroup, separated)
|
||||
|
||||
@@ -81,6 +81,7 @@ internal class MigLayoutBuilder : LayoutBuilderImpl {
|
||||
}
|
||||
|
||||
lc.noVisualPadding()
|
||||
lc.hideMode = 3
|
||||
|
||||
container.layout = MigLayout(lc)
|
||||
|
||||
@@ -209,6 +210,19 @@ private class MigLayoutRow(private val componentConstraints: MutableMap<Componen
|
||||
}
|
||||
}
|
||||
|
||||
override var visible: Boolean = true
|
||||
get() = field
|
||||
set(value) {
|
||||
if (field == value) {
|
||||
return
|
||||
}
|
||||
|
||||
field = value
|
||||
for (c in components) {
|
||||
c.isVisible = value
|
||||
}
|
||||
}
|
||||
|
||||
override var subRowsEnabled: Boolean = true
|
||||
get() = field
|
||||
set(value) {
|
||||
@@ -220,6 +234,17 @@ private class MigLayoutRow(private val componentConstraints: MutableMap<Componen
|
||||
_subRows?.forEach { it.enabled = value }
|
||||
}
|
||||
|
||||
override var subRowsVisible: Boolean = true
|
||||
get() = field
|
||||
set(value) {
|
||||
if (field == value) {
|
||||
return
|
||||
}
|
||||
|
||||
field = value
|
||||
_subRows?.forEach { it.visible = value }
|
||||
}
|
||||
|
||||
override operator fun JComponent.invoke(vararg constraints: CCFlags, gapLeft: Int, growPolicy: GrowPolicy?) {
|
||||
addComponent(this, constraints, gapLeft = gapLeft, growPolicy = growPolicy)
|
||||
}
|
||||
|
||||
@@ -45,8 +45,12 @@ import javax.swing.JLabel
|
||||
abstract class Row() {
|
||||
abstract var enabled: Boolean
|
||||
|
||||
abstract var visible: Boolean
|
||||
|
||||
abstract var subRowsEnabled: Boolean
|
||||
|
||||
abstract var subRowsVisible: Boolean
|
||||
|
||||
abstract val subRows: List<Row>
|
||||
|
||||
protected abstract val builder: LayoutBuilderImpl
|
||||
|
||||
@@ -24,6 +24,9 @@ interface StreamProvider {
|
||||
val enabled: Boolean
|
||||
get() = true
|
||||
|
||||
/**
|
||||
* Called only on `write`
|
||||
*/
|
||||
fun isApplicable(fileSpec: String, roamingType: RoamingType = RoamingType.DEFAULT) = true
|
||||
|
||||
/**
|
||||
@@ -33,14 +36,22 @@ interface StreamProvider {
|
||||
*/
|
||||
fun write(fileSpec: String, content: ByteArray, size: Int = content.size, roamingType: RoamingType = RoamingType.DEFAULT)
|
||||
|
||||
fun <R> read(fileSpec: String, roamingType: RoamingType = RoamingType.DEFAULT, consumer: (InputStream?) -> R): R
|
||||
/**
|
||||
* `true` if provider is applicable for file.
|
||||
*/
|
||||
fun read(fileSpec: String, roamingType: RoamingType = RoamingType.DEFAULT, consumer: (InputStream?) -> Unit): Boolean
|
||||
|
||||
fun processChildren(path: String, roamingType: RoamingType, filter: (name: String) -> Boolean, processor: (name: String, input: InputStream, readOnly: Boolean) -> Boolean)
|
||||
/**
|
||||
* `true` if provider is fully responsible and local sources must be not used.
|
||||
*/
|
||||
fun processChildren(path: String, roamingType: RoamingType, filter: (name: String) -> Boolean, processor: (name: String, input: InputStream, readOnly: Boolean) -> Boolean): Boolean
|
||||
|
||||
/**
|
||||
* Delete file or directory
|
||||
*
|
||||
* `true` if provider is fully responsible and local sources must be not used.
|
||||
*/
|
||||
fun delete(fileSpec: String, roamingType: RoamingType = RoamingType.DEFAULT)
|
||||
fun delete(fileSpec: String, roamingType: RoamingType = RoamingType.DEFAULT): Boolean
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
|
||||
+7
-5
@@ -27,24 +27,26 @@ import java.io.InputStream
|
||||
class SchemeManagerIprProvider(private val subStateTagName: String) : StreamProvider {
|
||||
private val nameToData = ContainerUtil.newConcurrentMap<String, ByteArray>()
|
||||
|
||||
override fun <R> read(fileSpec: String, roamingType: RoamingType, consumer: (InputStream?) -> R): R {
|
||||
val name = PathUtilRt.getFileName(fileSpec)
|
||||
return nameToData.get(name)?.let(ByteArray::inputStream).let { consumer(it) }
|
||||
override fun read(fileSpec: String, roamingType: RoamingType, consumer: (InputStream?) -> Unit): Boolean {
|
||||
nameToData.get(PathUtilRt.getFileName(fileSpec))?.let(ByteArray::inputStream).let { consumer(it) }
|
||||
return true
|
||||
}
|
||||
|
||||
override fun delete(fileSpec: String, roamingType: RoamingType) {
|
||||
override fun delete(fileSpec: String, roamingType: RoamingType): Boolean {
|
||||
nameToData.remove(PathUtilRt.getFileName(fileSpec))
|
||||
return true
|
||||
}
|
||||
|
||||
override fun processChildren(path: String,
|
||||
roamingType: RoamingType,
|
||||
filter: (String) -> Boolean,
|
||||
processor: (String, InputStream, Boolean) -> Boolean) {
|
||||
processor: (String, InputStream, Boolean) -> Boolean): Boolean {
|
||||
for ((name, data) in nameToData) {
|
||||
if (filter(name) && !data.inputStream().use { processor(name, it, false) }) {
|
||||
break
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun write(fileSpec: String, content: ByteArray, size: Int, roamingType: RoamingType) {
|
||||
|
||||
@@ -47,7 +47,7 @@ internal const val PLUGIN_NAME = "Settings Repository"
|
||||
|
||||
internal val LOG = logger<IcsManager>()
|
||||
|
||||
val icsManager by lazy(LazyThreadSafetyMode.NONE) {
|
||||
internal val icsManager by lazy(LazyThreadSafetyMode.NONE) {
|
||||
ApplicationLoadListener.EP_NAME.findExtension(IcsApplicationLoadListener::class.java).icsManager
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@ class IcsManager @JvmOverloads constructor(dir: Path, val schemeManagerFactory:
|
||||
|
||||
val settings: IcsSettings
|
||||
val repositoryManager: RepositoryManager = GitRepositoryManager(credentialsStore, dir.resolve("repository"))
|
||||
val readOnlySourcesManager = ReadOnlySourceManager(this, dir)
|
||||
|
||||
init {
|
||||
settings = try {
|
||||
@@ -69,8 +70,6 @@ class IcsManager @JvmOverloads constructor(dir: Path, val schemeManagerFactory:
|
||||
}
|
||||
}
|
||||
|
||||
val readOnlySourcesManager = ReadOnlySourceManager(settings, dir)
|
||||
|
||||
val repositoryService: RepositoryService = GitRepositoryService()
|
||||
|
||||
private val commitAlarm = SingleAlarm(Runnable {
|
||||
@@ -98,7 +97,11 @@ class IcsManager @JvmOverloads constructor(dir: Path, val schemeManagerFactory:
|
||||
}
|
||||
|
||||
inner class ApplicationLevelProvider : IcsStreamProvider(null) {
|
||||
override fun delete(fileSpec: String, roamingType: RoamingType) {
|
||||
override fun delete(fileSpec: String, roamingType: RoamingType): Boolean {
|
||||
if (!repositoryActive) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (syncManager.writeAndDeleteProhibited) {
|
||||
throw IllegalStateException("Delete is prohibited now")
|
||||
}
|
||||
@@ -106,6 +109,8 @@ class IcsManager @JvmOverloads constructor(dir: Path, val schemeManagerFactory:
|
||||
if (repositoryManager.delete(toRepositoryPath(fileSpec, roamingType))) {
|
||||
scheduleCommit()
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,9 +184,9 @@ class IcsManager @JvmOverloads constructor(dir: Path, val schemeManagerFactory:
|
||||
override val enabled: Boolean
|
||||
get() = this@IcsManager.active
|
||||
|
||||
override fun isApplicable(fileSpec: String, roamingType: RoamingType): Boolean = enabled
|
||||
override fun isApplicable(fileSpec: String, roamingType: RoamingType): Boolean = repositoryActive
|
||||
|
||||
override fun processChildren(path: String, roamingType: RoamingType, filter: (name: String) -> Boolean, processor: (name: String, input: InputStream, readOnly: Boolean) -> Boolean) {
|
||||
override fun processChildren(path: String, roamingType: RoamingType, filter: (name: String) -> Boolean, processor: (name: String, input: InputStream, readOnly: Boolean) -> Boolean): Boolean {
|
||||
val fullPath = toRepositoryPath(path, roamingType, null)
|
||||
|
||||
// first of all we must load read-only schemes - scheme could be overridden if bundled or read-only, so, such schemes must be loaded first
|
||||
@@ -189,7 +194,12 @@ class IcsManager @JvmOverloads constructor(dir: Path, val schemeManagerFactory:
|
||||
repository.processChildren(fullPath, filter) { name, input -> processor(name, input, true) }
|
||||
}
|
||||
|
||||
if (!repositoryActive) {
|
||||
return false
|
||||
}
|
||||
|
||||
repositoryManager.processChildren(fullPath, filter) { name, input -> processor(name, input, false) }
|
||||
return true
|
||||
}
|
||||
|
||||
override fun write(fileSpec: String, content: ByteArray, size: Int, roamingType: RoamingType) {
|
||||
@@ -206,9 +216,17 @@ class IcsManager @JvmOverloads constructor(dir: Path, val schemeManagerFactory:
|
||||
|
||||
protected open fun isAutoCommit(fileSpec: String, roamingType: RoamingType) = true
|
||||
|
||||
override fun <R> read(fileSpec: String, roamingType: RoamingType, consumer: (InputStream?) -> R): R = repositoryManager.read(toRepositoryPath(fileSpec, roamingType, projectId), consumer)
|
||||
override fun read(fileSpec: String, roamingType: RoamingType, consumer: (InputStream?) -> Unit): Boolean {
|
||||
if (!repositoryActive) {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun delete(fileSpec: String, roamingType: RoamingType) {
|
||||
repositoryManager.read(toRepositoryPath(fileSpec, roamingType, projectId), consumer)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun delete(fileSpec: String, roamingType: RoamingType): Boolean {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -218,6 +236,10 @@ class IcsApplicationLoadListener : ApplicationLoadListener {
|
||||
private set
|
||||
|
||||
override fun beforeApplicationLoaded(application: Application, configPath: String) {
|
||||
if (application.isUnitTestMode) {
|
||||
return
|
||||
}
|
||||
|
||||
val customPath = System.getProperty("ics.settingsRepository")
|
||||
val pluginSystemDir = if (customPath == null) Paths.get(configPath, "settingsRepository") else Paths.get(FileUtil.expandUserHome(customPath))
|
||||
icsManager = IcsManager(pluginSystemDir)
|
||||
|
||||
@@ -33,14 +33,14 @@ import org.jetbrains.settingsRepository.git.upstream
|
||||
import org.jetbrains.settingsRepository.git.use
|
||||
import java.nio.file.Path
|
||||
|
||||
class ReadOnlySourceManager(private val settings: IcsSettings, val rootDir: Path) {
|
||||
class ReadOnlySourceManager(private val icsManager: IcsManager, val rootDir: Path) {
|
||||
private val repositoryList = object : AtomicClearableLazyValue<List<Repository>>() {
|
||||
override fun compute(): List<Repository> {
|
||||
if (settings.readOnlySources.isEmpty()) {
|
||||
if (icsManager.settings.readOnlySources.isEmpty()) {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
return settings.readOnlySources.mapSmartNotNull { source ->
|
||||
return icsManager.settings.readOnlySources.mapSmartNotNull { source ->
|
||||
LOG.catchAndLog {
|
||||
if (!source.active) {
|
||||
return@mapSmartNotNull null
|
||||
@@ -64,7 +64,7 @@ class ReadOnlySourceManager(private val settings: IcsSettings, val rootDir: Path
|
||||
get() = repositoryList.value
|
||||
|
||||
fun setSources(sources: List<ReadonlySource>) {
|
||||
settings.readOnlySources = sources
|
||||
icsManager.settings.readOnlySources = sources
|
||||
repositoryList.drop()
|
||||
}
|
||||
|
||||
|
||||
@@ -152,7 +152,7 @@ internal class AutoSyncManager(private val icsManager: IcsManager) {
|
||||
if (!onAppExit &&
|
||||
!app.isDisposeInProgress &&
|
||||
updateResult != null &&
|
||||
updateStoragesFromStreamProvider(app.stateStore as ComponentStoreImpl, updateResult, app.messageBus)) {
|
||||
updateStoragesFromStreamProvider(icsManager, app.stateStore as ComponentStoreImpl, updateResult, app.messageBus)) {
|
||||
// force to avoid saveAll & confirmation
|
||||
app.exit(true, true, true)
|
||||
}
|
||||
|
||||
@@ -50,17 +50,18 @@ internal fun createRepositoryListEditor(): ConfigurableUi<IcsSettings> {
|
||||
}
|
||||
|
||||
return object: ConfigurableUi<IcsSettings> {
|
||||
private var noRepositoryRow: Row? = null
|
||||
private var repositoryRow: Row? = null
|
||||
|
||||
override fun isModified(settings: IcsSettings) = editor.isModified
|
||||
|
||||
override fun getComponent() = panel {
|
||||
row("Repository:") {
|
||||
if (editor.model.isEmpty) {
|
||||
hint("Use File -> Settings Repository... to configure")
|
||||
}
|
||||
else {
|
||||
editor.comboBox()
|
||||
deleteButton()
|
||||
}
|
||||
noRepositoryRow = row("Repository:") {
|
||||
hint("Use File -> Settings Repository... to configure")
|
||||
}
|
||||
repositoryRow = row("Repository:") {
|
||||
editor.comboBox()
|
||||
deleteButton()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,6 +83,9 @@ internal fun createRepositoryListEditor(): ConfigurableUi<IcsSettings> {
|
||||
editor.reset(list)
|
||||
editor.model.selectedItem = upstream
|
||||
|
||||
noRepositoryRow!!.visible = list.isEmpty()
|
||||
repositoryRow!!.visible = list.isNotEmpty()
|
||||
|
||||
deleteButton.isEnabled = editor.model.selectedItem != null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,7 +142,7 @@ internal class SyncManager(private val icsManager: IcsManager, private val autoS
|
||||
|
||||
if (updateResult != null) {
|
||||
val app = ApplicationManager.getApplication()
|
||||
restartApplication = updateStoragesFromStreamProvider(app.stateStore as ComponentStoreImpl, updateResult!!, app.messageBus,
|
||||
restartApplication = updateStoragesFromStreamProvider(icsManager, app.stateStore as ComponentStoreImpl, updateResult!!, app.messageBus,
|
||||
reloadAllSchemes = syncType == SyncType.OVERWRITE_LOCAL)
|
||||
}
|
||||
}
|
||||
@@ -158,30 +158,30 @@ internal class SyncManager(private val icsManager: IcsManager, private val autoS
|
||||
}
|
||||
return updateResult != null || isReadOnlySourcesChanged
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateCloudSchemes(indicator: ProgressIndicator): Boolean {
|
||||
val changedRootDirs = icsManager.readOnlySourcesManager.update(indicator) ?: return false
|
||||
val schemeManagersToReload = SmartList<SchemeManagerImpl<*, *>>()
|
||||
icsManager.schemeManagerFactory.value.process {
|
||||
val fileSpec = toRepositoryPath(it.fileSpec, it.roamingType)
|
||||
if (changedRootDirs.contains(fileSpec)) {
|
||||
schemeManagersToReload.add(it)
|
||||
}
|
||||
}
|
||||
|
||||
if (schemeManagersToReload.isNotEmpty()) {
|
||||
invokeAndWaitIfNeed {
|
||||
for (schemeManager in schemeManagersToReload) {
|
||||
schemeManager.reload()
|
||||
private fun updateCloudSchemes(indicator: ProgressIndicator): Boolean {
|
||||
val changedRootDirs = icsManager.readOnlySourcesManager.update(indicator) ?: return false
|
||||
val schemeManagersToReload = SmartList<SchemeManagerImpl<*, *>>()
|
||||
icsManager.schemeManagerFactory.value.process {
|
||||
val fileSpec = toRepositoryPath(it.fileSpec, it.roamingType)
|
||||
if (changedRootDirs.contains(fileSpec)) {
|
||||
schemeManagersToReload.add(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return schemeManagersToReload.isNotEmpty()
|
||||
if (schemeManagersToReload.isNotEmpty()) {
|
||||
invokeAndWaitIfNeed {
|
||||
for (schemeManager in schemeManagersToReload) {
|
||||
schemeManager.reload()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return schemeManagersToReload.isNotEmpty()
|
||||
}
|
||||
}
|
||||
|
||||
internal fun updateStoragesFromStreamProvider(store: ComponentStoreImpl, updateResult: UpdateResult, messageBus: MessageBus, reloadAllSchemes: Boolean = false): Boolean {
|
||||
internal fun updateStoragesFromStreamProvider(icsManager: IcsManager, store: ComponentStoreImpl, updateResult: UpdateResult, messageBus: MessageBus, reloadAllSchemes: Boolean = false): Boolean {
|
||||
val (changed, deleted) = (store.storageManager as StateStorageManagerImpl).getCachedFileStorages(updateResult.changed, updateResult.deleted, ::toIdeaPath)
|
||||
|
||||
val schemeManagersToReload = SmartList<SchemeManagerImpl<*, *>>()
|
||||
|
||||
Reference in New Issue
Block a user