Coverage for oc_ocdm / graph / entities / bibliographic / bibliographic_reference.py: 100%

50 statements  

« prev     ^ index     » next       coverage.py v7.13.4, created at 2026-03-28 18:52 +0000

1#!/usr/bin/python 

2 

3# SPDX-FileCopyrightText: 2020-2022 Simone Persiani <iosonopersia@gmail.com> 

4# 

5# SPDX-License-Identifier: ISC 

6 

7# -*- coding: utf-8 -*- 

8from __future__ import annotations 

9 

10from typing import TYPE_CHECKING 

11 

12from oc_ocdm.decorators import accepts_only 

13 

14if TYPE_CHECKING: 

15 from typing import Optional, List 

16 from rdflib import URIRef 

17 from oc_ocdm.graph.entities.bibliographic.reference_annotation import ReferenceAnnotation 

18 from oc_ocdm.graph.entities.bibliographic.bibliographic_resource import BibliographicResource 

19from oc_ocdm.graph.graph_entity import GraphEntity 

20from oc_ocdm.graph.entities.bibliographic_entity import BibliographicEntity 

21 

22 

23class BibliographicReference(BibliographicEntity): 

24 """Bibliographic reference (short: be): the particular textual bibliographic reference, 

25 usually occurring in the reference list (and denoted by one or more in-text reference 

26 pointers within the text of a citing bibliographic resource), that references another 

27 bibliographic resource. 

28 """ 

29 

30 def _merge_properties(self, other: GraphEntity, prefer_self: bool) -> None: 

31 """ 

32 The merge operation allows combining two ``BibliographicReference`` entities into a single one, 

33 by marking the second entity as to be deleted while also copying its data into the current 

34 ``BibliographicReference``. Moreover, every triple from the containing ``GraphSet`` referring to the second 

35 entity gets "redirected" to the current entity: **every other reference contained inside a 

36 different source (e.g. a triplestore) must be manually handled by the user!** 

37 

38 In case of functional properties, values from the current entity get overwritten 

39 by those coming from the second entity while, in all other cases, values from the 

40 second entity are simply appended to those of the current entity. In this context, 

41 ``rdfs:label`` is considered as a functional property, while ``rdf:type`` is not. 

42 

43 :param other: The entity which will be marked as to be deleted and whose properties will 

44 be merged into the current entity. 

45 :type other: BibliographicReference 

46 :raises TypeError: if the parameter is of the wrong type 

47 :return: None 

48 """ 

49 super()._merge_properties(other, prefer_self) 

50 assert isinstance(other, BibliographicReference) 

51 

52 content: Optional[str] = other.get_content() 

53 if content is not None: 

54 self.has_content(content) 

55 

56 annotations_list: List[ReferenceAnnotation] = other.get_annotations() 

57 for cur_annotation in annotations_list: 

58 self.has_annotation(cur_annotation) 

59 

60 referenced_br: Optional[BibliographicResource] = other.get_referenced_br() 

61 if referenced_br is not None: 

62 self.references_br(referenced_br) 

63 

64 # HAS BIBLIOGRAPHIC REFERENCE TEXT 

65 def get_content(self) -> Optional[str]: 

66 """ 

67 Getter method corresponding to the ``c4o:hasContent`` RDF predicate. 

68 

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

70 """ 

71 return self._get_literal(GraphEntity.iri_has_content) 

72 

73 @accepts_only('literal') 

74 def has_content(self, string: str) -> None: 

75 """ 

76 Setter method corresponding to the ``c4o:hasContent`` RDF predicate. 

77 

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

79 

80 `The literal text of a bibliographic reference occurring in the reference list (or 

81 elsewhere) within a bibliographic resource, that references another bibliographic 

82 resource. The reference text should be recorded “as given” in the citing bibliographic 

83 resource, including any errors (e.g. mis-spellings of authors’ names, or changes from 

84 “β” in the original published title to “beta” in the reference text) or omissions (e.g. 

85 omission of the title of the referenced bibliographic resource, or omission of sixth and 

86 subsequent authors’ names, as required by certain publishers), and in whatever format 

87 it has been made available. For instance, the reference text can be either as plain text 

88 or as a block of XML.` 

89 

90 :param string: The value that will be set as the object of the property related to this method 

91 :type string: str 

92 :raises TypeError: if the parameter is of the wrong type 

93 :return: None 

94 """ 

