Source code for oldman.model.converter

import types
from oldman.resource.resource import ClientResource, StoreResource


[docs]class ModelConversionManager(object): """TODO: describe and find a better name.""" def __init__(self): # { (client_model, data_store): store_model } self._client_to_store_models = {} # { store_model: client_model self._store_to_client_models = {} # { (client_model, store_model): converter} self._converters = {}
[docs] def register_model_converter(self, client_model, store_model, data_store, model_converter): self._client_to_store_models[(client_model, data_store)] = store_model self._store_to_client_models[store_model] = client_model self._converters[(client_model, store_model)] = model_converter
[docs] def convert_store_to_client_resources(self, store_resources, client_resource_manager): """TODO: describe """ if isinstance(store_resources, types.GeneratorType): return (self.convert_store_to_client_resource(r) for r in store_resources) # Otherwise, returns a list return [self.convert_store_to_client_resource(r, client_resource_manager) for r in store_resources]
[docs] def convert_store_to_client_resource(self, store_resource, client_resource_manager): client_former_types, client_new_types = self._extract_types_from_store_resource(store_resource) client_model_manager = client_resource_manager.model_manager # Mutable client_resource = ClientResource(client_resource_manager, client_model_manager, store_resource.store, id=store_resource.id, types=client_new_types, is_new=store_resource.is_new, former_types=client_former_types) store = store_resource.store # Client models from the most general to the more specific client_models = list(client_resource.models) client_models.reverse() for client_model in client_models: # Corresponding store model store_model = self._client_to_store_models.get((client_model, store)) if store_model is None: #TODO: find a better exception raise Exception("No store model associate to %s" % client_model.name) converter = self._converters[(client_model, store_model)] # Update the client resource according to the model properties converter.from_store_to_client(store_resource, client_resource) return client_resource
[docs] def convert_client_to_store_resource(self, client_resource): # Same store between the client_resource and the store_resource store = client_resource.store store_former_types, store_new_types = self._extract_types_from_client_resource(client_resource) #TODO: should we consider late IRI attributions? store_resource = StoreResource(store.model_manager, store, id=client_resource.id, types=store_new_types, is_new=client_resource.is_new, former_types=store_former_types) # From the most general to the more specific store_models = list(store_resource.models) store_models.reverse() for store_model in store_models: client_model = self._store_to_client_models.get(store_model) if client_model is None: #TODO: find a better exception raise Exception("No client model associate to %s" % store_model.name) converter = self._converters[(client_model, store_model)] # Update the client resource according to the model properties converter.from_client_to_store(client_resource, store_resource) return store_resource
def _extract_types_from_store_resource(self, store_resource): # Non model types new_types = set(store_resource.non_model_types) former_types = set(store_resource.former_non_model_types) for store_model in store_resource.models: client_model = self._store_to_client_models.get(store_model) if client_model is None: #TODO: See if relevant and find a better name raise Exception("No client model corresponding to %s" % store_model.name) client_model_type = client_model.class_iri if store_model.class_iri in store_resource.former_types: former_types.add(client_model_type) if client_model_type is not None: new_types.add(client_model_type) return former_types, new_types def _extract_types_from_client_resource(self, client_resource): # Non model types new_types = set(client_resource.non_model_types) former_types = set(client_resource.former_non_model_types) # Types corresponding to models store = client_resource.store for client_model in client_resource.models: store_model = self._client_to_store_models.get((client_model, store)) if store_model is None: #TODO: See if relevant and find a better name raise Exception("No store model corresponding to %s" % client_model.name) store_model_type = store_model.class_iri if client_model.class_iri in client_resource.former_types: former_types.add(store_model_type) new_types.add(store_model_type) return former_types, new_types
[docs]class ModelConverter(object): """TODO: find a better name and explain """
[docs] def from_client_to_store(self, client_resource, store_resource): raise NotImplementedError("Should be implemented by a sub-class")
[docs] def from_store_to_client(self, store_resource, client_resource): raise NotImplementedError("Should be implemented by a sub-class")
[docs]class DirectMappingModelConverter(ModelConverter): def __init__(self, client_to_store_mappings): """ :param client_to_store_mappings: Attribute mapping :return: """ self._client_to_store_mappings = client_to_store_mappings self._store_to_client_mappings = {v: k for k, v in client_to_store_mappings.items()}
[docs] def from_client_to_store(self, client_resource, store_resource): self._transfer_values(client_resource, store_resource, self._client_to_store_mappings)
[docs] def from_store_to_client(self, store_resource, client_resource): self._transfer_values(store_resource, client_resource, self._store_to_client_mappings)
@staticmethod def _transfer_values(source_resource, target_resource, mappings): for source_attr_name, target_attr_name in mappings.items(): # Attributes source_attr = source_resource.get_attribute(source_attr_name) target_attr = target_resource.get_attribute(target_attr_name) # Transfers a clone of the source entry source_entry = source_attr.get_entry(source_resource) if source_entry is not None: target_attr.set_entry(target_resource, source_entry.clone())
[docs]class EquivalentModelConverter(DirectMappingModelConverter): """TODO: describe """ def __init__(self, client_model, store_model): mappings = {attr_name: attr_name for attr_name in client_model.om_attributes} DirectMappingModelConverter.__init__(self, mappings) #TODO: check that the models are equivalent