[Zope-Checkins] CVS: Zope3/lib/python/Zope/ComponentArchitecture - GlobalAdapterService.py:1.1.2.1 GlobalFactoryService.py:1.1.2.1 GlobalResourceService.py:1.1.2.1 GlobalServiceManager.py:1.1.2.1 GlobalSkinService.py:1.1.2.1 GlobalUtilityService.py:1.1.2.1 GlobalViewService.py:1.1.2.1 IPlacefulComponentArchitecture.py:1.1.2.1 IServiceManager.py:1.1.2.1 IAdapterService.py:1.1.2.5 IFactory.py:1.1.2.4 IFactoryService.py:1.1.2.5 IResourceService.py:1.1.2.4 ISkinService.py:1.1.2.4 IUtilityService.py:1.1.2.5 ServiceManagerContainer.py:1.1.2.5 __init__.py:1.1.6.20 component.zcml:1.1.2.4 metaConfigure.py:1.1.2.21 IServiceService.py:NONE ResourceService.py:NONE Service.py:NONE SkinService.py:NONE ViewService.py:NONE hooks.py:NONE

Gary Poster garyposter@earthlink.net
Mon, 29 Apr 2002 19:20:43 -0400


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

Modified Files:
      Tag: Zope-3x-branch
	IAdapterService.py IFactory.py IFactoryService.py 
	IResourceService.py ISkinService.py IUtilityService.py 
	ServiceManagerContainer.py __init__.py component.zcml 
	metaConfigure.py 
Added Files:
      Tag: Zope-3x-branch
	GlobalAdapterService.py GlobalFactoryService.py 
	GlobalResourceService.py GlobalServiceManager.py 
	GlobalSkinService.py GlobalUtilityService.py 
	GlobalViewService.py IPlacefulComponentArchitecture.py 
	IServiceManager.py 
Removed Files:
      Tag: Zope-3x-branch
	IServiceService.py ResourceService.py Service.py 
	SkinService.py ViewService.py hooks.py 
Log Message:
ComponentArchitecture reorganization; addition of for_container; addition of IWriteContainer.isAddable.

good news: all tests pass; bad news: after the new security system, my changes have some problems.  I had to punt on the default contents view of all folders for instance--hasServiceManager is causing a problem for some reason I couldn't divine, even with Shane's Checker tool.  I commented out the offending code on the contents.pt just to keep things up.

I tagged before committing: gary_CA-reorganization

changes more in depth (as I understand it, all or most approved :-) ):

(in ComponentArchitecture:)
 * changing implementation names to Global* (i.e., AdapterService becomes 
GlobalAdapterService) and giving each its own file (many are clumped together 
in hooks.py)
 * removing hooks.py in ComponentArchitecture, putting all functions in appropriate module above (i.e. getAdapter will be in the adapter module)
 * largely removing indirection (_hook) except for getService and 
getNextService
 * changing IServiceService.py to IServiceManager
 * changing Service.py to GlobalServiceManager.py (and class name too)
 * removing "provide*" functions (i.e., provideAdapter, provideUtility, etc.) 
and "defineService" from the __init__.py imports
 * change all global services to classes with appropriate methods as per 
interfaces
 * update all tests 
 * remove all of the "provide*" functions from the interfaces
 * renamed IComponentArchitecture to IPlacefulComponentArchitecture (hereafter IPCA), after long discussion with SteveA 
 * list Resources as one of core CA services in IPlacefulComponentArchitecture
 * build actual IPCA interface, not just import of service interfaces (because we want IPCA to be placeful, but the service interfaces do not need to be)
 * place functions implementing ICA actually in __init__
 * explicitly setting up services in zcml
 * created Global service interfaces, and placed the "provides" and "set" and "define" functions there: however, to keep the main interfaces clean and clear, I placed these global interfaces in the same file as the global implementations, hoping to clarify that these are not reusable interfaces but descriptive, one-time interfaces
 * built PlacefulSetup in Zope.ComponentArchitecture.tests for more specific CleanUp (a subclass).  PlacefulSetup is in the tests folder of the local ServiceManager.  AddableSetup also is available, in the AddableService tests.

(elsewhere in Zope3)
 * built for_container in addables
 * built isAddable for containers (after discussion with Jim, we decided an addable "contains" attribute in the zcml might not be the way to go.  I chose the isAddable approach for a number of reasons)
 * addableservice does some more checks in getting the addable list, pertinent to the above and to whether it can find the appropriate factories
 * a few more tests: a start of one in the local event service, and some more here and there

I'm sorry to add to the confusion of the big security changes, but I needed to either trash these changes or commit them: I'm a bit out of time for the moment.  If all else fails, again, I did tag the previous version.



=== Added File Zope3/lib/python/Zope/ComponentArchitecture/GlobalAdapterService.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.
# 
##############################################################################
"""adapter service
"""

from IToIRegistry import IToIRegistry
from Exceptions import ComponentLookupError
from IAdapterService import IAdapterService
from Zope.ComponentArchitecture import _marker
from Zope.Proxy.ProxyIntrospection import removeAllProxies

