Skip to content

Commit a239fb6

Browse files
committed
fix(model-client): keep using role names by default
There is still too much code that needs to be migrated first. It's just important to have the new API to use it in new code, but enabling role IDs can be done later.
1 parent 04a96fd commit a239fb6

File tree

4 files changed

+52
-20
lines changed

4 files changed

+52
-20
lines changed

model-client/src/commonMain/kotlin/org/modelix/model/lazy/CLTree.kt

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class CLTree : ITree, IBulkTree {
3535
constructor(hash: String?, store: IDeserializingKeyValueStore) : this(if (hash == null) null else store.get<CPTree>(hash) { CPTree.deserialize(it) }, store)
3636
constructor(store: IDeserializingKeyValueStore) : this(null as CPTree?, store)
3737
constructor(data: CPTree?, store_: IDeserializingKeyValueStore) : this(data, null as RepositoryId?, store_)
38-
private constructor(data: CPTree?, repositoryId_: RepositoryId?, store_: IDeserializingKeyValueStore) {
38+
private constructor(data: CPTree?, repositoryId_: RepositoryId?, store_: IDeserializingKeyValueStore, useRoleIds: Boolean = false) {
3939
var repositoryId = repositoryId_
4040
var store = store_
4141
if (data == null) {
@@ -55,7 +55,7 @@ class CLTree : ITree, IBulkTree {
5555
arrayOf()
5656
)
5757
val idToHash = storeElement(root, CLHamtInternal.createEmpty(store))
58-
this.data = CPTree(repositoryId.id, KVEntryReference(idToHash.getData()), true)
58+
this.data = CPTree(repositoryId.id, KVEntryReference(idToHash.getData()), useRoleIds)
5959
} else {
6060
this.data = data
6161
}
@@ -113,33 +113,33 @@ class CLTree : ITree, IBulkTree {
113113
get() = resolveElement(ITree.ROOT_ID)
114114

115115
override fun setProperty(nodeId: Long, role: String, value: String?): ITree {
116-
checkRoleId(nodeId, role)
116+
checkPropertyRoleId(nodeId, role)
117117
var newIdToHash = nodesMap
118118
val newNodeData = resolveElement(nodeId)!!.getData().withPropertyValue(role, value)
119119
newIdToHash = newIdToHash!!.put(newNodeData)
120120
return CLTree(data.id, newIdToHash!!, store, data.usesRoleIds)
121121
}
122122

123123
override fun addNewChild(parentId: Long, role: String?, index: Int, childId: Long, concept: IConceptReference?): ITree {
124-
checkRoleId(parentId, role)
124+
checkChildRoleId(parentId, role)
125125
if (containsNode(childId)) {
126126
throw DuplicateNodeId("Node ID already exists: ${childId.toString(16)}")
127127
}
128128
return createNewNode(childId, concept).addChild(parentId, role, index, childId)
129129
}
130130

131131
override fun addNewChild(parentId: Long, role: String?, index: Int, childId: Long, concept: IConcept?): ITree {
132-
checkRoleId(parentId, role)
132+
checkChildRoleId(parentId, role)
133133
return addNewChild(parentId, role, index, childId, concept?.getReference())
134134
}
135135

136136
override fun addNewChildren(parentId: Long, role: String?, index: Int, newIds: LongArray, concepts: Array<IConcept?>): ITree {
137-
checkRoleId(parentId, role)
137+
checkChildRoleId(parentId, role)
138138
throw UnsupportedOperationException("Not implemented yet")
139139
}
140140

141141
override fun addNewChildren(parentId: Long, role: String?, index: Int, newIds: LongArray, concepts: Array<IConceptReference?>): ITree {
142-
checkRoleId(parentId, role)
142+
checkChildRoleId(parentId, role)
143143
TODO("Not yet implemented")
144144
}
145145

@@ -219,7 +219,7 @@ class CLTree : ITree, IBulkTree {
219219
}
220220

221221
override fun setReferenceTarget(sourceId: Long, role: String, target: INodeReference?): ITree {
222-
checkRoleId(sourceId, role)
222+
checkReferenceRoleId(sourceId, role)
223223
val source = resolveElement(sourceId)!!
224224
val refData: CPNodeRef? = when (target) {
225225
null -> null
@@ -303,7 +303,7 @@ class CLTree : ITree, IBulkTree {
303303
}
304304

305305
override fun getChildren(parentId: Long, role: String?): Iterable<Long> {
306-
checkRoleId(parentId, role)
306+
checkChildRoleId(parentId, role)
307307
val parent = resolveElement(parentId)
308308
val children = parent!!.getChildren(BulkQuery(store)).execute()
309309
return children
@@ -340,7 +340,7 @@ class CLTree : ITree, IBulkTree {
340340
}
341341

342342
override fun getProperty(nodeId: Long, role: String): String? {
343-
checkRoleId(nodeId, role)
343+
checkPropertyRoleId(nodeId, role)
344344
val node = resolveElement(nodeId)
345345
return node!!.getData().getPropertyValue(role)
346346
}
@@ -356,7 +356,7 @@ class CLTree : ITree, IBulkTree {
356356
}
357357

358358
override fun getReferenceTarget(sourceId: Long, role: String): INodeReference? {
359-
checkRoleId(sourceId, role)
359+
checkReferenceRoleId(sourceId, role)
360360
val node = resolveElement(sourceId)!!
361361
val targetRef = node.getData().getReferenceTarget(role)
362362
return when {
@@ -373,7 +373,7 @@ class CLTree : ITree, IBulkTree {
373373
}
374374

375375
override fun moveChild(targetParentId: Long, targetRole: String?, targetIndex_: Int, childId: Long): ITree {
376-
checkRoleId(targetParentId, targetRole)
376+
checkChildRoleId(targetParentId, targetRole)
377377
if (childId == ITree.ROOT_ID) throw RuntimeException("Moving the root node is not allowed")
378378
var ancestor = targetParentId
379379
while (ancestor != ITree.ROOT_ID) {
@@ -556,13 +556,45 @@ class CLTree : ITree, IBulkTree {
556556
return "CLTree[$hash]"
557557
}
558558

559-
private fun checkRoleId(nodeId: Long, role: String?) {
560-
if (role != null && usesRoleIds() && role.matches(roleNamePattern) && getConceptReference(nodeId) != null) {
561-
throw IllegalArgumentException("A role UID is expected, but this looks like a name: $role")
559+
private fun checkChildRoleId(nodeId: Long, role: String?) = checkRoleId(nodeId, role) { it.getAllChildLinks() }
560+
private fun checkReferenceRoleId(nodeId: Long, role: String?) = checkRoleId(nodeId, role) { it.getAllReferenceLinks() }
561+
private fun checkPropertyRoleId(nodeId: Long, role: String?) = checkRoleId(nodeId, role) { it.getAllProperties() }
562+
private fun checkRoleId(nodeId: Long, role: String?, rolesGetter: (IConcept) -> Iterable<IRole>) {
563+
if (role != null && usesRoleIds()) {
564+
val concept = getConceptReference(nodeId)?.tryResolve()
565+
if (concept != null && rolesGetter(concept).any { it.getSimpleName() == role }) {
566+
throw IllegalArgumentException("A role UID is expected, but a name was provided: $role")
567+
}
562568
}
563569
}
564570

565571
companion object {
566-
var roleNamePattern: Regex = Regex("""[a-zA-Z]+""")
572+
fun builder(store: IDeserializingKeyValueStore) = Builder(store)
573+
}
574+
575+
class Builder(var store: IDeserializingKeyValueStore) {
576+
private var repositoryId: RepositoryId? = null
577+
private var useRoleIds: Boolean = false
578+
579+
fun useRoleIds(value: Boolean = true): Builder {
580+
this.useRoleIds = value
581+
return this
582+
}
583+
584+
fun repositoryId(id: RepositoryId): Builder {
585+
this.repositoryId = id
586+
return this
587+
}
588+
589+
fun repositoryId(id: String): Builder = repositoryId(RepositoryId(id))
590+
591+
fun build(): CLTree {
592+
return CLTree(
593+
data = null as CPTree?,
594+
repositoryId_ = repositoryId ?: RepositoryId.random(),
595+
store_ = store,
596+
useRoleIds = useRoleIds
597+
)
598+
}
567599
}
568600
}

model-client/src/commonTest/kotlin/org/modelix/model/TreeSerializationTest.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class TreeSerializationTest {
5959
val mapStore = MapBaseStore()
6060
var store = mapStore
6161
var objectStore = ObjectStoreCache(store)
62-
val initialTree = CLTree(RepositoryId("tree01"), objectStore)
62+
val initialTree = CLTree.builder(objectStore).repositoryId("tree01").useRoleIds(true).build()
6363
val initialVersion = CLVersion.createRegularVersion(
6464
id = 1,
6565
time = null,
@@ -315,7 +315,7 @@ class TreeSerializationTest {
315315
val deserializedTree = deserializedVersion.tree
316316
assertTree(deserializedTree)
317317

318-
val branch = PBranch(CLTree(RepositoryId("tree01"), ObjectStoreCache(MapBaseStore())), IdGenerator.newInstance(2))
318+
val branch = PBranch(CLTree.builder(ObjectStoreCache(MapBaseStore())).repositoryId("tree01").useRoleIds(true).build(), IdGenerator.newInstance(2))
319319
branch.runWrite {
320320
for (operation in deserializedVersion.operations) {
321321
operation.apply(branch.writeTransaction, deserializedVersion.store)

model-client/src/jvmMain/kotlin/org/modelix/model/client/ReplicatedRepository.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ actual open class ReplicatedRepository actual constructor(
250250
var initialVersion = if (versionHash.isNullOrEmpty()) null else loadFromHash(versionHash, store)
251251
val initialTree = MutableObject<CLTree>()
252252
if (initialVersion == null) {
253-
initialTree.setValue(CLTree(branchReference.repositoryId, store))
253+
initialTree.setValue(CLTree.builder(store).repositoryId(branchReference.repositoryId).build())
254254
initialVersion = createVersion(initialTree.value, arrayOf(), null)
255255
client.asyncStore!!.put(branchReference.getKey(), initialVersion.hash)
256256
} else {

model-server/src/main/kotlin/org/modelix/model/server/handlers/DeprecatedLightModelServer.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ class DeprecatedLightModelServer(val client: LocalModelClient) {
173173
post("/{repositoryId}/init") {
174174
// TODO error if it already exists
175175
val repositoryId = RepositoryId(call.parameters["repositoryId"]!!)
176-
val newTree = CLTree(repositoryId, getStore())
176+
val newTree = CLTree.builder(getStore()).repositoryId(repositoryId).build()
177177
val userId = call.getUserName()
178178
val newVersion = CLVersion.createRegularVersion(
179179
client.idGenerator.generate(),

0 commit comments

Comments
 (0)