mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Fix concurrent modification exception
This commit is contained in:
@@ -139,8 +139,9 @@ class EntryKDB : EntryVersioned<Int, UUID, GroupKDB, EntryKDB>, NodeKDBInterface
|
||||
dest.writeInt(binaryDataId ?: -1)
|
||||
}
|
||||
|
||||
fun updateWith(source: EntryKDB) {
|
||||
super.updateWith(source)
|
||||
fun updateWith(source: EntryKDB,
|
||||
updateParents: Boolean = true) {
|
||||
super.updateWith(source, updateParents)
|
||||
title = source.title
|
||||
username = source.username
|
||||
password = source.password
|
||||
|
||||
@@ -110,8 +110,10 @@ class EntryKDBX : EntryVersioned<UUID, UUID, GroupKDBX, EntryKDBX>, NodeKDBXInte
|
||||
* Update with deep copy of each entry element
|
||||
* @param source
|
||||
*/
|
||||
fun updateWith(source: EntryKDBX, copyHistory: Boolean = true) {
|
||||
super.updateWith(source)
|
||||
fun updateWith(source: EntryKDBX,
|
||||
copyHistory: Boolean = true,
|
||||
updateParents: Boolean = true) {
|
||||
super.updateWith(source, updateParents)
|
||||
usageCount = source.usageCount
|
||||
locationChanged = DateInstant(source.locationChanged)
|
||||
customData = CustomData(source.customData)
|
||||
|
||||
@@ -53,8 +53,9 @@ class GroupKDB : GroupVersioned<Int, UUID, GroupKDB, EntryKDB>, NodeKDBInterface
|
||||
dest.writeInt(groupFlags)
|
||||
}
|
||||
|
||||
fun updateWith(source: GroupKDB) {
|
||||
super.updateWith(source)
|
||||
fun updateWith(source: GroupKDB,
|
||||
updateParents: Boolean = true) {
|
||||
super.updateWith(source, updateParents)
|
||||
groupFlags = source.groupFlags
|
||||
}
|
||||
|
||||
|
||||
@@ -102,8 +102,9 @@ class GroupKDBX : GroupVersioned<UUID, UUID, GroupKDBX, EntryKDBX>, NodeKDBXInte
|
||||
dest.writeParcelable(ParcelUuid(previousParentGroup), flags)
|
||||
}
|
||||
|
||||
fun updateWith(source: GroupKDBX) {
|
||||
super.updateWith(source)
|
||||
fun updateWith(source: GroupKDBX,
|
||||
updateParents: Boolean = true) {
|
||||
super.updateWith(source, updateParents)
|
||||
usageCount = source.usageCount
|
||||
locationChanged = DateInstant(source.locationChanged)
|
||||
// Add all custom elements in map
|
||||
|
||||
@@ -51,12 +51,15 @@ abstract class GroupVersioned
|
||||
dest.writeString(titleGroup)
|
||||
}
|
||||
|
||||
protected fun updateWith(source: GroupVersioned<GroupId, EntryId, Group, Entry>) {
|
||||
super.updateWith(source)
|
||||
protected fun updateWith(source: GroupVersioned<GroupId, EntryId, Group, Entry>,
|
||||
updateParents: Boolean = true) {
|
||||
super.updateWith(source, updateParents)
|
||||
titleGroup = source.titleGroup
|
||||
removeChildren()
|
||||
childGroups.addAll(source.childGroups)
|
||||
childEntries.addAll(source.childEntries)
|
||||
if (updateParents) {
|
||||
removeChildren()
|
||||
childGroups.addAll(source.childGroups)
|
||||
childEntries.addAll(source.childEntries)
|
||||
}
|
||||
}
|
||||
|
||||
override var title: String
|
||||
|
||||
@@ -68,9 +68,12 @@ abstract class NodeVersioned<IdType, Parent : GroupVersionedInterface<Parent, En
|
||||
return 0
|
||||
}
|
||||
|
||||
protected fun updateWith(source: NodeVersioned<IdType, Parent, Entry>) {
|
||||
protected fun updateWith(source: NodeVersioned<IdType, Parent, Entry>,
|
||||
updateParents: Boolean = true) {
|
||||
this.nodeId = copyNodeId(source.nodeId)
|
||||
this.parent = source.parent
|
||||
if (updateParents) {
|
||||
this.parent = source.parent
|
||||
}
|
||||
this.icon = source.icon
|
||||
this.creationTime = DateInstant(source.creationTime)
|
||||
this.lastModificationTime = DateInstant(source.lastModificationTime)
|
||||
|
||||
@@ -80,7 +80,8 @@ class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
|
||||
database.settingsChanged = databaseToMerge.settingsChanged
|
||||
}
|
||||
|
||||
val rootGroupId = database.rootGroup?.nodeId
|
||||
val rootGroup = database.rootGroup
|
||||
val rootGroupId = rootGroup?.nodeId
|
||||
val rootGroupToMerge = databaseToMerge.rootGroup
|
||||
val rootGroupIdToMerge = rootGroupToMerge?.nodeId
|
||||
|
||||
@@ -91,16 +92,18 @@ class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
|
||||
// UUID of the root group to merge is unknown
|
||||
if (database.getGroupById(rootGroupIdToMerge) == null) {
|
||||
// Change it to copy children database root
|
||||
// TODO Test merge root
|
||||
databaseToMerge.removeGroupIndex(rootGroupToMerge)
|
||||
rootGroupToMerge.nodeId = rootGroupId
|
||||
databaseToMerge.addGroupIndex(rootGroupToMerge)
|
||||
}
|
||||
|
||||
// Merge root group
|
||||
mergeGroup(rootGroupToMerge, databaseToMerge)
|
||||
if (rootGroup.lastModificationTime.date
|
||||
.before(rootGroupToMerge.lastModificationTime.date)) {
|
||||
rootGroup.updateWith(rootGroupToMerge, updateParents = false)
|
||||
}
|
||||
// Merge children
|
||||
databaseToMerge.rootGroup?.doForEachChild(
|
||||
rootGroupToMerge.doForEachChild(
|
||||
object : NodeHandler<EntryKDBX>() {
|
||||
override fun operate(node: EntryKDBX): Boolean {
|
||||
mergeEntry(node, databaseToMerge)
|
||||
@@ -206,16 +209,19 @@ class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
|
||||
|
||||
private fun mergeEntry(nodeToMerge: EntryKDBX, databaseToMerge: DatabaseKDBX) {
|
||||
val entryId = nodeToMerge.nodeId
|
||||
val entryToMerge = databaseToMerge.getEntryById(entryId)
|
||||
val entry = database.getEntryById(entryId)
|
||||
val deletedObject = database.getDeletedObject(entryId)
|
||||
|
||||
if (entryToMerge != null) {
|
||||
databaseToMerge.getEntryById(entryId)?.let { srcEntryToMerge ->
|
||||
// Retrieve parent in current database
|
||||
var parentEntryToMerge: GroupKDBX? = null
|
||||
entryToMerge.parent?.nodeId?.let {
|
||||
srcEntryToMerge.parent?.nodeId?.let {
|
||||
parentEntryToMerge = database.getGroupById(it)
|
||||
}
|
||||
val entryToMerge = EntryKDBX().apply {
|
||||
updateWith(srcEntryToMerge, copyHistory = true, updateParents = false)
|
||||
}
|
||||
|
||||
// Copy attachments in main pool
|
||||
val newAttachments = mutableListOf<Attachment>()
|
||||
entryToMerge.getAttachments(databaseToMerge.attachmentPool).forEach { attachment ->
|
||||
@@ -257,7 +263,7 @@ class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
|
||||
) {
|
||||
addHistory(entry, entryToMerge)
|
||||
if (parentEntryToMerge == entry.parent) {
|
||||
entry.updateWith(entryToMerge)
|
||||
entry.updateWith(entryToMerge, copyHistory = true, updateParents = false)
|
||||
} else {
|
||||
// Update entry with databaseEntryToMerge and merge history
|
||||
database.removeEntryFrom(entry, entry.parent)
|
||||
@@ -289,7 +295,7 @@ class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
|
||||
it.lastModificationTime == entryA.lastModificationTime
|
||||
} == null) {
|
||||
val history = EntryKDBX().apply {
|
||||
updateWith(entryA, false)
|
||||
updateWith(entryA, copyHistory = false, updateParents = false)
|
||||
parent = null
|
||||
}
|
||||
entryB.addEntryToHistory(history)
|
||||
@@ -298,16 +304,18 @@ class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
|
||||
|
||||
private fun mergeGroup(nodeToMerge: GroupKDBX, databaseToMerge: DatabaseKDBX) {
|
||||
val groupId = nodeToMerge.nodeId
|
||||
val groupToMerge = databaseToMerge.getGroupById(groupId)
|
||||
val group = database.getGroupById(groupId)
|
||||
val deletedObject = database.getDeletedObject(groupId)
|
||||
|
||||
if (groupToMerge != null) {
|
||||
databaseToMerge.getGroupById(groupId)?.let { srcGroupToMerge ->
|
||||
// Retrieve parent in current database
|
||||
var parentGroupToMerge: GroupKDBX? = null
|
||||
groupToMerge.parent?.nodeId?.let {
|
||||
srcGroupToMerge.parent?.nodeId?.let {
|
||||
parentGroupToMerge = database.getGroupById(it)
|
||||
}
|
||||
val groupToMerge = GroupKDBX().apply {
|
||||
updateWith(srcGroupToMerge, updateParents = false)
|
||||
}
|
||||
|
||||
if (group == null) {
|
||||
// If group parent to add exists and in current database
|
||||
@@ -325,7 +333,7 @@ class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
|
||||
.before(groupToMerge.lastModificationTime.date)
|
||||
) {
|
||||
if (parentGroupToMerge == group.parent) {
|
||||
group.updateWith(groupToMerge)
|
||||
group.updateWith(groupToMerge, false)
|
||||
} else {
|
||||
database.removeGroupFrom(group, group.parent)
|
||||
if (parentGroupToMerge != null) {
|
||||
|
||||
Reference in New Issue
Block a user