class IGlobalAdapterService(IAdapterService):

    def provideAdapter(forInterface, providedInterface, maker):
        """Provide an adapter

        An adapter provides an interface for objects that have another
        interface.

        Arguments:

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

        providedInterface -- The provided interface

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

class GlobalAdapterService:
    
    __implements__=IGlobalAdapterService
    
    def __init__(self):
        self.__adapters=IToIRegistry()
    
    def provideAdapter(self, forInterface, providedInterface, maker):
        """see IGlobalAdapterService interface"""
        self.__adapters.register(forInterface, providedInterface, maker)

    def getAdapter(self, object, interface, default=_marker):
        """see IAdapterService interface"""
        clean_object=removeAllProxies(object)
        if interface.isImplementedBy(clean_object): return object
        makers = self.__adapters.getForObject(clean_object, interface)
        if makers is None:
            if default is not _marker: return default
            raise ComponentLookupError(object, interface)
        result = object
        for maker in makers:
            result = maker(result)
        return result

    _clear = __init__

# the global adapter service instance (see component.zcml )
adapterService = GlobalAdapterService()




_clear         = adapterService._clear

# Register our cleanup with Testing.CleanUp to make writing unit tests simpler.
from Zope.Testing.CleanUp import addCleanUp
addCleanUp(_clear)
del addCleanUp

=== Added File Zope3/lib/python/Zope/ComponentArchitecture/GlobalFactoryService.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.
# 
##############################################################################
"""factory service
"""


from Interface.Verify import verifyObject
from IFactory import IFactory
from IFactoryService import IFactoryService
from Zope.ComponentArchitecture.Exceptions import ComponentLookupError
from Zope.Proxy.ProxyIntrospection import removeAllProxies


class IGlobalFactoryService(IFactoryService):

    def provideFactory(name, factory):
        """Provide a factory for the given name.
        """

class GlobalFactoryService:
    
    __implements__ = IGlobalFactoryService
    
    def __init__(self):
        self.__factories={}

    def provideFactory(self, name, factory):
        """See IGlobalFactoryService interface"""
        verifyObject(IFactory, removeAllProxies(factory))
        self.__factories[name] = factory

    def createObject(self, name, *args, **kwargs):
        """See IFactoryService interface"""
        try: return self.__factories[name](*args, **kwargs)
        except KeyError:
            raise ComponentLookupError(name)
    
    def getInterfaces(self, name):
        """See IFactoryService interface"""
        try: return self.__factories[name].getInterfaces()
        except KeyError:
            raise ComponentLookupError(name)

    _clear = __init__

# the global factory service instance (see component.zcml )
factoryService = GlobalFactoryService()




_clear         = factoryService._clear

# Register our cleanup with Testing.CleanUp to make writing unit tests simpler.
from Zope.Testing.CleanUp import addCleanUp
addCleanUp(_clear)
del addCleanUp

=== Added File Zope3/lib/python/Zope/ComponentArchitecture/GlobalResourceService.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: GlobalResourceService.py,v 1.1.2.1 2002/04/29 23:20:10 poster Exp $
"""

from IToIRegistry import IRegistry
from Exceptions import ComponentLookupError
from Zope.ComponentArchitecture import getSkin, _marker
from IResourceService import IResourceService

class IGlobalResourceService(IResourceService):

    def provideResource(name, type, component, layer=''):
        """Provide a resource

        A resource is an inependent component that provides a view
        type.  It is like a view except that it acts by itself,
        typically to support views. Common resources include images,
        style sheets, etc.

        Arguments:

        name -- The resource name

        type -- The resource type, expressed as an interface

        component -- the resource component.

        layer -- Optional skin layer. Layers are used to define skins.
        """

class GlobalResourceService:

    def __init__(self):
        self.__layers = {}

    __implements__ = IGlobalResourceService
        
    # Implementation methods for interface
    # Zope.ComponentArchitecture.IResourceService.

    def getResource(self, object, name, type, default=_marker, skin=''):
        '''See interface IResourceService'''
        for layername in getSkin(object, skin, type):
            layer = self.__layers.get(layername)
            if not layer: continue
            reg = layer.get(name, None)
            if reg is None: continue
            c = reg.getForObject(object, type)
            if c is None: continue
            return c

        if default is _marker:
            raise ComponentLookupError(object, name, type)

        return default

    def getRequestResource(self, object, name, request, default=_marker):
        '''See interface IResourceService'''

        type = request.getViewType()
        skin = request.getViewSkin()

        return self.getResource(object, name, type, default, skin)
        
        
    def provideResource(self, name, type, component, layer=''):
        '''See interface IGlobalResourceService'''

        resources = self.__layers.get(layer)
        if resources is None:
            resources = self.__layers[layer] = {}

        reg = resources.get(name, None)
        if reg is None:
            reg = resources[name] = IRegistry()

        reg.register(type, component)

    _clear = __init__
    
resourceService = GlobalResourceService()




_clear             = resourceService._clear


# Register our cleanup with Testing.CleanUp to make writing unit tests simpler.
from Zope.Testing.CleanUp import addCleanUp
addCleanUp(_clear)
del addCleanUp


