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

58 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 Optional 

18 

19 from oc_ocdm.graph.entities.bibliographic.responsible_agent import ResponsibleAgent 

20from oc_ocdm.graph.entities.bibliographic_entity import BibliographicEntity 

21from oc_ocdm.graph.graph_entity import GraphEntity 

22 

23 

24class AgentRole(BibliographicEntity): 

25 """Agent role (short: ar): a particular role held by an agent with respect to a bibliographic resource.""" 

26 

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

28 """ 

29 The merge operation allows combining two ``AgentRole`` entities into a single one, 

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

31 ``AgentRole``. Moreover, every triple from the containing ``GraphSet`` referring to the second 

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

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

34 

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

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

37 second entity are simply 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: AgentRole 

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

48 

49 next_ar: Optional[AgentRole] = other.get_next() 

50 if next_ar is not None: 

51 self.has_next(next_ar) 

52 

53 resp_agent: Optional[ResponsibleAgent] = other.get_is_held_by() 

54 if resp_agent is not None: 

55 self.is_held_by(resp_agent) 

56 

57 role_type: Optional[str] = other.get_role_type() 

58 if role_type is not None: 

59 if role_type == GraphEntity.iri_publisher: 

60 self.create_publisher() 

61 elif role_type == GraphEntity.iri_author: 

62 self.create_author() 

63 elif role_type == GraphEntity.iri_editor: 

64 self.create_editor() 

65 

66 # HAS NEXT (AgentRole) 

67 def get_next(self) -> Optional[AgentRole]: 

68 """ 

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

70 

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

72 """ 

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

74 if uri is not None: 

75 return self.g_set.add_ar(self.resp_agent, self.source, uri) 

76 

77 @accepts_only('ar') 

78 def has_next(self, ar_res: AgentRole) -> None: 

79 """ 

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

81 

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

83 

84 `The previous role in a sequence of agent roles of the same type associated with the 

85 same bibliographic resource (so as to define, for instance, an ordered list of authors).` 

86 

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

88 :type ar_res: AgentRole 

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

90 :return: None 

91 """ 

92 self.remove_next() 

93 self.g.add((self.res, GraphEntity.iri_has_next, RDFTerm("uri", str(ar_res.res)))) 

94 

95 def remove_next(self) -> None: 

96 """ 

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

98 

99 :return: None 

100 """ 

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

102 

103 # IS HELD BY (ResponsibleAgent) 

104 def get_is_held_by(self) -> Optional[ResponsibleAgent]: 

105 """ 

106 Getter method corresponding to the ``pro:isHeldBy`` RDF predicate. 

107 

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

109 """ 

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

111 if uri is not None: 

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

113 

114 @accepts_only('ra') 

115 def is_held_by(self, ra_res: ResponsibleAgent): 

116 """ 

117 Setter method corresponding to the ``pro:isHeldBy`` RDF predicate. 

118 

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

120 

121 `The agent holding this role with respect to a particular bibliographic resource.` 

122 

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

124 :type ra_res: ResponsibleAgent 

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

126 :return: None 

127 """ 

128 self.remove_is_held_by() 

129 self.g.add((self.res, GraphEntity.iri_is_held_by, RDFTerm("uri", str(ra_res.res)))) 

130 

131 def remove_is_held_by(self) -> None: 

132 """ 

133 Remover method corresponding to the ``pro:isHeldBy`` RDF predicate. 

134 

135 :return: None 

136 """ 

137 self.g.remove((self.res, GraphEntity.iri_is_held_by, None)) 

138 

139 # HAS ROLE TYPE 

140 def get_role_type(self) -> Optional[str]: 

141 """ 

142 Getter method corresponding to the ``pro:withRole`` RDF predicate. 

143 

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

145 """ 

146 uri: Optional[str] = self._get_uri_reference(GraphEntity.iri_with_role) 

147 return uri 

148 

149 def create_publisher(self) -> None: 

150 """ 

151 Setter method corresponding to the ``pro:withRole`` RDF predicate. 

152 It implicitly sets the object value ``pro:publisher``. 

153 

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

155 

156 `The specific type of role under consideration (e.g. author, editor or publisher).` 

157 

158 :return: None 

159 """ 

160 self.remove_role_type() 

161 self.g.add((self.res, GraphEntity.iri_with_role, RDFTerm("uri", GraphEntity.iri_publisher))) 

162 

163 def create_author(self) -> None: 

164 """ 

165 Setter method corresponding to the ``pro:withRole`` RDF predicate. 

166 It implicitly sets the object value ``pro:author``. 

167 

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

169 

170 `The specific type of role under consideration (e.g. author, editor or publisher).` 

171 

172 :return: None 

173 """ 

174 self.remove_role_type() 

175 self.g.add((self.res, GraphEntity.iri_with_role, RDFTerm("uri", GraphEntity.iri_author))) 

176 

177 def create_editor(self) -> None: 

178 """ 

179 Setter method corresponding to the ``pro:withRole`` RDF predicate. 

180 It implicitly sets the object value ``pro:editor``. 

181 

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

183 

184 `The specific type of role under consideration (e.g. author, editor or publisher).` 

185 

186 :return: None 

187 """ 

188 self.remove_role_type() 

189 self.g.add((self.res, GraphEntity.iri_with_role, RDFTerm("uri", GraphEntity.iri_editor))) 

190 

191 def remove_role_type(self) -> None: 

192 """ 

193 Remover method corresponding to the ``pro:withRole`` RDF predicate. 

194 

195 :return: None 

196 """ 

197 self.g.remove((self.res, GraphEntity.iri_with_role, None))