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

68 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 oc_ocdm.decorators import accepts_only 

21 

22if TYPE_CHECKING: 

23 from typing import Optional, List 

24 from rdflib import URIRef 

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

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

27from oc_ocdm.graph.graph_entity import GraphEntity 

28from oc_ocdm.graph.entities.bibliographic_entity import BibliographicEntity 

29 

30 

31class ReferencePointer(BibliographicEntity): 

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

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

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

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

36 

37 @accepts_only('rp') 

38 def merge(self, other: ReferencePointer) -> None: 

39 """ 

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

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

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

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

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

45 

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

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

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

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

50 

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

52 be merged into the current entity. 

53 :type other: ReferencePointer 

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

55 :return: None 

56 """ 

57 super(ReferencePointer, self).merge(other) 

58 

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

60 if content is not None: 

61 self.has_content(content) 

62 

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

64 if next_rp is not None: 

65 self.has_next_rp(next_rp) 

66 

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

68 if denoted_be is not None: 

69 self.denotes_be(denoted_be) 

70 

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

72 for cur_an in an_list: 

73 self.has_annotation(cur_an) 

74 

75 # HAS REFERENCE POINTER TEXT 

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

77 """ 

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

79 

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

81 """ 

82 return self._get_literal(GraphEntity.iri_has_content) 

83 

84 @accepts_only('literal') 

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

86 """ 

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

88 

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

90 

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

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

93 

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

95 :type string: str 

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

97 :return: None 

98 """ 

99 self.remove_content() 

100 self._create_literal(GraphEntity.iri_has_content, string) 

101 

102 def remove_content(self) -> None: 

103 """ 

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

105 

106 :return: None 

107 """ 

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

109 

110 # HAS NEXT (ReferencePointer) 

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

112 """ 

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

114 

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

116 """ 

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

118 if uri is not None: 

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

120 

121 @accepts_only('rp') 

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

123 """ 

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

125 

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

127 

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

129 pointer list.` 

130 

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

132 :type rp_res: ReferencePointer 

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

134 :return: None 

135 """ 

136 self.remove_next_rp() 

137 self.g.add((self.res, GraphEntity.iri_has_next, rp_res.res)) 

138 

139 def remove_next_rp(self) -> None: 

140 """ 

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

142 

143 :return: None 

144 """ 

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

146 

147 # DENOTES (BibliographicReference) 

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

149 """ 

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

151 

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

153 """ 

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

155 if uri is not None: 

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

157 

158 @accepts_only('be') 

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

160 """ 

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

162 

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

164 

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

166 the in-text reference pointer.` 

167 

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

169 :type be_res: BibliographicReference 

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

171 :return: None 

172 """ 

173 self.remove_denoted_be() 

174 self.g.add((self.res, GraphEntity.iri_denotes, be_res.res)) 

175 

176 def remove_denoted_be(self) -> None: 

177 """ 

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

179 

180 :return: None 

181 """ 

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

183 

184 # HAS ANNOTATION (ReferenceAnnotation) 

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

186 """ 

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

188 

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

190 """ 

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

192 result: List[ReferenceAnnotation] = [] 

193 for uri in uri_list: 

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

195 return result 

196 

197 @accepts_only('an') 

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

199 """ 

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

201 

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

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

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

205 

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

207 :type an_res: ReferenceAnnotation 

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

209 :return: None 

210 """ 

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

212 

213 @accepts_only('an') 

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

215 """ 

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

217 

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

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

220 

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

222 related to this method (defaults to None) 

223 :type an_res: ReferenceAnnotation 

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

225 :return: None 

226 """ 

227 if an_res is not None: 

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

229 else: 

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