=== Added File Zope3/lib/python/Zope/ComponentArchitecture/GlobalServiceManager.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: GlobalServiceManager.py,v 1.1.2.1 2002/04/29 23:20:10 poster Exp $
"""

from Zope.Exceptions import DuplicationError
from IServiceManager import IServiceManager
from Exceptions import ComponentLookupError


class IGlobalServiceManager(IServiceManager):
    
    def defineService(name, interface):
        """Define a new service of the given name implementing the given
        interface.  If the name already exists, raises
        Zope.Exceptions.DuplicationError"""
    
    def provideService(name, component):
        """provide a service component to do the work of the named
        service.  If a service component has already been assigned to
        this name, raise Zope.Exceptions.DuplicationError; if the name
        has not been defined, raises
        Zope.ComponentArchitecture.GlobalServiceManager.UndefinedService;
        if the component does not implement the registered interface for
        the service name, raises
        Zope.ComponentArchitecture.GlobalServiceManager.InvalidService.
        """

class UndefinedService(Exception):
    """An attempt to register a service that has not been defined
    """

class InvalidService(Exception):
    """An attempt to register a service that doesn't implement
       the required interface
    """
    
class GlobalServiceManager:
    """service manager"""

    __implements__ = IGlobalServiceManager

    def __init__(self):
        self.__defs     = {}
        self.__services = {}
    
    def defineService(self, name, interface):
        """see IGlobalServiceManager interface"""

        if name in self.__defs:
            raise DuplicationError(name)

        self.__defs[name] = interface

    def getServiceDefinitions(self):
        """see IServiceManager Interface"""
        return self.__defs.items()

    def provideService(self, name, component):
        """see IGlobalServiceManager interface"""

        if name in self.__services:
            raise DuplicationError(name)

        if name not in self.__defs:
            raise UndefinedService(name)

        if not self.__defs[name].isImplementedBy(component):
            raise InvalidService(name, component, self.__defs[name])

        self.__services[name] = component

    def getService(self, name):
        """see IServiceManager interface"""

        try:
            return self.__services[name]
        except KeyError:
            raise ComponentLookupError(name)

    _clear = __init__


serviceManager = GlobalServiceManager() # the global service manager instance



_clear         = serviceManager._clear

# Register our cleanup with Testing.CleanUp to make writing unit tests simpler.
from Zope.Testing.CleanUp import addCleanUp
addCleanUp(_clear)
del addCleanUp


=== Added File Zope3/lib/python/Zope/ComponentArchitecture/GlobalSkinService.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: GlobalSkinService.py,v 1.1.2.1 2002/04/29 23:20:10 poster Exp $
"""

from IToIRegistry import IToIRegistry
from Exceptions import ComponentLookupError
from ISkinService import ISkinService
from IToIRegistry import DataRegistry
from Zope.Proxy.ProxyIntrospection import removeAllProxies


class IGlobalSkinService(ISkinService):

    def defineSkin(name, view_type, layers):
        """Define a skin for a given view type as a sequence of layers

        There is a predefined skin, '', with a single layer, ''.
        """

_default = ('',)

class GlobalSkinService:

    def __init__(self):
        self.__skins = {}

    __implements__ = IGlobalSkinService
        
    # Implementation methods for interface
    # Zope.ComponentArchitecture.ISkinService.

    def defineSkin(self, name, view_type, layers):
        '''See interface IGlobalSkinService'''
        
        reg = self.__skins.get(name, None)
        if reg is None:
            reg = self.__skins[name] = DataRegistry()

        reg.register(view_type, layers)

    def getSkin(self, object, name, view_type):
        '''See interface ISkinService'''

        clean_object=removeAllProxies(object)
        reg = self.__skins.get(name, None)
        if reg is not None:
            layers = reg.getForObject(clean_object, view_type)
            if layers is not None:
                return layers
        if not name:
            return _default
        return ('',)

    _clear = __init__
    
skinService = GlobalSkinService()



_clear     = skinService._clear

# Register our cleanup with Testing.CleanUp to make writing unit tests simpler.
from Zope.Testing.CleanUp import addCleanUp
addCleanUp(_clear)
del addCleanUp


=== Added File Zope3/lib/python/Zope/ComponentArchitecture/GlobalUtilityService.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.
# 
##############################################################################
"""utility service

$Id: GlobalUtilityService.py,v 1.1.2.1 2002/04/29 23:20:10 poster Exp $
"""

from IUtilityService import IUtilityService
from IToIRegistry import IRegistry
from Exceptions import ComponentLookupError

class IGlobalUtilityService(IUtilityService):

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

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

class GlobalUtilityService:
    
    __implements__=IGlobalUtilityService
    
    def __init__(self):
        self.__utilities=IRegistry()

    def provideUtility(self, providedInterface, component):
        """See IGlobalUtilityService interface"""
        self.__utilities.register(providedInterface, component)

    def getUtility(self, interface, default=None):
        """See IUtilityService interface"""
        c=self.__utilities.get(None, interface)
        if c is None:
            if default: return default
            raise ComponentLookupError(interface)
        return c
    
    _clear = __init__

# the global utility service instance (see component.zcml )
utilityService = GlobalUtilityService()




_clear         = utilityService._clear

# Register our cleanup with Testing.CleanUp to make writing unit tests simpler.
from Zope.Testing.CleanUp import addCleanUp
addCleanUp(_clear)
del addCleanUp

