Coverage for oc_ocdm / graph / entities / bibliographic / pointer_list.py: 97%

37 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.reference_pointer import ReferencePointer 

20from oc_ocdm.graph.entities.bibliographic_entity import BibliographicEntity 

21from oc_ocdm.graph.graph_entity import GraphEntity 

22 

23 

24class PointerList(BibliographicEntity): 

25 """Pointer list (short: pl): a textual device (e.g. '[1, 2, 3]' or '[4-9]') which includes a 

26 number of reference pointers denoting the specific bibliographic references to which 

27 the list pertains.""" 

28 

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

30 """ 

31 The merge operation allows combining two ``PointerList`` entities into a single one, 

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

33 ``PointerList``. Moreover, every triple from the containing ``GraphSet`` referring to the second 

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

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

36 

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

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

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

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

41 

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

43 be merged into the current entity. 

44 :type other: PointerList 

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

46 :return: None 

47 """ 

48 super()._merge_properties(other, prefer_self) 

49 assert isinstance(other, PointerList) 

50 

51 content: Optional[str] = self.get_content() 

52 if content is not None: 

53 self.has_content(content) 

54 

55 rp_list: List[ReferencePointer] = other.get_contained_elements() 

56 for cur_rp in rp_list: 

57 self.contains_element(cur_rp) 

58 

59 # HAS POINTER LIST TEXT 

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

61 """ 

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

63 

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

65 """ 

66 return self._get_literal(GraphEntity.iri_has_content) 

67 

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

69 """ 

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

71 

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

73 

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

75 :type string: str 

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

77 :return: None 

78 """ 

79 self.remove_content() 

80 self._create_literal(GraphEntity.iri_has_content, string) 

81 

82 def remove_content(self) -> None: 

83 """ 

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

85 

86 :return: None 

87 """ 

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

89 

90 # HAS ELEMENT (ReferencePointer) 

91 def get_contained_elements(self) -> List[ReferencePointer]: 

92 """ 

93 Getter method corresponding to the ``co:element`` RDF predicate. 

94 

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

96 """ 

97 uri_list: List[str] = self._get_multiple_uri_references(GraphEntity.iri_has_element, 'rp') 

98 result: List[ReferencePointer] = [] 

99 for uri in uri_list: 

100 result.append(self.g_set.add_rp(self.resp_agent, self.source, uri)) 

101 return result 

102 

103 @accepts_only('rp') 

104 def contains_element(self, rp_res: ReferencePointer) -> None: 

105 """ 

106 Setter method corresponding to the ``co:element`` RDF predicate. 

107 

108 `The in-text reference pointer that is part of the in-text reference pointer list present at 

109 a particular location within the body of the citing work.` 

110 

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

112 :type rp_res: ReferencePointer 

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

114 :return: None 

115 """ 

116 self.g.add((self.res, GraphEntity.iri_has_element, RDFTerm("uri", str(rp_res.res)))) 

117 

118 @accepts_only('rp') 

119 def remove_contained_element(self, rp_res: ReferencePointer | None = None) -> None: 

120 """ 

121 Remover method corresponding to the ``co:element`` RDF predicate. 

122 

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

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

125 

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

127 related to this method (defaults to None) 

128 :type rp_res: ReferencePointer 

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

130 :return: None 

131 """ 

132 if rp_res is not None: 

133 self.g.remove((self.res, GraphEntity.iri_has_element, RDFTerm("uri", str(rp_res.res)))) 

134 else: 

135 self.g.remove((self.res, GraphEntity.iri_has_element, None))