#3045: [RFC] Ordered ExtensionPoint implementation
-------------------------+--------------------------------------------------
 Reporter:  athomas      |       Owner:  jonas
     Type:  enhancement  |      Status:  new  
 Priority:  low          |   Milestone:       
Component:  general      |     Version:  devel
 Severity:  trivial      |    Keywords:       
-------------------------+--------------------------------------------------
 In the same vein as `SingletonExtensionPoint`, this uses a config entry to
 determine the order in which the extensions are returned:

 {{{
 #!python
 class ExtensionPoint(property):
     """ An extension point, possibly ordered by a configuration option.
 Entries
     missing from the option can be excluded. """
     def __init__(self, interface, cfg_section=None, cfg_property=None,
                  exclude_missing=False):
         property.__init__(self, self.extensions)
         self.interface = interface
         self.__doc__ = 'List of components that implement `%s`' % \
                        self.interface.__name__
         self.cfg_section = cfg_section or 'interfaces'
         self.cfg_property = cfg_property or interface.__name__.lower()
         self.exclude_missing = exclude_missing

     def extensions(self, component):
         """Return a list of components that declare to implement the
         extension point interface."""
         order = filter(None, component.config.getlist(self.cfg_section,
                                                       self.cfg_property))
         extensions = ComponentMeta._registry.get(self.interface, [])
         extensions = filter(None, [component.compmgr[cls] for cls in
 extensions
                                    if not self.exclude_missing
                                    or not order
                                    or cls.__name__ in order])
         if order:
             def compare(x, y):
                 x, y = x.__class__.__name__, y.__class__.__name__
                 if x not in order:
                     return int(y in order)
                 if y not in order:
                     return -int(x in order)
                 return cmp(order.index(x), order.index(y))
             extensions.sort(compare)
         return extensions

     def __repr__(self):
         """Return a textual representation of the extension point."""
         return '<ExtensionPoint %s>' % self.interface.__name__
 }}}

 This could replace the existing !ExtensionPoint class and add ordering
 automatically to all existing interfaces. Ordering for any interface can
 be specified in the `[interfaces]` section. eg.

 {{{
 [interfaces]
 iconfigurable = TicketSystem, WikiSystem
 ipermissionrequestor = PermissionSystem
 }}}

-- 
Ticket URL: <http://projects.edgewall.com/trac/ticket/3045>
The Trac Project <http://trac.edgewall.com/>
_______________________________________________
Trac-Tickets mailing list
[email protected]
http://lists.edgewall.com/mailman/listinfo/trac-tickets

Reply via email to