=== Added File Zope3/lib/python/Zope/ComponentArchitecture/GlobalViewService.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: GlobalViewService.py,v 1.1.2.1 2002/04/29 23:20:10 poster Exp $
"""

from IToIRegistry import IToIRegistry, IToIDataRegistry
from Exceptions import ComponentLookupError
from Zope.ComponentArchitecture import getSkin, _marker
from IViewService import IViewService
from Zope.Exceptions import NotFoundError
from Zope.Proxy.ProxyIntrospection import removeAllProxies

class IGlobalViewService(IViewService):
    
    def setDefaultViewName(i_required, i_provided, name):
        '''Add name to our registry of default view names for
           the interfaces given.
        '''
    def provideView(forInterface, name, type, maker, layer=''):
        ""

class GlobalViewService:

    __implements__ = IGlobalViewService

    def __init__(self):
        self.__layers = {}
        self.__default_view_names = IToIDataRegistry()

    def setDefaultViewName(self, i_required, i_provided, name):
        self.__default_view_names.register(i_required,
                                           i_provided,
                                           name)
        
    # Implementation methods for interface
    # Zope.ComponentArchitecture.IViewService.

    def getViewDefinitions(self, name=None, used_for=None, type=None,
                           layer=None):
        '''See interface IViewService'''

        result = []

        if layer is None:
            layers = self.__layers.keys()
        else:
            layers = [layer]

        for layername in layers:
            layer = self.__layers[layername]
            if name is None:
                names = layer.keys()
            else:
                names = [name]

            for n in names:
                result.extend(
                    [{ 'name': n,
                       'used_for': definition['used_for'],
                       'type': definition['provides'],
                       'layer': layername,
                       'factory': definition['factory'],
                       }
                     for definition
                     in layer[n].getDefinitions(used_for, type)
                     ]
                    )
                    
        return result                

    def getView(self, object, name, type, default=_marker, skin=''):
        '''See interface IViewService'''
        clean_object=removeAllProxies(object)
        for layername in getSkin(object, skin, type):
            layer = self.__layers.get(layername)
            if not layer:
                continue
            reg = layer.get(name, None)
            if reg is None:
                continue
            makers = reg.getForObject(clean_object, type)
            if makers is None:
                continue

            result = object
            for maker in makers:
                result = maker(result)

            return result
        
        if default is _marker:
            raise ComponentLookupError(object, name, type)
        return default

    def getRequestView(self, object, name, request, default=_marker):
        '''See interface IViewService'''

        type = request.getViewType()
        skin = request.getViewSkin()

        view =  self.getView(object, name, type, default, skin)

        # using self as marker
        setViewRequest = getattr(view, 'setViewRequest', self)        
        if setViewRequest is not self:
            setViewRequest(request)

        return view
        
        
    def provideView(self, forInterface, name, type, maker, layer=''):
        '''See interface IGlobalViewService'''

        views = self.__layers.get(layer)
        if views is None:
            views = self.__layers[layer] = {}

        reg = views.get(name, None)
        if reg is None:
            reg = views[name] = IToIRegistry()

        reg.register(forInterface, type, maker)

    def getDefaultViewName(self, object, type, default=_marker):
        '''See interface IViewService'''
        name = self.__default_view_names.getForObject(object, type)
        if name is None:
            if default is not _marker:
                return default
            raise NotFoundError, \
                  'No default view name found for object %s' % object
        return name


    def getRequestDefaultViewName(self, object, request, default=_marker):
        '''See interface IViewService'''
        return self.getDefaultViewName(object,
                                       request.getViewType(),
                                       default=default
                                       )

    _clear = __init__
    
viewService = GlobalViewService()





_clear         = viewService._clear


# Register our cleanup with Testing.CleanUp to make writing unit tests simpler.
from Zope.Testing.CleanUp import addCleanUp
addCleanUp(_clear)
del addCleanUp


=== Added File Zope3/lib/python/Zope/ComponentArchitecture/IPlacefulComponentArchitecture.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: IPlacefulComponentArchitecture.py,v 1.1.2.1 2002/04/29 23:20:10 poster Exp $
"""
from Interface import Interface

