Coverage for oc_ocdm / graph / entities / bibliographic / citation.py: 97%
87 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-05-08 20:23 +0000
« prev ^ index » next coverage.py v7.13.4, created at 2026-05-08 20:23 +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.constants import XSD_DURATION
15from oc_ocdm.decorators import accepts_only
16from oc_ocdm.support.support import get_datatype_from_iso_8601
18if TYPE_CHECKING:
19 from typing import Optional
21 from oc_ocdm.graph.entities.bibliographic.bibliographic_resource import BibliographicResource
22from oc_ocdm.graph.entities.bibliographic_entity import BibliographicEntity
23from oc_ocdm.graph.graph_entity import GraphEntity
26class Citation(BibliographicEntity):
27 """Citation (short: ci): a permanent conceptual directional link from the citing
28 bibliographic resource to a cited bibliographic resource. A citation is created by the
29 performative act of an author citing a published work that is relevant to the current
30 work by using a particular textual device. Typically, citations are made by including a
31 bibliographic reference in the reference list of the citing work and by denoting such a
32 bibliographic reference using one or more in-text reference pointers (e.g. '[1]'), or by
33 the inclusion within the citing work of a link, in the form of an HTTP Uniform Resource
34 Locator (URL), to the cited bibliographic resource on the World Wide Web."""
36 def _merge_properties(self, other: GraphEntity, prefer_self: bool) -> None:
37 """
38 The merge operation allows combining two ``Citation`` entities into a single one,
39 by marking the second entity as to be deleted while also copying its data into the current
40 ``Citation``. Moreover, every triple from the containing ``GraphSet`` referring to the second
41 entity gets "redirected" to the current entity: **every other reference contained inside a
42 different source (e.g. a triplestore) must be manually handled by the user!**
44 In case of functional properties, values from the current entity get overwritten
45 by those coming from the second entity while, in all other cases, values from the
46 second entity are simply appended to those of the current entity. In this context,
47 ``rdfs:label`` is considered as a functional property, while ``rdf:type`` is not.
49 :param other: The entity which will be marked as to be deleted and whose properties will
50 be merged into the current entity.
51 :type other: Citation
52 :raises TypeError: if the parameter is of the wrong type
53 :return: None
54 """
55 super()._merge_properties(other, prefer_self)
56 assert isinstance(other, Citation)
58 citing_br: Optional[BibliographicResource] = other.get_citing_entity()
59 if citing_br is not None:
60 self.has_citing_entity(citing_br)
62 cited_br: Optional[BibliographicResource] = other.get_cited_entity()
63 if cited_br is not None:
64 self.has_cited_entity(cited_br)
66 creation_date: Optional[str] = other.get_citation_creation_date()
67 if creation_date is not None:
68 self.has_citation_creation_date(creation_date)
70 time_span: Optional[str] = other.get_citation_time_span()
71 if time_span is not None:
72 self.has_citation_time_span(time_span)
74 characterization: Optional[str] = other.get_citation_characterization()
75 if characterization is not None:
76 self.has_citation_characterization(characterization)
78 # HAS CITING DOCUMENT (BibliographicResource)
79 def get_citing_entity(self) -> Optional[BibliographicResource]:
80 """
81 Getter method corresponding to the ``cito:hasCitingEntity`` RDF predicate.
83 :return: The requested value if found, None otherwise
84 """
85 uri: Optional[str] = self._get_uri_reference(GraphEntity.iri_has_citing_entity, 'br')
86 if uri is not None:
87 return self.g_set.add_br(self.resp_agent, self.source, uri)
89 @accepts_only('br')
90 def has_citing_entity(self, citing_res: BibliographicResource) -> None:
91 """
92 Setter method corresponding to the ``cito:hasCitingEntity`` RDF predicate.
94 **WARNING: this is a functional property, hence any existing value will be overwritten!**
96 `The bibliographic resource which acts as the source for the citation.`
98 :param citing_res: The value that will be set as the object of the property related to this method
99 :type citing_res: BibliographicResource
100 :raises TypeError: if the parameter is of the wrong type
101 :return: None
102 """
103 self.remove_citing_entity()
104 self.g.add((self.res, GraphEntity.iri_has_citing_entity, RDFTerm("uri", str(citing_res.res))))
106 def remove_citing_entity(self) -> None:
107 """
108 Remover method corresponding to the ``cito:hasCitingEntity`` RDF predicate.
110 :return: None
111 """
112 self.g.remove((self.res, GraphEntity.iri_has_citing_entity, None))
114 # HAS CITED DOCUMENT (BibliographicResource)
115 def get_cited_entity(self) -> Optional[BibliographicResource]:
116 """
117 Getter method corresponding to the ``cito:hasCitedEntity`` RDF predicate.
119 :return: The requested value if found, None otherwise
120 """
121 uri: Optional[str] = self._get_uri_reference(GraphEntity.iri_has_cited_entity, 'br')
122 if uri is not None:
123 return self.g_set.add_br(self.resp_agent, self.source, uri)
125 @accepts_only('br')
126 def has_cited_entity(self, cited_res: BibliographicResource) -> None:
127 """
128 Setter method corresponding to the ``cito:hasCitedEntity`` RDF predicate.
130 **WARNING: this is a functional property, hence any existing value will be overwritten!**
132 `The bibliographic resource which acts as the target for the citation.`
134 :param cited_res: The value that will be set as the object of the property related to this method
135 :type cited_res: BibliographicResource
136 :raises TypeError: if the parameter is of the wrong type
137 :return: None
138 """
139 self.remove_cited_entity()
140 self.g.add((self.res, GraphEntity.iri_has_cited_entity, RDFTerm("uri", str(cited_res.res))))
142 def remove_cited_entity(self) -> None:
143 """
144 Remover method corresponding to the ``c4o:hasCitedEntity`` RDF predicate.
146 :return: None
147 """
148 self.g.remove((self.res, GraphEntity.iri_has_cited_entity, None))
150 # HAS CITATION CREATION DATE
151 def get_citation_creation_date(self) -> Optional[str]:
152 """
153 Getter method corresponding to the ``cito:hasCitationCreationDate`` RDF predicate.
155 :return: The requested value if found, None otherwise
156 """
157 return self._get_literal(GraphEntity.iri_has_citation_creation_date)
159 def has_citation_creation_date(self, string: str) -> None:
160 """
161 Setter method corresponding to the ``cito:hasCitationCreationDate`` RDF predicate.
163 **WARNING: this is a functional property, hence any existing value will be overwritten!**
165 `The date on which the citation was created. This has the same numerical value
166 as the publication date of the citing bibliographic resource, but is a property
167 of the citation itself. When combined with the citation time span, it permits
168 that citation to be located in history.`
170 :param string: The value that will be set as the object of the property related to this method. **It must
171 be a string compliant with the** ``ISO 8601`` **standard.**
172 :type string: str
173 :raises TypeError: if the parameter is of the wrong type
174 :return: None
175 """
176 cur_type, string = get_datatype_from_iso_8601(string)
177 if cur_type is not None and string is not None:
178 self.remove_citation_creation_date()
179 self._create_literal(GraphEntity.iri_has_citation_creation_date, string, cur_type, False)
181 def remove_citation_creation_date(self) -> None:
182 """
183 Remover method corresponding to the ``c4o:hasCitationCreationDate`` RDF predicate.
185 :return: None
186 """
187 self.g.remove((self.res, GraphEntity.iri_has_citation_creation_date, None))
189 # HAS CITATION TIME SPAN
190 def get_citation_time_span(self) -> Optional[str]:
191 """
192 Getter method corresponding to the ``cito:hasCitationTimeSpan`` RDF predicate.
194 :return: The requested value if found, None otherwise
195 """
196 return self._get_literal(GraphEntity.iri_has_citation_time_span)
198 def has_citation_time_span(self, string: str) -> None:
199 """
200 Setter method corresponding to the ``cito:hasCitationTimeSpan`` RDF predicate.
202 **WARNING: this is a functional property, hence any existing value will be overwritten!**
204 `The date interval between the publication date of the cited bibliographic resource and
205 the publication date of the citing bibliographic resource.`
207 :param string: The value that will be set as the object of the property related to this method. **It must
208 be a string compliant with the** ``xsd:duration`` **datatype.**
209 :type string: str
210 :raises TypeError: if the parameter is of the wrong type
211 :return: None
212 """
213 self.remove_citation_time_span()
214 self._create_literal(GraphEntity.iri_has_citation_time_span, string, XSD_DURATION, False)
216 def remove_citation_time_span(self) -> None:
217 """
218 Remover method corresponding to the ``c4o:hasCitationTimeSpan`` RDF predicate.
220 :return: None
221 """
222 self.g.remove((self.res, GraphEntity.iri_has_citation_time_span, None))
224 # HAS CITATION CHARACTERIZATION
225 def get_citation_characterization(self) -> Optional[str]:
226 """
227 Getter method corresponding to the ``cito:hasCitationCharacterisation`` RDF predicate.
229 :return: The requested value if found, None otherwise
230 """
231 uri: Optional[str] = self._get_uri_reference(GraphEntity.iri_citation_characterisation)
232 return uri
234 def has_citation_characterization(self, thing_res: str) -> None:
235 """
236 Setter method corresponding to the ``cito:hasCitationCharacterisation`` RDF predicate.
238 **WARNING: this is a functional property, hence any existing value will be overwritten!**
240 `The citation function characterizing the purpose of the citation.`
242 :param thing_res: The value that will be set as the object of the property related to this method
243 :type thing_res: URIRef
244 :raises TypeError: if the parameter is of the wrong type
245 :return: None
246 """
247 self.remove_citation_characterization()
248 self.g.add((self.res, GraphEntity.iri_citation_characterisation, RDFTerm("uri", str(thing_res))))
250 def remove_citation_characterization(self) -> None:
251 """
252 Remover method corresponding to the ``c4o:hasCitationCharacterisation`` RDF predicate.
254 :return: None
255 """
256 self.g.remove((self.res, GraphEntity.iri_citation_characterisation, None))
258 # HAS TYPE
259 def create_self_citation(self) -> None:
260 """
261 Setter method corresponding to the ``rdf:type`` RDF predicate.
262 It implicitly sets the object value ``cito:SelfCitation``.
264 **WARNING: the OCDM specification admits at most two types for an entity.
265 The main type cannot be edited or removed. Any existing secondary type
266 will be overwritten!**
268 :return: None
269 """
270 self._create_type(GraphEntity.iri_self_citation)
272 def create_affiliation_self_citation(self) -> None:
273 """
274 Setter method corresponding to the ``rdf:type`` RDF predicate.
275 It implicitly sets the object value ``cito:AffiliationSelfCitation``.
277 **WARNING: the OCDM specification admits at most two types for an entity.
278 The main type cannot be edited or removed. Any existing secondary type
279 will be overwritten!**
281 :return: None
282 """
283 self._create_type(GraphEntity.iri_affiliation_self_citation)
285 def create_author_network_self_citation(self) -> None:
286 """
287 Setter method corresponding to the ``rdf:type`` RDF predicate.
288 It implicitly sets the object value ``cito:AuthorNetworkSelfCitation``.
290 **WARNING: the OCDM specification admits at most two types for an entity.
291 The main type cannot be edited or removed. Any existing secondary type
292 will be overwritten!**
294 :return: None
295 """
296 self._create_type(GraphEntity.iri_author_network_self_citation)
298 def create_author_self_citation(self) -> None:
299 """
300 Setter method corresponding to the ``rdf:type`` RDF predicate.
301 It implicitly sets the object value ``cito:AuthorSelfCitation``.
303 **WARNING: the OCDM specification admits at most two types for an entity.
304 The main type cannot be edited or removed. Any existing secondary type
305 will be overwritten!**
307 :return: None
308 """
309 self._create_type(GraphEntity.iri_author_self_citation)
311 def create_funder_self_citation(self) -> None:
312 """
313 Setter method corresponding to the ``rdf:type`` RDF predicate.
314 It implicitly sets the object value ``cito:FunderSelfCitation``.
316 **WARNING: the OCDM specification admits at most two types for an entity.
317 The main type cannot be edited or removed. Any existing secondary type
318 will be overwritten!**
320 :return: None
321 """
322 self._create_type(GraphEntity.iri_funder_self_citation)
324 def create_journal_self_citation(self) -> None:
325 """
326 Setter method corresponding to the ``rdf:type`` RDF predicate.
327 It implicitly sets the object value ``cito:JournalSelfCitation``.
329 **WARNING: the OCDM specification admits at most two types for an entity.
330 The main type cannot be edited or removed. Any existing secondary type
331 will be overwritten!**
333 :return: None
334 """
335 self._create_type(GraphEntity.iri_journal_self_citation)
337 def create_journal_cartel_citation(self) -> None:
338 """
339 Setter method corresponding to the ``rdf:type`` RDF predicate.
340 It implicitly sets the object value ``cito:JournalCartelCitation``.
342 **WARNING: the OCDM specification admits at most two types for an entity.
343 The main type cannot be edited or removed. Any existing secondary type
344 will be overwritten!**
346 :return: None
347 """
348 self._create_type(GraphEntity.iri_journal_cartel_citation)
350 def create_distant_citation(self) -> None:
351 """
352 Setter method corresponding to the ``rdf:type`` RDF predicate.
353 It implicitly sets the object value ``cito:DistantCitation``.
355 **WARNING: the OCDM specification admits at most two types for an entity.
356 The main type cannot be edited or removed. Any existing secondary type
357 will be overwritten!**
359 :return: None
360 """
361 self._create_type(GraphEntity.iri_distant_citation)