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

37 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# 

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 By default, functional values from the current entity get overwritten by values 

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

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

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

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

42 

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

44 be merged into the current entity. 

45 :type other: PointerList 

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

47 :return: None 

48 """ 

49 super()._merge_properties(other, prefer_self) 

50 assert isinstance(other, PointerList) 

51 

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

53 if content is not None and self._should_merge_functional_property(self.get_content(), prefer_self): 

54 self.has_content(content) 

55 

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

57 for cur_rp in rp_list: 

58 self.contains_element(cur_rp) 

59 

60 # HAS POINTER LIST TEXT 

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

62 """ 

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

64 

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

66 """ 

67 return self._get_literal(GraphEntity.iri_has_content) 

68 

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

70 """ 

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

72 

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

74 

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

76 :type string: str 

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

78 :return: None 

79 """ 

80 self.remove_content() 

81 self._create_literal(GraphEntity.iri_has_content, string) 

82 

83 def remove_content(self) -> None: 

84 """ 

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

86 

87 :return: None 

88 """ 

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

90 

91 # HAS ELEMENT (ReferencePointer) 

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

93 """ 

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

95 

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

97 """ 

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

99 result: List[ReferencePointer] = [] 

100 for uri in uri_list: 

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

102 return result 

103 

104 @accepts_only("rp") 

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

106 """ 

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

108 

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

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

111 

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

113 :type rp_res: ReferencePointer 

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

115 :return: None 

116 """ 

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

118 

119 @accepts_only("rp") 

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

121 """ 

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

123 

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

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

126 

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

128 related to this method (defaults to None) 

129 :type rp_res: ReferencePointer 

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

131 :return: None 

132 """ 

133 if rp_res is not None: 

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

135 else: 

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