[Zope-Checkins] CVS: Zope3/lib/python/Zope/App/OFS/Services/ServiceManager - IBindingAware.py:1.1.2.1 IServiceManager.py:1.1.2.1 ServiceManager.py:1.1.2.1 __init__.py:1.1.2.1 hooks.py:1.1.2.1 service-manager.zcml:1.1.2.1

Christian Theune ct@gocept.com
Sat, 25 May 2002 05:29:20 -0400


Update of /cvs-repository/Zope3/lib/python/Zope/App/OFS/Services/ServiceManager
In directory cvs.zope.org:/tmp/cvs-serv32651/lib/python/Zope/App/OFS/Services/ServiceManager

Added Files:
      Tag: ctheune-services_move-branch
	IBindingAware.py IServiceManager.py ServiceManager.py 
	__init__.py hooks.py service-manager.zcml 
Log Message:
First part of moving Zope.App.OFS.ServiceManager to Zope.App.OFS.Services.ServiceManager
(physically moved the files)


=== Added File Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/IBindingAware.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
# 
##############################################################################
"""

Revision information:
$Id: IBindingAware.py,v 1.1.2.1 2002/05/25 09:29:19 ctheune Exp $
"""

from Interface import Interface

class IBindingAware(Interface):
    
    def bound(name):
        """Called when an immediately-containing service manager binds this object to
        perform the named service"""
    
    def unbound(name):
        """Called when an immediately-containing service manager unbinds this object
        from performing the named service"""

=== Added File Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/IServiceManager.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
# 
##############################################################################
"""

$Id: IServiceManager.py,v 1.1.2.1 2002/05/25 09:29:19 ctheune Exp $
"""
from Interface import Interface
from Zope.ComponentArchitecture.IServiceManager import IServiceManager as \
  IGlobalServiceManager
  # XXX fix once this package is changed to LocalServiceManager
from Zope.App.OFS.Container.IContainer import IContainer

class IServiceManager(IGlobalServiceManager, IContainer):
    """
    Service Managers act as containers for Services.
    
    If a Service Manager is asked for a service it
    checks for those it contains, before using a context
    based lookup to find another service manager to delegate
    to. If no other service manager is found they defer
    to the ComponentArchitecture ServiceManager which
    contains file based services.
    """

    def bindService(serviceName, serviceComponentName):
        """provide a service implementation.  If the named object
        implements IBindingAware, the wrapped object is notified as per
        that interface"""

    def unbindService(serviceName):
        """no longer provide a service implementation.  If the named
        object implements IBindingAware, the wrapped object is notified
        as per that interface"""

    def getBoundService(name):
        """retrieve a bound service implimentation

        Get the component currently bound to the named Service
        in this ServiceService.  Does not search context.
        """
        


=== Added File Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/ServiceManager.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
# 
##############################################################################
"""

$Id: ServiceManager.py,v 1.1.2.1 2002/05/25 09:29:19 ctheune Exp $
"""

from IServiceManager import IServiceManager
from Zope.ComponentArchitecture.IServiceManagerContainer \
     import IServiceManagerContainer
from Zope.ComponentArchitecture import getService, \
     getNextServiceManager, getNextService
from Zope.ComponentArchitecture.GlobalServiceManager import UndefinedService
from Zope.ComponentArchitecture.GlobalServiceManager import InvalidService
from Zope.Exceptions import NotFoundError, ZopeError
from Zope.App.OFS.Content.Folder.Folder import Folder
from Zope.ContextWrapper import ContextMethod
from Zope.Proxy.ContextWrapper import ContextWrapper
from Zope.App.OFS.Container.BTreeContainer import BTreeContainer
from Zope.Proxy.ProxyIntrospection import removeAllProxies
from IBindingAware import IBindingAware

