oldaplib 0.3.0__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 +30 -4
- 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 +11 -1
- 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.0.dist-info → oldaplib-0.3.2.dist-info}/METADATA +1 -1
- {oldaplib-0.3.0.dist-info → oldaplib-0.3.2.dist-info}/RECORD +30 -30
- {oldaplib-0.3.0.dist-info → oldaplib-0.3.2.dist-info}/WHEEL +0 -0
oldaplib/src/resourceclass.py
CHANGED
|
@@ -39,15 +39,16 @@ from oldaplib.src.model import Model
|
|
|
39
39
|
from oldaplib.src.helpers.attributechange import AttributeChange
|
|
40
40
|
from oldaplib.src.propertyclass import PropertyClass, Attributes, HasPropertyData, PropTypes
|
|
41
41
|
from oldaplib.src.xsd.xsd_nonnegativeinteger import Xsd_nonNegativeInteger
|
|
42
|
+
from oldaplib.src.xsd.xsd_qname import Xsd_QName
|
|
42
43
|
from oldaplib.src.xsd.xsd_string import Xsd_string
|
|
43
44
|
|
|
44
45
|
#
|
|
45
46
|
# Datatype definitions
|
|
46
47
|
#
|
|
47
48
|
RC = TypeVar('RC', bound='ResourceClass')
|
|
48
|
-
AttributeTypes =
|
|
49
|
+
AttributeTypes = Xsd_QName | LangString | Xsd_boolean | ObservableDict | None
|
|
49
50
|
ResourceClassAttributesContainer = Dict[ResClassAttribute, AttributeTypes]
|
|
50
|
-
SuperclassParam = Union[
|
|
51
|
+
SuperclassParam = Union[Xsd_QName, str, list[Union[Xsd_QName, str]], tuple[Union[Xsd_QName, str], ...] , set[Union[Xsd_QName, str]], None]
|
|
51
52
|
AttributeParams = LangString | Xsd_boolean | SuperclassParam
|
|
52
53
|
|
|
53
54
|
|
|
@@ -83,9 +84,9 @@ class ResourceClass(Model, Notify):
|
|
|
83
84
|
_sysproject: Project = None
|
|
84
85
|
_sharedproject: Project = None
|
|
85
86
|
_externalOntology: Xsd_boolean
|
|
86
|
-
_owlclass_iri:
|
|
87
|
+
_owlclass_iri: Xsd_QName | None
|
|
87
88
|
_attributes: ResourceClassAttributesContainer
|
|
88
|
-
_properties: dict[
|
|
89
|
+
_properties: dict[Xsd_QName, HasProperty]
|
|
89
90
|
__version: SemanticVersion
|
|
90
91
|
__from_triplestore: bool
|
|
91
92
|
_test_in_use: bool
|
|
@@ -103,9 +104,9 @@ class ResourceClass(Model, Notify):
|
|
|
103
104
|
:raises OldapErrorNotFound: If the superclass is not found.
|
|
104
105
|
:raises OldapErrorValue: If the superclass is not a valid IRI.
|
|
105
106
|
"""
|
|
106
|
-
scval =
|
|
107
|
+
scval = Xsd_QName(sc, validate=validate)
|
|
107
108
|
sucla = None
|
|
108
|
-
if scval
|
|
109
|
+
if scval:
|
|
109
110
|
match scval.prefix:
|
|
110
111
|
case self._project.projectShortName:
|
|
111
112
|
sucla = ResourceClass.read(self._con, self._project, scval)
|
|
@@ -206,13 +207,13 @@ class ResourceClass(Model, Notify):
|
|
|
206
207
|
"""
|
|
207
208
|
if isinstance(superclass, (list, tuple, set)):
|
|
208
209
|
for sc in superclass:
|
|
209
|
-
scIri =
|
|
210
|
+
scIri = Xsd_QName(sc, validate=validate)
|
|
210
211
|
if scIri not in self._attributes[ResClassAttribute.SUPERCLASS]:
|
|
211
212
|
raise OldapErrorValue(f'Superclass "{scIri}" not found in superclass list')
|
|
212
213
|
del self._attributes[ResClassAttribute.SUPERCLASS][scIri]
|
|
213
214
|
self.notify()
|
|
214
215
|
else:
|
|
215
|
-
superclassIri =
|
|
216
|
+
superclassIri = Xsd_QName(superclass, validate=validate)
|
|
216
217
|
if superclassIri not in self._attributes[ResClassAttribute.SUPERCLASS]:
|
|
217
218
|
raise OldapErrorValue(f'Superclass "{superclass}" not found in superclass list')
|
|
218
219
|
del self._attributes[ResClassAttribute.SUPERCLASS][superclassIri]
|
|
@@ -222,7 +223,7 @@ class ResourceClass(Model, Notify):
|
|
|
222
223
|
def __init__(self, *,
|
|
223
224
|
con: IConnection,
|
|
224
225
|
project: Project | Iri | Xsd_NCName | str,
|
|
225
|
-
owlclass_iri:
|
|
226
|
+
owlclass_iri: Xsd_QName | str | None = None,
|
|
226
227
|
hasproperties: List[HasProperty] | None = None,
|
|
227
228
|
_externalOntology: bool | Xsd_boolean = False,
|
|
228
229
|
notifier: Callable[[PropClassAttr], None] | None = None,
|
|
@@ -291,16 +292,16 @@ class ResourceClass(Model, Notify):
|
|
|
291
292
|
context.use(self._project.projectShortName)
|
|
292
293
|
self._graph = self._project.projectShortName
|
|
293
294
|
|
|
294
|
-
if isinstance(owlclass_iri,
|
|
295
|
+
if isinstance(owlclass_iri, Xsd_QName):
|
|
295
296
|
self._owlclass_iri = owlclass_iri
|
|
296
297
|
elif owlclass_iri is not None:
|
|
297
|
-
self._owlclass_iri =
|
|
298
|
+
self._owlclass_iri = Xsd_QName(owlclass_iri)
|
|
298
299
|
else:
|
|
299
300
|
self._owlclass_iri = None
|
|
300
301
|
new_kwargs: dict[str, Any] = {}
|
|
301
302
|
for name, value in kwargs.items():
|
|
302
303
|
if name == ResClassAttribute.SUPERCLASS.value.fragment:
|
|
303
|
-
if value
|
|
304
|
+
if value:
|
|
304
305
|
new_kwargs[name] = self.assign_superclass(value)
|
|
305
306
|
else:
|
|
306
307
|
new_kwargs[name] = value
|
|
@@ -309,7 +310,7 @@ class ResourceClass(Model, Notify):
|
|
|
309
310
|
# a subclass of "oldap:Thing"! We don't do it for system things with a prefix of "oldap".
|
|
310
311
|
#
|
|
311
312
|
if owlclass_iri.prefix != "oldap":
|
|
312
|
-
thing_iri =
|
|
313
|
+
thing_iri = Xsd_QName('oldap:Thing', validate=False)
|
|
313
314
|
if self._owlclass_iri != thing_iri:
|
|
314
315
|
if not new_kwargs.get(ResClassAttribute.SUPERCLASS.value.fragment):
|
|
315
316
|
new_kwargs[ResClassAttribute.SUPERCLASS.value.fragment] = self.assign_superclass(thing_iri)
|
|
@@ -322,8 +323,8 @@ class ResourceClass(Model, Notify):
|
|
|
322
323
|
self._properties = {}
|
|
323
324
|
if hasproperties is not None:
|
|
324
325
|
for hasprop in hasproperties:
|
|
325
|
-
if isinstance(hasprop.prop,
|
|
326
|
-
fixed_prop =
|
|
326
|
+
if isinstance(hasprop.prop, Xsd_QName): # Reference to an external, standalone property definition
|
|
327
|
+
fixed_prop = Xsd_QName(str(hasprop.prop).removesuffix("Shape"), validate=validate)
|
|
327
328
|
try:
|
|
328
329
|
hasprop.prop = PropertyClass.read(self._con, self._project, fixed_prop)
|
|
329
330
|
except OldapErrorNotFound as err:
|
|
@@ -354,7 +355,7 @@ class ResourceClass(Model, Notify):
|
|
|
354
355
|
self.clear_changeset()
|
|
355
356
|
|
|
356
357
|
def update_notifier(self,
|
|
357
|
-
notifier: Callable[[AttributeClass |
|
|
358
|
+
notifier: Callable[[AttributeClass | Xsd_QName], None] | None = None,
|
|
358
359
|
notify_data: AttributeClass | None = None,):
|
|
359
360
|
"""
|
|
360
361
|
Updates the notifier for the current instance and any nested attributes or
|
|
@@ -387,7 +388,7 @@ class ResourceClass(Model, Notify):
|
|
|
387
388
|
attributes = {}
|
|
388
389
|
for key, value in self._attributes.items():
|
|
389
390
|
if key.fragment == 'superclass':
|
|
390
|
-
attributes[key.fragment] = [x for x in value.keys() if x != 'oldap:Thing']
|
|
391
|
+
attributes[key.fragment] = [x for x in value.keys() if x != Xsd_QName('oldap:Thing')]
|
|
391
392
|
else:
|
|
392
393
|
attributes[key.fragment] = value
|
|
393
394
|
return attributes | super()._as_dict() | {
|
|
@@ -441,8 +442,8 @@ class ResourceClass(Model, Notify):
|
|
|
441
442
|
else:
|
|
442
443
|
return value
|
|
443
444
|
|
|
444
|
-
def _change_setter(self, key: ResClassAttribute |
|
|
445
|
-
if not isinstance(key, (ResClassAttribute,
|
|
445
|
+
def _change_setter(self, key: ResClassAttribute | Xsd_QName, value: AttributeParams | HasProperty) -> None:
|
|
446
|
+
if not isinstance(key, (ResClassAttribute, Xsd_QName)):
|
|
446
447
|
raise ValueError(f'Invalid key type {type(key)} of key {key}')
|
|
447
448
|
if getattr(value, 'set_notifier', None) is not None:
|
|
448
449
|
value.set_notifier(self.notifier, key)
|
|
@@ -460,10 +461,10 @@ class ResourceClass(Model, Notify):
|
|
|
460
461
|
if key == ResClassAttribute.SUPERCLASS: # we can only change the superclass in the instance of ResourceClass if it's not in use
|
|
461
462
|
self._test_in_use = True
|
|
462
463
|
|
|
463
|
-
elif isinstance(key,
|
|
464
|
+
elif isinstance(key, Xsd_QName): # Iri, we add a HasProrty instance
|
|
464
465
|
if self._properties.get(key) is None: # Property not set -> CREATE action
|
|
465
466
|
self._changeset[key] = ResourceClassPropertyChange(None, Action.CREATE, False)
|
|
466
|
-
if isinstance(value.prop,
|
|
467
|
+
if isinstance(value.prop, Xsd_QName): # we just add a reference to an existing (!) standalone property!
|
|
467
468
|
try:
|
|
468
469
|
p = PropertyClass.read(self._con, project=self._project, property_class_iri=value.prop)
|
|
469
470
|
value.prop = p
|
|
@@ -480,7 +481,7 @@ class ResourceClass(Model, Notify):
|
|
|
480
481
|
self._changeset[key] = ResourceClassPropertyChange(self._properties[key], Action.REPLACE, True)
|
|
481
482
|
else:
|
|
482
483
|
self._changeset[key] = ResourceClassPropertyChange(self._changeset[key].old_value, Action.REPLACE, True)
|
|
483
|
-
if isinstance(value.prop,
|
|
484
|
+
if isinstance(value.prop, Xsd_QName):
|
|
484
485
|
try:
|
|
485
486
|
p = PropertyClass.read(self._con, project=self._project, property_class_iri=value.prop)
|
|
486
487
|
value.prop = p
|
|
@@ -539,26 +540,26 @@ class ResourceClass(Model, Notify):
|
|
|
539
540
|
return instance
|
|
540
541
|
|
|
541
542
|
|
|
542
|
-
def __getitem__(self, key: ResClassAttribute |
|
|
543
|
+
def __getitem__(self, key: ResClassAttribute | Xsd_QName) -> AttributeTypes | HasProperty | Xsd_QName:
|
|
543
544
|
if isinstance(key, ResClassAttribute):
|
|
544
545
|
return super().__getitem__(key)
|
|
545
|
-
elif isinstance(key,
|
|
546
|
+
elif isinstance(key, Xsd_QName):
|
|
546
547
|
return self._properties.get(key)
|
|
547
548
|
else:
|
|
548
549
|
return None
|
|
549
550
|
|
|
550
|
-
def get(self, key: ResClassAttribute |
|
|
551
|
+
def get(self, key: ResClassAttribute | Xsd_QName) -> AttributeTypes | HasProperty | Xsd_QName | None:
|
|
551
552
|
if isinstance(key, ResClassAttribute):
|
|
552
553
|
return self._attributes.get(key)
|
|
553
|
-
elif isinstance(key,
|
|
554
|
+
elif isinstance(key, Xsd_QName):
|
|
554
555
|
return self._properties.get(key)
|
|
555
556
|
else:
|
|
556
557
|
return None
|
|
557
558
|
|
|
558
|
-
def __setitem__(self, key: ResClassAttribute |
|
|
559
|
+
def __setitem__(self, key: ResClassAttribute | Xsd_QName, value: AttributeParams | HasProperty) -> None:
|
|
559
560
|
self._change_setter(key, value)
|
|
560
561
|
|
|
561
|
-
def __delitem__(self, key: ResClassAttribute |
|
|
562
|
+
def __delitem__(self, key: ResClassAttribute | Xsd_QName) -> None:
|
|
562
563
|
"""
|
|
563
564
|
Removes the specified key from the ResourceClass instance. The method handles keys of type
|
|
564
565
|
`ResClassAttribute` and `Iri` differently internally. For a `ResClassAttribute`
|
|
@@ -571,11 +572,11 @@ class ResourceClass(Model, Notify):
|
|
|
571
572
|
:type key: ResClassAttribute | Iri
|
|
572
573
|
:raises ValueError: If the key type is not `ResClassAttribute` or `Iri`.
|
|
573
574
|
"""
|
|
574
|
-
if not isinstance(key, (ResClassAttribute,
|
|
575
|
+
if not isinstance(key, (ResClassAttribute, Xsd_QName)):
|
|
575
576
|
raise ValueError(f'Invalid key type {type(key).__name__} of key {key}')
|
|
576
577
|
if isinstance(key, ResClassAttribute):
|
|
577
578
|
super().__delitem__(key)
|
|
578
|
-
elif isinstance(key,
|
|
579
|
+
elif isinstance(key, Xsd_QName):
|
|
579
580
|
if self._changeset.get(key) is None:
|
|
580
581
|
self._changeset[key] = ResourceClassPropertyChange(self._properties[key], Action.DELETE, False)
|
|
581
582
|
else:
|
|
@@ -584,13 +585,13 @@ class ResourceClass(Model, Notify):
|
|
|
584
585
|
self._test_in_use = True
|
|
585
586
|
self.notify()
|
|
586
587
|
|
|
587
|
-
def __delattr__(self, item: str):
|
|
588
|
+
def __delattr__(self, item: str | Xsd_QName):
|
|
588
589
|
try:
|
|
589
590
|
attr = ResClassAttribute.from_name(item)
|
|
590
591
|
super().__delitem__(attr)
|
|
591
592
|
except ValueError as err:
|
|
592
593
|
try:
|
|
593
|
-
iri =
|
|
594
|
+
iri = Xsd_QName(item, validate=True)
|
|
594
595
|
if self._changeset.get(iri) is None:
|
|
595
596
|
self._changeset[iri] = ResourceClassPropertyChange(self._properties[iri], Action.DELETE, False)
|
|
596
597
|
else:
|
|
@@ -602,7 +603,7 @@ class ResourceClass(Model, Notify):
|
|
|
602
603
|
self.notify()
|
|
603
604
|
|
|
604
605
|
@property
|
|
605
|
-
def owl_class_iri(self) ->
|
|
606
|
+
def owl_class_iri(self) -> Xsd_QName:
|
|
606
607
|
return self._owlclass_iri
|
|
607
608
|
|
|
608
609
|
@property
|
|
@@ -614,7 +615,7 @@ class ResourceClass(Model, Notify):
|
|
|
614
615
|
return self._externalOntology
|
|
615
616
|
|
|
616
617
|
@property
|
|
617
|
-
def properties(self) -> dict[
|
|
618
|
+
def properties(self) -> dict[Xsd_QName, HasProperty]:
|
|
618
619
|
return self._properties
|
|
619
620
|
|
|
620
621
|
@property
|
|
@@ -641,14 +642,14 @@ class ResourceClass(Model, Notify):
|
|
|
641
642
|
def changeset_clear(self) -> None:
|
|
642
643
|
super().clear_changeset()
|
|
643
644
|
|
|
644
|
-
def notifier(self, what: ResClassAttribute |
|
|
645
|
+
def notifier(self, what: ResClassAttribute | Xsd_QName):
|
|
645
646
|
if isinstance(what, ResClassAttribute):
|
|
646
647
|
self._changeset[what] = AttributeChange(None, Action.MODIFY)
|
|
647
|
-
elif isinstance(what,
|
|
648
|
+
elif isinstance(what, Xsd_QName):
|
|
648
649
|
self._changeset[what] = ResourceClassPropertyChange(None, Action.MODIFY, True)
|
|
649
650
|
self.notify()
|
|
650
651
|
|
|
651
|
-
def __sc_changed(self, oldval: ObservableDict[
|
|
652
|
+
def __sc_changed(self, oldval: ObservableDict[Xsd_QName, RC]):
|
|
652
653
|
if self._changeset.get(ResClassAttribute.SUPERCLASS) is None:
|
|
653
654
|
self._changeset[ResClassAttribute.SUPERCLASS] = AttributeChange(oldval, Action.MODIFY)
|
|
654
655
|
|
|
@@ -681,7 +682,7 @@ class ResourceClass(Model, Notify):
|
|
|
681
682
|
@staticmethod
|
|
682
683
|
def __query_shacl(con: IConnection,
|
|
683
684
|
project: Project,
|
|
684
|
-
owl_class_iri:
|
|
685
|
+
owl_class_iri: Xsd_QName) -> Attributes:
|
|
685
686
|
"""
|
|
686
687
|
Executes a SPARQL query to retrieve the attributes of a given OWL class from a SHACL
|
|
687
688
|
graph using the provided connection and project context. This function processes the
|
|
@@ -734,7 +735,7 @@ class ResourceClass(Model, Notify):
|
|
|
734
735
|
continue # processes later – points to a BNode containing the property definition or to a PropertyShape...
|
|
735
736
|
else:
|
|
736
737
|
attriri = r['attriri']
|
|
737
|
-
if isinstance(r['value'],
|
|
738
|
+
if isinstance(r['value'], Xsd_QName):
|
|
738
739
|
if attributes.get(attriri) is None:
|
|
739
740
|
attributes[attriri] = []
|
|
740
741
|
attributes[attriri].append(r['value'])
|
|
@@ -776,7 +777,7 @@ class ResourceClass(Model, Notify):
|
|
|
776
777
|
self._attributes[ResClassAttribute.SUPERCLASS] = ObservableDict(on_change=self.__sc_changed)
|
|
777
778
|
for v in val:
|
|
778
779
|
if str(v).endswith("Shape"):
|
|
779
|
-
owliri =
|
|
780
|
+
owliri = Xsd_QName(str(v)[:-5], validate=False)
|
|
780
781
|
if owliri.prefix == 'oldap':
|
|
781
782
|
conf = GlobalConfig(self._con)
|
|
782
783
|
sysproj = conf.sysproject
|
|
@@ -801,8 +802,8 @@ class ResourceClass(Model, Notify):
|
|
|
801
802
|
@staticmethod
|
|
802
803
|
def __query_resource_props(con: IConnection,
|
|
803
804
|
project: Project,
|
|
804
|
-
owlclass_iri:
|
|
805
|
-
sa_props: dict[
|
|
805
|
+
owlclass_iri: Xsd_QName,
|
|
806
|
+
sa_props: dict[Xsd_QName, PropertyClass] | None = None) -> List[HasProperty | Xsd_QName]:
|
|
806
807
|
"""
|
|
807
808
|
This method queries and returns a list of properties defined in a sh:NodeShape. The properties may be
|
|
808
809
|
given "inline" as BNode or may be a reference to an external sh:PropertyShape. These external shapes will be
|
|
@@ -870,25 +871,13 @@ class ResourceClass(Model, Notify):
|
|
|
870
871
|
"""
|
|
871
872
|
jsonobj = con.query(query)
|
|
872
873
|
res = QueryProcessor(context=context, query_result=jsonobj)
|
|
873
|
-
propinfos: Dict[
|
|
874
|
+
propinfos: Dict[Xsd_QName | BNode, Attributes] = {}
|
|
874
875
|
#
|
|
875
876
|
# first we run over all triples to gather the information about the properties of the possible
|
|
876
877
|
# BNode based sh:property-Shapes.
|
|
877
878
|
# NOTE: some of the nodes may actually be QNames referencing shapes defines as "standalone" sh:PropertyShape's.
|
|
878
879
|
#
|
|
879
880
|
for r in res:
|
|
880
|
-
if isinstance(r['prop'], Iri):
|
|
881
|
-
# we have a reference to a property shape of a standalone property: we read it
|
|
882
|
-
# and add it to the list of standalone properties if it does not exist yet
|
|
883
|
-
if str(r['prop']).endswith("Shape"):
|
|
884
|
-
refprop = Iri(str(r['prop'])[:-5], validate=False)
|
|
885
|
-
if not sa_props:
|
|
886
|
-
sa_props: dict[Iri, PropertyClass] = {}
|
|
887
|
-
if not refprop in sa_props:
|
|
888
|
-
sa_props[refprop] = PropertyClass.read(con=con, project=project, property_class_iri=refprop)
|
|
889
|
-
sa_props[refprop]._externalOntology = Xsd_boolean(True)
|
|
890
|
-
else:
|
|
891
|
-
raise OldapErrorInconsistency(f'Value "{r['prop']}" must end with "Shape".')
|
|
892
881
|
if isinstance(r['prop'], BNode):
|
|
893
882
|
# it's a blank node containing the property information
|
|
894
883
|
# if it's a new BNode, let's add the property attributes for this new property defintion
|
|
@@ -896,10 +885,23 @@ class ResourceClass(Model, Notify):
|
|
|
896
885
|
continue # TODO: get rid of the triple "BNODE sh:path sh:type !!!
|
|
897
886
|
if r['prop'] not in propinfos:
|
|
898
887
|
propinfos[r['prop']]: Attributes = {}
|
|
899
|
-
if r.get('attriri') and not isinstance(r['attriri'],
|
|
888
|
+
if r.get('attriri') and not isinstance(r['attriri'], Xsd_QName):
|
|
900
889
|
raise OldapError(f"There is some inconsistency in this shape! ({r['attriri']})")
|
|
901
890
|
# now let's process the triples of the property (blank) node
|
|
902
891
|
PropertyClass.process_triple(r, propinfos[r['prop']])
|
|
892
|
+
continue
|
|
893
|
+
if isinstance(r['prop'], Xsd_QName):
|
|
894
|
+
# we have a reference to a property shape of a standalone property: we read it
|
|
895
|
+
# and add it to the list of standalone properties if it does not exist yet
|
|
896
|
+
if str(r['prop']).endswith("Shape"):
|
|
897
|
+
refprop = Xsd_QName(str(r['prop'])[:-5], validate=False)
|
|
898
|
+
if not sa_props:
|
|
899
|
+
sa_props: dict[Xsd_QName, PropertyClass] = {}
|
|
900
|
+
if not refprop in sa_props:
|
|
901
|
+
sa_props[refprop] = PropertyClass.read(con=con, project=project, property_class_iri=refprop)
|
|
902
|
+
sa_props[refprop]._externalOntology = Xsd_boolean(True)
|
|
903
|
+
else:
|
|
904
|
+
raise OldapErrorInconsistency(f'Value "{r['prop']}" must end with "Shape".')
|
|
903
905
|
|
|
904
906
|
propinfos2 = {v["sh:path"]: v for v in propinfos.values() if "sh:path" in v}
|
|
905
907
|
|
|
@@ -916,10 +918,10 @@ class ResourceClass(Model, Notify):
|
|
|
916
918
|
proplist.append(HasProperty(con=con,
|
|
917
919
|
project=project,
|
|
918
920
|
prop=sa_props[prop_iri],
|
|
919
|
-
minCount=attributes.get(
|
|
920
|
-
maxCount=attributes.get(
|
|
921
|
-
order=attributes.get(
|
|
922
|
-
group=attributes.get(
|
|
921
|
+
minCount=attributes.get(Xsd_QName('sh:minCount')),
|
|
922
|
+
maxCount=attributes.get(Xsd_QName('sh:maxCount')),
|
|
923
|
+
order=attributes.get(Xsd_QName('sh:order')),
|
|
924
|
+
group=attributes.get(Xsd_QName('sh:group'))))
|
|
923
925
|
else:
|
|
924
926
|
prop = PropertyClass(con=con, project=project)
|
|
925
927
|
haspropdata = prop.parse_shacl(attributes=attributes)
|
|
@@ -1021,8 +1023,8 @@ class ResourceClass(Model, Notify):
|
|
|
1021
1023
|
def read(cls,
|
|
1022
1024
|
con: IConnection,
|
|
1023
1025
|
project: Project | Iri | Xsd_NCName | str,
|
|
1024
|
-
owl_class_iri:
|
|
1025
|
-
sa_props: dict[
|
|
1026
|
+
owl_class_iri: Xsd_QName | str,
|
|
1027
|
+
sa_props: dict[Xsd_QName, PropertyClass] | None = None,
|
|
1026
1028
|
ignore_cache: bool = False) -> Self:
|
|
1027
1029
|
"""
|
|
1028
1030
|
Reads and retrieves a class instance from the data source based on the provided
|
|
@@ -1059,8 +1061,8 @@ class ResourceClass(Model, Notify):
|
|
|
1059
1061
|
if not isinstance(project, (Iri, Xsd_NCName)):
|
|
1060
1062
|
project = IriOrNCName(project, validate=True)
|
|
1061
1063
|
project = Project.read(con, project)
|
|
1062
|
-
if not isinstance(owl_class_iri,
|
|
1063
|
-
owl_class_iri =
|
|
1064
|
+
if not isinstance(owl_class_iri, Xsd_QName):
|
|
1065
|
+
owl_class_iri = Xsd_QName(owl_class_iri, validate=True)
|
|
1064
1066
|
|
|
1065
1067
|
cache = CacheSingletonRedis()
|
|
1066
1068
|
if not ignore_cache:
|
|
@@ -1069,7 +1071,7 @@ class ResourceClass(Model, Notify):
|
|
|
1069
1071
|
tmp.update_notifier()
|
|
1070
1072
|
return tmp
|
|
1071
1073
|
|
|
1072
|
-
hasproperties: list[HasProperty |
|
|
1074
|
+
hasproperties: list[HasProperty | Xsd_QName] = ResourceClass.__query_resource_props(con=con,
|
|
1073
1075
|
project=project,
|
|
1074
1076
|
owlclass_iri=owl_class_iri,
|
|
1075
1077
|
sa_props=sa_props)
|
|
@@ -1195,10 +1197,10 @@ class ResourceClass(Model, Notify):
|
|
|
1195
1197
|
sparql += f'{blank:{(indent + 3) * indent_inc}}rdfs:comment {self._attributes[ResClassAttribute.COMMENT].toRdf} ;\n'
|
|
1196
1198
|
if self._attributes.get(ResClassAttribute.SUPERCLASS) is not None:
|
|
1197
1199
|
sc = {x.toRdf for x in self._attributes[ResClassAttribute.SUPERCLASS].keys()}
|
|
1198
|
-
if
|
|
1199
|
-
sc.add(
|
|
1200
|
+
if Xsd_QName('oldap:Thing', validate=False).toRdf not in sc:
|
|
1201
|
+
sc.add(Xsd_QName('oldap:Thing', validate=False).toRdf)
|
|
1200
1202
|
else:
|
|
1201
|
-
sc = {
|
|
1203
|
+
sc = {Xsd_QName('oldap:Thing', validate=False).toRdf}
|
|
1202
1204
|
valstr = ", ".join(sc)
|
|
1203
1205
|
sparql += f'{blank:{(indent + 3)*indent_inc}}rdfs:subClassOf {valstr}'
|
|
1204
1206
|
i = 0
|
|
@@ -1206,7 +1208,7 @@ class ResourceClass(Model, Notify):
|
|
|
1206
1208
|
if not (hp.minCount or hp.maxCount or self._attributes.get(PropClassAttr.DATATYPE) or self._attributes.get(PropClassAttr.CLASS)):
|
|
1207
1209
|
continue
|
|
1208
1210
|
sparql += ' ,\n'
|
|
1209
|
-
if isinstance(hp.prop,
|
|
1211
|
+
if isinstance(hp.prop, Xsd_QName):
|
|
1210
1212
|
sparql += f'{blank:{(indent + 3) * indent_inc}}[\n'
|
|
1211
1213
|
sparql += f'{blank:{(indent + 4) * indent_inc}}rdf:type owl:Restriction ;\n'
|
|
1212
1214
|
sparql += f'{blank:{(indent + 4) * indent_inc}}owl:onProperty {hp.prop.toRdf}'
|
|
@@ -1331,7 +1333,7 @@ class ResourceClass(Model, Notify):
|
|
|
1331
1333
|
f.write(f'{blank:{indent * indent_inc}}}}\n')
|
|
1332
1334
|
|
|
1333
1335
|
def __add_new_property_ref_shacl(self, *,
|
|
1334
|
-
iri:
|
|
1336
|
+
iri: Xsd_QName,
|
|
1335
1337
|
hasprop: HasProperty | None = None,
|
|
1336
1338
|
indent: int = 0, indent_inc: int = 4) -> str:
|
|
1337
1339
|
blank = ''
|
|
@@ -1346,8 +1348,8 @@ class ResourceClass(Model, Notify):
|
|
|
1346
1348
|
return sparql
|
|
1347
1349
|
|
|
1348
1350
|
def __delete_property_ref_shacl(self,
|
|
1349
|
-
owlclass_iri:
|
|
1350
|
-
propclass_iri:
|
|
1351
|
+
owlclass_iri: Xsd_QName,
|
|
1352
|
+
propclass_iri: Xsd_QName,
|
|
1351
1353
|
indent: int = 0,
|
|
1352
1354
|
indent_inc: int = 4) -> str:
|
|
1353
1355
|
blank = ''
|
|
@@ -1369,8 +1371,8 @@ class ResourceClass(Model, Notify):
|
|
|
1369
1371
|
return sparql
|
|
1370
1372
|
|
|
1371
1373
|
def __delete_property_ref_onto(self,
|
|
1372
|
-
owlclass_iri:
|
|
1373
|
-
propclass_iri:
|
|
1374
|
+
owlclass_iri: Xsd_QName,
|
|
1375
|
+
propclass_iri: Xsd_QName,
|
|
1374
1376
|
indent: int = 0,
|
|
1375
1377
|
indent_inc: int = 4) -> str:
|
|
1376
1378
|
blank = ''
|
|
@@ -1401,7 +1403,7 @@ class ResourceClass(Model, Notify):
|
|
|
1401
1403
|
# we loop over all items in the changeset of the resource
|
|
1402
1404
|
#
|
|
1403
1405
|
for item, change in self._changeset.items():
|
|
1404
|
-
item: Union[
|
|
1406
|
+
item: Union[Xsd_QName, HasProperty]
|
|
1405
1407
|
if isinstance(item, ResClassAttribute): # we have just an attribute or ResourceClass
|
|
1406
1408
|
#
|
|
1407
1409
|
# Do the changes to the ResourceClass attributes
|
|
@@ -1451,7 +1453,7 @@ class ResourceClass(Model, Notify):
|
|
|
1451
1453
|
last_modified=self._modified)
|
|
1452
1454
|
if sparql:
|
|
1453
1455
|
sparql_list.append(sparql)
|
|
1454
|
-
elif isinstance(item,
|
|
1456
|
+
elif isinstance(item, Xsd_QName): # noinspection PyUnreachableCode
|
|
1455
1457
|
#
|
|
1456
1458
|
# Something affected the self._properties
|
|
1457
1459
|
#
|
|
@@ -1462,7 +1464,7 @@ class ResourceClass(Model, Notify):
|
|
|
1462
1464
|
# We add a new HasPropertyClass instance with attached PropertyClass or reference
|
|
1463
1465
|
#
|
|
1464
1466
|
sparql: str | None = None
|
|
1465
|
-
if isinstance(self._properties[propiri].prop,
|
|
1467
|
+
if isinstance(self._properties[propiri].prop, Xsd_QName):
|
|
1466
1468
|
# -> reference to an external, foreign property!
|
|
1467
1469
|
sparql = self.__add_new_property_ref_shacl(iri=self._properties[propiri].prop,
|
|
1468
1470
|
hasprop=self._properties[propiri])
|
|
@@ -1534,7 +1536,7 @@ class ResourceClass(Model, Notify):
|
|
|
1534
1536
|
# now update the attached props
|
|
1535
1537
|
#
|
|
1536
1538
|
for key, value in self._properties[item].changeset.items():
|
|
1537
|
-
if isinstance(key,
|
|
1539
|
+
if isinstance(key, Xsd_QName):
|
|
1538
1540
|
#
|
|
1539
1541
|
# the attached PropertyClass instance has changed
|
|
1540
1542
|
#
|
|
@@ -1571,14 +1573,14 @@ class ResourceClass(Model, Notify):
|
|
|
1571
1573
|
return sparql
|
|
1572
1574
|
|
|
1573
1575
|
def __add_new_property_ref_onto(self, *,
|
|
1574
|
-
prop: PropertyClass |
|
|
1576
|
+
prop: PropertyClass | Xsd_QName,
|
|
1575
1577
|
hasprop: HasProperty | None,
|
|
1576
1578
|
indent: int = 0, indent_inc: int = 4) -> str:
|
|
1577
1579
|
blank = ''
|
|
1578
1580
|
sparql = f'INSERT DATA {{#E\n'
|
|
1579
1581
|
sparql += f' GRAPH {self._graph}:onto {{\n'
|
|
1580
1582
|
sparql += f'{blank:{indent * indent_inc}}{self._owlclass_iri} rdfs:subClassOf [\n'
|
|
1581
|
-
if isinstance(prop,
|
|
1583
|
+
if isinstance(prop, Xsd_QName):
|
|
1582
1584
|
sparql += prop.create_owl_part2(haspropdata=hasprop.haspropdata)
|
|
1583
1585
|
elif isinstance(prop, PropertyClass):
|
|
1584
1586
|
sparql += f'{blank:{(indent + 1) * indent_inc}}rdf:type owl:Restriction ;\n'
|
|
@@ -1592,8 +1594,8 @@ class ResourceClass(Model, Notify):
|
|
|
1592
1594
|
return sparql
|
|
1593
1595
|
|
|
1594
1596
|
def __delete_property_ref_owl(self,
|
|
1595
|
-
owlclass_iri:
|
|
1596
|
-
propclass_iri:
|
|
1597
|
+
owlclass_iri: Xsd_QName,
|
|
1598
|
+
propclass_iri: Xsd_QName,
|
|
1597
1599
|
indent: int = 0,
|
|
1598
1600
|
indent_inc: int = 4):
|
|
1599
1601
|
blank = ''
|
|
@@ -1624,7 +1626,7 @@ class ResourceClass(Model, Notify):
|
|
|
1624
1626
|
# we loop over all items in the changeset of the resource
|
|
1625
1627
|
#
|
|
1626
1628
|
for item, change in self._changeset.items():
|
|
1627
|
-
item: Union[ResClassAttribute,
|
|
1629
|
+
item: Union[ResClassAttribute, Xsd_QName]
|
|
1628
1630
|
if isinstance(item, ResClassAttribute): # we have just an attribute or ResourceClass
|
|
1629
1631
|
#
|
|
1630
1632
|
# Do the changes to the ResourceClass attributes
|
|
@@ -1681,7 +1683,7 @@ class ResourceClass(Model, Notify):
|
|
|
1681
1683
|
sparql += f'{blank:{indent * indent_inc}}}}'
|
|
1682
1684
|
sparql_list.append(sparql)
|
|
1683
1685
|
|
|
1684
|
-
elif isinstance(item,
|
|
1686
|
+
elif isinstance(item, Xsd_QName): # Something affected the self._properties
|
|
1685
1687
|
#
|
|
1686
1688
|
# Something affected the self._properties
|
|
1687
1689
|
#
|
|
@@ -1691,7 +1693,7 @@ class ResourceClass(Model, Notify):
|
|
|
1691
1693
|
#
|
|
1692
1694
|
# We add a new HasPropertyClass instance with attached PropertyClass or reference
|
|
1693
1695
|
#
|
|
1694
|
-
if isinstance(self._properties[propiri].prop,
|
|
1696
|
+
if isinstance(self._properties[propiri].prop, Xsd_QName):
|
|
1695
1697
|
# -> reference to an external, foreign property! prop is Iri!
|
|
1696
1698
|
sparql = self.__add_new_property_ref_onto(prop=self._properties[propiri].prop, # is an Iri
|
|
1697
1699
|
hasprop=self._properties[propiri])
|
|
@@ -1750,7 +1752,7 @@ class ResourceClass(Model, Notify):
|
|
|
1750
1752
|
#
|
|
1751
1753
|
sparql = self._properties[propiri].update_owl(self._graph, self._owlclass_iri, propiri)
|
|
1752
1754
|
sparql_list.append(sparql)
|
|
1753
|
-
elif isinstance(key,
|
|
1755
|
+
elif isinstance(key, Xsd_QName):
|
|
1754
1756
|
sparql = self._properties[propiri].prop.update_owl(owlclass_iri=self._owlclass_iri,
|
|
1755
1757
|
timestamp=timestamp)
|
|
1756
1758
|
sparql_list.append(sparql)
|
oldaplib/src/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.3.
|
|
1
|
+
__version__ = "0.3.2"
|
oldaplib/src/xsd/xsd_qname.py
CHANGED
|
@@ -197,3 +197,24 @@ class Xsd_QName(Xsd):
|
|
|
197
197
|
"""
|
|
198
198
|
parts = self._value.split(':')
|
|
199
199
|
return parts[1]
|
|
200
|
+
|
|
201
|
+
@property
|
|
202
|
+
def is_qname(self) -> bool:
|
|
203
|
+
"""
|
|
204
|
+
Checks if the Iri is an Iri QName
|
|
205
|
+
:return: True if the Iri is an Iri QName, False otherwise
|
|
206
|
+
:rtype: bool
|
|
207
|
+
"""
|
|
208
|
+
return True
|
|
209
|
+
|
|
210
|
+
@property
|
|
211
|
+
def as_qname(self) -> Self:
|
|
212
|
+
"""
|
|
213
|
+
Return the Iri as a QName instance
|
|
214
|
+
:return: QName instance, or None if the Iri is represented as QName
|
|
215
|
+
:rtype: Xsd_QName | None
|
|
216
|
+
"""
|
|
217
|
+
return self
|
|
218
|
+
|
|
219
|
+
if __name__ == "__main__":
|
|
220
|
+
q = Xsd_QName({})
|