oldaplib 0.3.1__py3-none-any.whl → 0.3.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- oldaplib/src/datamodel.py +19 -19
- oldaplib/src/enums/haspropertyattr.py +2 -1
- oldaplib/src/hasproperty.py +22 -23
- oldaplib/src/helpers/Notify.py +7 -6
- oldaplib/src/helpers/irincname.py +50 -4
- oldaplib/src/helpers/observable_dict.py +4 -2
- oldaplib/src/helpers/query_processor.py +2 -1
- oldaplib/src/helpers/tools.py +11 -11
- oldaplib/src/model.py +1 -1
- oldaplib/src/objectfactory.py +22 -22
- oldaplib/src/oldaplist.py +1 -1
- oldaplib/src/permissionset.py +15 -10
- oldaplib/src/propertyclass.py +26 -27
- oldaplib/src/resourceclass.py +88 -86
- oldaplib/src/version.py +1 -1
- oldaplib/src/xsd/xsd_qname.py +21 -0
- oldaplib/test/test_datamodel.py +168 -169
- oldaplib/test/test_hasproperty.py +65 -65
- oldaplib/test/test_objectfactory.py +1 -1
- oldaplib/test/test_observable_dict.py +10 -0
- oldaplib/test/test_oldaplist.py +9 -9
- oldaplib/test/test_oldaplistnode.py +30 -30
- oldaplib/test/test_permissionset.py +14 -14
- oldaplib/test/test_project.py +4 -4
- oldaplib/test/test_propertyclass.py +89 -91
- oldaplib/test/test_resourceclass.py +342 -336
- oldaplib/test/test_user.py +8 -8
- {oldaplib-0.3.1.dist-info → oldaplib-0.3.2.dist-info}/METADATA +1 -1
- {oldaplib-0.3.1.dist-info → oldaplib-0.3.2.dist-info}/RECORD +30 -30
- {oldaplib-0.3.1.dist-info → oldaplib-0.3.2.dist-info}/WHEEL +0 -0
oldaplib/src/datamodel.py
CHANGED
|
@@ -71,10 +71,10 @@ class DataModel(Model):
|
|
|
71
71
|
_project: Project
|
|
72
72
|
__context: Context
|
|
73
73
|
__version: SemanticVersion
|
|
74
|
-
__propclasses: dict[
|
|
75
|
-
__resclasses: dict[
|
|
76
|
-
__resclasses_changeset: dict[
|
|
77
|
-
__propclasses_changeset: dict[
|
|
74
|
+
__propclasses: dict[Xsd_QName, PropertyClass | None]
|
|
75
|
+
__resclasses: dict[Xsd_QName, ResourceClass | None]
|
|
76
|
+
__resclasses_changeset: dict[Xsd_QName, ResourceClassChange]
|
|
77
|
+
__propclasses_changeset: dict[Xsd_QName, PropertyClassChange]
|
|
78
78
|
|
|
79
79
|
def __init__(self, *,
|
|
80
80
|
con: IConnection,
|
|
@@ -219,7 +219,7 @@ class DataModel(Model):
|
|
|
219
219
|
instance.__propclasses_changeset = deepcopy(self.__propclasses_changeset, memo)
|
|
220
220
|
return instance
|
|
221
221
|
|
|
222
|
-
def __getitem__(self, key:
|
|
222
|
+
def __getitem__(self, key: Xsd_QName) -> PropertyClass | ResourceClass:
|
|
223
223
|
if key in self.__resclasses:
|
|
224
224
|
return self.__resclasses[key]
|
|
225
225
|
if key in self.__propclasses:
|
|
@@ -227,7 +227,7 @@ class DataModel(Model):
|
|
|
227
227
|
else:
|
|
228
228
|
raise KeyError(key)
|
|
229
229
|
|
|
230
|
-
def __setitem__(self, key:
|
|
230
|
+
def __setitem__(self, key: Xsd_QName, value: PropertyClass | ResourceClass) -> None:
|
|
231
231
|
if isinstance(value, PropertyClass):
|
|
232
232
|
if self.__propclasses.get(key) is None:
|
|
233
233
|
self.__propclasses_changeset[key] = PropertyClassChange(None, Action.CREATE)
|
|
@@ -243,9 +243,9 @@ class DataModel(Model):
|
|
|
243
243
|
else:
|
|
244
244
|
raise OldapErrorValue(f'"{key}" must be either PropertyClass or ResourceClass (is "{type(value).__name__}")')
|
|
245
245
|
|
|
246
|
-
def __delitem__(self, key:
|
|
247
|
-
if not isinstance(key,
|
|
248
|
-
key =
|
|
246
|
+
def __delitem__(self, key: Xsd_QName | str) -> None:
|
|
247
|
+
if not isinstance(key, Xsd_QName):
|
|
248
|
+
key = Xsd_QName(key, validate=True)
|
|
249
249
|
if key in self.__propclasses:
|
|
250
250
|
self.__propclasses_changeset[key] = PropertyClassChange(self.__propclasses[key], Action.DELETE)
|
|
251
251
|
del self.__propclasses[key]
|
|
@@ -255,7 +255,7 @@ class DataModel(Model):
|
|
|
255
255
|
else:
|
|
256
256
|
raise OldapErrorValue(f'"{key}" must be either PropertyClass or ResourceClass')
|
|
257
257
|
|
|
258
|
-
def get(self, key:
|
|
258
|
+
def get(self, key: Xsd_QName | str) -> PropertyClass | ResourceClass | None:
|
|
259
259
|
"""
|
|
260
260
|
Retrieves an instance of `PropertyClass` or `ResourceClass` associated with the
|
|
261
261
|
specified `key`. The `key` can be either an `Iri` instance or a string. If the
|
|
@@ -270,8 +270,8 @@ class DataModel(Model):
|
|
|
270
270
|
:raises OldapErrorValue: If the `key` is not a valid Iri object.
|
|
271
271
|
:raises OldapErrorNotFound: If no instance is found for the given `key`.
|
|
272
272
|
"""
|
|
273
|
-
if not isinstance(key,
|
|
274
|
-
key =
|
|
273
|
+
if not isinstance(key, Xsd_QName):
|
|
274
|
+
key = Xsd_QName(key, validate=True)
|
|
275
275
|
if key in self.__propclasses:
|
|
276
276
|
return self.__propclasses[key]
|
|
277
277
|
elif key in self.__resclasses:
|
|
@@ -279,7 +279,7 @@ class DataModel(Model):
|
|
|
279
279
|
else:
|
|
280
280
|
return None
|
|
281
281
|
|
|
282
|
-
def get_propclasses(self) -> list[
|
|
282
|
+
def get_propclasses(self) -> list[Xsd_QName]:
|
|
283
283
|
"""
|
|
284
284
|
Get a list of the IRIs of the standalone property classes.
|
|
285
285
|
|
|
@@ -291,7 +291,7 @@ class DataModel(Model):
|
|
|
291
291
|
"""
|
|
292
292
|
return [x for x in self.__propclasses]
|
|
293
293
|
|
|
294
|
-
def get_resclasses(self) -> list[
|
|
294
|
+
def get_resclasses(self) -> list[Xsd_QName]:
|
|
295
295
|
"""
|
|
296
296
|
Get a list of the IRIs of the resource classes.
|
|
297
297
|
|
|
@@ -304,7 +304,7 @@ class DataModel(Model):
|
|
|
304
304
|
return [x for x in self.__resclasses]
|
|
305
305
|
|
|
306
306
|
@property
|
|
307
|
-
def changeset(self) -> dict[
|
|
307
|
+
def changeset(self) -> dict[Xsd_QName, PropertyClassChange | ResourceClassChange]:
|
|
308
308
|
return self.__resclasses_changeset | self.__propclasses_changeset
|
|
309
309
|
|
|
310
310
|
def changeset_clear(self) -> None:
|
|
@@ -318,7 +318,7 @@ class DataModel(Model):
|
|
|
318
318
|
self.__resclasses_changeset = {}
|
|
319
319
|
self.clear_changeset()
|
|
320
320
|
|
|
321
|
-
def notifier(self, what:
|
|
321
|
+
def notifier(self, what: Xsd_QName) -> None:
|
|
322
322
|
if what in self.__propclasses:
|
|
323
323
|
self.__propclasses_changeset[what] = PropertyClassChange(None, Action.MODIFY)
|
|
324
324
|
elif what in self.__resclasses:
|
|
@@ -329,7 +329,7 @@ class DataModel(Model):
|
|
|
329
329
|
@classmethod
|
|
330
330
|
def read(cls,
|
|
331
331
|
con: IConnection,
|
|
332
|
-
project: Project |
|
|
332
|
+
project: Project | Xsd_QName | Xsd_NCName | str,
|
|
333
333
|
ignore_cache: bool = False):
|
|
334
334
|
"""
|
|
335
335
|
Reads the data model from the given project by querying the triple store.
|
|
@@ -421,7 +421,7 @@ class DataModel(Model):
|
|
|
421
421
|
projectid = r['graph'].prefix
|
|
422
422
|
propnameshacl = str(r['prop'])
|
|
423
423
|
propclassiri = propnameshacl.removesuffix("Shape")
|
|
424
|
-
propclass = PropertyClass.read(con, projectid,
|
|
424
|
+
propclass = PropertyClass.read(con, projectid, Xsd_QName(propclassiri, validate=False), ignore_cache=ignore_cache)
|
|
425
425
|
propclass.force_external()
|
|
426
426
|
propclasses.append(propclass)
|
|
427
427
|
sa_props = {x.property_class_iri: x for x in propclasses}
|
|
@@ -451,7 +451,7 @@ class DataModel(Model):
|
|
|
451
451
|
try:
|
|
452
452
|
if resclassiri == 'test:Book':
|
|
453
453
|
pass
|
|
454
|
-
resclass = ResourceClass.read(con, project,
|
|
454
|
+
resclass = ResourceClass.read(con, project, Xsd_QName(resclassiri, validate=False), sa_props=sa_props, ignore_cache=ignore_cache)
|
|
455
455
|
except OldapError as er:
|
|
456
456
|
print(f'Error reading resource class {resclassiri}: {er}')
|
|
457
457
|
|
|
@@ -6,6 +6,7 @@ from oldaplib.src.xsd.xsd_decimal import Xsd_decimal
|
|
|
6
6
|
from oldaplib.src.xsd.xsd_integer import Xsd_integer
|
|
7
7
|
from oldaplib.src.xsd.xsd_ncname import Xsd_NCName
|
|
8
8
|
from oldaplib.src.xsd.xsd_nonnegativeinteger import Xsd_nonNegativeInteger
|
|
9
|
+
from oldaplib.src.xsd.xsd_qname import Xsd_QName
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
@unique
|
|
@@ -14,4 +15,4 @@ class HasPropertyAttr(AttributeClass):
|
|
|
14
15
|
MIN_COUNT = ('sh:minCount', False, False, Xsd_nonNegativeInteger)
|
|
15
16
|
MAX_COUNT = ('sh:maxCount', False, False, Xsd_nonNegativeInteger)
|
|
16
17
|
ORDER = ('sh:order', False, False, Xsd_decimal)
|
|
17
|
-
GROUP = ('sh:group', False, False,
|
|
18
|
+
GROUP = ('sh:group', False, False, Xsd_QName)
|
oldaplib/src/hasproperty.py
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
from copy import deepcopy
|
|
2
|
-
from dataclasses import dataclass
|
|
3
2
|
from enum import Enum
|
|
4
3
|
from functools import partial
|
|
5
|
-
from pprint import pprint
|
|
6
4
|
from typing import Callable, Self, Any
|
|
7
5
|
|
|
8
6
|
from oldaplib.src.enums.action import Action
|
|
9
7
|
from oldaplib.src.enums.attributeclass import AttributeClass
|
|
10
8
|
from oldaplib.src.enums.haspropertyattr import HasPropertyAttr
|
|
11
|
-
from oldaplib.src.enums.propertyclassattr import PropClassAttr
|
|
12
9
|
from oldaplib.src.helpers.Notify import Notify
|
|
13
10
|
from oldaplib.src.helpers.irincname import IriOrNCName
|
|
14
11
|
from oldaplib.src.helpers.oldaperror import OldapErrorNotFound
|
|
@@ -20,10 +17,10 @@ from oldaplib.src.project import Project
|
|
|
20
17
|
from oldaplib.src.propertyclass import PropertyClass, HasPropertyData
|
|
21
18
|
from oldaplib.src.xsd.iri import Iri
|
|
22
19
|
from oldaplib.src.xsd.xsd_datetime import Xsd_dateTime
|
|
23
|
-
from oldaplib.src.xsd.xsd_decimal import Xsd_decimal
|
|
24
|
-
from oldaplib.src.xsd.xsd_integer import Xsd_integer
|
|
25
20
|
from oldaplib.src.xsd.xsd_ncname import Xsd_NCName
|
|
26
21
|
from oldaplib.src.xsd.xsd_nonnegativeinteger import Xsd_nonNegativeInteger
|
|
22
|
+
from oldaplib.src.xsd.xsd_qname import Xsd_QName
|
|
23
|
+
|
|
27
24
|
|
|
28
25
|
@serializer
|
|
29
26
|
class PropType(Enum):
|
|
@@ -53,16 +50,16 @@ class HasProperty(Model, Notify):
|
|
|
53
50
|
"""
|
|
54
51
|
|
|
55
52
|
|
|
56
|
-
_prop: PropertyClass |
|
|
53
|
+
_prop: PropertyClass | Xsd_QName | None
|
|
57
54
|
_project: Project | None
|
|
58
55
|
_type: PropType | None
|
|
59
56
|
|
|
60
57
|
def __init__(self, *,
|
|
61
58
|
con: IConnection,
|
|
62
59
|
project: Project | Iri | Xsd_NCName | str,
|
|
63
|
-
prop: PropertyClass |
|
|
64
|
-
notifier: Callable[[
|
|
65
|
-
notify_data:
|
|
60
|
+
prop: PropertyClass | Xsd_QName | None = None,
|
|
61
|
+
notifier: Callable[[Xsd_QName], None] | None = None,
|
|
62
|
+
notify_data: Xsd_QName | None = None,
|
|
66
63
|
creator: Iri | None = None, # DO NO USE! Only for jsonify!!
|
|
67
64
|
created: Xsd_dateTime | None = None, # DO NO USE! Only for jsonify!!
|
|
68
65
|
contributor: Iri | None = None, # DO NO USE! Only for jsonify!!
|
|
@@ -103,8 +100,8 @@ class HasProperty(Model, Notify):
|
|
|
103
100
|
if not isinstance(project, (Iri, Xsd_NCName)):
|
|
104
101
|
project = IriOrNCName(project, validate=validate)
|
|
105
102
|
self._project = Project.read(self._con, project)
|
|
106
|
-
if isinstance(prop,
|
|
107
|
-
fixed_prop =
|
|
103
|
+
if isinstance(prop, Xsd_QName):
|
|
104
|
+
fixed_prop = Xsd_QName(str(prop).removesuffix("Shape"))
|
|
108
105
|
try:
|
|
109
106
|
self._prop = PropertyClass.read(self._con, self._project, fixed_prop)
|
|
110
107
|
self._type = PropType.STANDALONE
|
|
@@ -129,8 +126,8 @@ class HasProperty(Model, Notify):
|
|
|
129
126
|
self._changeset = {}
|
|
130
127
|
|
|
131
128
|
def update_notifier(self,
|
|
132
|
-
notifier: Callable[[AttributeClass |
|
|
133
|
-
notify_data: HasPropertyAttr |
|
|
129
|
+
notifier: Callable[[AttributeClass | Xsd_QName], None] | None = None,
|
|
130
|
+
notify_data: HasPropertyAttr | Xsd_QName | None = None):
|
|
134
131
|
self.set_notifier(notifier, notify_data)
|
|
135
132
|
if isinstance(self._prop, PropertyClass):
|
|
136
133
|
self._prop.set_notifier(self.notifier, self._prop.property_class_iri)
|
|
@@ -177,11 +174,11 @@ class HasProperty(Model, Notify):
|
|
|
177
174
|
return self._type
|
|
178
175
|
|
|
179
176
|
@property
|
|
180
|
-
def prop(self) -> PropertyClass |
|
|
177
|
+
def prop(self) -> PropertyClass | Xsd_QName | None:
|
|
181
178
|
return self._prop
|
|
182
179
|
|
|
183
180
|
@prop.setter
|
|
184
|
-
def prop(self, prop: PropertyClass |
|
|
181
|
+
def prop(self, prop: PropertyClass | Xsd_QName) -> None:
|
|
185
182
|
self._prop = prop
|
|
186
183
|
|
|
187
184
|
@property
|
|
@@ -191,12 +188,12 @@ class HasProperty(Model, Notify):
|
|
|
191
188
|
order=self._attributes.get(HasPropertyAttr.ORDER, None),
|
|
192
189
|
group=self._attributes.get(HasPropertyAttr.GROUP, None))
|
|
193
190
|
|
|
194
|
-
def notifier(self, attr: HasPropertyAttr | Iri) -> None:
|
|
191
|
+
def notifier(self, attr: HasPropertyAttr | Iri | Xsd_QName) -> None:
|
|
195
192
|
#if attr == HasPropertyAttr.PROP:
|
|
196
193
|
# return
|
|
197
194
|
if isinstance(attr, HasPropertyAttr):
|
|
198
195
|
self._changeset[attr] = AttributeChange(self._attributes[attr], Action.MODIFY)
|
|
199
|
-
elif isinstance(attr,
|
|
196
|
+
elif isinstance(attr, Xsd_QName):
|
|
200
197
|
self._changeset[attr] = AttributeChange(None, Action.MODIFY)
|
|
201
198
|
self.notify()
|
|
202
199
|
|
|
@@ -230,13 +227,13 @@ class HasProperty(Model, Notify):
|
|
|
230
227
|
|
|
231
228
|
def update_shacl(self,
|
|
232
229
|
graph: Xsd_NCName,
|
|
233
|
-
resclass_iri:
|
|
234
|
-
propclass_iri:
|
|
230
|
+
resclass_iri: Xsd_QName,
|
|
231
|
+
propclass_iri: Xsd_QName,
|
|
235
232
|
indent: int = 0, indent_inc: int = 4) -> str:
|
|
236
233
|
blank = ''
|
|
237
234
|
sparql_list = []
|
|
238
235
|
for attr, change in self._changeset.items():
|
|
239
|
-
if isinstance(attr,
|
|
236
|
+
if isinstance(attr, Xsd_QName): # if it's an IRI, the attached PropertyClass has changed. We don't process this here
|
|
240
237
|
continue
|
|
241
238
|
sparql = f'WITH {graph}:shacl\n'
|
|
242
239
|
if change.action != Action.CREATE:
|
|
@@ -251,7 +248,7 @@ class HasProperty(Model, Notify):
|
|
|
251
248
|
|
|
252
249
|
sparql += f'{blank:{indent * indent_inc}}WHERE {{\n'
|
|
253
250
|
sparql += f'{blank:{(indent + 1) * indent_inc}}{resclass_iri}Shape sh:property ?prop .\n'
|
|
254
|
-
if isinstance(self._prop,
|
|
251
|
+
if isinstance(self._prop, Xsd_QName) or self._prop.internal is None:
|
|
255
252
|
sparql += f'{blank:{(indent + 1) * indent_inc}}?prop sh:node {propclass_iri}Shape.\n'
|
|
256
253
|
else:
|
|
257
254
|
sparql += f'{blank:{(indent + 1) * indent_inc}}?prop sh:path {propclass_iri} .\n'
|
|
@@ -264,8 +261,8 @@ class HasProperty(Model, Notify):
|
|
|
264
261
|
|
|
265
262
|
def update_owl(self,
|
|
266
263
|
graph: Xsd_NCName,
|
|
267
|
-
resclass_iri:
|
|
268
|
-
propclass_iri:
|
|
264
|
+
resclass_iri: Xsd_QName,
|
|
265
|
+
propclass_iri: Xsd_QName,
|
|
269
266
|
indent: int = 0, indent_inc: int = 4) -> str:
|
|
270
267
|
blank = ''
|
|
271
268
|
if HasPropertyAttr.MIN_COUNT in self._changeset or HasPropertyAttr.MAX_COUNT in self._changeset:
|
|
@@ -302,3 +299,5 @@ class HasProperty(Model, Notify):
|
|
|
302
299
|
sparql += f'{blank:{indent * indent_inc}}}}'
|
|
303
300
|
|
|
304
301
|
return sparql
|
|
302
|
+
else:
|
|
303
|
+
return ''
|
oldaplib/src/helpers/Notify.py
CHANGED
|
@@ -5,6 +5,7 @@ from pystrict import strict
|
|
|
5
5
|
|
|
6
6
|
from oldaplib.src.enums.attributeclass import AttributeClass
|
|
7
7
|
from oldaplib.src.xsd.iri import Iri
|
|
8
|
+
from oldaplib.src.xsd.xsd_qname import Xsd_QName
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
#@strict
|
|
@@ -15,12 +16,12 @@ class Notify:
|
|
|
15
16
|
as of type LangString or PropertyRestriction to notify PropertyClass that something has changed,
|
|
16
17
|
e.g. the change of value
|
|
17
18
|
"""
|
|
18
|
-
_notifier: Callable[[Enum | Iri], None]
|
|
19
|
-
_notify_data: Enum | Iri | None
|
|
19
|
+
_notifier: Callable[[Enum | Iri | Xsd_QName], None]
|
|
20
|
+
_notify_data: Enum | Iri | Xsd_QName | None
|
|
20
21
|
|
|
21
22
|
def __init__(self,
|
|
22
|
-
notifier: Callable[[Enum | Iri], None] | None = None,
|
|
23
|
-
data: Enum | Iri | None = None):
|
|
23
|
+
notifier: Callable[[Enum | Iri | Xsd_QName], None] | None = None,
|
|
24
|
+
data: Enum | Iri | Xsd_QName | None = None):
|
|
24
25
|
"""
|
|
25
26
|
Constructor of the notifier. Usually, the notifier is only used a base class and not used directly.
|
|
26
27
|
:param notifier: The callable that is to be called by the subclass when an item is beeing chaged
|
|
@@ -30,8 +31,8 @@ class Notify:
|
|
|
30
31
|
self._notify_data = data
|
|
31
32
|
|
|
32
33
|
def set_notifier(self,
|
|
33
|
-
notifier: Callable[[Enum | AttributeClass | Iri], None],
|
|
34
|
-
data: Enum | Iri | None = None) -> None:
|
|
34
|
+
notifier: Callable[[Enum | AttributeClass | Iri | Xsd_QName], None],
|
|
35
|
+
data: Enum | Xsd_QName | Iri | None = None) -> None:
|
|
35
36
|
"""
|
|
36
37
|
Sets the notifier callback function and the data it should return...
|
|
37
38
|
:param notifier: A callable that is to be called by the subclass when an item changes
|
|
@@ -1,33 +1,79 @@
|
|
|
1
1
|
from oldaplib.src.xsd.iri import Iri
|
|
2
2
|
from oldaplib.src.xsd.xsd_ncname import Xsd_NCName
|
|
3
|
+
from oldaplib.src.xsd.xsd_qname import Xsd_QName
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
class IriOrNCName:
|
|
6
7
|
|
|
7
|
-
def __init__(self, value: Iri | Xsd_NCName | str, validate: bool = False):
|
|
8
|
+
def __init__(self, value: Iri | Xsd_QName | Xsd_NCName | str, validate: bool = False):
|
|
8
9
|
self.__iri: Iri | None = None
|
|
9
10
|
self.__ncname: Xsd_NCName | None = None
|
|
11
|
+
self.__qname: Xsd_QName | None = None
|
|
10
12
|
if isinstance(value, Iri):
|
|
11
13
|
self.__iri = value
|
|
12
14
|
self.__ncname = None
|
|
15
|
+
self.__qname = None
|
|
13
16
|
elif isinstance(value, Xsd_NCName):
|
|
14
17
|
self.__ncname = Xsd_NCName(value)
|
|
15
18
|
self.__iri = None
|
|
19
|
+
self.__qname = None
|
|
20
|
+
elif isinstance(value, Xsd_QName):
|
|
21
|
+
self.__qname = Xsd_QName(value)
|
|
22
|
+
self.__iri = None
|
|
23
|
+
self.__ncname = None
|
|
16
24
|
else:
|
|
17
25
|
if ':' in str(value): # must be IRI or QName
|
|
18
|
-
|
|
19
|
-
|
|
26
|
+
try:
|
|
27
|
+
self.__qname = Xsd_QName(value, validate=validate)
|
|
28
|
+
self.__iri = None
|
|
29
|
+
self.__ncname = None
|
|
30
|
+
except:
|
|
31
|
+
self.__iri = Iri(value, validate=validate)
|
|
32
|
+
self.__ncname = None
|
|
33
|
+
self.__qname = None
|
|
20
34
|
else:
|
|
21
35
|
self.__ncname = Xsd_NCName(value, validate=validate)
|
|
22
36
|
self.__iri = None
|
|
37
|
+
self.__qname = None
|
|
38
|
+
|
|
39
|
+
@property
|
|
40
|
+
def is_iri(self) -> bool:
|
|
41
|
+
return self.__iri is not None
|
|
42
|
+
|
|
43
|
+
@property
|
|
44
|
+
def is_ncname(self) -> bool:
|
|
45
|
+
return self.__ncname is not None
|
|
46
|
+
|
|
47
|
+
@property
|
|
48
|
+
def is_qname(self) -> bool:
|
|
49
|
+
return self.__qname is not None
|
|
50
|
+
|
|
51
|
+
@property
|
|
52
|
+
def as_iri(self) -> Iri | None:
|
|
53
|
+
if self.__iri:
|
|
54
|
+
return self.__iri
|
|
55
|
+
elif self.__qname:
|
|
56
|
+
return Iri(self.__qname)
|
|
57
|
+
else:
|
|
58
|
+
return None
|
|
59
|
+
|
|
60
|
+
@property
|
|
61
|
+
def as_qname(self) -> Xsd_QName | None:
|
|
62
|
+
return self.__qname if self.__qname else None
|
|
63
|
+
|
|
64
|
+
@property
|
|
65
|
+
def as_ncname(self) -> Xsd_NCName | None:
|
|
66
|
+
return self.__ncname if self.__ncname else None
|
|
23
67
|
|
|
24
68
|
def value(self) -> tuple[Xsd_NCName| None, Iri | None]:
|
|
25
|
-
return self.
|
|
69
|
+
return self.as_ncname, self.as_iri
|
|
26
70
|
|
|
27
71
|
def __str__(self):
|
|
28
72
|
if self.__iri is not None:
|
|
29
73
|
return str(self.__iri)
|
|
30
74
|
elif self.__ncname is not None:
|
|
31
75
|
return str(self.__ncname)
|
|
76
|
+
elif self.__qname is not None:
|
|
77
|
+
return str(self.__qname)
|
|
32
78
|
else:
|
|
33
79
|
return "???"
|
|
@@ -50,7 +50,7 @@ class ObservableDict(UserDict):
|
|
|
50
50
|
for item in obsdict:
|
|
51
51
|
self[item['key']] = item['val']
|
|
52
52
|
|
|
53
|
-
def __setitem__(self, key, value):
|
|
53
|
+
def __setitem__(self, key, value) -> None:
|
|
54
54
|
if key in self.data:
|
|
55
55
|
self._changeset[key] = AttributeChange(self.data[key], Action.MODIFY)
|
|
56
56
|
else:
|
|
@@ -59,12 +59,14 @@ class ObservableDict(UserDict):
|
|
|
59
59
|
self.__on_change(self.copy())
|
|
60
60
|
super().__setitem__(key, value)
|
|
61
61
|
|
|
62
|
-
def __delitem__(self, key):
|
|
62
|
+
def __delitem__(self, key) -> None:
|
|
63
63
|
self._changeset[key] = AttributeChange(self.data[key], Action.DELETE)
|
|
64
64
|
if self.__on_change:
|
|
65
65
|
self.__on_change(self.copy())
|
|
66
66
|
super().__delitem__(key)
|
|
67
67
|
|
|
68
|
+
def __bool__(self) -> bool:
|
|
69
|
+
return len(self) > 0
|
|
68
70
|
|
|
69
71
|
def copy(self) -> Self:
|
|
70
72
|
return ObservableDict(self.data.copy())
|
|
@@ -73,7 +73,8 @@ class QueryProcessor:
|
|
|
73
73
|
if tmp is None:
|
|
74
74
|
row[name] = Iri(valobj["value"], validate=False)
|
|
75
75
|
else:
|
|
76
|
-
row[name] = Iri(tmp, validate=False)
|
|
76
|
+
#row[name] = Iri(tmp, validate=False)
|
|
77
|
+
row[name] = tmp
|
|
77
78
|
elif valobj["type"] == "bnode":
|
|
78
79
|
row[name] = BNode(f'_:{valobj["value"]}', validate=False)
|
|
79
80
|
elif valobj["type"] == "literal":
|
oldaplib/src/helpers/tools.py
CHANGED
|
@@ -38,7 +38,7 @@ class RdfModifyRes:
|
|
|
38
38
|
def __rdf_modify_property(cls, *,
|
|
39
39
|
shacl: bool,
|
|
40
40
|
action: Action,
|
|
41
|
-
owlclass_iri:
|
|
41
|
+
owlclass_iri: Xsd_QName,
|
|
42
42
|
graph: Xsd_QName,
|
|
43
43
|
ele: RdfModifyItem,
|
|
44
44
|
last_modified: Xsd_dateTime,
|
|
@@ -78,7 +78,7 @@ class RdfModifyRes:
|
|
|
78
78
|
def shacl(cls, *,
|
|
79
79
|
action: Action,
|
|
80
80
|
graph: Xsd_NCName,
|
|
81
|
-
owlclass_iri:
|
|
81
|
+
owlclass_iri: Xsd_QName,
|
|
82
82
|
ele: RdfModifyItem,
|
|
83
83
|
last_modified: Xsd_dateTime,
|
|
84
84
|
indent: int = 0, indent_inc: int = 4):
|
|
@@ -91,7 +91,7 @@ class RdfModifyRes:
|
|
|
91
91
|
def onto(cls, *,
|
|
92
92
|
action: Action,
|
|
93
93
|
graph: Xsd_NCName,
|
|
94
|
-
owlclass_iri:
|
|
94
|
+
owlclass_iri: Xsd_QName,
|
|
95
95
|
ele: RdfModifyItem,
|
|
96
96
|
last_modified: Xsd_dateTime,
|
|
97
97
|
indent: int = 0, indent_inc: int = 4):
|
|
@@ -107,8 +107,8 @@ class RdfModifyProp:
|
|
|
107
107
|
def __rdf_modify_property(cls, *,
|
|
108
108
|
shacl: bool,
|
|
109
109
|
action: Action,
|
|
110
|
-
owlclass_iri:
|
|
111
|
-
pclass_iri:
|
|
110
|
+
owlclass_iri: Xsd_QName | None = None,
|
|
111
|
+
pclass_iri: Xsd_QName,
|
|
112
112
|
graph: Xsd_QName,
|
|
113
113
|
ele: RdfModifyItem,
|
|
114
114
|
last_modified: Xsd_dateTime,
|
|
@@ -150,8 +150,8 @@ class RdfModifyProp:
|
|
|
150
150
|
def shacl(cls, *,
|
|
151
151
|
action: Action,
|
|
152
152
|
graph: Xsd_NCName,
|
|
153
|
-
owlclass_iri:
|
|
154
|
-
pclass_iri:
|
|
153
|
+
owlclass_iri: Xsd_QName | None = None,
|
|
154
|
+
pclass_iri: Xsd_QName,
|
|
155
155
|
ele: RdfModifyItem,
|
|
156
156
|
last_modified: Xsd_dateTime,
|
|
157
157
|
indent: int = 0, indent_inc: int = 4) -> str:
|
|
@@ -164,8 +164,8 @@ class RdfModifyProp:
|
|
|
164
164
|
def onto(cls, *,
|
|
165
165
|
action: Action,
|
|
166
166
|
graph: Xsd_NCName,
|
|
167
|
-
owlclass_iri:
|
|
168
|
-
pclass_iri:
|
|
167
|
+
owlclass_iri: Xsd_QName | None = None,
|
|
168
|
+
pclass_iri: Xsd_QName,
|
|
169
169
|
ele: RdfModifyItem,
|
|
170
170
|
last_modified: Xsd_dateTime,
|
|
171
171
|
indent: int = 0, indent_inc: int = 4) -> str:
|
|
@@ -177,8 +177,8 @@ class RdfModifyProp:
|
|
|
177
177
|
@classmethod
|
|
178
178
|
def replace_rdfset(cls, *,
|
|
179
179
|
action: Action,
|
|
180
|
-
owlclass_iri:
|
|
181
|
-
pclass_iri:
|
|
180
|
+
owlclass_iri: Xsd_QName | None = None,
|
|
181
|
+
pclass_iri: Xsd_QName,
|
|
182
182
|
graph: Xsd_QName,
|
|
183
183
|
ele: RdfModifyItem,
|
|
184
184
|
last_modified: Xsd_dateTime,
|
oldaplib/src/model.py
CHANGED
|
@@ -46,7 +46,7 @@ class Model:
|
|
|
46
46
|
_contributor: Iri | None
|
|
47
47
|
_modified: Xsd_dateTime | None
|
|
48
48
|
_attributes: dict[Enum, Any]
|
|
49
|
-
_changeset: dict[AttributeClass |
|
|
49
|
+
_changeset: dict[AttributeClass | Xsd_QName, AttributeChange]
|
|
50
50
|
_validate: bool
|
|
51
51
|
|
|
52
52
|
def __init__(self, *,
|
oldaplib/src/objectfactory.py
CHANGED
|
@@ -72,7 +72,7 @@ class ResourceInstance:
|
|
|
72
72
|
:type changeset: dict[Iri, AttributeChange]
|
|
73
73
|
"""
|
|
74
74
|
_iri: Iri
|
|
75
|
-
_values: dict[
|
|
75
|
+
_values: dict[Xsd_QName, LangString | ObservableSet]
|
|
76
76
|
_graph: Xsd_NCName
|
|
77
77
|
_changeset: dict[Iri, AttributeChange]
|
|
78
78
|
|
|
@@ -104,7 +104,7 @@ class ResourceInstance:
|
|
|
104
104
|
self._superclass_objs = {}
|
|
105
105
|
self._changeset = {}
|
|
106
106
|
|
|
107
|
-
def set_values(propclass: dict[
|
|
107
|
+
def set_values(propclass: dict[Xsd_QName, HasProperty]):
|
|
108
108
|
for prop_iri, hasprop in propclass.items():
|
|
109
109
|
if kwargs.get(str(prop_iri)) or kwargs.get(prop_iri.fragment):
|
|
110
110
|
value = kwargs[str(prop_iri)] if kwargs.get(str(prop_iri)) else kwargs[prop_iri.fragment]
|
|
@@ -143,20 +143,20 @@ class ResourceInstance:
|
|
|
143
143
|
else:
|
|
144
144
|
self.validate_value(self._values[prop_iri], hasprop.prop)
|
|
145
145
|
|
|
146
|
-
def process_superclasses(superclass: dict[
|
|
146
|
+
def process_superclasses(superclass: dict[Xsd_QName, ResourceClass]):
|
|
147
147
|
for sc_iri, sc in superclass.items():
|
|
148
148
|
if sc.superclass:
|
|
149
149
|
process_superclasses(sc.superclass)
|
|
150
|
-
if sc.owl_class_iri ==
|
|
150
|
+
if sc.owl_class_iri == Xsd_QName("oldap:Thing", validate=False):
|
|
151
151
|
timestamp = Xsd_dateTimeStamp()
|
|
152
|
-
if not self._values.get(
|
|
153
|
-
self._values[
|
|
154
|
-
if not self._values.get(
|
|
155
|
-
self._values[
|
|
156
|
-
if not self._values.get(
|
|
157
|
-
self._values[
|
|
158
|
-
if not self._values.get(
|
|
159
|
-
self._values[
|
|
152
|
+
if not self._values.get(Xsd_QName('oldap:createdBy', validate=False)):
|
|
153
|
+
self._values[Xsd_QName('oldap:createdBy', validate=False)] = ObservableSet({self._con.userIri})
|
|
154
|
+
if not self._values.get(Xsd_QName('oldap:creationDate', validate=False)):
|
|
155
|
+
self._values[Xsd_QName('oldap:creationDate', validate=False)] = ObservableSet({timestamp})
|
|
156
|
+
if not self._values.get(Xsd_QName('oldap:lastModifiedBy', validate=False)):
|
|
157
|
+
self._values[Xsd_QName('oldap:lastModifiedBy', validate=False)] = ObservableSet({self._con.userIri})
|
|
158
|
+
if not self._values.get(Xsd_QName('oldap:lastModificationDate', validate=False)):
|
|
159
|
+
self._values[Xsd_QName('oldap:lastModificationDate', validate=False)] = ObservableSet({timestamp})
|
|
160
160
|
set_values(sc.properties)
|
|
161
161
|
for iri, prop in sc.properties.items():
|
|
162
162
|
self.properties[iri] = prop
|
|
@@ -289,7 +289,7 @@ class ResourceInstance:
|
|
|
289
289
|
raise OldapErrorInconsistency(
|
|
290
290
|
f'Property {property} with LESS_THAN={property[PropClassAttr.LESS_THAN_OR_EQUALS]} has invalid value: "{max_value}" NOT LESS_THAN "{min_other_value}".')
|
|
291
291
|
|
|
292
|
-
def notifier(self, prop_iri:
|
|
292
|
+
def notifier(self, prop_iri: Xsd_QName):
|
|
293
293
|
hasprop = self.properties[prop_iri]
|
|
294
294
|
self.validate_value(self._values[prop_iri], hasprop)
|
|
295
295
|
|
|
@@ -329,14 +329,14 @@ class ResourceInstance:
|
|
|
329
329
|
return False, f'Actor does not have {permission} in project "{self.project.projectShortName}".'
|
|
330
330
|
|
|
331
331
|
def __get_value(self: Self, prefix: str, fragment: str) -> Xsd | ValueType | None:
|
|
332
|
-
attr =
|
|
332
|
+
attr = Xsd_QName(prefix, fragment, validate=False)
|
|
333
333
|
tmp = self._values.get(attr, None)
|
|
334
334
|
if tmp is not None and str(attr) in {'oldap:createdBy', 'oldap:creationDate', 'oldap:lastModifiedBy', 'oldap:lastModificationDate'}:
|
|
335
335
|
return next(iter(tmp))
|
|
336
336
|
return tmp
|
|
337
337
|
|
|
338
338
|
def __set_value(self: Self, value: ValueType | Xsd | None, prefix: str, fragment: str) -> None:
|
|
339
|
-
prop_iri =
|
|
339
|
+
prop_iri = Xsd_QName(prefix, fragment, validate=False)
|
|
340
340
|
hasprop = self.properties.get(prop_iri)
|
|
341
341
|
|
|
342
342
|
#
|
|
@@ -388,7 +388,7 @@ class ResourceInstance:
|
|
|
388
388
|
self._values[prop_iri] = convert2datatype(value, hasprop.prop.datatype)
|
|
389
389
|
|
|
390
390
|
def __del_value(self: Self, prefix: str, fragment: str) -> None:
|
|
391
|
-
prop_iri =
|
|
391
|
+
prop_iri = Xsd_QName(prefix, fragment, validate=False)
|
|
392
392
|
hasprop = self.properties.get(prop_iri)
|
|
393
393
|
|
|
394
394
|
if hasprop.get(HasPropertyAttr.MIN_COUNT): # testing for MIN_COUNT conformance
|
|
@@ -396,7 +396,7 @@ class ResourceInstance:
|
|
|
396
396
|
raise OldapErrorValue(f'{self.name}: Property {prop_iri} with MIN_COUNT={hasprop[HasPropertyAttr.MIN_COUNT]} cannot be deleted.')
|
|
397
397
|
|
|
398
398
|
self._changeset[prop_iri] = AttributeChange(self._values.get(prop_iri), Action.DELETE)
|
|
399
|
-
attr =
|
|
399
|
+
attr = Xsd_QName(prefix, fragment, validate=False)
|
|
400
400
|
del self._values[attr]
|
|
401
401
|
|
|
402
402
|
@property
|
|
@@ -404,7 +404,7 @@ class ResourceInstance:
|
|
|
404
404
|
return self._iri
|
|
405
405
|
|
|
406
406
|
@property
|
|
407
|
-
def changeset(self) -> dict[
|
|
407
|
+
def changeset(self) -> dict[Xsd_QName, AttributeChange]:
|
|
408
408
|
return self._changeset
|
|
409
409
|
|
|
410
410
|
def clear_changeset(self) -> None:
|
|
@@ -451,10 +451,10 @@ class ResourceInstance:
|
|
|
451
451
|
|
|
452
452
|
timestamp = Xsd_dateTimeStamp()
|
|
453
453
|
if self.name == "Thing":
|
|
454
|
-
self._values[
|
|
455
|
-
self._values[
|
|
456
|
-
self._values[
|
|
457
|
-
self._values[
|
|
454
|
+
self._values[Xsd_QName('oldap:createdBy', validate=False)] = ObservableSet({self._con.userIri})
|
|
455
|
+
self._values[Xsd_QName('oldap:creationDate', validate=False)] = ObservableSet({timestamp})
|
|
456
|
+
self._values[Xsd_QName('oldap:lastModifiedBy', validate=False)] = ObservableSet({self._con.userIri})
|
|
457
|
+
self._values[Xsd_QName('oldap:lastModificationDate', validate=False)] = ObservableSet({timestamp})
|
|
458
458
|
|
|
459
459
|
indent: int = 0
|
|
460
460
|
indent_inc: int = 4
|
oldaplib/src/oldaplist.py
CHANGED
|
@@ -383,7 +383,7 @@ class OldapList(Model):
|
|
|
383
383
|
last_nodeiri = None
|
|
384
384
|
for r in res:
|
|
385
385
|
nodeiri = r['node']
|
|
386
|
-
if last_nodeiri != nodeiri:
|
|
386
|
+
if last_nodeiri is None or last_nodeiri != nodeiri:
|
|
387
387
|
prefix, id = str(nodeiri).split(':')
|
|
388
388
|
ln = OldapListNode(con=self._con,
|
|
389
389
|
**self.info,
|