class ServiceManager(BTreeContainer):

    __implements__ = IServiceManager

    def __init__(self):
        self.__bindings = {}
        super(ServiceManager, self).__init__()


    def getServiceDefinitions(wrapped_self):
        clean_self=removeAllProxies(wrapped_self)
        """ see IServiceManager Interface """
        # Get the services defined here and above us, if any (as held
        # in a ServiceInterfaceService, presumably)
        sm=getNextServiceManager(wrapped_self)
        if sm is not None:
            serviceDefs=sm.getServiceDefinitions()
        else: serviceDefs={}
        # since there is no way to define an interface TTW right now,
        # worrying about this further is pointless--it probably will be
        # an interface service evetually though...so this would be useful then:

        serviceInterfaceServ= \
             clean_self.__bindings.get('ServiceInterfaceService')
        if serviceInterfaceServ:
            serviceDefs.update(dict(
               removeAllProxies(
                   wrapped_self.getObject(serviceInterfaceServ).objectItems()
                   )
               ))
        return serviceDefs

    getServiceDefinitions=ContextMethod(getServiceDefinitions)

    def getService(wrapped_self, name):
        """ see IServiceManager Interface"""
        clean_self=removeAllProxies(wrapped_self)

        service = clean_self.__bindings.get(name)

        if service:
            return ContextWrapper(wrapped_self.getObject(service),
                                  wrapped_self, name=service) # we want
        # to traverse by component name, not service name

        return getNextService(wrapped_self, name)

    getService=ContextMethod(getService)

    def getBoundService(self, name):
        """ see IServiceManager Interface"""

        return self.__bindings.get(name)

    def bindService(wrapped_self, serviceName, serviceComponentName):
        """ see IServiceManager Interface"""
        clean_self=removeAllProxies(wrapped_self)

        # This could raise a KeyError if we don't have this component
        clean_serviceComponent = wrapped_self.getObject(
            serviceComponentName
           )
        wrapped_serviceComponent=ContextWrapper(
            clean_serviceComponent,
            wrapped_self,
            name=serviceComponentName)

        for name,interface in wrapped_self.getServiceDefinitions():
            if name == serviceName:
                if not interface.isImplementedBy(clean_serviceComponent):
                    raise InvalidService(serviceName,
                                         serviceComponentName,
                                         interface)
            break

        # Services are added to the Manager through the Folder interface
        # self.setObject(name, component)
        
        if IBindingAware.isImplementedBy(clean_serviceComponent):
            wrapped_serviceComponent.bound(serviceName)

        clean_self.__bindings[serviceName] = serviceComponentName

        # trigger persistence
        clean_self.__bindings = clean_self.__bindings

    bindService=ContextMethod(bindService) # needed because of call to
    # getServiceDefinitions, as well as IBindingAware stuff

    def unbindService(wrapped_self, serviceName):
        """ see IServiceManager Interface """
        clean_self=removeAllProxies(wrapped_self)
        serviceComponentName=clean_self.__bindings[serviceName]
        
        clean_serviceComponent = wrapped_self.getObject(
            serviceComponentName
           )
        wrapped_serviceComponent=ContextWrapper(
            clean_serviceComponent,
            wrapped_self,
            name=serviceComponentName)
        
        if IBindingAware.isImplementedBy(clean_serviceComponent):
            wrapped_serviceComponent.unbound(serviceName)

        del clean_self.__bindings[serviceName]

        # trigger persistence
        clean_self.__bindings = clean_self.__bindings
    
    unbindService=ContextMethod(unbindService)


    def delObject(self, name):
        '''See interface IWriteContainer'''
        if name in self.__bindings.values():
            # Should we silently unbind the service?
            # self.unbindService(name)
            # No, let's raise an exception
            raise ZopeError("Cannot remove a bound service. Unbind it first.")
        BTreeContainer.delObject(self, name)


=== Added File Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/__init__.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
# 
##############################################################################



=== Added File Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/hooks.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
# 
##############################################################################
"""

$Id: hooks.py,v 1.1.2.1 2002/05/25 09:29:19 ctheune Exp $
"""
from Zope.ComponentArchitecture.IServiceManager import IServiceManager
from Zope.ComponentArchitecture.IServiceManagerContainer import \
 IServiceManagerContainer
from Zope.Proxy.ContextWrapper import getWrapperContainer, ContextWrapper
from Zope.ComponentArchitecture import getServiceManager
from Zope.ComponentArchitecture.Exceptions import ComponentLookupError
from Zope.ComponentArchitecture.GlobalServiceManager import serviceManager
from Zope.Proxy.ProxyIntrospection import removeAllProxies
    
def getServiceManager_hook(context):
    """
    context based lookup, with fallback to component architecture
    service manager if no service manager found within context
    """
    while context is not None:
        clean_context=removeAllProxies(context)
        # if the context is actually a service or service manager...
        if IServiceManager.isImplementedBy(clean_context):
            return context
        if IServiceManagerContainer.isImplementedBy(
            clean_context) and clean_context.hasServiceManager():
            return ContextWrapper(context.getServiceManager(), context, name="Services;etc")
        context = getWrapperContainer(context)
    return serviceManager

def getNextServiceManager_hook(context):
    """if the context is a service manager or a placeful service, tries
    to return the next highest service manager"""
    context=getServiceManager(context)
    if context is serviceManager: return None
    context=getWrapperContainer(context)
    while context and not \
          IServiceManagerContainer.isImplementedBy(removeAllProxies(context)):
        context=getWrapperContainer(context) # we should be
    # able to rely on the first step getting us a
    # ServiceManagerContainer
    context=getWrapperContainer(context)
    return getServiceManager(context)


=== Added File Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/service-manager.zcml ===
<zopeConfigure
   xmlns='http://namespaces.zope.org/zope'
   xmlns:security='http://namespaces.zope.org/security'
   xmlns:zmi='http://namespaces.zope.org/zmi'
   xmlns:browser='http://namespaces.zope.org/browser'
>

<security:protectClass name="Zope.App.OFS.ServiceManager+"
   permission_id="Zope.Public">
   
    <security:protect
               interface="Zope.App.OFS.Container.IContainer.IReadContainer"
               permission_id="Zope.Public" />
    <security:protect
               interface="Zope.App.OFS.Container.IContainer.IWriteContainer"
               permission_id="Zope.ManageServices" />
   
   <security:protect
               interface="Zope.App.OFS.ServiceManager.IServiceManager+"
               permission_id="Zope.ManageServices" />
    
   </security:protectClass>

<include package="Zope.App.OFS.ServiceManager.Views" file="views.zcml" />

<hook module="Zope.ComponentArchitecture" name="getServiceManager"
   implementation=".hooks.getServiceManager_hook" />
<hook module="Zope.ComponentArchitecture"
    name="getNextServiceManager"
    implementation=".hooks.getNextServiceManager_hook" />

</zopeConfigure>