Coverage for oc_ocdm / graph / entities / bibliographic / responsible_agent.py: 92%

51 statements  

« prev     ^ index     » next       coverage.py v7.13.4, created at 2026-07-06 20:05 +0000

1#!/usr/bin/python 

2 

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

4# SPDX-FileCopyrightText: 2021 Arcangelo Massari <arcangelo.massari@unibo.it> 

5# 

6# SPDX-License-Identifier: ISC 

7 

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

9from __future__ import annotations 

10 

11from typing import TYPE_CHECKING 

12 

13from triplelite import RDFTerm 

14 

15if TYPE_CHECKING: 

16 from typing import List, Optional 

17from oc_ocdm.graph.entities.bibliographic_entity import BibliographicEntity 

18from oc_ocdm.graph.graph_entity import GraphEntity 

19 

20 

21class ResponsibleAgent(BibliographicEntity): 

22 """Responsible agent (short: ra): the agent (usually a person or an organisation) having 

23 a certain role with respect to a bibliographic resource (e.g. an author of a paper or 

24 book, or an editor of a journal).""" 

25 

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

27 """ 

28 The merge operation allows combining two ``ResponsibleAgent`` entities into a single one, 

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

30 ``ResponsibleAgent``. Moreover, every triple from the containing ``GraphSet`` referring to the second 

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

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

33 

34 By default, functional values from the current entity get overwritten by values 

35 from the second entity. When ``prefer_self`` is True, existing functional values 

36 from the current entity are kept. Non-functional values from the second entity 

37 are appended to those of the current entity. In this context, 

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

39 

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

41 be merged into the current entity. 

42 :type other: ResponsibleAgent 

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

44 :return: None 

45 """ 

46 super()._merge_properties(other, prefer_self) 

47 assert isinstance(other, ResponsibleAgent) 

48 

49 name: Optional[str] = other.get_name() 

50 if name is not None and self._should_merge_functional_property(self.get_name(), prefer_self): 

51 self.has_name(name) 

52 

53 given_name: Optional[str] = other.get_given_name() 

54 if given_name is not None and self._should_merge_functional_property(self.get_given_name(), prefer_self): 

55 self.has_given_name(given_name) 

56 

57 family_name: Optional[str] = other.get_family_name() 

58 if family_name is not None and self._should_merge_functional_property(self.get_family_name(), prefer_self): 

59 self.has_family_name(family_name) 

60 

61 related_agents: List[str] = other.get_related_agents() 

62 for cur_agent in related_agents: 

63 self.has_related_agent(cur_agent) 

64 

65 # HAS NAME 

66 def get_name(self) -> Optional[str]: 

67 """ 

68 Getter method corresponding to the ``foaf:name`` RDF predicate. 

69 

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

71 """ 

72 return self._get_literal(GraphEntity.iri_name) 

73 

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

75 """ 

76 Setter method corresponding to the ``foaf:name`` RDF predicate. 

77 

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

79 

80 `The name of an agent (for people, usually in the format: given name followed by family 

81 name, separated by a space).` 

82 

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

84 :type string: str 

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

86 :return: None 

87 """ 

88 self.remove_name() 

89 self._create_literal(GraphEntity.iri_name, string) 

90 

91 def remove_name(self) -> None: 

92 """ 

93 Remover method corresponding to the ``foaf:name`` RDF predicate. 

94 

95 :return: None 

96 """ 

97 self.g.remove((self.res, GraphEntity.iri_name, None)) 

98 

99 # HAS GIVEN NAME 

100 def get_given_name(self) -> Optional[str]: 

101 """ 

102 Getter method corresponding to the ``foaf:givenName`` RDF predicate. 

103 

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

105 """ 

106 return self._get_literal(GraphEntity.iri_given_name) 

107 

108 def has_given_name(self, string: str) -> None: 

109 """ 

110 Setter method corresponding to the ``foaf:givenName`` RDF predicate. 

111 

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

113 

114 `The given name of an agent, if a person.` 

115 

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

117 :type string: str 

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

119 :return: None 

120 """ 

121 self.remove_given_name() 

122 self._create_literal(GraphEntity.iri_given_name, string) 

123 

124 def remove_given_name(self) -> None: 

125 """ 

126 Remover method corresponding to the ``foaf:givenName`` RDF predicate. 

127 

128 :return: None 

129 """ 

130 self.g.remove((self.res, GraphEntity.iri_given_name, None)) 

131 

132 # HAS FAMILY NAME 

133 def get_family_name(self) -> Optional[str]: 

134 """ 

135 Getter method corresponding to the ``foaf:familyName`` RDF predicate. 

136 

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

138 """ 

139 return self._get_literal(GraphEntity.iri_family_name) 

140 

141 def has_family_name(self, string: str) -> None: 

142 """ 

143 Setter method corresponding to the ``foaf:familyName`` RDF predicate. 

144 

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

146 

147 `The family name of an agent, if a person.` 

148 

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

150 :type string: str 

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

152 :return: None 

153 """ 

154 self.remove_family_name() 

155 self._create_literal(GraphEntity.iri_family_name, string) 

156 

157 def remove_family_name(self) -> None: 

158 """ 

159 Remover method corresponding to the ``foaf:familyName`` RDF predicate. 

160 

161 :return: None 

162 """ 

163 self.g.remove((self.res, GraphEntity.iri_family_name, None)) 

164 

165 # HAS RELATED AGENT 

166 def get_related_agents(self) -> List[str]: 

167 """ 

168 Getter method corresponding to the ``dcterms:relation`` RDF predicate. 

169 

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

171 """ 

172 uri_list: List[str] = self._get_multiple_uri_references(GraphEntity.iri_relation) 

173 return uri_list 

174 

175 def has_related_agent(self, thing_res: str) -> None: 

176 """ 

177 Setter method corresponding to the ``dcterms:relation`` RDF predicate. 

178 

179 `An external agent that/who is related in some relevant way with this responsible agent 

180 (e.g. for inter-linking purposes).` 

181 

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

183 :type thing_res: str 

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

185 :return: None 

186 """ 

187 self.g.add((self.res, GraphEntity.iri_relation, RDFTerm("uri", str(thing_res)))) 

188 

189 def remove_related_agent(self, thing_res: str | None = None) -> None: 

190 """ 

191 Remover method corresponding to the ``dcterms:relation`` RDF predicate. 

192 

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

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

195 

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

197 related to this method (defaults to None) 

198 :type thing_res: URIRef 

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

200 :return: None 

201 """ 

202 if thing_res is not None: 

203 self.g.remove((self.res, GraphEntity.iri_relation, RDFTerm("uri", str(thing_res)))) 

204 else: 

205 self.g.remove((self.res, GraphEntity.iri_relation, None))