[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)