new step 'accessors' in the 'service plc start'
[plcapi.git] / PLC / Accessor.py
1 #
2 # Thierry Parmentelat - INRIA
3 #
4 #
5 # just a placeholder for storing accessor-related tag checkers
6 # this is filled by the accessors factory
7 #
8 # NOTE. If you ever come to manually delete a TagType that was created
9 # by the Factory, you need to restart your python instance / web server
10 # as the cached information then becomes wrong
11
12 from PLC.TagTypes import TagTypes, TagType
13 from PLC.Roles import Roles, Role
14
15 # implementation
16 class Accessor (object) :
17     """This is placeholder for storing accessor-related tag checkers.
18 Methods in this class are defined by the accessors factory
19
20 This is implemented as a singleton, so we can cache results over time"""
21
22     _instance = None
23
24     tag_locators={}
25
26     def __init__ (self, api):
27         self.api=api
28         # 'tagname'=>'tag_id'
29         self.cache={}
30
31     def has_cache (self,tagname): return self.cache.has_key(tagname)
32     def get_cache (self,tagname): return self.cache[tagname]
33     def set_cache (self,tagname,tag_type): self.cache[tagname]=tag_type
34
35     def locate_or_create_tag (self, tagname, category, description, roles):
36         "search tag type from tagname & create if needed"
37
38         # cached ?
39         if self.has_cache (tagname):
40             return self.get_cache(tagname)
41         # search
42         tag_types = TagTypes (self.api, {'tagname':tagname})
43         if tag_types:
44             tag_type = tag_types[0]
45         else:
46             # not found: create it
47             tag_type_fields = {'tagname':tagname,
48                                'category' :  category,
49                                'description' : description}
50             tag_type = TagType (self.api, tag_type_fields)
51             tag_type.sync()
52             for role in roles:
53                 try: 
54                     role_obj=Roles (self.api, role)[0]
55                     tag_type.add_role(role_obj)
56                 except:
57                     # xxx todo find a more appropriate way of notifying this
58                     print "Accessor.locate_or_create_tag: Could not add role %r to tag_type %s"%(role,tagname)
59         self.set_cache(tagname,tag_type)
60         return tag_type
61
62     # a locator is a function that retrieves - or creates - a tag_type instance
63     @staticmethod
64     def register_tag_locator (name, tag_locator):
65         Accessor.tag_locators[name]=tag_locator
66
67     @staticmethod
68     def retrieve_tag_locator (name):
69         return Accessor.tag_locators[name]
70     
71     # this is designed to be part of the 'service plc start' sequence
72     # it ensures the creation of all the tagtypes defined 
73     # in the various accessors
74     # it's not easy to have define_accessors do this because at
75     # load-time as we do not have an instance of API yet
76     def run_all_tag_locators (self):
77         for (name, tag_locator) in Accessor.tag_locators.items():
78             tag_locator(self)
79
80 ####################
81 # make it a singleton so we can cache stuff in there over time
82 def AccessorSingleton (api):
83     if not Accessor._instance:
84         Accessor._instance = Accessor(api)
85     return Accessor._instance