Coverage Summary for Class: BizGenAppSettingsSoftUpdaterImpl (ru.eda.plgn.bizgen.plugin.settings.persistent)
| Class |
Method, %
|
Branch, %
|
Line, %
|
Instruction, %
|
| BizGenAppSettingsSoftUpdaterImpl |
100%
(5/5)
|
75%
(6/8)
|
100%
(20/20)
|
96.8%
(120/124)
|
| BizGenAppSettingsSoftUpdaterImpl$Companion |
100%
(5/5)
|
75%
(3/4)
|
100%
(21/21)
|
98.4%
(126/128)
|
| Total |
100%
(10/10)
|
75%
(9/12)
|
100%
(41/41)
|
97.6%
(246/252)
|
package ru.eda.plgn.bizgen.plugin.settings.persistent
import ru.eda.plgn.bizgen.plugin.actions.GeneratorActionProvider
import ru.eda.plgn.bizgen.plugin.di.BizGenService
import ru.eda.plgn.bizgen.plugin.di.getBizGenService
import ru.eda.plgn.bizgen.plugin.settings.model.BizGenAppSettings.ActionSettingsView
import ru.eda.plgn.bizgen.plugin.settings.model.BizGenAppSettings.PersistenceActionSetting
/**
* Мягкое обновление настроек генераторов.
*
* @author Dmitry_Emelyanenko
*/
fun interface BizGenAppSettingsSoftUpdater : BizGenService {
/**
* Обновление сохраненных генераторов.
*
* Процесс обновления выглядит следующим образом:
* - Удаление генератора, если он отсутствует среди доступных
* - Если есть среди доступных, то оставляем состояние активности и позицию без изменений и обновляем только название (на всякий случай)
* - Новые генераторы добавляем в конец и по умолчанию делаем их активными
*
* @param savedActions загружаемые настройки генераторов
* @return обновленные настройки генераторов
*/
fun softUpdateActions(savedActions: MutableList<PersistenceActionSetting>): MutableList<PersistenceActionSetting>
}
/** Реализация [BizGenAppSettingsSoftUpdater]. */
class BizGenAppSettingsSoftUpdaterImpl : BizGenAppSettingsSoftUpdater {
override fun softUpdateActions(savedActions: MutableList<PersistenceActionSetting>): MutableList<PersistenceActionSetting> {
val actualActions = getActualActions()
removeNotActualActions(savedActions, actualActions)
updateActualActions(savedActions, actualActions)
addNewActualActions(savedActions, actualActions)
return savedActions
}
private fun addNewActualActions(savedActions: MutableList<PersistenceActionSetting>, actualActions: List<ActionSettingsView>) {
val nextPosition = savedActions.maxOfOrNull { it.position }?.let { it + 1 } ?: 0
val savedActionids = savedActions.map { it.id }
actualActions
.filter { it.id !in savedActionids }
.forEachIndexed { index, newAction ->
savedActions.add(
PersistenceActionSetting(
id = newAction.id,
position = index + nextPosition,
description = newAction.description,
active = true,
)
)
}
}
private companion object {
val notActualCriteria: (PersistenceActionSetting, List<ActionSettingsView>) -> Boolean = { current, actuals ->
current.id !in actuals.map { it.id }
}
fun removeNotActualActions(saved: MutableList<PersistenceActionSetting>, actual: List<ActionSettingsView>) {
// находим позиции действий, которые потеряли актуальность
val notActualActionPositions = saved.filter { notActualCriteria(it, actual) }.map { it.position }
// удаляем неактуальные действия
saved.removeIf { notActualCriteria(it, actual) }
restorePositions(saved, notActualActionPositions)
}
fun updateActualActions(saved: List<PersistenceActionSetting>, actuals: List<ActionSettingsView>) {
val actualsById = actuals.associateBy { it.id }
saved.forEach { savedAction ->
actualsById[savedAction.id]?.let { actual ->
savedAction.apply { description = actual.description }
}
}
}
fun restorePositions(saved: List<PersistenceActionSetting>, removedPositions: List<Int>) {
return saved.forEach { action ->
/*
Определяем сколько было удалено действий относительно позиции текущего действия.
Например:
1) Текущая позиция = 5
2) Были удалены позиции 1,4,6,8
3) Получается, что наша позиция должна сместиться на 2, так как её затрагивает удаление первой и четвертой позиций
*/
val fondShift = removedPositions.filter { removeIndex -> removeIndex < action.position }.size
action.position -= fondShift
}
}
fun getActualActions(): List<ActionSettingsView> {
return getBizGenService<GeneratorActionProvider>().getInfos().map { info ->
PersistenceActionSetting(
id = info.id,
position = -1,
description = info.name,
active = true
)
}
}
}
}