class IPlacefulComponentArchitecture(Interface):
    """The Component Architecture is defined by six key services,
    all of which are managed by service managers.
    """

    # basic service manager tools
    
    def getServiceManager(context):
        """returns the nearest service manager to the context; if the
        context is None the global service manager is always returned"""

    def getService(context, name):
        """returns the service defined by 'name' nearest to the context;
        if the context is None the pertinent global service is always
        returned"""

    def getServiceDefinitions(context): 
        """returns a dictionary of the service definitions pertinent to
        the given context, in the format {nameString: serviceInterface}.
        If the context is None the global definitions will be returned.
        The default behavior of placeful service managers is to include
        service definitions above them, but this can be overridden"""

    # placeful service convenience tools

    def getNextServiceManager(context):
        """Given a placefully wrapped service manager, service, or
        service component, will return the next placeful service manager
        (wrapped) above the current service manager, or the global
        service manager if none is higher.  if the context is the global
        service manager, the function raises
        Zope.ComponentArchitecture.ComponentLookupError"""

    def getNextService(context, name):
        """Identical to getNextServiceManager, but will try to find the
        next named service, proceeding finally to the global versions,
        and then returning 
        Zope.ComponentArchitecture.ComponentLookupError"""

    # Utility service

    def getUtility(context, interface, default=None):
        """returns the nearest utility to the context that implements
        the specified interface.  If one is not found, returns default
        if it is passed as an argument, or raises
        Zope.ComponentArchitecture.ComponentLookupError otherwise"""

    # Adapter service

    def getAdapter(object, interface, default=None, context=None):
        """returns the nearest adapter to the context that can adapt
        object to interface.  If context is not specified, attempts to
        use wrapping around object to specify a context.  If a matching
        adapter cannot be found, returns default if it is passed as an argument, or raises
        Zope.ComponentArchitecture.ComponentLookupError otherwise"""

    # Factory service

    def createObject(context, name, *args, **kwargs):
        """finds the factory of the given name that is nearest to the
        context, and passes the other given arguments to the factory
        to create a new instance. Returns a reference to the new
        object.  If a matching factory cannot be found raises
        Zope.ComponentArchitecture.ComponentLookupError"""

    def getFactoryInterfaces(context, name):
        """finds the factory of the given name that is nearest to the
        context, and returns the interface or interface tuple that
        object instances created by the named factory will implement."""

    # Skin service

    def getSkin(wrapped_object, name, view_type):
        """returns the nearest skin (sequence of layer names) to the
        object, as specified by the name and the view type (browser,
        xml-rpc, etc.) as expressed by an interface.  If a matching skin
        is not found, raises
        Zope.ComponentArchitecture.ComponentLookupError
        
        There is a predefined skin in the global skin service, '', with
        a single layer, ''."""

    # View service

    def getView(wrapped_object, name, view_type, default=None, skin=''):
        """Return the named view of a given type for an object and the
        given skin.  The nearest one to the object is found.  The type
        is expressed as an interface.  If a
        matching view cannot be found, returns default
        if it is passed as an argument, or raises
        Zope.ComponentArchitecture.ComponentLookupError otherwise.
        """

    def getRequestView(wrapped_object, name, request, default=None):
        """Look up a named view for a given request and object.  The
        request must implement IViewRequest: it provides the view
        type and the skin name.  The nearest one to the object is
        found.  If the view implements setViewRequest, that method is
        called with the Request.  If a matching view cannot be found,
        returns default if it is passed as an argument, or raises
        Zope.ComponentArchitecture.ComponentLookupError otherwise.
        """

    def getDefaultViewName(wrapped_object, view_type, default=None):
        """Look up the name of the default view of the object for the
        given view type.  The nearest one to the object is
        found.  If a matching
        default view name cannot be found, returns the default argument
        if it is passed as an argument, or raises Zope.NotFoundError otherwise.
        """

    def getRequestDefaultViewName(wrapped_object, request, default=None):
        """Look up the name of the default view of the object for the
        given request.  The request must implement IViewRequest, and
        provides the desired view type.  The nearest one to the object is
        found.  If a matching
        default view name cannot be found, returns the default argument
        if it is passed as an argument, or raises Zope.NotFoundError otherwise.
        """

    def getViewDefinitions(context, name=None, used_for=None, \
                           view_type=None, layer=None):
        """Get matching view definitions for the given context.  If the
        context is None then it will explicitly use the global view
        service.

        Get view definitions as a sequence of mapping objects with keys:

        - name

        - used_for

        - type

        - layer

        - factory

        The arguments may be given as keyword arguments and define a
        query for the retrieval.
        """

    # Resource service

    def getResource(wrapped_object, name, type, default=None, skin=''):
        """Look up a named resource of a given type

        The type is expressed as an interface.

        The object provides a place to look for placeful resources.
        
        If the component can't be found, and a default argument was
        passed to the function, the default argument is returned.

        A Zope.ComponentArchitecture.ComponentLookupError will be
        raised if the component can't be found otherwise.
        """

    def getRequestResource(wrapped_object, name, request, default=None):
        """Look up a named resource for a given request

        The request must implement IViewRequest.

        The object provides a place to look for placeful resources.
        
        If the component can't be found, and a default argument was
        passed to the function, the default argument is returned.

        A Zope.ComponentArchitecture.ComponentLookupError will be
        raised if the component can't be found.
        """

=== Added File Zope3/lib/python/Zope/ComponentArchitecture/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/04/29 23:20:10 poster Exp $
"""

from Interface import Interface

class IServiceManager(Interface):

    def getServiceDefinitions():
        """Retrieve all Service Definitions

        Should return a list of tuples (name, interface)
        """        

    def getService(name):
        """retrieve a service implementation

        Default implimentations search the context for the next
        ServiceService implimentation if the requested Service
        is not found.
        
        If none is found anywhere, raises ComponentLookupError
        """


=== Zope3/lib/python/Zope/ComponentArchitecture/IAdapterService.py 1.1.2.4 => 1.1.2.5 ===
 class IAdapterService(Interface):
 
-    def provideAdapter(forInterface, providedInterface, maker):
-        """Provide an adapter
-
-        An adapter provides an interface for objects that have another
-        interface.
-
-        Arguments:
-
-        forInterface -- The interface the adapter provides an interface for.
-
-        providedInterface -- The provided interface
-
-        maker -- a callable object that gets an adapter component for
-        a context component.
-        """
-
-    def getAdapter(object, interface, default=None, place=None):
+    def getAdapter(object, interface, default=None):
         """Look up an adapter that provides an interface for an object
-
-        The place argument provides a place to look for placeful adapters.
-        
-        If no place argument is given, place defaults to object.
 
         A Zope.ComponentArchitecture.ComponentLookupError will be
         raised if the component can't be found.


=== Zope3/lib/python/Zope/ComponentArchitecture/IFactory.py 1.1.2.3 => 1.1.2.4 ===
     def __call__():
         """Return an instance of the objects we're a factory for."""
