@@ -9,7 +9,6 @@ class ModelImporter(private val root: INode, val stats: ImportStats? = null) {
9
9
10
10
private val originalIdToExisting: MutableMap <String , INode > = mutableMapOf ()
11
11
private val originalIdToSpec: MutableMap <String , NodeData > = mutableMapOf ()
12
- private val originalIdToRef: MutableMap <String , INodeReference > = mutableMapOf ()
13
12
14
13
fun import (jsonFile : File ) {
15
14
require(jsonFile.exists())
@@ -23,48 +22,41 @@ class ModelImporter(private val root: INode, val stats: ImportStats? = null) {
23
22
stats?.reset()
24
23
originalIdToExisting.clear()
25
24
originalIdToSpec.clear()
26
- originalIdToRef.clear()
27
25
28
26
syncProperties(root, data.root) // root original id is required for following operations
29
- val allExistingNodes = root.getDescendants(true ).toList()
30
27
buildSpecIndex(data.root)
31
28
32
- syncAllProperties(allExistingNodes )
33
- buildExistingIndex(allExistingNodes )
29
+ syncAllProperties(root.getDescendants( false ) )
30
+ buildExistingIndex(root )
34
31
35
- sortAllExistingChildren(allExistingNodes )
32
+ sortAllExistingChildren(root )
36
33
val addedNodes = addAllMissingChildren(root)
37
- syncAllProperties(addedNodes)
34
+ syncAllProperties(addedNodes.asSequence() )
38
35
39
- val allNodes = allExistingNodes + addedNodes
36
+ handleAllMovesAcrossParents(root)
40
37
41
- handleAllMovesAcrossParents(allNodes)
38
+ addedNodes.forEach {node ->
39
+ node.originalId()?.let { originalIdToExisting[it] = node }
40
+ }
42
41
43
- buildRefIndex(allNodes)
44
- syncAllReferences(allNodes)
42
+ syncAllReferences(root)
45
43
46
44
deleteAllExtraChildren(root)
47
45
}
48
46
49
- private fun buildExistingIndex (allNodes : List < INode > ) {
50
- allNodes .forEach {node ->
47
+ private fun buildExistingIndex (root : INode ) {
48
+ root.getDescendants( true ) .forEach {node ->
51
49
node.originalId()?.let { originalIdToExisting[it] = node }
52
50
}
53
51
}
54
52
55
- private fun buildRefIndex (allNodes : List <INode >) {
56
- allNodes.forEach {node ->
57
- node.originalId()?.let { originalIdToRef[it] = node.reference }
58
- }
59
- }
60
-
61
53
private fun buildSpecIndex (nodeData : NodeData ) {
62
54
nodeData.originalId()?.let { originalIdToSpec[it] = nodeData }
63
55
nodeData.children.forEach { buildSpecIndex(it) }
64
56
}
65
57
66
- private fun syncAllProperties (allNodes : List <INode >) {
67
- allNodes .forEach {node ->
58
+ private fun syncAllProperties (nodeSequence : Sequence <INode >) {
59
+ nodeSequence .forEach {node ->
68
60
originalIdToSpec[node.originalId()]?.let { spec -> syncProperties(node, spec) }
69
61
}
70
62
}
@@ -86,23 +78,23 @@ class ModelImporter(private val root: INode, val stats: ImportStats? = null) {
86
78
toBeRemoved.forEach { node.setPropertyValueWithStats(it, null ) }
87
79
}
88
80
89
- private fun syncAllReferences (allNodes : List < INode > ) {
90
- allNodes .forEach {node ->
91
- originalIdToSpec[node.originalId()]?.let { spec -> syncReferences(node, spec, originalIdToRef ) }
81
+ private fun syncAllReferences (root : INode ) {
82
+ root.getDescendants( true ) .forEach {node ->
83
+ originalIdToSpec[node.originalId()]?.let { spec -> syncReferences(node, spec) }
92
84
}
93
85
}
94
86
95
- private fun syncReferences (node : INode , nodeData : NodeData , originalIdToRef : Map < String , INodeReference > ) {
87
+ private fun syncReferences (node : INode , nodeData : NodeData ) {
96
88
nodeData.references.forEach {
97
- if (node.getReferenceTargetRef(it.key) != originalIdToRef [it.value]) {
98
- node.setReferenceTargetWithStats(it.key, originalIdToRef [it.value])
89
+ if (node.getReferenceTargetRef(it.key) != originalIdToExisting [it.value]?.reference ) {
90
+ node.setReferenceTargetWithStats(it.key, originalIdToExisting [it.value]?.reference )
99
91
}
100
92
}
101
93
val toBeRemoved = node.getReferenceRoles().toSet().subtract(nodeData.references.keys)
102
94
toBeRemoved.forEach { node.setReferenceTargetWithStats(it, null ) }
103
95
}
104
96
105
- private fun addAllMissingChildren (node : INode ): MutableList <INode > {
97
+ private fun addAllMissingChildren (node : INode ): List <INode > {
106
98
val addedNodes = mutableListOf<INode >()
107
99
originalIdToSpec[node.originalId()]?.let {
108
100
addedNodes.addAll(
@@ -135,10 +127,8 @@ class ModelImporter(private val root: INode, val stats: ImportStats? = null) {
135
127
}
136
128
}
137
129
138
- private fun sortAllExistingChildren (
139
- allNodes : Iterable <INode >
140
- ) {
141
- allNodes.forEach { node ->
130
+ private fun sortAllExistingChildren (root : INode ) {
131
+ root.getDescendants(true ).forEach { node ->
142
132
originalIdToSpec[node.originalId()]?.let { sortExistingChildren(node, it) }
143
133
}
144
134
}
@@ -177,18 +167,18 @@ class ModelImporter(private val root: INode, val stats: ImportStats? = null) {
177
167
}
178
168
}
179
169
180
- private fun handleAllMovesAcrossParents (allNodes : List < INode > ) {
181
- val moves = collectMovesAcrossParents(allNodes )
170
+ private fun handleAllMovesAcrossParents (root : INode ) {
171
+ val moves = collectMovesAcrossParents(root )
182
172
while (moves.isNotEmpty()) {
183
173
val nextMove = moves.first { ! it.nodeToBeMoved.getDescendants(false ).contains(it.targetParent) }
184
174
performMoveAcrossParents(nextMove.targetParent, nextMove.nodeToBeMoved)
185
175
moves.remove(nextMove)
186
176
}
187
177
}
188
178
189
- private fun collectMovesAcrossParents (allNodes : List < INode > ): MutableList <MoveAcrossParents > {
179
+ private fun collectMovesAcrossParents (root : INode ): MutableList <MoveAcrossParents > {
190
180
val movesAcrossParents = mutableListOf<MoveAcrossParents >()
191
- allNodes .forEach {node ->
181
+ root.getDescendants( true ) .forEach {node ->
192
182
val nodeData = originalIdToSpec[node.originalId()] ? : return @forEach
193
183
194
184
val missingIds = nodeData.children.map { it.originalId() }.toSet()
0 commit comments