initial import of ussd-pad
[ussd-widget] / ussd-pad / src / opt / ussd-pad / com / Container.py
1 """
2 Runtime container for running components.
3 """
4
5 from Component import Component
6 import msgs
7 from utils import logging
8
9 import os
10 import sys
11
12
13 class Container(Component):
14     """
15     Runtime container for running components.
16     The Container loads and instantiates components.
17     """
18     
19     def __init__(self, paths, whitelist = []):
20         """
21         @param paths: paths where to look for components
22         """
23     
24         self.__components = []
25         self.__devices = []
26         self.__whitelist = whitelist
27         
28         Component.__init__(self)
29         
30         for p in paths:
31             if (os.path.exists(p)):
32                 self.load_path(p)
33
34         for c in self.__components:
35             self.emit_message(msgs.COM_EV_COMPONENT_LOADED, c)
36
37         for dev in self.__devices:
38             self.emit_message(msgs.CORE_EV_DEVICE_ADDED, dev.get_device_id(), dev)
39
40
41         
42     def __find_modules(self, path):
43         """
44         Returns a list of the modules of all components under the given path.
45         """
46         
47         modules = []
48
49         dirs = os.listdir(path)
50         dirs.sort()
51         # a module called "core" gets loaded first
52         if ("core" in dirs):
53             dirs.remove("core")
54             dirs = ["core"] + dirs
55
56         for f in dirs:
57             comppath = os.path.join(path, f)
58             if (not os.path.isdir(comppath) or f.startswith(".")):
59                 continue
60
61             elif (self.__whitelist and not f in self.__whitelist and f != "core"):
62                 logging.info("not loading component: %s", f)
63                 continue
64             
65             mod = self.__load_module(comppath)
66             if (mod):
67                 modules.append(mod)
68         #end for
69
70         return modules
71
72
73     def __load_module(self, path):
74         """
75         Loads and returns the module from the given path. Returns None if
76         the module could not be loaded.
77         """
78         
79         syspath = sys.path[:]
80         sys.path = [os.path.dirname(path)] + syspath
81         
82         try:
83             mod = __import__(os.path.basename(path))
84             mod._syspath = os.path.dirname(path)
85             sys.path = syspath
86             return mod
87         except:
88             logging.error("could not load component [%s]:\n%s" \
89                           % (path, logging.stacktrace()))
90             sys.path = syspath
91             return None
92         
93         
94     def __register_messages(self, mod):
95         """
96         Registers the messages of the given module.
97         """
98         
99         if (hasattr(mod, "messages")):
100             for msg in mod.messages:
101                 logging.debug("registering message: %s", msg)
102                 msgs._register(msg)
103         #end if        
104
105
106     def __load_components(self, mod):
107         """
108         Loads the components of the given module.
109         """
110
111         syspath = sys.path[:]
112         sys.path = [mod._syspath] + syspath
113
114         logging.debug("loading module [%s]", mod.__file__)
115         
116         try:
117             classes = mod.get_classes()
118         except AttributeError:
119             classes = []
120         except:
121             logging.error(logging.stacktrace())
122             classes = []
123             
124         for c in classes:
125             try:
126                 logging.debug("creating [%s]" % c.__name__)
127                 comp = c()
128                 #comp._attach_to_message_bus()
129                 self.__components.append(comp)
130                 
131             except:
132                 logging.error("could not instantiate class [%s]:\n%s" %
133                               (`c`, logging.stacktrace()))
134         #end for        
135
136         try:
137             device_classes = mod.get_devices()
138         except AttributeError:
139             device_classes = []
140         except:
141             logging.error(logging.stacktrace())
142             device_classes = []
143
144         for c in device_classes:
145             try:
146                 logging.debug("adding device [%s]" % c.__name__)
147                 comp = c()
148                 #comp._attach_to_message_bus()
149                 self.__devices.append(comp)
150
151             except:
152                 logging.error("could not instantiate class [%s]:\n%s" %
153                               (`c`, logging.stacktrace()))
154         #end for
155         
156         sys.path = syspath
157
158             
159
160
161
162     def load_path(self, path):
163         """
164         Loads all components from the given path.
165         
166         @param path: path of components directory
167         """
168         
169         #self.__components = []
170         #self.__devices = []
171         
172         mods = self.__find_modules(path)
173         for mod in mods:
174             self.__register_messages(mod)
175         for mod in mods:
176             self.emit_message(msgs.COM_EV_LOADING_MODULE, mod.__name__)
177             self.__load_components(mod)
178