Coverage for oc_ocdm / graph / entities / bibliographic / agent_role.py: 100%
57 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-28 18:52 +0000
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-28 18:52 +0000
1#!/usr/bin/python
3# SPDX-FileCopyrightText: 2020-2022 Simone Persiani <iosonopersia@gmail.com>
4#
5# SPDX-License-Identifier: ISC
7# -*- coding: utf-8 -*-
8from __future__ import annotations
10from typing import TYPE_CHECKING
12from oc_ocdm.decorators import accepts_only
14if TYPE_CHECKING:
15 from typing import Optional
16 from rdflib import URIRef
17 from oc_ocdm.graph.entities.bibliographic.responsible_agent import ResponsibleAgent
18from oc_ocdm.graph.graph_entity import GraphEntity
19from oc_ocdm.graph.entities.bibliographic_entity import BibliographicEntity
22class AgentRole(BibliographicEntity):
23 """Agent role (short: ar): a particular role held by an agent with respect to a bibliographic resource."""
25 def _merge_properties(self, other: GraphEntity, prefer_self: bool) -> None:
26 """
27 The merge operation allows combining two ``AgentRole`` entities into a single one,
28 by marking the second entity as to be deleted while also copying its data into the current
29 ``AgentRole``. Moreover, every triple from the containing ``GraphSet`` referring to the second
30 entity gets "redirected" to the current entity: **every other reference contained inside a
31 different source (e.g. a triplestore) must be manually handled by the user!**
33 In case of functional properties, values from the current entity get overwritten
34 by those coming from the second entity while, in all other cases, values from the
35 second entity are simply appended to those of the current entity. In this context,
36 ``rdfs:label`` is considered as a functional property, while ``rdf:type`` is not.
38 :param other: The entity which will be marked as to be deleted and whose properties will
39 be merged into the current entity.
40 :type other: AgentRole
41 :raises TypeError: if the parameter is of the wrong type
42 :return: None
43 """
44 super()._merge_properties(other, prefer_self)
45 assert isinstance(other, AgentRole)
47 next_ar: Optional[AgentRole] = other.get_next()
48 if next_ar is not None:
49 self.has_next(next_ar)
51 resp_agent: Optional[ResponsibleAgent] = other.get_is_held_by()
52 if resp_agent is not None:
53 self.is_held_by(resp_agent)
55 role_type: Optional[URIRef] = other.get_role_type()
56 if role_type is not None:
57 if role_type == GraphEntity.iri_publisher:
58 self.create_publisher()
59 elif role_type == GraphEntity.iri_author:
60 self.create_author()
61 elif role_type == GraphEntity.iri_editor:
62 self.create_editor()
64 # HAS NEXT (AgentRole)
65 def get_next(self) -> Optional[AgentRole]:
66 """
67 Getter method corresponding to the ``oco:hasNext`` RDF predicate.
69 :return: The requested value if found, None otherwise
70 """
71 uri: Optional[URIRef] = self._get_uri_reference(GraphEntity.iri_has_next, 'ar')
72 if uri is not None:
73 return self.g_set.add_ar(self.resp_agent, self.source, uri)
75 @accepts_only('ar')
76 def has_next(self, ar_res: AgentRole) -> None:
77 """
78 Setter method corresponding to the ``oco:hasNext`` RDF predicate.
80 **WARNING: this is a functional property, hence any existing value will be overwritten!**
82 `The previous role in a sequence of agent roles of the same type associated with the
83 same bibliographic resource (so as to define, for instance, an ordered list of authors).`
85 :param ar_res: The value that will be set as the object of the property related to this method
86 :type ar_res: AgentRole
87 :raises TypeError: if the parameter is of the wrong type
88 :return: None
89 """
90 self.remove_next()
91 self.g.add((self.res, GraphEntity.iri_has_next, ar_res.res))
93 def remove_next(self) -> None:
94 """
95 Remover method corresponding to the ``oco:hasNext`` RDF predicate.
97 :return: None
98 """
99 self.g.remove((self.res, GraphEntity.iri_has_next, None))
101 # IS HELD BY (ResponsibleAgent)
102 def get_is_held_by(self) -> Optional[ResponsibleAgent]:
103 """
104 Getter method corresponding to the ``pro:isHeldBy`` RDF predicate.
106 :return: The requested value if found, None otherwise
107 """
108 uri: Optional[URIRef] = self._get_uri_reference(GraphEntity.iri_is_held_by, 'ra')
109 if uri is not None:
110 return self.g_set.add_ra(self.resp_agent, self.source, uri)
112 @accepts_only('ra')
113 def is_held_by(self, ra_res: ResponsibleAgent):
114 """
115 Setter method corresponding to the ``pro:isHeldBy`` RDF predicate.
117 **WARNING: this is a functional property, hence any existing value will be overwritten!**
119 `The agent holding this role with respect to a particular bibliographic resource.`
121 :param ra_res: The value that will be set as the object of the property related to this method
122 :type ra_res: ResponsibleAgent
123 :raises TypeError: if the parameter is of the wrong type
124 :return: None
125 """
126 self.remove_is_held_by()
127 self.g.add((self.res, GraphEntity.iri_is_held_by, ra_res.res))
129 def remove_is_held_by(self) -> None:
130 """
131 Remover method corresponding to the ``pro:isHeldBy`` RDF predicate.
133 :return: None
134 """
135 self.g.remove((self.res, GraphEntity.iri_is_held_by, None))
137 # HAS ROLE TYPE
138 def get_role_type(self) -> Optional[URIRef]:
139 """
140 Getter method corresponding to the ``pro:withRole`` RDF predicate.
142 :return: The requested value if found, None otherwise
143 """
144 uri: Optional[URIRef] = self._get_uri_reference(GraphEntity.iri_with_role)
145 return uri
147 def create_publisher(self) -> None:
148 """
149 Setter method corresponding to the ``pro:withRole`` RDF predicate.
150 It implicitly sets the object value ``pro:publisher``.
152 **WARNING: this is a functional property, hence any existing value will be overwritten!**
154 `The specific type of role under consideration (e.g. author, editor or publisher).`
156 :return: None
157 """
158 self.remove_role_type()
159 self.g.add((self.res, GraphEntity.iri_with_role, GraphEntity.iri_publisher))
161 def create_author(self) -> None:
162 """
163 Setter method corresponding to the ``pro:withRole`` RDF predicate.
164 It implicitly sets the object value ``pro:author``.
166 **WARNING: this is a functional property, hence any existing value will be overwritten!**
168 `The specific type of role under consideration (e.g. author, editor or publisher).`
170 :return: None
171 """
172 self.remove_role_type()
173 self.g.add((self.res, GraphEntity.iri_with_role, GraphEntity.iri_author))
175 def create_editor(self) -> None:
176 """
177 Setter method corresponding to the ``pro:withRole`` RDF predicate.
178 It implicitly sets the object value ``pro:editor``.
180 **WARNING: this is a functional property, hence any existing value will be overwritten!**
182 `The specific type of role under consideration (e.g. author, editor or publisher).`
184 :return: None
185 """
186 self.remove_role_type()
187 self.g.add((self.res, GraphEntity.iri_with_role, GraphEntity.iri_editor))
189 def remove_role_type(self) -> None:
190 """
191 Remover method corresponding to the ``pro:withRole`` RDF predicate.
193 :return: None
194 """
195 self.g.remove((self.res, GraphEntity.iri_with_role, None))