@@ -7,6 +7,10 @@ import java.io.File
7
7
8
8
class ModelImporter (private val root : INode , val stats : ImportStats ? = null ) {
9
9
10
+ private val originalIdToExisting: MutableMap <String , INode > = mutableMapOf ()
11
+ private val originalIdToSpec: MutableMap <String , NodeData > = mutableMapOf ()
12
+ private val originalIdToRef: MutableMap <String , INodeReference > = mutableMapOf ()
13
+
10
14
fun import (jsonFile : File ) {
11
15
require(jsonFile.exists())
12
16
require(jsonFile.extension == " json" )
@@ -17,54 +21,49 @@ class ModelImporter(private val root: INode, val stats: ImportStats? = null) {
17
21
18
22
fun import (data : ModelData ) {
19
23
stats?.reset()
24
+ originalIdToExisting.clear()
25
+ originalIdToSpec.clear()
26
+ originalIdToRef.clear()
20
27
21
28
syncProperties(root, data.root) // root original id is required for following operations
22
29
val allExistingNodes = root.getDescendants(true ).toList()
23
- val originalIdToSpec : MutableMap < String , NodeData > = buildSpecIndex(data.root)
30
+ buildSpecIndex(data.root)
24
31
25
- syncAllProperties(allExistingNodes, originalIdToSpec )
26
- val originalIdToExisting = buildExistingIndex(allExistingNodes)
32
+ syncAllProperties(allExistingNodes)
33
+ buildExistingIndex(allExistingNodes)
27
34
28
- sortAllExistingChildren(allExistingNodes, originalIdToExisting, originalIdToSpec )
29
- val addedNodes = addAllMissingChildren(root, originalIdToExisting, originalIdToSpec )
30
- syncAllProperties(addedNodes, originalIdToSpec )
35
+ sortAllExistingChildren(allExistingNodes)
36
+ val addedNodes = addAllMissingChildren(root)
37
+ syncAllProperties(addedNodes)
31
38
32
39
val allNodes = allExistingNodes + addedNodes
33
40
34
- handleAllMovesAcrossParents(allNodes, originalIdToExisting, originalIdToSpec )
41
+ handleAllMovesAcrossParents(allNodes)
35
42
36
- val originalIdToRef : MutableMap < String , INodeReference > = buildRefIndex(allNodes)
37
- syncAllReferences(allNodes, originalIdToSpec, originalIdToRef )
43
+ buildRefIndex(allNodes)
44
+ syncAllReferences(allNodes)
38
45
39
- deleteAllExtraChildren(root, originalIdToSpec )
46
+ deleteAllExtraChildren(root)
40
47
}
41
48
42
- private fun buildExistingIndex (allNodes : List <INode >): MutableMap <String , INode > {
43
- val originalIdToExisting: MutableMap <String , INode > = mutableMapOf ()
49
+ private fun buildExistingIndex (allNodes : List <INode >) {
44
50
allNodes.forEach {node ->
45
51
node.originalId()?.let { originalIdToExisting[it] = node }
46
52
}
47
- return originalIdToExisting
48
53
}
49
54
50
- private fun buildRefIndex (allNodes : List <INode >): MutableMap <String , INodeReference > {
51
- val originalIdToRef: MutableMap <String , INodeReference > = mutableMapOf ()
55
+ private fun buildRefIndex (allNodes : List <INode >) {
52
56
allNodes.forEach {node ->
53
57
node.originalId()?.let { originalIdToRef[it] = node.reference }
54
58
}
55
- return originalIdToRef
56
59
}
57
60
58
- private fun buildSpecIndex (
59
- nodeData : NodeData ,
60
- originalIdToSpec : MutableMap <String , NodeData > = mutableMapOf()
61
- ): MutableMap <String , NodeData > {
61
+ private fun buildSpecIndex (nodeData : NodeData ) {
62
62
nodeData.originalId()?.let { originalIdToSpec[it] = nodeData }
63
- nodeData.children.forEach { buildSpecIndex(it, originalIdToSpec) }
64
- return originalIdToSpec
63
+ nodeData.children.forEach { buildSpecIndex(it) }
65
64
}
66
65
67
- private fun syncAllProperties (allNodes : List <INode >, originalIdToSpec : MutableMap < String , NodeData > ) {
66
+ private fun syncAllProperties (allNodes : List <INode >) {
68
67
allNodes.forEach {node ->
69
68
originalIdToSpec[node.originalId()]?.let { spec -> syncProperties(node, spec) }
70
69
}
@@ -87,7 +86,7 @@ class ModelImporter(private val root: INode, val stats: ImportStats? = null) {
87
86
toBeRemoved.forEach { node.setPropertyValueWithStats(it, null ) }
88
87
}
89
88
90
- private fun syncAllReferences (allNodes : List <INode >, originalIdToSpec : MutableMap < String , NodeData >, originalIdToRef : Map < String , INodeReference > ) {
89
+ private fun syncAllReferences (allNodes : List <INode >) {
91
90
allNodes.forEach {node ->
92
91
originalIdToSpec[node.originalId()]?.let { spec -> syncReferences(node, spec, originalIdToRef) }
93
92
}
@@ -103,29 +102,20 @@ class ModelImporter(private val root: INode, val stats: ImportStats? = null) {
103
102
toBeRemoved.forEach { node.setReferenceTargetWithStats(it, null ) }
104
103
}
105
104
106
- private fun addAllMissingChildren (
107
- node : INode ,
108
- originalIdToExisting : MutableMap <String , INode >,
109
- originalIdToSpec : MutableMap <String , NodeData >
110
- ): MutableList <INode > {
105
+ private fun addAllMissingChildren (node : INode ): MutableList <INode > {
111
106
val addedNodes = mutableListOf<INode >()
112
107
originalIdToSpec[node.originalId()]?.let {
113
108
addedNodes.addAll(
114
- addMissingChildren(node, it, originalIdToExisting, originalIdToSpec )
109
+ addMissingChildren(node, it)
115
110
)
116
111
}
117
112
node.allChildren.forEach {
118
- addedNodes.addAll(addAllMissingChildren(it, originalIdToExisting, originalIdToSpec ))
113
+ addedNodes.addAll(addAllMissingChildren(it))
119
114
}
120
115
return addedNodes
121
116
}
122
117
123
- private fun addMissingChildren (
124
- node : INode ,
125
- nodeData : NodeData ,
126
- originalIdToExisting : MutableMap <String , INode >,
127
- originalIdToSpec : MutableMap <String , NodeData >
128
- ): List <INode > {
118
+ private fun addMissingChildren (node : INode , nodeData : NodeData ): List <INode > {
129
119
val specifiedChildren = nodeData.children.toList()
130
120
val toBeAdded = specifiedChildren.filter { ! originalIdToExisting.contains(it.originalId()) }
131
121
@@ -146,21 +136,14 @@ class ModelImporter(private val root: INode, val stats: ImportStats? = null) {
146
136
}
147
137
148
138
private fun sortAllExistingChildren (
149
- allNodes : List <INode >,
150
- originalIdToExisting : MutableMap <String , INode >,
151
- originalIdToSpec : MutableMap <String , NodeData >
139
+ allNodes : Iterable <INode >
152
140
) {
153
141
allNodes.forEach { node ->
154
- originalIdToSpec[node.originalId()]?.let { sortExistingChildren(node, it, originalIdToExisting, originalIdToSpec ) }
142
+ originalIdToSpec[node.originalId()]?.let { sortExistingChildren(node, it) }
155
143
}
156
144
}
157
145
158
- private fun sortExistingChildren (
159
- node : INode ,
160
- nodeData : NodeData ,
161
- originalIdToExisting : MutableMap <String , INode >,
162
- originalIdToSpec : MutableMap <String , NodeData >
163
- ) {
146
+ private fun sortExistingChildren (node : INode , nodeData : NodeData ) {
164
147
val existingChildren = node.allChildren.toList()
165
148
val existingIds = existingChildren.map { it.originalId() }
166
149
val specifiedChildren = nodeData.children
@@ -194,24 +177,16 @@ class ModelImporter(private val root: INode, val stats: ImportStats? = null) {
194
177
}
195
178
}
196
179
197
- private fun handleAllMovesAcrossParents (
198
- allNodes : List <INode >,
199
- originalIdToExisting : MutableMap <String , INode >,
200
- originalIdToSpec : MutableMap <String , NodeData >
201
- ) {
202
- val moves = collectMovesAcrossParents(allNodes, originalIdToExisting, originalIdToSpec)
180
+ private fun handleAllMovesAcrossParents (allNodes : List <INode >) {
181
+ val moves = collectMovesAcrossParents(allNodes)
203
182
while (moves.isNotEmpty()) {
204
183
val nextMove = moves.first { ! it.nodeToBeMoved.getDescendants(false ).contains(it.targetParent) }
205
- performMoveAcrossParents(nextMove.targetParent, nextMove.nodeToBeMoved, originalIdToSpec )
184
+ performMoveAcrossParents(nextMove.targetParent, nextMove.nodeToBeMoved)
206
185
moves.remove(nextMove)
207
186
}
208
187
}
209
188
210
- private fun collectMovesAcrossParents (
211
- allNodes : List <INode >,
212
- originalIdToExisting : MutableMap <String , INode >,
213
- originalIdToSpec : MutableMap <String , NodeData >
214
- ): MutableList <MoveAcrossParents > {
189
+ private fun collectMovesAcrossParents (allNodes : List <INode >): MutableList <MoveAcrossParents > {
215
190
val movesAcrossParents = mutableListOf<MoveAcrossParents >()
216
191
allNodes.forEach {node ->
217
192
val nodeData = originalIdToSpec[node.originalId()] ? : return @forEach
@@ -231,11 +206,7 @@ class ModelImporter(private val root: INode, val stats: ImportStats? = null) {
231
206
232
207
private data class MoveAcrossParents (val targetParent : INode , val nodeToBeMoved : INode )
233
208
234
- private fun performMoveAcrossParents (
235
- node : INode ,
236
- toBeMovedHere : INode ,
237
- originalIdToSpec : MutableMap <String , NodeData >
238
- ) {
209
+ private fun performMoveAcrossParents (node : INode , toBeMovedHere : INode ) {
239
210
val nodeData = originalIdToSpec[node.originalId()] ? : return
240
211
val existingChildren = node.allChildren.toList()
241
212
val spec = originalIdToSpec[toBeMovedHere.originalId()]!!
@@ -250,7 +221,7 @@ class ModelImporter(private val root: INode, val stats: ImportStats? = null) {
250
221
251
222
}
252
223
253
- private fun deleteAllExtraChildren (root : INode , originalIdToSpec : MutableMap < String , NodeData > ) {
224
+ private fun deleteAllExtraChildren (root : INode ) {
254
225
val toBeRemoved = mutableListOf<INode >()
255
226
root.allChildren.forEach {
256
227
if (! originalIdToSpec.containsKey(it.originalId())) {
@@ -261,7 +232,7 @@ class ModelImporter(private val root: INode, val stats: ImportStats? = null) {
261
232
it.parent?.removeChildWithStats(it)
262
233
}
263
234
root.allChildren.forEach {
264
- deleteAllExtraChildren(it, originalIdToSpec )
235
+ deleteAllExtraChildren(it)
265
236
}
266
237
}
267
238
0 commit comments