+    def getInterfaces():
+        """Return the interface(s) that objects created by this factory
+        will implement."""


=== Zope3/lib/python/Zope/ComponentArchitecture/IFactoryService.py 1.1.2.4 => 1.1.2.5 ===
 class IFactoryService(Interface):
 
-    def provideFactory(name, factory):
-        """Provide a factory for the given name.
-        """
-
-    def createObject(place, name):
-        """Create a new object using the factory with the given name
-
-        The place provides a place to look for placeful views.
+    def createObject(name, *args, **kwargs):
+        """Create a new object using the factory with the given name,
+        passing all remaining arguments to the factory transparently.
 
         A Zope.ComponentArchitecture.ComponentLookupError will be
         raised if the factory component can't be found.
         """
+    def getInterfaces(name):
+        """returns the interface or interface tuple that
+        object instances created by the named factory will implement."""
+    
\ No newline at end of file


=== Zope3/lib/python/Zope/ComponentArchitecture/IResourceService.py 1.1.2.3 => 1.1.2.4 ===
 class IResourceService(Interface):
 
-    def provideResource(name, type, component, layer=''):
-        """Provide a resource
-
-        A resource is an inependent component that provides a view
-        type.  It is like a view except that it acts by itself,
-        typically to support views. Common resources include images,
-        style sheets, ets.
-
-        Arguments:
-
-        name -- The resource name
-
-        type -- The resource type, expressed as an interface
-
-        component -- the resource component.
-
-        layer -- Optional skin layer. Layers are used to define skins.
-        """
-
     def getResource(object, name, type, default=None, skin=''):
         """Look up a named resource of a given type
 


=== Zope3/lib/python/Zope/ComponentArchitecture/ISkinService.py 1.1.2.3 => 1.1.2.4 ===
 class ISkinService(Interface):
 
-    def defineSkin(skin, type, layers):
-        """Define a skin for a given view type as a sequence of layers
-
-        There is a predefined skin, '', with a single layer, ''.
-        """
-
-    def getSkin(object, skin, type):
+    def getSkin(object, name, view_type):
         """Return the sequence of layers (names) making up the skin.
 
         The object provides a place to look for placeful skin definitions.
 
         If the skin was not defined, an empty sequence will be returned.
-        """
+        """
\ No newline at end of file


=== Zope3/lib/python/Zope/ComponentArchitecture/IUtilityService.py 1.1.2.4 => 1.1.2.5 ===
 class IUtilityService(Interface):
 
-    def provideUtility(providedInterface, component):
-        """Provide a utility
+    def getUtility(interface, default=None):
+        """Look up a utility that provides an interface in this
+        service, delegating to the next higher service if one is not
+        found.  If one is not found, returns default if not None, or raises
+        Zope.ComponentArchitecture.ComponentLookupError otherwise"""
 
-        A utility is a component that provides an interface.
-        """
-
-    def getUtility(place, interface, default=None):
-        """Look up a utility that provides an interface
-
-        The place argument provides a place to look for placeful adapters.
-
-        A Zope.ComponentArchitecture.ComponentLookupError will be
-        raised if the component can't be found.
-        """


=== Zope3/lib/python/Zope/ComponentArchitecture/ServiceManagerContainer.py 1.1.2.4 => 1.1.2.5 ===
 
 from IServiceManagerContainer import IServiceManagerContainer
-from IServiceService import IServiceService
+from IServiceManager import IServiceManager
 from Zope.ComponentArchitecture.Exceptions import ComponentLookupError
-from Zope.ContextWrapper import Wrapper, ContextMethod
+from Zope.Proxy.ContextWrapper import ContextWrapper
+from Zope.ContextWrapper import ContextMethod
 
 _marker = object()
 
@@ -41,7 +42,7 @@
         '''See interface IServiceManagerContainer'''
 
         try:
-            return Wrapper(wrapped_self.__sm, wrapped_self) # no name
+            return ContextWrapper(wrapped_self.__sm, wrapped_self) # no name
         except AttributeError:
             if default is _marker:
                 raise ComponentLookupError
@@ -53,10 +54,10 @@
     def setServiceManager(self, sm):
         '''See interface IServiceManagerContainer'''
 
-        if IServiceService.isImplementedBy(sm):
+        if IServiceManager.isImplementedBy(sm):
             self.__sm = sm
         else:
-            raise ValueError('setServiceManager requires an IServiceService')
+            raise ValueError('setServiceManager requires an IServiceManager')
 
     #
     ############################################################


=== Zope3/lib/python/Zope/ComponentArchitecture/__init__.py 1.1.6.19 => 1.1.6.20 ===
 """
 
-# XXX We really shouldn't have the mutators here. 
+from IPlacefulComponentArchitecture import IPlacefulComponentArchitecture
+from Exceptions import ComponentLookupError
+from GlobalServiceManager import serviceManager
+__implements__ = IPlacefulComponentArchitecture
 
-from IComponentArchitecture import IComponentArchitecture
 
+_marker = object() # this exact marker is used throughout CA
 
