=== trac/core.py ================================================================== --- trac/core.py (revision 6827) +++ trac/core.py (local) @@ -18,8 +18,8 @@ from trac.util import TracError -__all__ = ['Component', 'ExtensionPoint', 'implements', 'Interface', - 'TracError'] +__all__ = ['Component', 'ExtensionPoint', 'SingletonExtensionPoint', + 'implements', 'Interface', 'TracError'] class Interface(object): @@ -51,6 +51,24 @@ return '' % self.interface.__name__ +class SingletonExtensionPoint(property): + def __init__(self, interface, cfg_section, cfg_property, default=None): + property.__init__(self, self.implementation) + self.xtnpt = ExtensionPoint(interface) + self.cfg_section = cfg_section + self.cfg_property = cfg_property + self.default = default + + def implementation(self, component): + cfgvalue = component.config.get(self.cfg_section, self.cfg_property) + for impl in self.xtnpt.extensions(component): + if impl.__class__.__name__ == cfgvalue: + return impl + if self.default is not None: + return self.default + raise AttributeError, "Can't find implementation" + + class ComponentMeta(type): """Meta class for components. === trac/perm.py ================================================================== --- trac/perm.py (revision 6827) +++ trac/perm.py (local) @@ -78,7 +78,7 @@ implements(IPermissionRequestor) requestors = ExtensionPoint(IPermissionRequestor) - stores = ExtensionPoint(IPermissionStore) + store = SingletonExtensionPoint(IPermissionStore, 'trac', 'permission_store') # Public API @@ -160,19 +160,7 @@ actions.append(action) return [('TRAC_ADMIN', actions)] - # Internal methods - def _get_store(self): - """Return the `IPermissionStore` implementation selected in the - configuration.""" - selected_store = self.config.get('trac', 'permission_store') - for store in self.stores: - if store.__class__.__name__ == selected_store: - return store - raise TracError, 'Invalid permission store "%s"' % selected_store - store = property(fget=lambda self: self._get_store()) - - class IPermissionGroupProvider(Interface): """ Extension point interface for components that provide information about user === trac/web/main.py ================================================================== --- trac/web/main.py (revision 6827) +++ trac/web/main.py (local) @@ -60,6 +60,8 @@ authenticators = ExtensionPoint(IAuthenticator) handlers = ExtensionPoint(IRequestHandler) + default_handler = SingletonExtensionPoint(IRequestHandler, + 'trac', 'default_handler') def authenticate(self, req): for authenticator in self.authenticators: @@ -88,14 +90,13 @@ # Select the component that should handle the request chosen_handler = None - default_handler = None if not req.path_info or req.path_info == '/': - default_handler = self.config.get('trac', 'default_handler') - for handler in self.handlers: - if handler.match_request(req) or \ - handler.__class__.__name__ == default_handler: - chosen_handler = handler - break + chosen_handler = self.default_handler + else: + for handler in self.handlers: + if handler.match_request(req): + chosen_handler = handler + break chrome.populate_hdf(req, chosen_handler)