95 self.remove_content() 

96 self._create_literal(GraphEntity.iri_has_content, string) 

97 

98 def remove_content(self) -> None: 

99 """ 

100 Remover method corresponding to the ``c4o:hasContent`` RDF predicate. 

101 

102 :return: None 

103 """ 

104 self.g.remove((self.res, GraphEntity.iri_has_content, None)) 

105 

106 # HAS ANNOTATION (ReferenceAnnotation) 

107 def get_annotations(self) -> List[ReferenceAnnotation]: 

108 """ 

109 Getter method corresponding to the ``oco:hasAnnotation`` RDF predicate. 

110 

111 :return: A list containing the requested values if found, None otherwise 

112 """ 

113 uri_list: List[URIRef] = self._get_multiple_uri_references(GraphEntity.iri_has_annotation, 'an') 

114 result: List[ReferenceAnnotation] = [] 

115 for uri in uri_list: 

116 result.append(self.g_set.add_an(self.resp_agent, self.source, uri)) 

117 return result 

118 

119 @accepts_only('an') 

120 def has_annotation(self, an_res: ReferenceAnnotation) -> None: 

121 """ 

122 Setter method corresponding to the ``oco:hasAnnotation`` RDF predicate. 

123 

124 `An annotation characterizing the related citation, in terms of its citation function (the 

125 reason for that citation).` 

126 

127 :param an_res: The value that will be set as the object of the property related to this method 

128 :type an_res: ReferenceAnnotation 

129 :raises TypeError: if the parameter is of the wrong type 

130 :return: None 

131 """ 

132 self.g.add((self.res, GraphEntity.iri_has_annotation, an_res.res)) 

133 

134 @accepts_only('an') 

135 def remove_annotation(self, an_res: ReferenceAnnotation | None = None) -> None: 

136 """ 

137 Remover method corresponding to the ``oco:hasAnnotation`` RDF predicate. 

138 

139 **WARNING: this is a non-functional property, hence, if the parameter 

140 is None, any existing value will be removed!** 

141 

142 :param an_res: If not None, the specific object value that will be removed from the property 

143 related to this method (defaults to None) 

144 :type an_res: ReferenceAnnotation 

145 :raises TypeError: if the parameter is of the wrong type 

146 :return: None 

147 """ 

148 if an_res is not None: 

149 self.g.remove((self.res, GraphEntity.iri_has_annotation, an_res.res)) 

150 else: 

151 self.g.remove((self.res, GraphEntity.iri_has_annotation, None)) 

152 

153 # REFERENCES (BibliographicResource) 

154 def get_referenced_br(self) -> Optional[BibliographicResource]: 

155 """ 

156 Getter method corresponding to the ``biro:references`` RDF predicate. 

157 

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

159 """ 

160 uri: Optional[URIRef] = self._get_uri_reference(GraphEntity.iri_references, 'br') 

161 if uri is not None: 

162 return self.g_set.add_br(self.resp_agent, self.source, uri) 

163 

164 @accepts_only('br') 

165 def references_br(self, br_res: BibliographicResource) -> None: 

166 """ 

167 Setter method corresponding to the ``biro:references`` RDF predicate. 

168 

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

170 

171 `The bibliographic reference that cites this bibliographic resource.` 

172 

173 :param br_res: The value that will be set as the object of the property related to this method 

174 :type br_res: BibliographicResource 

175 :raises TypeError: if the parameter is of the wrong type 

176 :return: None 

177 """ 

178 self.remove_referenced_br() 

179 self.g.add((self.res, GraphEntity.iri_references, br_res.res)) 

180 

181 def remove_referenced_br(self) -> None: 

182 """ 

183 Remover method corresponding to the ``biro:references`` RDF predicate. 

184 

185 :return: None 

186 """ 

187 self.g.remove((self.res, GraphEntity.iri_references, None))