-from hooks import provideAdapter, getAdapter
-from hooks import provideUtility, getUtility
-from hooks import provideFactory, createObject
-from hooks import getServiceManager, getNextServiceManager, \
-    getService, getServiceDefinitions, getNextService, \
-    getGlobalServiceManager
-from Service import defineService, provideService
-from SkinService import getSkin, defineSkin
-from ViewService import getView, provideView, getRequestView
-from ViewService import getDefaultViewName, getRequestDefaultViewName, \
-     setDefaultViewName
-from ResourceService import getResource, provideResource, getRequestResource
-
-def _clear():
-    from hooks import _clear;       _clear()
-    from Service import _clear;     _clear()
-    from ViewService import _clear; _clear()
-    from ResourceService import _clear; _clear()
-    from SkinService import _clear; _clear()
+# placeful component architecture functions
 
-__implements__ = IComponentArchitecture
+# basic service manager tools
+
+def getServiceManager(context): # hookable
+    return getServiceManager_hook(context)
+
+def getServiceManager_hook(context): # default hook
+    return serviceManager
+
+def getService(context, name):
+    return getServiceManager(context).getService(name)
+
+def getServiceDefinitions(context): 
+    return getServiceManager(context).getServiceDefinitions()
+
+# placeful service manager convenience tools
+
+def getNextServiceManager(context): # hookable
+    return getNextServiceManager_hook(context)
+
+def getNextServiceManager_hook(context): #default hook
+    raise ComponentLookupError
+    
+def getNextService(context, name):
+    sm=getNextServiceManager(context)
+    if sm:
+        return sm.getService(name)
+    return None
+
+
+# Utility service
+
+def getUtility(context, interface, default=None):
+    return getService(context, 'Utilities').getUtility(interface, default)
+
+# Adapter service
+
+def getAdapter(object, interface, default=_marker, context=None):
+    if context is None:
+        context = object
+    return getService(context, 'Adapters').getAdapter(object, interface, default)
+
+# Factory service
+
+def createObject(context, name, *args, **kwargs):
+    return getService(context, 'Factories').createObject(name, *args, **kwargs)
+
+def getFactoryInterfaces(context, name):
+    return getService(context, 'Factories').getInterfaces(name)
+
+# Skin service
+
+def getSkin(wrapped_object, name, view_type):
+    return getService(wrapped_object, 
+                      'Skins').getSkin(wrapped_object, name, view_type)
+
+# View service
+
+def getView(wrapped_object, name, view_type, default=_marker, skin=''):
+    return getService(wrapped_object, 
+                      'Views').getView(wrapped_object, name, view_type,
+                                                default, skin)
+
+def getRequestView(wrapped_object, name, request, default=_marker):
+    return getService(wrapped_object, 
+                      'Views').getRequestView(wrapped_object, name,
+                                                       request, default)
+
+def getDefaultViewName(wrapped_object, view_type, default=_marker):
+    return getService(wrapped_object, 
+                      'Views').getDefaultViewName(wrapped_object,
+                                                           view_type, default)
+
+def getRequestDefaultViewName(wrapped_object, request, default=_marker):
+    return getService(wrapped_object, 
+                      'Views').getRequestDefaultViewName(wrapped_object,
+                                                           request, default)
+
+def getViewDefinitions(context, name=None, used_for=None, 
+                       view_type=None, layer=None):
+    return getService(context, 'Views').getViewDefinitions(context,
+                                                           name, used_for,
+                                                           view_type, layer)
+
+# Resource service
+
+def getResource(wrapped_object, name, type, default=_marker, skin=''):
+    return getService(wrapped_object, 
+                      'Resources').getResource(wrapped_object, name,
+                                                        type, default, skin)
+
+def getRequestResource(wrapped_object, name, request, default=_marker):
+    return getService(wrapped_object,
+                      'Resources').getRequestResource(wrapped_object, name,
+                                                               request,
+                                                               default)
+
+
+#def _clear():
+#    from Service import _clear;     _clear()
+#    from ViewService import _clear; _clear()
+#    from ResourceService import _clear; _clear()
+#    from SkinService import _clear; _clear()


=== Zope3/lib/python/Zope/ComponentArchitecture/component.zcml 1.1.2.3 => 1.1.2.4 ===
 >
 
-<serviceType name='Views' 
-             interface='Zope.ComponentArchitecture.IViewService.' />
+<serviceType name='Utilities'
+             interface='.IUtilityService+' />
+<service name='Utilities'
+             component='.GlobalUtilityService.utilityService' />
+
+<serviceType name='Adapters'
+             interface='.IAdapterService+' />
+<service name='Adapters'
+             component='.GlobalAdapterService.adapterService' />
+
+<serviceType name='Factories'
+             interface='.IFactoryService+' />
+<service name='Factories'
+             component='.GlobalFactoryService.factoryService' />
 
+<serviceType name='Skins'
+             interface='.ISkinService+' />
+<service name='Skins'
+             component='.GlobalSkinService.skinService' />
+
+<serviceType name='Views' 
+             interface='.IViewService+' />
 <service name='Views'
-         component='Zope.ComponentArchitecture.ViewService.viewService' />
+         component='.GlobalViewService.viewService' />
+
+<serviceType name='Resources'
+             interface='.IResourceService+' />
+<service name='Resources'
+             component='.GlobalResourceService.resourceService' />
 
