Source code for oldman.core.parsing.value

import logging

from rdflib import URIRef, Literal
from rdflib.collection import Collection

from oldman.core.exception import OMStoreError


[docs]class AttributeValueExtractor(object): """An :class:`~oldman.parsing.value.AttributeValueExtractor` object extracts values from RDF graphs for a given :class:`~oldman.attribute.OMAttribute` object. :param om_attribute: :class:`~oldman.attribute.OMAttribute` object. """ def __init__(self, om_attribute): self._logger = logging.getLogger(__name__) self._language = om_attribute.language self._value_format = om_attribute.value_format self._property_iri = URIRef(om_attribute.om_property.iri) self._container = om_attribute.container self._reversed = om_attribute.reversed try: self._extract_fct = AttributeValueExtractor._extract_fcts[self._container] except KeyError as e: raise NotImplementedError("Container %s is not supported" % e)
[docs] def extract_value(self, resource, subgraph): """Extracts a resource attribute value from a RDF graph. :param resource: :class:`~oldman.resource.Resource` object. :param subgraph: :class:`rdflib.graph.Graph` object containing the value to extract. :return: Collection or atomic value. """ instance_iri = URIRef(resource.id.iri) if self._reversed: raw_rdf_values = list(subgraph.subjects(self._property_iri, instance_iri)) else: raw_rdf_values = list(subgraph.objects(instance_iri, self._property_iri)) if len(raw_rdf_values) == 0: return None return self._extract_fct(self, raw_rdf_values, graph=subgraph)
def _extract_regular_values(self, raw_rdf_values, is_set=False, **kwargs): values = self._filter_and_convert(raw_rdf_values) length = len(values) if length == 0: return None if not is_set and length == 1: return values[0] return set(values) def _extract_set_values(self, raw_rdf_values, **kwargs): return self._extract_regular_values(raw_rdf_values, is_set=True, **kwargs) def _extract_list_values(self, raw_rdf_values, graph): """Filters by language (unique way to discriminate).""" if not self._language and len(raw_rdf_values) > 1: raise OMStoreError(u"Multiple list found for the property %s" % self._property_iri) final_list = None for vlist in raw_rdf_values: rdf_values = Collection(graph, vlist) values = self._filter_and_convert(rdf_values) if len(values) > 0: if final_list is not None: raise OMStoreError(u"Same language in multiple list for the property %s" % self._property_iri) final_list = values else: self._logger.debug("Void list %s in graph %s" % (final_list, graph.serialize(format="turtle"))) return final_list def _extract_language_map_values(self, raw_rdf_values, **kwargs): return {r.language: self._value_format.to_python(r) for r in raw_rdf_values} def _filter_and_convert(self, rdf_values): """Filters if language is specified.""" if self._language: rdf_values = [r for r in rdf_values if isinstance(r, Literal) and r.language == self._language] return [self._value_format.to_python(r) for r in rdf_values] _extract_fcts = {'@list': _extract_list_values, '@set': _extract_set_values, '@language': _extract_language_map_values, #TODO: support index maps None: _extract_regular_values}