Coverage for oc_ocdm / graph / entities / bibliographic / reference_annotation.py: 100%
23 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-07-06 20:05 +0000
« prev ^ index » next coverage.py v7.13.4, created at 2026-07-06 20:05 +0000
1#!/usr/bin/python
3# SPDX-FileCopyrightText: 2020-2022 Simone Persiani <iosonopersia@gmail.com>
4#
5# SPDX-License-Identifier: ISC
7# -*- coding: utf-8 -*-
8from __future__ import annotations
10from typing import TYPE_CHECKING
12from triplelite import RDFTerm
14from oc_ocdm.decorators import accepts_only
16if TYPE_CHECKING:
17 from typing import Optional
19 from oc_ocdm.graph.entities.bibliographic.citation import Citation
20from oc_ocdm.graph.entities.bibliographic_entity import BibliographicEntity
21from oc_ocdm.graph.graph_entity import GraphEntity
24class ReferenceAnnotation(BibliographicEntity):
25 """Reference annotation (short: an): an annotation, attached either to an in-text
26 reference pointer or to a bibliographic reference, describing the related citation. If an
27 in-text reference pointer is annotated, the related citation may be characterized with a
28 citation function (the reason for that citation) specific to the textual location of that
29 in-text reference pointer within the citing entity. If a bibliographic reference is
30 annotated, the related citation may be similarly characterized in a more general way
31 with a citation function (the reason for that citation)."""
33 def _merge_properties(self, other: GraphEntity, prefer_self: bool) -> None:
34 """
35 The merge operation allows combining two ``ReferenceAnnotation`` entities into a single one,
36 by marking the second entity as to be deleted while also copying its data into the current
37 ``ReferenceAnnotation``. Moreover, every triple from the containing ``GraphSet`` referring to the second
38 entity gets "redirected" to the current entity: **every other reference contained inside a
39 different source (e.g. a triplestore) must be manually handled by the user!**
41 By default, functional values from the current entity get overwritten by values
42 from the second entity. When ``prefer_self`` is True, existing functional values
43 from the current entity are kept. Non-functional values from the second entity
44 are appended to those of the current entity. In this context,
45 ``rdfs:label`` is considered as a functional property, while ``rdf:type`` is not.
47 :param other: The entity which will be marked as to be deleted and whose properties will
48 be merged into the current entity.
49 :type other: ReferenceAnnotation
50 :raises TypeError: if the parameter is of the wrong type
51 :return: None
52 """
53 super()._merge_properties(other, prefer_self)
54 assert isinstance(other, ReferenceAnnotation)
56 citation: Optional[Citation] = other.get_body_annotation()
57 if citation is not None and self._should_merge_functional_property(self.get_body_annotation(), prefer_self):
58 self.has_body_annotation(citation)
60 # HAS CITATION (Citation)
61 def get_body_annotation(self) -> Optional[Citation]:
62 """
63 Getter method corresponding to the ``oa:hasBody`` RDF predicate.
65 :return: The requested value if found, None otherwise
66 """
67 uri: Optional[str] = self._get_uri_reference(GraphEntity.iri_has_body, "ci")
68 if uri is not None:
69 return self.g_set.add_ci(self.resp_agent, self.source, uri)
71 @accepts_only("ci")
72 def has_body_annotation(self, ci_res: Citation) -> None:
73 """
74 Setter method corresponding to the ``oa:hasBody`` RDF predicate.
76 **WARNING: this is a functional property, hence any existing value will be overwritten!**
78 `The citation to which the annotation relates, that is relevant either to a bibliographic
79 reference or to an in-text reference pointer that denotes such a bibliographic reference.`
81 :param ci_res: The value that will be set as the object of the property related to this method
82 :type ci_res: Citation
83 :raises TypeError: if the parameter is of the wrong type
84 :return: None
85 """
86 self.remove_body_annotation()
87 self.g.add((self.res, GraphEntity.iri_has_body, RDFTerm("uri", str(ci_res.res))))
89 def remove_body_annotation(self) -> None:
90 """
91 Remover method corresponding to the ``oa:hasBody`` RDF predicate.
93 :return: None
94 """
95 self.g.remove((self.res, GraphEntity.iri_has_body, None))