root/gaphor/tags/gaphor-0.11.1/gaphor/application.py

Revision 1362, 5.8 kB (checked in by arj..@yirdis.nl, 1 year ago)

Added register and unregister methods to application.py for adapters, subscription adapters and handlers. Those methods should replace zope.components' provide* methods.

Also modified services, so they unregister their handlers properly.

Line 
1 """
2 The Application object. One application should be available.
3
4 All important services are present in the application object:
5  - plugin manager
6  - undo manager
7  - main window
8  - UML element factory
9  - action sets
10 """
11
12 import pkg_resources
13 from zope import component
14 from gaphor.interfaces import IService
15 from gaphor.event import ServiceInitializedEvent, ServiceShutdownEvent
16 import gaphor.UML
17
18
19 class _Application(object):
20     """
21     The Gaphor application is started from the Application instance. It behaves
22     as a singleton in many ways.
23
24     The Application is responsible for loading services and plugins. Services
25     are registered as "utilities" in a global registry.
26
27     Methods are provided that wrap zope.component's handle, adapter and
28     subscription registrations. In addition to registration methods also
29     unregister methods are provided. This way services can be properly
30     unregistered on shutdown for example.
31     """
32
33     # interface.implements(IApplication)
34    
35     def __init__(self):
36         self._uninitialized_services = {}
37         self.globalSiteManager = component.getGlobalSiteManager()
38
39     def init(self, services=None):
40         """
41         Initialize the application.
42         """
43         self.load_services(services)
44         self.init_all_services()
45
46     def load_services(self, services=None):
47         """
48         Load services from resources.
49
50         Services are registered as utilities in zope.component.
51         Service should provide an interface gaphor.interfaces.IService.
52         """
53         for ep in pkg_resources.iter_entry_points('gaphor.services'):
54             #print ep, dir(ep)
55             log.debug('found entry point service.%s' % ep.name)
56             cls = ep.load()
57             if not IService.implementedBy(cls):
58                 raise 'MisConfigurationException', 'Entry point %s doesn''t provide IService' % ep.name
59             if services is None or ep.name in services:
60                 srv = cls()
61                 self._uninitialized_services[ep.name] = srv
62
63     def init_all_services(self):
64         while self._uninitialized_services:
65             self.init_service(self._uninitialized_services.iterkeys().next())
66
67     def init_service(self, name):
68         """
69         Initialize a not yet initialized service.
70
71         Raises ComponentLookupError if the service has nor been found
72         """
73         try:
74             srv = self._uninitialized_services.pop(name)
75         except KeyError:
76             raise component.ComponentLookupError(IService, name)
77         else:
78             log.info('initializing service service.%s' % name)
79             srv.init(self)
80             self.globalSiteManager.registerUtility(srv, IService, name)
81             self.handle(ServiceInitializedEvent(name, srv))
82             return srv
83
84     distribution = property(lambda s: pkg_resources.get_distribution('gaphor'),
85                             doc='Get the PkgResources distribution for Gaphor')
86
87     def get_service(self, name):
88         try:
89             return self.globalSiteManager.getUtility(IService, name)
90         except component.ComponentLookupError:
91             return self.init_service(name)
92
93     def run(self):
94         import gtk
95         gtk.main()
96
97     def shutdown(self):
98         for name, srv in self.globalSiteManager.getUtilitiesFor(IService):
99             srv.shutdown()
100             self.handle(ServiceShutdownEvent(name, srv))
101             self.globalSiteManager.unregisterUtility(srv, IService, name)
102
103         # Re-initialize Zope's global site manager
104         # (cleanup adapters and utilities):
105         try:
106             self.globalSiteManager.__init__('base')
107         except Exception, e:
108             log.error('Re-initialization of the Zope SiteManager failed', e)
109         self.__init__()
110
111     # Wrap zope.component's SiteManager methods
112
113     def registerAdapter(self, factory, adapts=None, provides=None, name=''):
114         """
115         Register an adapter (factory) that adapts objects to a specific
116         interface. A name can be used to distinguish between different adapters
117         that adapt to the same interfaces.
118         """
119         self.globalSiteManager.registerAdapter(factory, adapts, provides,
120                               name, event=False)
121
122     def unregisterAdapter(self, factory=None,
123                           required=None, provided=None, name=u''):
124         """
125         Unregister a previously registered adapter.
126         """
127         self.globalSiteManager.unregisterAdapter(factory,
128                               required, provided, name)
129
130     def registerSubscriptionAdapter(self, factory, adapts=None, provides=None):
131         """
132         Register a subscription adapter. See registerAdapter().
133         """
134         self.globalSiteManager.registerSubscriptionAdapter(factory, adapts,
135                               provides, event=False)
136
137     def unregisterSubscriptionAdapter(self, factory=None,
138                           required=None, provided=None, name=u''):
139         """
140         Unregister a previously registered subscription adapter.
141         """
142         self.globalSiteManager.unregisterSubscriptionAdapter(factory,
143                               required, provided, name)
144
145     def registerHandler(self, factory, adapts=None):
146         """
147         Register a handler. Handlers are triggered (executed) when specific
148         events are emited through the handle() method.
149         """
150         self.globalSiteManager.registerHandler(factory, adapts, event=False)
151
152     def unregisterHandler(self, factory=None, required=None):
153         """
154         Unregister a previously registered handler.
155         """
156         self.globalSiteManager.unregisterHandler(factory, required)
157  
158     def handle(self, *objects):
159         """
160         Send event notifications to registered handlers.
161         """
162         self.globalSiteManager.handle(*objects)
163
164 # Make sure there is only one!
165 Application = _Application()
166
167
168 # vim:sw=4:et:ai
Note: See TracBrowser for help on using the browser.