[Zope-Checkins] CVS: Zope/lib/python/ComponentArchitecture - IToIRegistry.py:1.1.2.1 Presentation.py:1.1.4.3 ServiceManager.py:NONE

Shane Hathaway shane@digicool.com
Tue, 18 Sep 2001 10:28:04 -0400


Update of /cvs-repository/Zope/lib/python/ComponentArchitecture
In directory cvs.zope.org:/tmp/cvs-serv4245

Modified Files:
      Tag: ComponentArchitecture-branch
	Presentation.py 
Added Files:
      Tag: ComponentArchitecture-branch
	IToIRegistry.py 
Removed Files:
      Tag: ComponentArchitecture-branch
	ServiceManager.py 
Log Message:
Changed global presentation registry to an Interface/Interface registry.


=== Added File Zope/lib/python/ComponentArchitecture/IToIRegistry.py ===

"""
Registry of components that are registered as requiring
an interface and providing an interface.
"""

class IToIRegistry:  # Interface to Interface
    
    def __init__(self):
        self._reg = {}

    def _registerAll(self, require, primary_provide, c, provide):
        '''
        Registers a component using (require, provide) as a key.
        Also registers superinterfaces of the provided interface,
        stopping when the registry already has a component
        that provides a more general interface.
        '''
        reg = self._reg
        reg[(require, provide)] = (primary_provide, c)
        bases = getattr(provide, '__bases__', ())
        for base in bases:
            existing = reg.get((require, base), None)
            if existing is not None:
                existing_provide = existing[0]
                if existing_provide is not primary_provide:
                    if not existing_provide.extends(primary_provide):
                        continue
                    # else we are registering a general component
                    # after a more specific component.
            self._registerAll(require, primary_provide, c, base)

    def register(self, require, provide, c):
        '''
        Registers a component.
        '''
        self._registerAll(require, provide, c, provide)

    def get(self, ob_interface, provide):
        """
        Finds a registered component that provides the given interface.
        Returns None if not found.
        """
        c = self._reg.get((ob_interface, provide), None)
        if c is not None:
            return c[1]
        bases = getattr(ob_interface, '__bases__', ())
        if bases:
            # 'require' might be a subinterface of a required interface
            # for a registered component.
            for base in bases:
                c = self.get(base, provide)
                if c is not None:
                    return c
        return None



if __name__ == '__main__':

    import Interface

    class I1(Interface.Base): pass
    class I2(I1): pass
    class I3(I2): pass
    class I4(I3): pass
    class I5(I4): pass
    class I6(I5): pass

    class NamedClass:
        def name(self):
            return self.__class__.__name__

    class A2(NamedClass): __implements__ = I2  # Adapts I1 or I2
    class A4(NamedClass): __implements__ = I4  # Adapts I1, I2, I3, or I4
    class A6(NamedClass): __implements__ = I6  # Adapts I1 through I6

    class RequiredInterface (Interface.Base): pass
    class InputI (RequiredInterface): pass

    reg = IToIRegistry()
    reg.register(RequiredInterface, I2, A2())
    reg.register(RequiredInterface, I4, A4())
    reg.register(RequiredInterface, I6, A6())

    assert reg.get(InputI, I1).name() == 'A2'
    assert reg.get(InputI, I2).name() == 'A2'
    assert reg.get(InputI, I3).name() == 'A4'
    assert reg.get(InputI, I4).name() == 'A4'
    assert reg.get(InputI, I5).name() == 'A6'
    assert reg.get(InputI, I6).name() == 'A6'

    # Be sure that it doesn't matter in what order you register
    # non-conflicting adapters.
    reg = IToIRegistry()
    reg.register(RequiredInterface, I6, A6())
    reg.register(RequiredInterface, I4, A4())
    reg.register(RequiredInterface, I2, A2())
    
    assert reg.get(InputI, I1).name() == 'A2'
    assert reg.get(InputI, I2).name() == 'A2'
    assert reg.get(InputI, I3).name() == 'A4'
    assert reg.get(InputI, I4).name() == 'A4'
    assert reg.get(InputI, I5).name() == 'A6'
    assert reg.get(InputI, I6).name() == 'A6'

    print 'A-Ok!'



=== Zope/lib/python/ComponentArchitecture/Presentation.py 1.1.4.2 => 1.1.4.3 ===
 Presentation component management
 """
-# XXX Presentation output interface hierarchy is ignored for now.
 
 import Errors
 import Interface
 from Interface import objectImplements
 
 from Service import Service, findComponent
-from IToNRegistry import IToNRegistry
+from IToIRegistry import IToIRegistry
 
 _marker = []  # Create a new marker object.
 
@@ -103,33 +102,33 @@
     """
     """
 
-    def getUnboundComponent(inputs, name, output):
+    def getUnboundComponent(inputs, output, name):
         """
         Returns a presentation component.
         """
 
 
-_global_regs = {}  # output -> IToNRegistry
+_global_regs = {}  # name -> IToIRegistry
 
-def registerPresentation(input, name, output, unbound_comp):
-    reg = _global_regs.get(output, None)
+def registerPresentation(input, output, name, unbound_comp):
+    reg = _global_regs.get(name, None)
     if reg is None:
-        _global_regs[output] = reg = IToNRegistry()
-    reg.register(input, name, unbound_comp)
+        _global_regs[name] = reg = IToIRegistry()
+    reg.register(input, output, unbound_comp)
 
-def getPresentation(object, name, output, default=_marker):
+def getPresentation(object, output, name, default=_marker):
     """
     Finds a presentation for an object by examining what it implements.
     Searches in services then the global registry.
     """
     inputs = objectImplements(object)
     c = findComponent(PRESENTATION_SERVICE_NAME, object,
-                      (inputs, name, output))
+                      (inputs, output, name))
     if c is None:
-        reg = _global_regs.get(pres_type, None)
+        reg = _global_regs.get(name, None)
         if reg is not None:
-            for i in inputs:
-                c = reg.get(i, name)
+            for input in inputs:
+                c = reg.get(input, output)
                 if c is not None:
                     break
     if c is None:

=== Removed File Zope/lib/python/ComponentArchitecture/ServiceManager.py ===