diff --git a/shapes/annotation.ttl b/shapes/annotation.ttl new file mode 100644 index 0000000..d3958cb --- /dev/null +++ b/shapes/annotation.ttl @@ -0,0 +1,111 @@ +@prefix dc: . +@prefix dct: . +@prefix oa: . +@prefix prov: . +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix vs: . +@prefix xsd: . + +@prefix annotation_shape: . + +annotation_shape:AnnotationShape + a sh:NodeShape ; + sh:targetClass oa:Annotation ; + sh:name "Annotation Shape" ; + sh:description "SHACL shape describing a Web Annotation covering common note, bookmark, comment, and highlight cases." ; + dct:created "2026-04-23"^^xsd:date ; + vs:term_status "testing" ; + dc:source ; + prov:wasDerivedFrom ; + dct:references ; # references the oa:Annotation class from the W3C Web Annotation Vocabulary, which is the expected type of an annotation node, together with the oa:hasBody, oa:hasTarget, oa:bodyValue, and oa:motivatedBy properties used to relate an annotation to its body, target, textual body content, and motivation respectively. + dct:references ; # references the W3C Web Annotation Data Model recommendation which defines the conceptual model used by the Web Annotation Vocabulary. + sh:codeIdentifier "Annotation"; + + # Type: an annotation should be typed as oa:Annotation. + sh:property [ + sh:path rdf:type ; + sh:hasValue oa:Annotation ; + sh:name "Type" ; + sh:description "The RDF type of the annotation, which must include oa:Annotation." ; + sh:codeIdentifier "type"; + ] ; + + # Inline textual body (for simple comment / note cases). + # Per the Web Annotation Data Model (ยง3.2.4), an annotation SHOULD NOT + # have both oa:bodyValue and oa:hasBody. This shape does not enforce + # the exclusion (favouring interoperability) but consumers SHOULD + # populate only one of the two. + sh:property [ + sh:path oa:bodyValue ; + sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "Body Value" ; + sh:description "Textual content of the annotation body, used for plain-text comments or notes (Web Annotation Vocabulary, oa:bodyValue). SHOULD NOT be combined with oa:hasBody on the same annotation." ; + sh:codeIdentifier "bodyValue"; + ] ; + + # External or embedded body resource(s) (for richer body cases). + sh:property [ + sh:path oa:hasBody ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:name "Body" ; + sh:description "A resource that provides the content of the annotation (Web Annotation Vocabulary, oa:hasBody). May be repeated when an annotation has multiple bodies. SHOULD NOT be combined with oa:bodyValue on the same annotation." ; + sh:codeIdentifier "hasBody"; + ] ; + + # Target(s) the annotation is about. Required for an annotation to be meaningful. + sh:property [ + sh:path oa:hasTarget ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:minCount 1 ; + sh:name "Target" ; + sh:description "The resource (or specific resource) that the annotation is about (Web Annotation Vocabulary, oa:hasTarget)." ; + sh:codeIdentifier "hasTarget"; + ] ; + + # Motivation. Left open to the full Web Annotation motivation set so that + # the shape does not reject conforming annotations using motivations + # outside the common note-taking subset (e.g., oa:tagging, oa:replying). + # Apps focused on notes/bookmarks/highlights typically use oa:bookmarking, + # oa:commenting, or oa:highlighting. + sh:property [ + sh:path oa:motivatedBy ; + sh:nodeKind sh:IRI ; + sh:name "Motivation" ; + sh:description "Why the annotation was created (Web Annotation Vocabulary, oa:Motivation). Common note-taking values are oa:bookmarking, oa:commenting, and oa:highlighting." ; + sh:codeIdentifier "motivatedBy"; + ] ; + + # Creator. Permits a WebID IRI or an embedded agent description, matching + # the Web Annotation Data Model which allows the creator to be referenced + # or described inline. Cardinality is left open as the data model permits + # multiple creators (co-creation). + sh:property [ + sh:path dct:creator ; + sh:nodeKind sh:BlankNodeOrIRI ; + sh:name "Creator" ; + sh:description "The agent that created the annotation. Typically a WebID IRI in Solid, but the Web Annotation Data Model also permits an embedded agent description and multiple creators." ; + sh:codeIdentifier "creator"; + ] ; + + # Created date. + sh:property [ + sh:path dct:created ; + sh:datatype xsd:dateTime ; + sh:maxCount 1 ; + sh:name "Created" ; + sh:description "The date and time at which the annotation was created." ; + sh:codeIdentifier "created"; + ] ; + + # Last modified date. + sh:property [ + sh:path dct:modified ; + sh:datatype xsd:dateTime ; + sh:maxCount 1 ; + sh:name "Modified" ; + sh:description "The date and time at which the annotation was last modified." ; + sh:codeIdentifier "modified"; + ] .