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

63 statements  

« prev     ^ index     » next       coverage.py v7.13.4, created at 2026-05-08 20:23 +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 triplelite import RDFTerm 

13 

14from oc_ocdm.decorators import accepts_only 

15 

16if TYPE_CHECKING: 

17 from typing import List, Optional 

18 

19 from oc_ocdm.graph.entities.bibliographic.bibliographic_reference import BibliographicReference 

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

21from oc_ocdm.graph.entities.bibliographic_entity import BibliographicEntity 

22from oc_ocdm.graph.graph_entity import GraphEntity 

23 

24 

25class ReferencePointer(BibliographicEntity): 

26 """Reference pointer (long: in-text reference pointer; short: rp): a textual device (e.g. 

27 '[1]'), denoting a single bibliographic reference, that is embedded in the text of a 

28 document within the context of a particular sentence or text chunk. A bibliographic 

29 reference can be denoted in the text by one or more in-text reference pointers.""" 

30 

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

32 """ 

33 The merge operation allows combining two ``ReferencePointer`` entities into a single one, 

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

35 ``ReferencePointer``. Moreover, every triple from the containing ``GraphSet`` referring to the second 

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

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

38 

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

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

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

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

43 

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

45 be merged into the current entity. 

46 :type other: ReferencePointer 

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

48 :return: None 

49 """ 

50 super()._merge_properties(other, prefer_self) 

51 assert isinstance(other, ReferencePointer) 

52 

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

54 if content is not None: 

55 self.has_content(content) 

56 

57 next_rp: Optional[ReferencePointer] = other.get_next_rp() 

58 if next_rp is not None: 

59 self.has_next_rp(next_rp) 

60 

61 denoted_be: Optional[BibliographicReference] = other.get_denoted_be() 

62 if denoted_be is not None: 

63 self.denotes_be(denoted_be) 

64 

65 an_list: List[ReferenceAnnotation] = other.get_annotations() 

66 for cur_an in an_list: 

67 self.has_annotation(cur_an) 

68 

69 # HAS REFERENCE POINTER TEXT 

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

71 """ 

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

73 

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

75 """ 

76 return self._get_literal(GraphEntity.iri_has_content) 

77 

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

79 """ 

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

81 

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

83 

84 `The literal text of the textual device forming an in-text reference pointer and denoting 

85 a single bibliographic reference (e.g. “[1]”).` 

86 

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

88 :type string: str 

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

90 :return: None 

91 """ 

92 self.remove_content() 

93 self._create_literal(GraphEntity.iri_has_content, string) 

94 

95 def remove_content(self) -> None: 

96 """ 

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

98 

99 :return: None 

100 """ 

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

102 

103 # HAS NEXT (ReferencePointer) 

104 def get_next_rp(self) -> Optional[ReferencePointer]: 

105 """ 

106 Getter method corresponding to the ``oco:hasNext`` RDF predicate. 

107 

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

109 """ 

110 uri: Optional[str] = self._get_uri_reference(GraphEntity.iri_has_next, 'rp') 

111 if uri is not None: 

112 return self.g_set.add_rp(self.resp_agent, self.source, uri) 

113 

114 @accepts_only('rp') 

115 def has_next_rp(self, rp_res: ReferencePointer) -> None: 

116 """ 

117 Setter method corresponding to the ``oco:hasNext`` RDF predicate. 

118 

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

120 

121 `The following in-text reference pointer, when included within a single in-text reference 

122 pointer list.` 

123 

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

125 :type rp_res: ReferencePointer 

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

127 :return: None 

128 """ 

129 self.remove_next_rp() 

130 self.g.add((self.res, GraphEntity.iri_has_next, RDFTerm("uri", str(rp_res.res)))) 

131 

132 def remove_next_rp(self) -> None: 

133 """ 

134 Remover method corresponding to the ``oco:hasNext`` RDF predicate. 

135 

136 :return: None 

137 """ 

138 self.g.remove((self.res, GraphEntity.iri_has_next, None)) 

139 

140 # DENOTES (BibliographicReference) 

141 def get_denoted_be(self) -> Optional[BibliographicReference]: 

142 """ 

143 Getter method corresponding to the ``c4o:denotes`` RDF predicate. 

144 

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

146 """ 

147 uri: Optional[str] = self._get_uri_reference(GraphEntity.iri_denotes, 'be') 

148 if uri is not None: 

149 return self.g_set.add_be(self.resp_agent, self.source, uri) 

150 

151 @accepts_only('be') 

152 def denotes_be(self, be_res: BibliographicReference) -> None: 

153 """ 

154 Setter method corresponding to the ``c4o:denotes`` RDF predicate. 

155 

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

157 

158 `The bibliographic reference included in the list of bibliographic references, denoted by 

159 the in-text reference pointer.` 

160 

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

162 :type be_res: BibliographicReference 

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

164 :return: None 

165 """ 

166 self.remove_denoted_be() 

167 self.g.add((self.res, GraphEntity.iri_denotes, RDFTerm("uri", str(be_res.res)))) 

168 

169 def remove_denoted_be(self) -> None: 

170 """ 

171 Remover method corresponding to the ``c4o:denotes`` RDF predicate. 

172 

173 :return: None 

174 """ 

175 self.g.remove((self.res, GraphEntity.iri_denotes, None)) 

176 

177 # HAS ANNOTATION (ReferenceAnnotation) 

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

179 """ 

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

181 

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

183 """ 

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

185 result: List[ReferenceAnnotation] = [] 

186 for uri in uri_list: 

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

188 return result 

189 

190 @accepts_only('an') 

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

192 """ 

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

194 

195 `An annotation characterizing the citation to which the in-text reference pointer relates 

196 in terms of its citation function (the reason for that citation) specific to the textual 

197 location of that in-text reference pointer within the citing entity.` 

198 

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

200 :type an_res: ReferenceAnnotation 

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

202 :return: None 

203 """ 

204 self.g.add((self.res, GraphEntity.iri_has_annotation, RDFTerm("uri", str(an_res.res)))) 

205 

206 @accepts_only('an') 

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

208 """ 

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

210 

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

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

213 

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

215 related to this method (defaults to None) 

216 :type an_res: ReferenceAnnotation 

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

218 :return: None 

219 """ 

220 if an_res is not None: 

221 self.g.remove((self.res, GraphEntity.iri_has_annotation, RDFTerm("uri", str(an_res.res)))) 

222 else: 

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