X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=PLC%2FAccessor.py;h=e02d29eb6c915919d8434dffb39e3bd06c98d9f2;hb=79804af429d6b019b8427372213f733684c6981a;hp=ea69ccba59923e92c5a5213628e7654814a850c3;hpb=ec862388f729b7efaba464ce0d6d626f48453eef;p=plcapi.git diff --git a/PLC/Accessor.py b/PLC/Accessor.py index ea69ccb..e02d29e 100644 --- a/PLC/Accessor.py +++ b/PLC/Accessor.py @@ -1,5 +1,3 @@ -# $Id$ -# $URL$ # # Thierry Parmentelat - INRIA # @@ -11,7 +9,10 @@ # by the Factory, you need to restart your python instance / web server # as the cached information then becomes wrong +from PLC.Debug import log + from PLC.TagTypes import TagTypes, TagType +from PLC.Roles import Roles, Role # implementation class Accessor (object) : @@ -22,16 +23,19 @@ This is implemented as a singleton, so we can cache results over time""" _instance = None + tag_locators={} + def __init__ (self, api): self.api=api # 'tagname'=>'tag_id' self.cache={} + self.hash_name_to_role=dict ( [ (role['name'],role) for role in Roles(api)] ) def has_cache (self,tagname): return self.cache.has_key(tagname) def get_cache (self,tagname): return self.cache[tagname] - def set_cache (self,tagname,tag_id): self.cache[tagname]=tag_id + def set_cache (self,tagname,tag_type): self.cache[tagname]=tag_type - def locate_or_create_tag (self,tagname,category, description, min_role_id): + def locate_or_create_tag (self, tagname, category, description, roles, enforce=False): "search tag type from tagname & create if needed" # cached ? @@ -41,18 +45,56 @@ This is implemented as a singleton, so we can cache results over time""" tag_types = TagTypes (self.api, {'tagname':tagname}) if tag_types: tag_type = tag_types[0] + # enforce should only be set by the 'service plc start accessors' sequence + if enforce: + try: + tag_type.update({'category':category,'description':description}) + tag_type.sync() + roles_to_add = set(roles).difference(set(tag_type['roles'])) + for rolename in roles_to_add: + tag_type.add_role(self.hash_name_to_role[rolename]) + roles_to_delete = set(tag_type['roles']).difference(set(roles)) + for rolename in roles_to_delete: + tag_type.remove_role(self.hash_name_to_role[rolename]) + except: + # this goes in boot.log ... + print >> log, "WARNING, Could not enforce tag type, tagname=%s\n"%tagname + traceback.print_exc(file=log) + else: # not found: create it tag_type_fields = {'tagname':tagname, 'category' : category, - 'description' : description, - 'min_role_id': min_role_id} + 'description' : description} tag_type = TagType (self.api, tag_type_fields) tag_type.sync() - tag_type_id = tag_type['tag_type_id'] - self.set_cache(tagname,tag_type_id) - return tag_type_id + for role in roles: + try: + role_obj=Roles (self.api, role)[0] + tag_type.add_role(role_obj) + except: + # xxx todo find a more appropriate way of notifying this + print "Accessor.locate_or_create_tag: Could not add role %r to tag_type %s"%(role,tagname) + self.set_cache(tagname,tag_type) + return tag_type + + # a locator is a function that retrieves - or creates - a tag_type instance + @staticmethod + def register_tag_locator (name, tag_locator): + Accessor.tag_locators[name]=tag_locator + @staticmethod + def retrieve_tag_locator (name): + return Accessor.tag_locators[name] + + # this is designed to be part of the 'service plc start' sequence + # it ensures the creation of all the tagtypes defined + # in the various accessors, and enforces consistency to the DB + # it's not easy to have define_accessors do this because at + # load-time as we do not have an instance of API yet + def run_all_tag_locators (self): + for (name, tag_locator) in Accessor.tag_locators.items(): + tag_locator(self,enforce=True) #################### # make it a singleton so we can cache stuff in there over time