[Zope-Checkins] CVS: Zope3/lib/python/Zope/App/OFS/Services/ServiceManager - IComponentManager.py:1.1 IPackage.py:1.1 IPackages.py:1.1 IServiceDirective.py:1.1 Package.py:1.1 Packages.py:1.1 ServiceDirective.py:1.1 IBindingAware.py:1.3 IServiceManager.py:1.4 ServiceManager.py:1.4 configure.zcml:1.5
Jim Fulton
jim@zope.com
Thu, 11 Jul 2002 14:22:03 -0400
Update of /cvs-repository/Zope3/lib/python/Zope/App/OFS/Services/ServiceManager
In directory cvs.zope.org:/tmp/cvs-serv7355/lib/python/Zope/App/OFS/Services/ServiceManager
Modified Files:
IBindingAware.py IServiceManager.py ServiceManager.py
configure.zcml
Added Files:
IComponentManager.py IPackage.py IPackages.py
IServiceDirective.py Package.py Packages.py
ServiceDirective.py
Log Message:
Reimplemented service managers to be package based. Service managers
are no longer containers. They have a packages subobject (not a
packages service) that contains packages. TTW components are created
in packages. To register a component, create the appropriate component
directive objects (these should be called configuration objects).
This should be viewed as a prototype to illustrate the idea of
packages. Lots of things can change (especially UI) and many things
aren't done (e.g. visiting created directives).
In the course of this, I fixed a bunch of bugs and problems in
traversal machinery.
I also renamed Zope.ComponentArchitecture.IServiceManager back to
IServiceService, since this interface doesn't actually specify any
management.
=== Added File Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/IComponentManager.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: IComponentManager.py,v 1.1 2002/07/11 18:21:32 jim Exp $
"""
from Interface import Interface
class IComponentManager(Interface):
def queryComponent(type=None, filter=None, all=0):
"""Return all components that match the given type and filter
The objects are returned a sequence of mapping objects with keys:
path -- The component path
component -- The component
all -- A flag indicating whether all component managers in
this place should be queried, or just the local one.
"""
=== Added File Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/IPackage.py ===
##############################################################################
#
# Copyright (c) 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.
#
##############################################################################
"""XXX short summary goes here.
XXX longer description goes here.
$Id: IPackage.py,v 1.1 2002/07/11 18:21:32 jim Exp $
"""
from Zope.App.OFS.Container.IContainer import IContainer
class IPackage(IContainer):
"""Component and component configuration containers.
"""
=== Added File Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/IPackages.py ===
##############################################################################
#
# Copyright (c) 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.
#
##############################################################################
from Zope.App.OFS.Container.IContainer import IContainer
from Zope.App.OFS.Services.ServiceManager.IComponentManager import IComponentManager
class IPackages(IContainer, IComponentManager):
"""Packages objects contain database packages
They support simple containment as well as package query and lookup.
"""
doc = IPackages.__doc__ + """
$Id: IPackages.py,v 1.1 2002/07/11 18:21:32 jim Exp $
"""
=== Added File Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/IServiceDirective.py ===
##############################################################################
#
# Copyright (c) 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: IServiceDirective.py,v 1.1 2002/07/11 18:21:32 jim Exp $
"""
from Interface import Interface
from Interface.Attribute import Attribute
class IServiceDirective(Interface):
"""Service Configuration Directives
"""
service_type = Attribute("The service type id")
component_path = Attribute("The physical path to the component")
def getService(service_manager):
"""Return the service component named in the directive.
"""
__doc__ = IServiceDirective.__doc__ + __doc__
=== Added File Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/Package.py ===
##############################################################################
#
# Copyright (c) 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.
#
##############################################################################
"""XXX short summary goes here.
XXX longer description goes here.
$Id: Package.py,v 1.1 2002/07/11 18:21:32 jim Exp $
"""
__metaclass__ = type
from Zope.App.OFS.Container.BTreeContainer import BTreeContainer
from IPackage import IPackage
class Package(BTreeContainer):
__implements__ = IPackage
=== Added File Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/Packages.py ===
##############################################################################
#
# Copyright (c) 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.
#
##############################################################################
"""XXX short summary goes here.
XXX longer description goes here.
$Id: Packages.py,v 1.1 2002/07/11 18:21:32 jim Exp $
"""
__metaclass__ = type
from Zope.App.OFS.Container.BTreeContainer import BTreeContainer
from Zope.ContextWrapper import ContextMethod
from Zope.Proxy.ContextWrapper import ContextWrapper
from Zope.App.Traversing import getPhysicalPathString
from IPackages import IPackages
from IPackage import IPackage
class Packages(BTreeContainer):
__implements__ = IPackages
def queryComponent(self, type=None, filter=None, all=0):
local = []
path = getPhysicalPathString(self)
for package_name in self:
package = ContextWrapper(self[package_name], self,
name=package_name)
for name in package:
component = package[name]
if type is not None and not type.isImplementedBy(component):
continue
if filter is not None and not filter(component):
continue
local.append({'path': "%s/%s/%s" % (path, package_name, name),
'component': ContextWrapper(component, package,
name=name),
})
if all:
next_service_manager = getNextServiceManager(self)
if IComponentManager.isImplementedBy(next_service_manager):
more = next_service_manager.queryComponent(type, filter, all)
local += list(all)
return local
queryComponent = ContextMethod(queryComponent)
def setObject(self, name, object):
if not IPackage.isImplementedBy(object):
raise TypeError("Can only add packages")
return super(Packages, self).setObject(name, object)
=== Added File Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/ServiceDirective.py ===
##############################################################################
#
# Copyright (c) 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: ServiceDirective.py,v 1.1 2002/07/11 18:21:32 jim Exp $
"""
__metaclass__ = type
from Persistence import Persistent
from Zope.Security.Checker import CheckerPublic, InterfaceChecker
from Zope.Security.Proxy import Proxy
from Zope.App.Traversing import traverse
from IServiceDirective import IServiceDirective
class ServiceDirective(Persistent):
__doc__ = IServiceDirective.__doc__
__implements__ = IServiceDirective
def __init__(self, service_type, component_path, permission=None):
self.service_type = service_type
self.component_path = component_path
if permission == 'Zope.Public':
permission = CheckerPublic
self.permission = permission
def __repr__(self):
return "service(%s, %s)" % (self.service_type, self.component_path)
############################################################
# Implementation methods for interface
# Zope.App.OFS.Services.ServiceManager.IServiceDirective.
def getService(self, service_manager):
service = getattr(self, '_v_service', None)
if service is None:
service = traverse(service_manager, self.component_path)
if self.permission:
if type(service) is Proxy:
service = removeSecurityProxy(service)
interface = service_manager.getInterfaceFor(self.service_type)
checker = InterfaceChecker(interface, self.permission)
service = Proxy(service, checker)
self._v_service = service
return service
getService.__doc__ = IServiceDirective['getService'].__doc__
#
############################################################
__doc__ = ServiceDirective.__doc__ + __doc__
=== Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/IBindingAware.py 1.2 => 1.3 ===
class IBindingAware(Interface):
def bound(name):
- """Called when an immediately-containing service manager binds this object to
- perform the named service"""
+ """
+
+ 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"""
\ No newline at end of file
+ """
+
+ Called when an immediately-containing service manager unbinds
+ this object from performing the named service.
+
+ """
=== Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/IServiceManager.py 1.3 => 1.4 ===
$Id$
"""
-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
+from Zope.ComponentArchitecture.IServiceService import IServiceService
-class IServiceManager(IContainer, IGlobalServiceManager):
+from IComponentManager import IComponentManager
+
+from Interface.Attribute import Attribute
+
+class IServiceManager(IServiceService, IComponentManager):
"""Service Managers act as containers for Services.
If a Service Manager is asked for a service, it checks for those it
@@ -31,23 +31,53 @@
services.
"""
- def bindService(serviceName, serviceComponentName):
+ Packages = Attribute("""Package container""")
+
+
+ def bindService(service_directive):
"""Provide a service implementation.
If the named object implements IBindingAware, the wrapped object is
notified as per that interface.
"""
- def unbindService(serviceName):
+ def addService(service_directive):
+ """Add a registered service, but displace another active component
+
+ Register a service component, but don't make it active of
+ there is already a registered component providing the service.
+
+ """
+
+ def unbindService(service_directive):
"""No longer provide a service implementation.
If the named object implements IBindingAware, the wrapped object is
notified as per that interface.
"""
+ def disableService(service_type):
+ """Make the service type inactive in this service manager.
+
+ This doesn't unbind any services, but makes them all inactive.
+ """
+
+ def enableService(service_type, index):
+ """Make the service type inactive in this service manager.
+
+ This doesn't unbind any services, but makes them all inactive.
+ """
+
def getBoundService(name):
"""Retrieve a bound service implementation.
Get the component currently bound to the named Service in this
ServiceService. Does not search context.
"""
+
+ def getDirectives(service_type):
+ """Get the directives registered for a service
+ """
+
+ def getBoundServiceTypes():
+ """Get a sequence of the bound service types"""
=== Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/ServiceManager.py 1.3 => 1.4 ===
$Id$
"""
+from Persistence import Persistent
+
from Zope.Exceptions import NotFoundError, ZopeError
from Zope.ComponentArchitecture.IServiceManagerContainer \
@@ -25,6 +27,7 @@
from Zope.ComponentArchitecture.GlobalServiceManager import InvalidService
from Zope.ComponentArchitecture.Exceptions import ComponentLookupError
+from Zope.App.OFS.Container.IContainer import ISimpleReadContainer
from Zope.App.OFS.Content.Folder.Folder import Folder
from Zope.ContextWrapper import ContextMethod
from Zope.Proxy.ContextWrapper import ContextWrapper
@@ -32,131 +35,239 @@
from Zope.Proxy.ProxyIntrospection import removeAllProxies
from IBindingAware import IBindingAware
+from Packages import Packages
+from Package import Package
from IServiceManager import IServiceManager
+class ServiceManager(Persistent):
-class ServiceManager(BTreeContainer):
-
- __implements__ = IServiceManager
+ __implements__ = IServiceManager, ISimpleReadContainer
def __init__(self):
+
self.__bindings = {}
- super(ServiceManager, self).__init__()
+ # Bindings is of the form:
+ #
+ # {service_type -> [directives]}
+ #
+ # Where the first directive is always the active directive.
+
+ self.Packages = Packages()
+ self.Packages.setObject('default', Package())
- def getServiceDefinitions(wrapped_self):
- clean_self=removeAllProxies(wrapped_self)
- """ see IServiceManager Interface """
+ def getServiceDefinitions(self):
+ "See Zope.ComponentArchitecture.IServiceService.IServiceService"
+
# Get the services defined here and above us, if any (as held
# in a ServiceInterfaceService, presumably)
- sm=getNextServiceManager(wrapped_self)
+ sm = getNextServiceManager(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[serviceInterfaceServ].items()
- )
- ))
+ serviceDefs = sm.getServiceDefinitions()
+ else: serviceDefs = {}
+
return serviceDefs
- getServiceDefinitions=ContextMethod(getServiceDefinitions)
+ getServiceDefinitions = ContextMethod(getServiceDefinitions)
def queryService(self, name, default=None):
+ "See Zope.ComponentArchitecture.IServiceService.IServiceService"
try:
return self.getService(name)
except ComponentLookupError:
return default
- queryService=ContextMethod(queryService)
+ queryService = ContextMethod(queryService)
- def getService(wrapped_self, name):
- """ see IServiceManager Interface"""
- clean_self=removeAllProxies(wrapped_self)
-
- service = clean_self.__bindings.get(name)
+ def getService(self, name):
+ "See Zope.ComponentArchitecture.IServiceService.IServiceService"
+
+ service = self.__bindings.get(name)
if service:
- return ContextWrapper(wrapped_self[service],
- wrapped_self, name=service) # we want
- # to traverse by component name, not service name
+ service = service[0] # Get the active service directive
+ if service is not None: # not disabled
+ service = service.getService(self) # get the service
+ return service
- return getNextService(wrapped_self, name)
+ return getNextService(self, name)
+
+ getService = ContextMethod(getService)
- getService=ContextMethod(getService)
def getBoundService(self, name):
- """ see IServiceManager Interface"""
+ "See Zope.App.OFS.Services.ServiceManager.IServiceManager."
+
+ service = self.__bindings.get(name)
+ if service:
+ service = service[0] # Get the active service directive
+ service = service.getService(self) # get the service
+ return service
+
+ return None
+
+ def getInterfaceFor(self, service_type):
+ "See Zope.ComponentArchitecture.IServiceService.IServiceService"
+ for type, interface in self.getServiceDefinitions():
+ if type == service_type:
+ return interface
+
+ raise NameError(service_type)
+
+ getInterfaceFor = ContextMethod(getInterfaceFor)
+
+ def disableService(self, service_type):
+ "See Zope.App.OFS.Services.ServiceManager.IServiceManager."
+ directives = self.__bindings.get(service_type)
+ if directives and directives[0] is not None:
+ directives.insert(0, None)
+
+ def enableService(self, service_type, index):
+ "See Zope.App.OFS.Services.ServiceManager.IServiceManager."
+ self._disableFirstBeforeEnable(service_type)
+
+ directives = self.__bindings.get(service_type)
+ directive = directives[index]
+ del directives[index]
+ directives.insert(0, directive)
+
+
+ self._p_changed = 1
+
+ service = directive.getService(self)
+ if IBindingAware.isImplementedBy(service):
+ service.bound(service_type)
+
+
+ def _disableFirstBeforeEnable(self, service_type):
+ # Disable the first (active) service or remove the
+ # disabled marker prior to enabling a service.
+ directives = self.__bindings.get(service_type)
+
+ if directives:
+ if directives[0] is None:
+ # remove deactivation marker
+ del directives[0]
+ elif IBindingAware.isImplementedBy(directives[0]):
+ # unbind old service, if necessary
+ old_service = directives[0].getService(self)
+ old_service.unbound(service_type)
+
+
+ def bindService(self, directive):
+ "See "
+ "Zope.App.OFS.Services.ServiceManager.IServiceManager.IServiceManager"
+ service = directive.getService(self)
+ service_type = directive.service_type
+
+ interface = self.getInterfaceFor(service_type)
+
+ if not interface.isImplementedBy(service):
+ raise InvalidService(service_type, directive, interface)
- return self.__bindings.get(name)
+ self._disableFirstBeforeEnable(service_type)
- def bindService(wrapped_self, serviceName, serviceComponentName):
- """ see IServiceManager Interface"""
- clean_self=removeAllProxies(wrapped_self)
+ bindings = self.__bindings
+ if service_type not in bindings:
+ bindings[service_type] = [directive]
+ else:
+ directives = bindings[service_type]
+ directives.insert(0, directive)
+
+ self._p_changed = 1
+
+ if IBindingAware.isImplementedBy(service):
+ service.bound(service_type)
+
+ bindService = ContextMethod(bindService)
+
+ def addService(self, directive):
+ "See "
+ "Zope.App.OFS.Services.ServiceManager.IServiceManager.IServiceManager"
+ service = directive.getService(self)
+ service_type = directive.service_type
- # This could raise a KeyError if we don't have this component
- clean_serviceComponent = wrapped_self[serviceComponentName]
- wrapped_serviceComponent=ContextWrapper(
- clean_serviceComponent,
- wrapped_self,
- name=serviceComponentName)
+ interface = self.getInterfaceFor(service_type)
+
+ if not interface.isImplementedBy(service):
+ raise InvalidService(service_type, directive, interface)
- for name,interface in wrapped_self.getServiceDefinitions():
- if name == serviceName:
- if not interface.isImplementedBy(clean_serviceComponent):
- raise InvalidService(serviceName,
- serviceComponentName,
- interface)
- break
+ bindings = self.__bindings
+ if service_type not in bindings:
+ bindings[service_type] = []
+ bindings[service_type].append(directive)
+
+ self._p_changed = 1
+
+ if len(bindings) == 1 and IBindingAware.isImplementedBy(service):
+ service.bound(service_type)
- # Services are added to the Manager through the Folder interface
- # self.setObject(name, component)
+ addService = ContextMethod(addService)
+
+ def unbindService(self, directive):
+ "See Zope.App.OFS.Services.ServiceManager.IServiceManager.IServiceManager"
+ self = removeAllProxies(self)
+ service = directive.getService(self)
+ service_type = directive.service_type
+
+ directives = self.__bindings[service_type]
+ if directive not in directives:
+ raise KeyError(directive)
- if IBindingAware.isImplementedBy(clean_serviceComponent):
- wrapped_serviceComponent.bound(serviceName)
+ if IBindingAware.isImplementedBy(service):
+ service.unbound(service_type)
- clean_self.__bindings[serviceName] = serviceComponentName
- # trigger persistence
- clean_self.__bindings = clean_self.__bindings
+ self.__bindings[service_type] = [d for d in directives
+ if d != directive]
- bindService=ContextMethod(bindService) # needed because of call to
- # getServiceDefinitions, as well as IBindingAware stuff
+ self._p_changed = 1
+
+ unbindService = ContextMethod(unbindService)
- def unbindService(wrapped_self, serviceName):
- """ see IServiceManager Interface """
- clean_self=removeAllProxies(wrapped_self)
- serviceComponentName=clean_self.__bindings[serviceName]
-
- clean_serviceComponent = wrapped_self[serviceComponentName]
- wrapped_serviceComponent=ContextWrapper(
- clean_serviceComponent,
- wrapped_self,
- name=serviceComponentName)
+ def getDirectives(self, service_type):
+ "See "
+ "Zope.App.OFS.Services.ServiceManager.IServiceManager.IServiceManager"
+ return self.__bindings[service_type]
+
+ def getBoundServiceTypes(self):
+ "See Zope.App.OFS.Services.ServiceManager.IServiceManager.IServiceManager"
+ return self.__bindings.keys()
- if IBindingAware.isImplementedBy(clean_serviceComponent):
- wrapped_serviceComponent.unbound(serviceName)
- del clean_self.__bindings[serviceName]
+ ############################################################
+ # Implementation methods for interface
+ # Zope.App.OFS.Services.ServiceManager.IComponentManager.
- # trigger persistence
- clean_self.__bindings = clean_self.__bindings
-
- unbindService=ContextMethod(unbindService)
+ def queryComponent(self, type=None, filter=None, all=0):
+ Packages = ContextWrapper(self.Packages, self, name='Packages')
+ return Packages.queryComponent(type, filter, all)
+
+ queryComponent = ContextMethod(queryComponent)
+
+ #
+ ############################################################
+
+
+ def __getitem__(self, key):
+ "See Interface.Common.Mapping.IReadMapping"
+
+ result = self.get(key)
+ if result is None:
+ raise KeyError(key)
+
+ return result
+
+ def get(self, key, default=None):
+ "See Interface.Common.Mapping.IReadMapping"
+
+ if key == 'Packages':
+ return self.Packages
+
+ return self.queryService(key, default)
+
+ def __contains__(self, key):
+ "See Interface.Common.Mapping.IReadMapping"
+ return self.get(key) is not None
- def __delitem__(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.__delitem__(self, name)
=== Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/configure.zcml 1.4 => 1.5 ===
xmlns='http://namespaces.zope.org/zope'
xmlns:browser='http://namespaces.zope.org/browser'
>
+
<content class=".ServiceManager.">
<require
- permission="Zope.Public"
+ permission="Zope.View"
+ interface="Zope.App.OFS.Container.IContainer.ISimpleReadContainer" />
+ <require
+ permission="Zope.ManageServices"
+ interface="Zope.App.OFS.Services.ServiceManager.IServiceManager." />
+ </content>
+
+ <content class=".Packages.">
+ <require
+ permission="Zope.View"
interface="Zope.App.OFS.Container.IContainer.IReadContainer" />
<require
permission="Zope.ManageServices"
interface="Zope.App.OFS.Container.IContainer.IWriteContainer" />
<require
permission="Zope.ManageServices"
- interface="Zope.App.OFS.Services.ServiceManager.IServiceManager." />
+ interface=".IComponentManager." />
+ </content>
+
+ <content class=".Package.">
+ <require
+ permission="Zope.View"
+ interface="Zope.App.OFS.Container.IContainer.IReadContainer" />
+ <require
+ permission="Zope.ManageServices"
+ interface="Zope.App.OFS.Container.IContainer.IWriteContainer" />
+ </content>
+
+ <content class=".ServiceDirective.">
+ <require
+ permission="Zope.ManageServices"
+ interface=".IServiceDirective." />
</content>
+
+
<include package="Zope.App.OFS.Services.ServiceManager.Views" />