From d2e27205457a9d94e07c29cfa67f0ec23ad3d75b Mon Sep 17 00:00:00 2001 From: Alex Nelson Date: Fri, 14 Jun 2024 11:59:55 -0400 Subject: [PATCH] Add Non/InformationResource and UUID rule exception A follow-on patch will regenerate Make-managed files. References: * https://github.com/ucoProject/UCO/issues/606 Signed-off-by: Alex Nelson --- ontology/uco/core/core.ttl | 34 +++++++++++++ ontology/uco/identity/identity.ttl | 5 +- ontology/uco/observable/observable.ttl | 21 +++++++- tests/examples/Makefile | 2 + tests/examples/information_resource_PASS.json | 50 +++++++++++++++++++ tests/examples/test_validation.py | 10 ++++ 6 files changed, 119 insertions(+), 3 deletions(-) create mode 100644 tests/examples/information_resource_PASS.json diff --git a/ontology/uco/core/core.ttl b/ontology/uco/core/core.ttl index e4bf1777..df437303 100644 --- a/ontology/uco/core/core.ttl +++ b/ontology/uco/core/core.ttl @@ -284,6 +284,27 @@ core:IdentityAbstraction sh:targetClass core:IdentityAbstraction ; . +core:InformationResource + a + owl:Class , + sh:NodeShape + ; + rdfs:subClassOf core:UcoThing ; + owl:disjointWith core:NonInformationResource ; + sh:targetClass core:InformationResource ; + . + +core:InformationResource-disjointWith-NonInformationResource-shape + a sh:NodeShape ; + sh:message "core:InformationResource and core:NonInformationResource are disjoint classes. Assigning both types to a single node will be an error as of UCO 2.0.0."@en ; + sh:not [ + a sh:NodeShape ; + sh:class core:NonInformationResource ; + ] ; + sh:severity sh:Warning ; + sh:targetClass core:InformationResource ; + . + core:Item a owl:Class , @@ -317,6 +338,15 @@ core:ModusOperandi sh:targetClass core:ModusOperandi ; . +core:NonInformationResource + a + owl:Class , + sh:NodeShape + ; + rdfs:subClassOf core:UcoThing ; + sh:targetClass core:NonInformationResource ; + . + core:Relationship a owl:Class , @@ -485,6 +515,7 @@ core:UcoThing-identifier-regex-shape a sh:NodeShape ; rdfs:comment "This shape is given an independent IRI for applications that have sufficient controls in place to deactivate this advisory of node identification practice."@en ; rdfs:seeAlso sh:deactivated ; + sh:description "This shape advises that nodes identify themselves with IRIs that are sufficiently unique that collisions between independent node assigners are unlikely. This shape excepts nodes that are explicitly typed as Information Resources."@en ; sh:severity sh:Info ; sh:sparql [ a sh:SPARQLConstraint ; @@ -496,6 +527,9 @@ core:UcoThing-identifier-regex-shape SELECT $this WHERE { $this a/rdfs:subClassOf* core:UcoThing . + FILTER NOT EXISTS { + $this a/rdfs:subClassOf* core:InformationResource . + } FILTER ( ! REGEX ( STR($this), diff --git a/ontology/uco/identity/identity.ttl b/ontology/uco/identity/identity.ttl index 93c20b6f..edaccf9f 100644 --- a/ontology/uco/identity/identity.ttl +++ b/ontology/uco/identity/identity.ttl @@ -105,7 +105,10 @@ identity:Identity owl:Class , sh:NodeShape ; - rdfs:subClassOf core:IdentityAbstraction ; + rdfs:subClassOf + core:IdentityAbstraction , + core:NonInformationResource + ; rdfs:label "Identity"@en ; rdfs:comment "An identity is a grouping of identifying characteristics unique to an individual or organization."@en ; sh:targetClass identity:Identity ; diff --git a/ontology/uco/observable/observable.ttl b/ontology/uco/observable/observable.ttl index 37dc84be..e9a93ff7 100644 --- a/ontology/uco/observable/observable.ttl +++ b/ontology/uco/observable/observable.ttl @@ -2221,7 +2221,10 @@ observable:Device owl:Class , sh:NodeShape ; - rdfs:subClassOf observable:ObservableObject ; + rdfs:subClassOf + core:NonInformationResource , + observable:ObservableObject + ; rdfs:label "Device"@en ; rdfs:comment "A device is a piece of equipment or a mechanism designed to serve a special purpose or perform a special function. [based on https://www.merriam-webster.com/dictionary/device]"@en ; sh:targetClass observable:Device ; @@ -7359,12 +7362,26 @@ observable:WebPage owl:Class , sh:NodeShape ; - rdfs:subClassOf observable:ObservableObject ; + rdfs:subClassOf + core:InformationResource , + observable:WebResource + ; rdfs:label "WebPage"@en ; rdfs:comment "A web page is a specific collection of information provided by a website and displayed to a user in a web browser. A website typically consists of many web pages linked together in a coherent fashion. [based on https://en.wikipedia.org/wiki/Web_page]"@en ; sh:targetClass observable:WebPage ; . +observable:WebResource + a + owl:Class , + sh:NodeShape + ; + rdfs:subClassOf observable:ObservableObject ; + rdfs:label "WebResource"@en ; + rdfs:seeAlso ; + sh:targetClass observable:WebResource ; + . + observable:WhoIs a owl:Class , diff --git a/tests/examples/Makefile b/tests/examples/Makefile index 7921bb00..48be8ca5 100644 --- a/tests/examples/Makefile +++ b/tests/examples/Makefile @@ -35,6 +35,7 @@ all: \ has_facet_inverse_functional_XFAIL_validation.ttl \ hash_PASS_validation.ttl \ hash_XFAIL_validation.ttl \ + information_resource_PASS_validation.ttl \ location_PASS_validation.ttl \ location_XFAIL_validation.ttl \ message_thread_PASS_validation.ttl \ @@ -108,6 +109,7 @@ check: \ has_facet_inverse_functional_XFAIL_validation.ttl \ hash_PASS_validation.ttl \ hash_XFAIL_validation.ttl \ + information_resource_PASS_validation.ttl \ location_PASS_validation.ttl \ location_XFAIL_validation.ttl \ message_thread_PASS_validation.ttl \ diff --git a/tests/examples/information_resource_PASS.json b/tests/examples/information_resource_PASS.json new file mode 100644 index 00000000..bd977352 --- /dev/null +++ b/tests/examples/information_resource_PASS.json @@ -0,0 +1,50 @@ +{ + "@context": { + "core": "https://ontology.unifiedcyberontology.org/uco/core/", + "kb": "http://example.org/kb/", + "identity": "https://ontology.unifiedcyberontology.org/uco/identity/", + "observable": "https://ontology.unifiedcyberontology.org/uco/observable/", + "rdfs": "http://www.w3.org/2000/01/rdf-schema#" + }, + "@graph": [ + { + "@id": "http://example.org/~bob", + "@type": [ + "identity:Person", + "observable:WebPage" + ], + "core:name": "Bob", + "core:description": "Bob's company home page.", + "rdfs:comment": "This node will trigger a warning from conflating a node as both a person and the person's home page.", + "rdfs:seeAlso": [ + { + "@id": "kb:Person-a3d3af3d-ea1d-47f6-bc02-ac334ded6549" + }, + { + "@id": "kb:WebPage-1c05c378-124e-4d3c-898a-fb5a8d178cf8" + } + ] + }, + { + "@id": "kb:Person-a3d3af3d-ea1d-47f6-bc02-ac334ded6549", + "@type": "identity:Person", + "core:name": "Bob", + "rdfs:seeAlso": { + "@id": "http://example.org/~bob" + } + }, + { + "@id": "kb:WebPage-1c05c378-124e-4d3c-898a-fb5a8d178cf8", + "@type": "observable:WebPage", + "core:description": "Bob's company home page.", + "rdfs:seeAlso": { + "@id": "http://example.org/~bob" + } + }, + { + "@id": "http://example.org/~chris", + "@type": "observable:WebResource", + "rdfs:comment": "This node will trigger an info-level result from not designating itself a InformationResource, and not ending with a UUID." + } + ] +} diff --git a/tests/examples/test_validation.py b/tests/examples/test_validation.py index d4f39e6a..71ad8a00 100644 --- a/tests/examples/test_validation.py +++ b/tests/examples/test_validation.py @@ -275,6 +275,16 @@ def test_hash_XFAIL() -> None: } ) +def test_information_resource_PASS_validation() -> None: + confirm_validation_results( + "information_resource_PASS_validation.ttl", + True, + expected_focus_node_severities={ + ("http://example.org/~bob", str(NS_SH.Warning)), + ("http://example.org/~chris", str(NS_SH.Info)), + } + ) + def test_co_PASS_validation() -> None: confirm_validation_results("co_PASS_validation.ttl", True)