Coverage for oc_ocdm/graph/entities/bibliographic/citation.py: 69%
93 statements
« prev ^ index » next coverage.py v6.5.0, created at 2025-05-30 22:05 +0000
« prev ^ index » next coverage.py v6.5.0, created at 2025-05-30 22:05 +0000
1#!/usr/bin/python
2# -*- coding: utf-8 -*-
3# Copyright (c) 2016, Silvio Peroni <essepuntato@gmail.com>
4#
5# Permission to use, copy, modify, and/or distribute this software for any purpose
6# with or without fee is hereby granted, provided that the above copyright notice
7# and this permission notice appear in all copies.
8#
9# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
11# FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
12# OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
13# DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
14# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
15# SOFTWARE.
16from __future__ import annotations
18from typing import TYPE_CHECKING
20from rdflib import XSD
22from oc_ocdm.decorators import accepts_only
23from oc_ocdm.support.support import get_datatype_from_iso_8601
25if TYPE_CHECKING:
26 from typing import Optional
27 from rdflib import URIRef
28 from oc_ocdm.graph.entities.bibliographic.bibliographic_resource import BibliographicResource
29from oc_ocdm.graph.graph_entity import GraphEntity
30from oc_ocdm.graph.entities.bibliographic_entity import BibliographicEntity
33class Citation(BibliographicEntity):
34 """Citation (short: ci): a permanent conceptual directional link from the citing
35 bibliographic resource to a cited bibliographic resource. A citation is created by the
36 performative act of an author citing a published work that is relevant to the current
37 work by using a particular textual device. Typically, citations are made by including a
38 bibliographic reference in the reference list of the citing work and by denoting such a
39 bibliographic reference using one or more in-text reference pointers (e.g. '[1]'), or by
40 the inclusion within the citing work of a link, in the form of an HTTP Uniform Resource
41 Locator (URL), to the cited bibliographic resource on the World Wide Web."""
43 @accepts_only('ci')
44 def merge(self, other: Citation) -> None:
45 """
46 The merge operation allows combining two ``Citation`` entities into a single one,
47 by marking the second entity as to be deleted while also copying its data into the current
48 ``Citation``. Moreover, every triple from the containing ``GraphSet`` referring to the second
49 entity gets "redirected" to the current entity: **every other reference contained inside a
50 different source (e.g. a triplestore) must be manually handled by the user!**
52 In case of functional properties, values from the current entity get overwritten
53 by those coming from the second entity while, in all other cases, values from the
54 second entity are simply appended to those of the current entity. In this context,
55 ``rdfs:label`` is considered as a functional property, while ``rdf:type`` is not.
57 :param other: The entity which will be marked as to be deleted and whose properties will
58 be merged into the current entity.
59 :type other: Citation
60 :raises TypeError: if the parameter is of the wrong type
61 :return: None
62 """
63 super(Citation, self).merge(other)
65 citing_br: Optional[BibliographicResource] = other.get_citing_entity()
66 if citing_br is not None:
67 self.has_citing_entity(citing_br)
69 cited_br: Optional[BibliographicResource] = other.get_cited_entity()
70 if cited_br is not None:
71 self.has_cited_entity(cited_br)
73 creation_date: Optional[str] = other.get_citation_creation_date()
74 if creation_date is not None:
75 self.has_citation_creation_date(creation_date)
77 time_span: Optional[str] = other.get_citation_time_span()
78 if time_span is not None:
79 self.has_citation_time_span(time_span)
81 characterization: Optional[URIRef] = other.get_citation_characterization()
82 if characterization is not None:
83 self.has_citation_characterization(characterization)
85 # HAS CITING DOCUMENT (BibliographicResource)
86 def get_citing_entity(self) -> Optional[BibliographicResource]:
87 """
88 Getter method corresponding to the ``cito:hasCitingEntity`` RDF predicate.
90 :return: The requested value if found, None otherwise
91 """
92 uri: Optional[URIRef] = self._get_uri_reference(GraphEntity.iri_has_citing_entity, 'br')
93 if uri is not None:
94 return self.g_set.add_br(self.resp_agent, self.source, uri)
96 @accepts_only('br')
97 def has_citing_entity(self, citing_res: BibliographicResource) -> None:
98 """
99 Setter method corresponding to the ``cito:hasCitingEntity`` RDF predicate.
101 **WARNING: this is a functional property, hence any existing value will be overwritten!**
103 `The bibliographic resource which acts as the source for the citation.`
105 :param citing_res: The value that will be set as the object of the property related to this method
106 :type citing_res: BibliographicResource
107 :raises TypeError: if the parameter is of the wrong type
108 :return: None
109 """
110 self.remove_citing_entity()
111 self.g.add((self.res, GraphEntity.iri_has_citing_entity, citing_res.res))
113 def remove_citing_entity(self) -> None:
114 """
115 Remover method corresponding to the ``cito:hasCitingEntity`` RDF predicate.
117 :return: None
118 """
119 self.g.remove((self.res, GraphEntity.iri_has_citing_entity, None))
121 # HAS CITED DOCUMENT (BibliographicResource)
122 def get_cited_entity(self) -> Optional[BibliographicResource]:
123 """
124 Getter method corresponding to the ``cito:hasCitedEntity`` RDF predicate.
126 :return: The requested value if found, None otherwise
127 """
128 uri: Optional[URIRef] = self._get_uri_reference(GraphEntity.iri_has_cited_entity, 'br')
129 if uri is not None:
130 return self.g_set.add_br(self.resp_agent, self.source, uri)
132 @accepts_only('br')
133 def has_cited_entity(self, cited_res: BibliographicResource) -> None:
134 """
135 Setter method corresponding to the ``cito:hasCitedEntity`` RDF predicate.
137 **WARNING: this is a functional property, hence any existing value will be overwritten!**
139 `The bibliographic resource which acts as the target for the citation.`
141 :param cited_res: The value that will be set as the object of the property related to this method
142 :type cited_res: BibliographicResource
143 :raises TypeError: if the parameter is of the wrong type
144 :return: None
145 """
146 self.remove_cited_entity()
147 self.g.add((self.res, GraphEntity.iri_has_cited_entity, cited_res.res))
149 def remove_cited_entity(self) -> None:
150 """
151 Remover method corresponding to the ``c4o:hasCitedEntity`` RDF predicate.
153 :return: None
154 """
155 self.g.remove((self.res, GraphEntity.iri_has_cited_entity, None))
157 # HAS CITATION CREATION DATE
158 def get_citation_creation_date(self) -> Optional[str]:
159 """
160 Getter method corresponding to the ``cito:hasCitationCreationDate`` RDF predicate.
162 :return: The requested value if found, None otherwise
163 """
164 return self._get_literal(GraphEntity.iri_has_citation_creation_date)
166 @accepts_only('literal')
167 def has_citation_creation_date(self, string: str) -> None:
168 """
169 Setter method corresponding to the ``cito:hasCitationCreationDate`` RDF predicate.
171 **WARNING: this is a functional property, hence any existing value will be overwritten!**
173 `The date on which the citation was created. This has the same numerical value
174 as the publication date of the citing bibliographic resource, but is a property
175 of the citation itself. When combined with the citation time span, it permits
176 that citation to be located in history.`
178 :param string: The value that will be set as the object of the property related to this method. **It must
179 be a string compliant with the** ``ISO 8601`` **standard.**
180 :type string: str
181 :raises TypeError: if the parameter is of the wrong type
182 :return: None
183 """
184 cur_type, string = get_datatype_from_iso_8601(string)
185 if cur_type is not None and string is not None:
186 self.remove_citation_creation_date()
187 self._create_literal(GraphEntity.iri_has_citation_creation_date, string, cur_type, False)
189 def remove_citation_creation_date(self) -> None:
190 """
191 Remover method corresponding to the ``c4o:hasCitationCreationDate`` RDF predicate.
193 :return: None
194 """
195 self.g.remove((self.res, GraphEntity.iri_has_citation_creation_date, None))
197 # HAS CITATION TIME SPAN
198 def get_citation_time_span(self) -> Optional[str]:
199 """
200 Getter method corresponding to the ``cito:hasCitationTimeSpan`` RDF predicate.
202 :return: The requested value if found, None otherwise
203 """
204 return self._get_literal(GraphEntity.iri_has_citation_time_span)
206 @accepts_only('literal')
207 def has_citation_time_span(self, string: str) -> None:
208 """
209 Setter method corresponding to the ``cito:hasCitationTimeSpan`` RDF predicate.
211 **WARNING: this is a functional property, hence any existing value will be overwritten!**
213 `The date interval between the publication date of the cited bibliographic resource and
214 the publication date of the citing bibliographic resource.`
216 :param string: The value that will be set as the object of the property related to this method. **It must
217 be a string compliant with the** ``xsd:duration`` **datatype.**
218 :type string: str
219 :raises TypeError: if the parameter is of the wrong type
220 :return: None
221 """
222 self.remove_citation_time_span()
223 self._create_literal(GraphEntity.iri_has_citation_time_span, string, XSD.duration, False)
225 def remove_citation_time_span(self) -> None:
226 """
227 Remover method corresponding to the ``c4o:hasCitationTimeSpan`` RDF predicate.
229 :return: None
230 """
231 self.g.remove((self.res, GraphEntity.iri_has_citation_time_span, None))
233 # HAS CITATION CHARACTERIZATION
234 def get_citation_characterization(self) -> Optional[URIRef]:
235 """
236 Getter method corresponding to the ``cito:hasCitationCharacterisation`` RDF predicate.
238 :return: The requested value if found, None otherwise
239 """
240 uri: Optional[URIRef] = self._get_uri_reference(GraphEntity.iri_citation_characterisation)
241 return uri
243 @accepts_only('thing')
244 def has_citation_characterization(self, thing_res: URIRef) -> None:
245 """
246 Setter method corresponding to the ``cito:hasCitationCharacterisation`` RDF predicate.
248 **WARNING: this is a functional property, hence any existing value will be overwritten!**
250 `The citation function characterizing the purpose of the citation.`
252 :param thing_res: The value that will be set as the object of the property related to this method
253 :type thing_res: URIRef
254 :raises TypeError: if the parameter is of the wrong type
255 :return: None
256 """
257 self.remove_citation_characterization()
258 self.g.add((self.res, GraphEntity.iri_citation_characterisation, thing_res))
260 def remove_citation_characterization(self) -> None:
261 """
262 Remover method corresponding to the ``c4o:hasCitationCharacterisation`` RDF predicate.
264 :return: None
265 """
266 self.g.remove((self.res, GraphEntity.iri_citation_characterisation, None))
268 # HAS TYPE
269 def create_self_citation(self) -> None:
270 """
271 Setter method corresponding to the ``rdf:type`` RDF predicate.
272 It implicitly sets the object value ``cito:SelfCitation``.
274 **WARNING: the OCDM specification admits at most two types for an entity.
275 The main type cannot be edited or removed. Any existing secondary type
276 will be overwritten!**
278 :return: None
279 """
280 self._create_type(GraphEntity.iri_self_citation)
282 def create_affiliation_self_citation(self) -> None:
283 """
284 Setter method corresponding to the ``rdf:type`` RDF predicate.
285 It implicitly sets the object value ``cito:AffiliationSelfCitation``.
287 **WARNING: the OCDM specification admits at most two types for an entity.
288 The main type cannot be edited or removed. Any existing secondary type
289 will be overwritten!**
291 :return: None
292 """
293 self._create_type(GraphEntity.iri_affiliation_self_citation)
295 def create_author_network_self_citation(self) -> None:
296 """
297 Setter method corresponding to the ``rdf:type`` RDF predicate.
298 It implicitly sets the object value ``cito:AuthorNetworkSelfCitation``.
300 **WARNING: the OCDM specification admits at most two types for an entity.
301 The main type cannot be edited or removed. Any existing secondary type
302 will be overwritten!**
304 :return: None
305 """
306 self._create_type(GraphEntity.iri_author_network_self_citation)
308 def create_author_self_citation(self) -> None:
309 """
310 Setter method corresponding to the ``rdf:type`` RDF predicate.
311 It implicitly sets the object value ``cito:AuthorSelfCitation``.
313 **WARNING: the OCDM specification admits at most two types for an entity.
314 The main type cannot be edited or removed. Any existing secondary type
315 will be overwritten!**
317 :return: None
318 """
319 self._create_type(GraphEntity.iri_author_self_citation)
321 def create_funder_self_citation(self) -> None:
322 """
323 Setter method corresponding to the ``rdf:type`` RDF predicate.
324 It implicitly sets the object value ``cito:FunderSelfCitation``.
326 **WARNING: the OCDM specification admits at most two types for an entity.
327 The main type cannot be edited or removed. Any existing secondary type
328 will be overwritten!**
330 :return: None
331 """
332 self._create_type(GraphEntity.iri_funder_self_citation)
334 def create_journal_self_citation(self) -> None:
335 """
336 Setter method corresponding to the ``rdf:type`` RDF predicate.
337 It implicitly sets the object value ``cito:JournalSelfCitation``.
339 **WARNING: the OCDM specification admits at most two types for an entity.
340 The main type cannot be edited or removed. Any existing secondary type
341 will be overwritten!**
343 :return: None
344 """
345 self._create_type(GraphEntity.iri_journal_self_citation)
347 def create_journal_cartel_citation(self) -> None:
348 """
349 Setter method corresponding to the ``rdf:type`` RDF predicate.
350 It implicitly sets the object value ``cito:JournalCartelCitation``.
352 **WARNING: the OCDM specification admits at most two types for an entity.
353 The main type cannot be edited or removed. Any existing secondary type
354 will be overwritten!**
356 :return: None
357 """
358 self._create_type(GraphEntity.iri_journal_cartel_citation)
360 def create_distant_citation(self) -> None:
361 """
362 Setter method corresponding to the ``rdf:type`` RDF predicate.
363 It implicitly sets the object value ``cito:DistantCitation``.
365 **WARNING: the OCDM specification admits at most two types for an entity.
366 The main type cannot be edited or removed. Any existing secondary type
367 will be overwritten!**
369 :return: None
370 """
371 self._create_type(GraphEntity.iri_distant_citation)