Coverage for rdflib_ocdm / abstract_entity.py: 100%
5 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-21 12:35 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-21 12:35 +0000
1#!/usr/bin/python
3# SPDX-FileCopyrightText: 2016 Silvio Peroni <essepuntato@gmail.com>
4# SPDX-FileCopyrightText: 2023-2025 Arcangelo Massari <arcangelo.massari@unibo.it>
5#
6# SPDX-License-Identifier: ISC
9from __future__ import annotations
11from abc import ABC
12from typing import TYPE_CHECKING
14from rdflib import RDF, RDFS, Graph, Literal, URIRef
16from rdflib_ocdm.support import create_literal, create_type
18if TYPE_CHECKING:
19 from typing import ClassVar, Dict, Iterable, List, Optional
21class AbstractEntity(ABC): # pragma: no cover
22 """
23 Abstract class which represents a generic entity.
24 It sits at the top of the entity class hierarchy.
25 """
27 short_name_to_type_iri: ClassVar[Dict[str, URIRef]] = {}
29 def __init__(self) -> None:
30 """
31 Constructor of the ``AbstractEntity`` class.
32 """
33 self.g: Graph = Graph()
34 self.res: URIRef = URIRef("")
36 def remove_every_triple(self) -> None:
37 """
38 Remover method that removes every triple from the current entity.
40 :return: None
41 """
42 self.g.remove((None, None, None))
44 # LABEL
45 def get_label(self) -> Optional[str]:
46 """
47 Getter method corresponding to the ``rdfs:label`` RDF predicate.
49 :return: The requested value if found, None otherwise
50 """
51 return self._get_literal(RDFS.label)
53 def create_label(self, string: str) -> None:
54 """
55 Setter method corresponding to the ``rdfs:label`` RDF predicate.
57 **WARNING: this is a functional property, hence any existing value will be overwritten!**
59 :param string: The value that will be set as the object of the property related to this method
60 :type string: str
61 :return: None
62 """
63 self.remove_label()
64 self._create_literal(RDFS.label, string)
66 def remove_label(self) -> None:
67 """
68 Remover method corresponding to the ``rdfs:label`` RDF predicate.
70 :return: None
71 """
72 self.g.remove((self.res, RDFS.label, None))
74 def _create_literal(self, p: URIRef, s: str, dt: URIRef = None, nor: bool = True) -> None:
75 """
76 Adds an RDF triple with a literal object inside the graph of the entity
78 :param p: The predicate
79 :type p: URIRef
80 :param s: The string to add as a literal value
81 :type s: str
82 :param dt: The object's datatype, if present
83 :type dt: URIRef, optional
84 :param nor: Whether to normalize the graph or not
85 :type nor: bool, optional
86 :return: None
87 """
88 create_literal(self.g, self.res, p, s, dt, nor)
90 # TYPE
91 def get_types(self) -> List[URIRef]:
92 """
93 Getter method corresponding to the ``rdf:type`` RDF predicate.
95 :return: A list containing the requested values if found, None otherwise
96 """
97 uri_list: List[URIRef] = self._get_multiple_uri_references(RDF.type)
98 return uri_list
100 def _create_type(self, res_type: URIRef, identifier: str = None) -> None:
101 """
102 Setter method corresponding to the ``rdf:type`` RDF predicate.
104 :param res_type: The value that will be set as the object of the property related to this method
105 :type res_type: URIRef
106 :return: None
107 """
108 create_type(self.g, self.res, res_type, identifier)
110 def remove_type(self) -> None:
111 """
112 Remover method corresponding to the ``rdf:type`` RDF predicate.
114 :return: None
115 """
116 self.g.remove((self.res, RDF.type, None))
118 # Overrides __str__ method
119 def __str__(self) -> str:
120 return str(self.res)
122 def add_triples(self, iterable_of_triples: Iterable) -> None:
123 """
124 A utility method that allows to add a batch of triples into the graph of the entity.
126 **WARNING: Only triples that have this entity as their subject will be imported!**
128 :param iterable_of_triples: A collection of triples to be added to the entity
129 :type iterable_of_triples: Iterable
130 :return: None
131 """
132 for s, p, o in iterable_of_triples:
133 if s == self.res: # This guarantees that only triples belonging to the resource will be added
134 self.g.add((s, p, o))
136 def _get_literal(self, predicate: URIRef) -> Optional[str]:
137 result: Optional[str] = None
138 for o in self.g.objects(self.res, predicate):
139 if type(o) == Literal:
140 result = str(o)
141 break
142 return result
144 def _get_multiple_literals(self, predicate: URIRef) -> List[str]:
145 result: List[str] = []
146 for o in self.g.objects(self.res, predicate):
147 if type(o) == Literal:
148 result.append(str(o))
149 return result
151 def _get_uri_reference(self, predicate: URIRef) -> Optional[URIRef]:
152 result: Optional[URIRef] = None
153 for o in self.g.objects(self.res, predicate):
154 if type(o) == URIRef:
155 result = o
156 break
157 return result
159 def _get_multiple_uri_references(self, predicate: URIRef) -> List[URIRef]:
160 result: List[URIRef] = []
161 for o in self.g.objects(self.res, predicate):
162 if type(o) == URIRef:
163 result.append(o)
164 return result