1 # Thierry Parmentelat - INRIA
4 from types import NoneType
6 from PLC.Method import Method
7 from PLC.Auth import Auth
8 from PLC.Parameter import Parameter, Mixed
10 from PLC.Faults import *
12 from PLC.Nodes import Node
13 from PLC.Interfaces import Interface
14 from PLC.Slices import Slice
15 from PLC.Ilinks import Ilink
17 from PLC.TagTypes import TagTypes, TagType
19 # known classes : { class -> secondary_key }
20 taggable_classes = { Node : 'hostname',
25 # xxx probably defined someplace else
26 all_roles = [ 'admin', 'pi', 'tech', 'user', 'node' ]
28 # generates 2 method classes:
29 # Get<classname><methodsuffix> (auth, id_or_name) -> tagvalue or None
30 # Set<classname><methodsuffix> (auth, id_or_name, tagvalue) -> None
31 # tagvalue is always a string, no cast nor typecheck for now
33 # note: tag_min_role_id gets attached to the tagtype instance,
34 # while get_roles and set_roles get attached to the created methods
36 # returns a tuple (get_method, set_method)
37 # See Accessors* for examples
39 def get_set_factory (objclass, methodsuffix,
40 tagname, category, description, tag_min_role_id=10,
41 get_roles=['admin'], set_roles=['admin']):
43 if objclass not in taggable_classes:
45 raise PLCInvalidArgument,"PLC.Accessors.Factory: unknown class %s"%objclass.__name__
47 raise PLCInvalidArgument,"PLC.Accessors.Factory: unknown class ??"
48 classname=objclass.__name__
49 get_name = "Get" + classname + methodsuffix
50 set_name = "Set" + classname + methodsuffix
52 # create method objects under PLC.Method.Method
53 get_class = type (get_name, (Method,),
54 {"__doc__":"Accessor 'get' method designed for %s objects using tag %s"%\
56 set_class = type (set_name, (Method,),
57 {"__doc__":"Accessor 'set' method designed for %s objects using tag %s"%\
60 get_accepts = [ Auth () ]
61 primary_key=objclass.primary_key
62 secondary_key = taggable_classes[objclass]
64 get_accepts += [ objclass.fields[primary_key] ]
66 get_accepts += [ Mixed (objclass.fields[primary_key], objclass.fields[secondary_key]) ]
67 # for set, idem + one additional arg
68 set_accepts = get_accepts + [ Parameter (str,"New tag value") ]
71 get_returns = Mixed (Parameter (str), Parameter(NoneType))
72 set_returns = Parameter(NoneType)
75 setattr(get_class,'roles',get_roles)
76 setattr(get_class,'accepts',get_accepts)
77 setattr(get_class,'returns', get_returns)
78 setattr(get_class,'skip_typecheck',True)
80 setattr(set_class,'roles',set_roles)
81 setattr(set_class,'accepts',set_accepts)
82 setattr(set_class,'returns', set_returns)
83 setattr(set_class,'skip_typecheck',True)
85 # body of the get method
86 def get_call (self, auth, id_or_name):
87 print 'Automagical Accessor get method',classname,get_name,tagname,primary_key,secondary_key
88 print 'Warning: PLC/Accessors/Factory is an ongoing work'
89 tag_type_id = locate_or_create_tag_type_id (self.api, tagname,
90 category, description, tag_min_role_id)
92 setattr (get_class,"call",get_call)
94 # body of the set method
95 def set_call (self, auth, id_or_name, tagvalue):
96 print 'Automagical Accessor set method',classname,get_name,tagname,primary_key,secondary_key
97 print 'Warning: PLC/Accessors/Factory is an ongoing work'
99 setattr (set_class,"call",set_call)
101 return ( get_class, set_class )
103 ### might need to use a cache
104 def locate_or_create_tag_type_id (api, tagname, category, description, min_role_id):
106 tag_types = TagTypes (api, {'tagname':tagname})
107 # not found: create it
109 print 'FOUND preexisting'
110 tag_type_id = tag_types[0]['tag_type_id']
112 print 'not FOUND : creating'
113 tag_type_fields = {'tagname':tagname,
114 'category' : category,
115 'description' : description,
116 'min_role_id': min_role_id}
117 tag_type = TagType (api, tag_type_fields)
119 tag_type_id = tag_type['tag_type_id']