''' Created on Dec 10, 2012 @author: steger ''' from threading import RLock from DataProcessing.DataError import DataError, SamplerError #FIXME: import dependency problem, circular reference #from DataProcessing.DataReader import DataReader class DataSource(object): ''' #FIXME: docs @summary: a template to represent any data generated by a tool or derived via various operations on data @ivar source: pointer to the origin of the data @note: DataSource instances reference their ancestor via the source property, in a recursive manner, the last item needs to implement a read and a write lock @ivar data: pointer to the actual data container @note: results of operations on data yield their result in the container referenced by the data property, the original data generator's data and source properties are meant to be the same @ivar name: a name for the data source class @ivar um: reference to the unit model of the ancient data source ''' PASS = 0 CLEARED = 1 EXPANDED = 2 def __init__(self, dependency = None): self._readers = set() if dependency is None: self._inputreader = None else: self._inputreader = self.readerClass(dependency) self._processlock = RLock() self._data = None #FIXME: import error def registerReader(self, reader): ''' @summary: registers a reader to catch clear and update events @param reader: data consumer @type reader: DataReader @raise DataError: wrong argument ''' try: # if isinstance(reader, DataReader): self._readers.add(reader) if len(self): reader.sourceexpanded() else: reader.sourcecleared() # else: except SamplerError: pass except: raise raise DataError("Expecting a DataReader, got %s" % reader) def deregisterReader(self, reader): ''' @summary: removes a registered reader @param reader: data consumer @type reader: DataReader ''' try: self._readers.remove(reader) except KeyError: pass def __len__(self): raise DataError("%s must implement __len__ method" % self) def __getitem__(self, k): raise DataError("%s must implement __getitem__ method" % self) @property def name(self): raise DataError("%s must implement name property" % self) @property def readerClass(self): raise DataError("%s must implement readerClass property" % self) @property def data(self): self.process() return self._data def process(self): ''' @summary: recursively process data records of the source chain @return: status of the data processing @rtype: int ''' with self._processlock: if self._inputreader: # print "PROC SRC", self, self._inputreader.source self._inputreader.source.process() # print "PROC", self status = self._process() if status & self.CLEARED: # print "SRC cleared", self self._sourcecleared() if status & self.EXPANDED: # print "SRC expanded", self self._sourceexpanded() return status def _process(self): raise DataError("%s must implement _process method returning process status" % self) def _sourcecleared(self): for r in self._readers: r.sourcecleared() def _sourceexpanded(self): for r in self._readers: r.sourceexpanded()