[Zope-Checkins] CVS: Zope3/lib/python/Zope/ComponentArchitecture - IComponentArchitecture.py:1.1.2.1 IToIRegistry.py:1.1.4.1 __init__.py:1.1.6.1 hooks.py:1.1.2.1

Jim Fulton jim@zope.com
Fri, 16 Nov 2001 16:13:24 -0500


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

Added Files:
      Tag: Zope-3x-branch
	IComponentArchitecture.py IToIRegistry.py __init__.py hooks.py 
Log Message:
Component Architecture

=== Added File Zope3/lib/python/Zope/ComponentArchitecture/IComponentArchitecture.py ===

from Interface import Interface

class IComponentArchitecture(Interface):

    def provideFeature(forInterface, providedInterface, maker):
        """Provide a feature

        A feature provides an interface for objects that have another
        interface.

        Arguments:

        forInterface -- The interface the feature provides an interface for.

        providedInterface -- The provided interface

        maker -- a callable object that gets an feature component for
        a context component.
        """

    def getFeature(object, interface, default=None):
        """Look up a feature that provides an interface for an object

        The object also provides a place to look for placeful features.
        """

    def provideUtility(providedInterface, component):
        """Provide a utility

        A utility is a component that provides an interface.
        """

    def getUtility(object, interface, default=None):
        """Look up a utility that provides an interface

        The object provides a place to look for placeful features.
        """

    def providePresentation(forInterface, name, type, maker):
        """Provide a presentation

        A presentation provides some type of presentation (e.g. browser, ftp)
        for components of a given interface.

        Arguments:

        forInterface -- The interface the presentation is for

        name -- The presentation name

        type -- The presentation type, expressed as an interface

        maker -- a callable object that gets an presentation component for
        a context component.
        """

    def getPresentation(object, name, type, default=None):
        """Look up a named presentation of a given type for an object

        The type is expressed as an interface.

        The object also provides a place to look for placeful presentations.
        """


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

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

from Interface.Util import objectImplements

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 _find(self, require, provide):
        return self._reg.get((require, provide), None)

    def get(self, ob_interface, provide):
        """
        Finds a registered component that provides the given interface.
        Returns None if not found.
        """
        c = self._find(ob_interface, provide)
        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

    def getForObject(self, ob, provided):
        for i in objectImplements(ob):
            c=self.get(i, provided)
            if c is not None: return c
        return self.get(None, provided)
        


class IToIRegistryWithLabels (IToIRegistry):
    """
    Supports the use of label interfaces for inputs.
    """
    def register(self, require, provide, c):
        '''
        Registers a component.
        '''
        if isinstance(require, LabelInterface):
            # register the name instead of the interface.
            require = require.getName()
        self._registerAll(require, provide, c, provide)

    def _find(self, require, provide):
        if isinstance(require, LabelInterface):
            # Look up the name instead of the interface.
            return self._reg.get((require.getName(), provide), None)
        else:
            return self._reg.get((require, provide), None)


=== Added File Zope3/lib/python/Zope/ComponentArchitecture/__init__.py ===
from hooks import provideFeature, getFeature
from hooks import provideUtility, getUtility
from hooks import providePresentation, getPresentation


=== Added File Zope3/lib/python/Zope/ComponentArchitecture/hooks.py ===
"""Provide a hookable component architecture
"""

def provideFeature(forInterface, providedInterface, maker):
    return provideFeature_hook(forInterface, providedInterface, maker)

def getFeature(object, interface, default=None):
    return getFeature_hook(object, interface, default)

def provideUtility(providedInterface, component):
    return provideUtility_hook(providedInterface, component)

def getUtility(object, interface, default=None):
    return getUtility_hook(object, interface, default)

def providePresentation(forInterface, name, type, maker):
    return providePresentation_hook(forInterface, name, type, maker)

def getPresentation(object, name, type, default=None):
    return getPresentation_hook(object, name, type, default)

# default hooks

from IToIRegistry import IToIRegistry

_features = IToIRegistry()
def provideFeature_hook(forInterface, providedInterface, maker):
    _features.register(forInterface, providedInterface, maker)

def getFeature_hook(object, interface, default=None):
    if interface.isImplementedBy(object): return object
    c=_features.getForObject(object, interface)
    if c is None: return default
    return c(object)

_utilities = IToIRegistry()
def provideUtility_hook(providedInterface, component):
    _utilities.register(None, providedInterface, component)

def getUtility_hook(object, interface, default=None):
    c=_utilities.get(None, interface)
    if c is None: return default
    return c

_presentations = {}
def providePresentation_hook(forInterface, name, type, maker):
    reg=_presentations.get(name, None)
    if reg is None:
        reg=IToIRegistry()
        _presentations[name]=reg
    reg.register(forInterface, type, maker)

def getPresentation_hook(object, name, type, default=None):
    reg=_presentations.get(name, None)
    if reg is None: return default
    c=reg.getForObject(object, type)
    if c is None: return default
    return c(object)