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

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 

17 

18from typing import TYPE_CHECKING 

19 

20from rdflib import XSD 

21 

22from oc_ocdm.decorators import accepts_only 

23from oc_ocdm.support.support import get_datatype_from_iso_8601 

24 

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 

31 

32 

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.""" 

42 

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!** 

51 

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. 

56 

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) 

64 

65 citing_br: Optional[BibliographicResource] = other.get_citing_entity() 

66 if citing_br is not None: 

67 self.has_citing_entity(citing_br) 

68 

69 cited_br: Optional[BibliographicResource] = other.get_cited_entity() 

70 if cited_br is not None: 

71 self.has_cited_entity(cited_br) 

72 

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) 

76 

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) 

80 

81 characterization: Optional[URIRef] = other.get_citation_characterization() 

82 if characterization is not None: 

83 self.has_citation_characterization(characterization) 

84 

85 # HAS CITING DOCUMENT (BibliographicResource) 

86 def get_citing_entity(self) -> Optional[BibliographicResource]: 

87 """ 

88 Getter method corresponding to the ``cito:hasCitingEntity`` RDF predicate. 

89 

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) 

95 

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. 

100 

101 **WARNING: this is a functional property, hence any existing value will be overwritten!** 

102 

103 `The bibliographic resource which acts as the source for the citation.` 

104 

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)) 

112 

113 def remove_citing_entity(self) -> None: 

114 """ 

115 Remover method corresponding to the ``cito:hasCitingEntity`` RDF predicate. 

116 

117 :return: None 

118 """ 

119 self.g.remove((self.res, GraphEntity.iri_has_citing_entity, None)) 

120 

121 # HAS CITED DOCUMENT (BibliographicResource) 

122 def get_cited_entity(self) -> Optional[BibliographicResource]: 

123 """ 

124 Getter method corresponding to the ``cito:hasCitedEntity`` RDF predicate. 

125 

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) 

131 

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. 

136 

137 **WARNING: this is a functional property, hence any existing value will be overwritten!** 

138 

139 `The bibliographic resource which acts as the target for the citation.` 

140 

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)) 

148 

149 def remove_cited_entity(self) -> None: 

150 """ 

151 Remover method corresponding to the ``c4o:hasCitedEntity`` RDF predicate. 

152 

153 :return: None 

154 """ 

155 self.g.remove((self.res, GraphEntity.iri_has_cited_entity, None)) 

156 

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. 

161 

162 :return: The requested value if found, None otherwise 

163 """ 

164 return self._get_literal(GraphEntity.iri_has_citation_creation_date) 

165 

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. 

170 

171 **WARNING: this is a functional property, hence any existing value will be overwritten!** 

172 

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.` 

177 

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) 

188 

189 def remove_citation_creation_date(self) -> None: 

190 """ 

191 Remover method corresponding to the ``c4o:hasCitationCreationDate`` RDF predicate. 

192 

193 :return: None 

194 """ 

195 self.g.remove((self.res, GraphEntity.iri_has_citation_creation_date, None)) 

196 

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. 

201 

202 :return: The requested value if found, None otherwise 

203 """ 

204 return self._get_literal(GraphEntity.iri_has_citation_time_span) 

205 

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. 

210 

211 **WARNING: this is a functional property, hence any existing value will be overwritten!** 

212 

213 `The date interval between the publication date of the cited bibliographic resource and 

214 the publication date of the citing bibliographic resource.` 

215 

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) 

224 

225 def remove_citation_time_span(self) -> None: 

226 """ 

227 Remover method corresponding to the ``c4o:hasCitationTimeSpan`` RDF predicate. 

228 

229 :return: None 

230 """ 

231 self.g.remove((self.res, GraphEntity.iri_has_citation_time_span, None)) 

232 

233 # HAS CITATION CHARACTERIZATION 

234 def get_citation_characterization(self) -> Optional[URIRef]: 

235 """ 

236 Getter method corresponding to the ``cito:hasCitationCharacterisation`` RDF predicate. 

237 

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 

242 

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. 

247 

248 **WARNING: this is a functional property, hence any existing value will be overwritten!** 

249 

250 `The citation function characterizing the purpose of the citation.` 

251 

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)) 

259 

260 def remove_citation_characterization(self) -> None: 

261 """ 

262 Remover method corresponding to the ``c4o:hasCitationCharacterisation`` RDF predicate. 

263 

264 :return: None 

265 """ 

266 self.g.remove((self.res, GraphEntity.iri_citation_characterisation, None)) 

267 

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``. 

273 

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!** 

277 

278 :return: None 

279 """ 

280 self._create_type(GraphEntity.iri_self_citation) 

281 

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``. 

286 

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!** 

290 

291 :return: None 

292 """ 

293 self._create_type(GraphEntity.iri_affiliation_self_citation) 

294 

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``. 

299 

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!** 

303 

304 :return: None 

305 """ 

306 self._create_type(GraphEntity.iri_author_network_self_citation) 

307 

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``. 

312 

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!** 

316 

317 :return: None 

318 """ 

319 self._create_type(GraphEntity.iri_author_self_citation) 

320 

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``. 

325 

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!** 

329 

330 :return: None 

331 """ 

332 self._create_type(GraphEntity.iri_funder_self_citation) 

333 

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``. 

338 

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!** 

342 

343 :return: None 

344 """ 

345 self._create_type(GraphEntity.iri_journal_self_citation) 

346 

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``. 

351 

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!** 

355 

356 :return: None 

357 """ 

358 self._create_type(GraphEntity.iri_journal_cartel_citation) 

359 

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``. 

364 

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!** 

368 

369 :return: None 

370 """ 

371 self._create_type(GraphEntity.iri_distant_citation)