from utils.datatypes import * class Element(object): """ Base class for elements with typed properties. Classes deriving from this base class have to call _register_property(name, datatype, setter, getter, default, doc) in the constructor. Properties can then be set with set_prop(key, value) and can be read with get_prop(key, value) If you don't need any special setter or getter methods, then you can use the predefined _setp(key, value) and _getp(key) methods. """ __slots__ = ('__name', '__properties', '__property_handlers', '__ident_counter') AUTHORIZED_METHODS = () # counter for unique IDs __ident_counter = 0 def __init__(self, name): # name of the element self.__name = name # values of the properties self.__properties = {} # table: property name -> (setter, getter, datatype, doc) self.__property_handlers = {} new_id = "id%d" % self.__ident_counter self.__ident_counter += 1 self._register_property("id", TYPE_STRING, self._setp, self._getp, new_id, doc = "Unique identifier") # # Registers the given property with the given setter and getter methods. # def _register_property(self, name, datatype, setter, getter, default = None, doc = ""): self.__property_handlers[name] = (setter, getter, datatype, doc) self._setp(name, default) # # Sets the given property as a string. # def set_prop_from_string(self, key, value): value = str(value) # to stay compatible with sensors :( key = key.replace("_", "-") try: datatype = self.get_datatype_of_property(key) except KeyError: datatype = TYPE_ANY from utils import typeconverter self.set_prop(key, typeconverter.str2type(datatype, value)) # # Sets the given property. # def set_prop(self, key, value): key = key.replace("_", "-") try: setter = self.__property_handlers[key][0] datatype = self.__property_handlers[key][2] except KeyError: raise UserError(_("No such property: %s") % key, _("The element %s does not have the " "%s property.") % (self.__name, key)) if (not setter): raise UserError(_("Permission Error"), _("The property %s of element %s " "is not writable.") % (key, self.__name)) elif (dtype_check(datatype, value)): setter(key, value) else: actual_type = dtype_guess(value) raise UserError(_("Type Error"), _("The property %s of element %s " "got a value of wrong type.\n" "Expected %s, but got %s." % (key, self.__name, datatype[0], actual_type[0]))) # # Returns the value of the given property. # def get_prop(self, key): key = key.replace("_", "-") try: getter = self.__property_handlers[key] [1] except KeyError: raise KeyError("Error: No such property: %s" % key) if (not getter): raise UserError(_("Permission Error"), _("The property %s of element %s " "is not readable.") % (key, self.__name)) else: return getter(key) # # Returns the datatype of the given property. # def get_datatype_of_property(self, prop): # we intentionally don't catch the KeyError here return self.__property_handlers[prop][2] # # Returns the documentation string of the given property. # def get_doc_of_property(self, prop): try: doc = self.__property_handlers[prop][3] except: return "" return doc # # Returns a list of the names of all available properties. # def get_props(self): return self.__property_handlers.keys() # # Generic setter and getter methods for properties. # def _setp(self, key, value): self.__properties[key] = value def _getp(self, key): return self.__properties[key] # # Returns the element's name # def get_name(self): return self.__name