-<hookable module=".hooks" name="getServiceManager" />
-<hookable module=".hooks" name="getNextServiceManager" />
-<hookable module=".hooks" name="getService" />
-<hookable module=".hooks" name="getServiceDefinitions" />
-<hookable module=".hooks" name="getNextService" />
-<hookable module=".hooks" name="getAdapter" />
-<hookable module=".hooks" name="provideAdapter" />
-<hookable module=".hooks" name="getUtility" />
-<hookable module=".hooks" name="provideUtility" />
-<hookable module=".hooks" name="createObject" />
-<hookable module=".hooks" name="provideFactory" />
+<hookable name=".getServiceManager" />
+<hookable name=".getNextServiceManager" />
 
 </zopeConfigure>


=== Zope3/lib/python/Zope/ComponentArchitecture/metaConfigure.py 1.1.2.20 => 1.1.2.21 ===
 # 
 ##############################################################################
-from hooks import provideAdapter, provideUtility, provideFactory
-from ViewService import provideView, setDefaultViewName
-from ResourceService import provideResource
-from SkinService import defineSkin
+
+from Zope.ComponentArchitecture import getService, getServiceManager
 from Zope.Configuration import namespace
-from Service import defineService, provideService
+#from GlobalServiceManager import serviceManager
+#from GlobalViewService import viewService
+#from GlobalUtilityService import utilityService
+#from GlobalFactoryService import factoryService
+#from GlobalSkinService import skinService
+#from GlobalResourceService import resourceService
+#from GlobalAdapterService import adapterService
 from Zope.Configuration.Action import Action
 
+# I prefer the indirection (using getService and getServiceManager vs.
+# directly importing the various services)  not only because it makes
+# unit tests easier, but also because it reinforces that the services
+# should always be obtained through the
+# IPlacefulComponentArchitecture interface methods
+
+def handler(serviceName, methodName, *args, **kwargs):
+    method=getattr(getService(None, serviceName), methodName)
+    method(*args, **kwargs)
+
+def managerHandler(methodName, *args, **kwargs):
+    method=getattr(getServiceManager(None), methodName)
+    method(*args, **kwargs)
 
 def adapter(_context, factory, provides, for_=None):
     if for_ is not None: for_ = _context.resolve(for_)
@@ -26,8 +43,8 @@
     return [
         Action(
             discriminator = ('adapter', for_, provides),
-            callable = provideAdapter,
-            args = (for_, provides, _context.resolve(factory)),
+            callable = handler,
+            args = ('Adapters', 'provideAdapter', for_, provides, _context.resolve(factory)),
             )
         ]
 
@@ -37,8 +54,8 @@
     return [
         Action(
             discriminator = ('utility', provides),
-            callable = provideUtility,
-            args = (provides, component),
+            callable = handler,
+            args = ('Utilities', 'provideUtility', provides, component),
             )
         ]
 
@@ -51,8 +68,8 @@
     return [
         Action(
             discriminator = ('factory', factory_id),
-            callable = provideFactory,
-            args = (factory_id, component),
+            callable = handler,
+            args = ('Factories','provideFactory',factory_id, component),
             )
         ]
 
@@ -63,8 +80,8 @@
     return [
         Action(
             discriminator = ('view', for_, name, type, layer),
-            callable = provideView,
-            args = (for_, name, type, factory, layer),
+            callable = handler,
+            args = ('Views','provideView',for_, name, type, factory, layer),
             )
         ]
 
@@ -75,13 +92,13 @@
     return [
         Action(
             discriminator = ('view', for_, name, type),
-            callable = provideView, 
-            args = (for_, name, type, factory, layer),
+            callable = handler, 
+            args = ('Views','provideView',for_, name, type, factory, layer),
             ),
         Action(
             discriminator = ('defaultViewName', for_, name, type),
-            callable = setDefaultViewName,
-            args = (for_, type, name),
+            callable = handler,
+            args = ('Views','setDefaultViewName', for_, type, name),
             )
         ]
 
@@ -92,8 +109,8 @@
     return [
         Action(
             discriminator = ('resource', name, type, layer),
-            callable = provideResource,
-            args = (name, type, component, layer),
+            callable = handler,
+            args = ('Resources','provideResource',name, type, component, layer),
             )
         ]
 
@@ -101,8 +118,8 @@
     return [
         Action(
             discriminator = ('serviceType', name),        
-            callable = defineService,
-            args = (name, _context.resolve(interface)),
+            callable = managerHandler,
+            args = ('defineService',name, _context.resolve(interface)),
             )
         ]
 
@@ -111,8 +128,8 @@
     return [
         Action(
             discriminator = ('service', name),        
-            callable = provideService,
-            args = (name, component),
+            callable = managerHandler,
+            args = ('provideService', name, component),
             )
         ]
 
@@ -122,8 +139,8 @@
     return [
         Action(
             discriminator = ('skin', name, type),
-            callable = defineSkin,
-            args = (name, type, layers)
+            callable = handler,
+            args = ('Skins','defineSkin',name, type, layers)
             )
         ]
 

=== Removed File Zope3/lib/python/Zope/ComponentArchitecture/IServiceService.py ===

=== Removed File Zope3/lib/python/Zope/ComponentArchitecture/ResourceService.py ===

=== Removed File Zope3/lib/python/Zope/ComponentArchitecture/Service.py ===

=== Removed File Zope3/lib/python/Zope/ComponentArchitecture/SkinService.py ===

=== Removed File Zope3/lib/python/Zope/ComponentArchitecture/ViewService.py ===

=== Removed File Zope3/lib/python/Zope/ComponentArchitecture/hooks.py ===