[Zope3-checkins] CVS: Zope3/lib/python/Zope/App/OFS/Services/ServiceManager - ConfigurationManager.py:1.2 IConfigurationManager.py:1.2 IServiceConfiguration.py:1.2 ServiceConfiguration.py:1.2 INameResolver.py:1.2 IBindingAware.py:1.5 IServiceManager.py:1.5 ServiceManager.py:1.10 configure.zcml:1.7 IServiceDirective.py:NONE ServiceDirective.py:NONE
Jim Fulton
jim@zope.com
Sat, 30 Nov 2002 13:39:47 -0500
Update of /cvs-repository/Zope3/lib/python/Zope/App/OFS/Services/ServiceManager
In directory cvs.zope.org:/tmp/cvs-serv12171/lib/python/Zope/App/OFS/Services/ServiceManager
Modified Files:
IBindingAware.py IServiceManager.py ServiceManager.py
configure.zcml
Added Files:
ConfigurationManager.py IConfigurationManager.py
IServiceConfiguration.py ServiceConfiguration.py
INameResolver.py
Removed Files:
IServiceDirective.py ServiceDirective.py
Log Message:
- Updated to use new configuration framework.
- Updated PlacefulSetup to register the standard traversal adapters
and views during setup.
- Service managers now support hierarchical module lookup.
=== Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/ConfigurationManager.py 1.1 => 1.2 ===
--- /dev/null Sat Nov 30 13:39:47 2002
+++ Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/ConfigurationManager.py Sat Nov 30 13:39:16 2002
@@ -0,0 +1,140 @@
+##############################################################################
+#
+# 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$
+"""
+
+__metaclass__ = type
+
+from Persistence import Persistent
+from IConfigurationManager import IConfigurationManager
+
+class ConfigurationManager(Persistent):
+ """Configuration manager
+
+ Manages configurations within a package.
+ """
+
+ __implements__ = IConfigurationManager
+
+ def __init__(self):
+ self._data = ()
+ self._next = 0
+
+ def __getitem__(self, key):
+ "See Zope.App.OFS.Container.IContainer.IItemContainer"
+ v = self.get(key)
+ if v is None:
+ raise KeyError, key
+ return v
+
+ def get(self, key, default=None):
+ "See Interface.Common.Mapping.IReadMapping"
+ for k, v in self._data:
+ if k == key:
+ return v
+ return default
+
+ def __contains__(self, key):
+ "See Interface.Common.Mapping.IReadMapping"
+ return self.get(key) is not None
+
+
+ def keys(self):
+ "See Interface.Common.Mapping.IEnumerableMapping"
+ return [k for k, v in self._data]
+
+ def values(self):
+ "See Interface.Common.Mapping.IEnumerableMapping"
+ return [v for k, v in self._data]
+
+ def items(self):
+ "See Interface.Common.Mapping.IEnumerableMapping"
+ return self._data
+
+ def __len__(self):
+ "See Interface.Common.Mapping.IEnumerableMapping"
+ return len(self._data)
+
+ def setObject(self, key, object):
+ "See Zope.App.OFS.Container.IContainer.IWriteContainer"
+ self._next += 1
+ key = str(self._next)
+ self._data += ((key, object), )
+ return key
+
+ def __delitem__(self, key):
+ "See Zope.App.OFS.Container.IContainer.IWriteContainer"
+ if key not in self:
+ raise KeyError, key
+ self._data = tuple(
+ [item
+ for item in self._data
+ if item[0] != key]
+ )
+
+ def moveTop(self, names):
+ self._data = tuple(
+ [item for item in self._data if (item[0] in names)]
+ +
+ [item for item in self._data if (item[0] not in names)]
+ )
+
+ def moveBottom(self, names):
+ self._data = tuple(
+ [item for item in self._data if (item[0] not in names)]
+ +
+ [item for item in self._data if (item[0] in names)]
+ )
+
+ def _moveUpOrDown(self, names, direction):
+ # Move each named item by one position. Note that this
+ # might require moving some unnamed objects by more than
+ # one position.
+
+ indexes = {}
+
+ # Copy named items to positions one less than they currently have
+ i = -1
+ for item in self._data:
+ i += 1
+ if item[0] in names:
+ j = max(i + direction, 0)
+ while j in indexes:
+ j += 1
+
+ indexes[j] = item
+
+ # Fill in the rest where there's room.
+ i = 0
+ for item in self._data:
+ if item[0] not in names:
+ while i in indexes:
+ i += 1
+ indexes[i] = item
+
+ items = indexes.items()
+ items.sort()
+
+ self._data = tuple([item[1] for item in items])
+
+ def moveUp(self, names):
+ self._moveUpOrDown(names, -1)
+
+ def moveDown(self, names):
+ self._moveUpOrDown(names, 1)
+
+
+
+__doc__ = ConfigurationManager.__doc__ + __doc__
=== Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/IConfigurationManager.py 1.1 => 1.2 ===
--- /dev/null Sat Nov 30 13:39:47 2002
+++ Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/IConfigurationManager.py Sat Nov 30 13:39:16 2002
@@ -0,0 +1,41 @@
+##############################################################################
+#
+# 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$
+"""
+
+from Zope.App.OFS.Container.IContainer import IContainerNamesContainer
+
+class IConfigurationManager(IContainerNamesContainer):
+ """Manage Configuration Directives
+ """
+
+ def moveTop(names):
+ """Move the objects corresponding to the given names to the top
+ """
+
+ def moveUp(names):
+ """Move the objects corresponding to the given names up
+ """
+
+ def moveBottom(names):
+ """Move the objects corresponding to the given names to the bottom
+ """
+
+ def moveDown(names):
+ """Move the objects corresponding to the given names down
+ """
+
+__doc__ = IConfigurationManager.__doc__ + __doc__
+
=== Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/IServiceConfiguration.py 1.1 => 1.2 ===
--- /dev/null Sat Nov 30 13:39:47 2002
+++ Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/IServiceConfiguration.py Sat Nov 30 13:39:16 2002
@@ -0,0 +1,38 @@
+##############################################################################
+#
+# 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$
+"""
+
+from Interface.Attribute import Attribute
+from Zope.App.OFS.Services.ConfigurationInterfaces import IConfiguration
+
+class IServiceConfiguration(IConfiguration):
+ """Service Configuration
+
+ Service configurations are dependent on the components that they
+ configure. They register themselves as component dependents.
+
+ """
+
+ serviceType = Attribute("The service type id")
+
+ componentPath = Attribute("The physical path to the component")
+
+ def getService(service_manager):
+ """Return the service component named in the directive.
+ """
+
+__doc__ = IServiceConfiguration.__doc__ + __doc__
+
=== Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/ServiceConfiguration.py 1.1 => 1.2 ===
--- /dev/null Sat Nov 30 13:39:47 2002
+++ Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/ServiceConfiguration.py Sat Nov 30 13:39:16 2002
@@ -0,0 +1,150 @@
+##############################################################################
+#
+# 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$
+"""
+
+__metaclass__ = type
+
+from Persistence import Persistent
+from Zope.Security.Checker import CheckerPublic, InterfaceChecker
+from Zope.Security.Proxy import Proxy
+from Zope.App.DependencyFramework.Exceptions import DependencyError
+from Zope.App.Traversing import traverse
+from IServiceConfiguration import IServiceConfiguration
+from Zope.Proxy.ProxyIntrospection import removeAllProxies
+from Zope.App.Traversing import getPhysicalRoot
+from Zope.ComponentArchitecture import getService, getServiceManager
+from Zope.App.Traversing import getPhysicalPathString
+from ServiceManager import ServiceManager
+from Zope.App.OFS.Container.IAddNotifiable import IAddNotifiable
+from Zope.App.OFS.Container.IDeleteNotifiable import IDeleteNotifiable
+from Zope.App.DependencyFramework.IDependable import IDependable
+from Zope.ComponentArchitecture import getServiceManager, getAdapter
+from Zope.ContextWrapper import ContextMethod
+from Zope.App.OFS.Services.Configuration import ConfigurationStatusProperty
+from Zope.ContextWrapper import ContextProperty
+from IBindingAware import IBindingAware
+from Zope.App.OFS.Services.ConfigurationInterfaces import Active
+from Zope.App.OFS.Services.ConfigurationInterfaces import Registered
+from Zope.App.OFS.Services.ConfigurationInterfaces import Unregistered
+
+class ServiceConfiguration(Persistent):
+ __doc__ = IServiceConfiguration.__doc__
+
+ __implements__ = IServiceConfiguration, IAddNotifiable, IDeleteNotifiable
+
+ status = ConfigurationStatusProperty('Services')
+
+ def __init__(self, service_type, component_path, permission=None):
+ self.serviceType = service_type
+ self.componentPath = component_path
+ if permission == 'Zope.Public':
+ permission = CheckerPublic
+
+ self.permission = permission
+
+ def __repr__(self):
+ return "service(%s, %s)" % (self.serviceType, self.componentPath)
+
+ ############################################################
+ # Implementation methods for interface
+ # Zope.App.OFS.Services.ServiceManager.IServiceConfiguration.
+
+ def getService(self):
+ service_manager = getServiceManager(self)
+
+ service = getattr(self, '_v_service', None)
+ if service is None:
+
+ # We have to be clever here. We need to do an honest to
+ # god unrestricted traveral, which means we have to
+ # traverse from an unproxies object. But, it's not enough
+ # for the service manager to be unproxies, because the
+ # path is an absolute path. When absolute paths are
+ # traversed, the traverser finds the physical root and
+ # traverses from there, so we need to make sure the
+ # physical root isn;t proxied.
+
+ # get the root and unproxy it.
+ root = removeAllProxies(getPhysicalRoot(service_manager))
+ service = traverse(root, self.componentPath)
+
+ if self.permission:
+ if type(service) is Proxy:
+ # XXX what is this?
+ service = removeSecurityProxy(service)
+
+ interface = service_manager.getInterfaceFor(self.serviceType)
+
+ checker = InterfaceChecker(interface, self.permission)
+
+ service = Proxy(service, checker)
+
+
+ self._v_service = service
+
+
+ return service
+
+ getService.__doc__ = IServiceConfiguration['getService'].__doc__
+
+ getService = ContextMethod(getService)
+
+ ############################################################
+
+ def activated(self):
+ service = self.getService()
+ if IBindingAware.isImplementedBy(service):
+ service.bound(self.serviceType)
+
+ activated = ContextMethod(activated)
+
+ def deactivated(self):
+ service = self.getService()
+ if IBindingAware.isImplementedBy(service):
+ service.unbound(self.serviceType)
+
+ deactivated = ContextMethod(deactivated)
+
+ def manage_afterAdd(self, configuration, container):
+ "See Zope.App.OFS.Container.IAddNotifiable"
+ sm = getServiceManager(configuration)
+ service = configuration.getService()
+ dependents = getAdapter(service, IDependable)
+ objectpath = getPhysicalPathString(configuration)
+ dependents.addDependent(objectpath)
+
+ def manage_beforeDelete(self, configuration, container):
+ "See Zope.App.OFS.Container.IDeleteNotifiable"
+ assert self == configuration
+ service_type = self.serviceType
+ sm = getServiceManager(self)
+ service = self.getService()
+ objectstatus = self.status
+ dependents = getAdapter(service, IDependable)
+ objectpath = getPhysicalPathString(self)
+
+ if objectstatus == Active:
+ raise DependencyError("Can't delete active configurations")
+ elif objectstatus == Registered:
+ self.status = Unregistered
+
+ dependents.removeDependent(objectpath)
+
+ manage_beforeDelete = ContextMethod(manage_beforeDelete)
+
+__doc__ = ServiceConfiguration.__doc__ + __doc__
+
+
=== Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/INameResolver.py 1.1 => 1.2 ===
--- /dev/null Sat Nov 30 13:39:47 2002
+++ Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/INameResolver.py Sat Nov 30 13:39:17 2002
@@ -0,0 +1,31 @@
+##############################################################################
+#
+# 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$
+"""
+
+from Interface import Interface
+
+class INameResolver(Interface):
+ """Objects that can resolve dotted names to objects
+ """
+
+ def resolve(dotted_name):
+ """Resolve the given dotted name to a module global variable.
+
+ If the name ends with a trailing dot, the last name segment
+ may be repeated.
+ """
+
+__doc__ = INameResolver.__doc__ + __doc__
=== Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/IBindingAware.py 1.4 => 1.5 ===
--- Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/IBindingAware.py:1.4 Mon Nov 11 03:36:08 2002
+++ Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/IBindingAware.py Sat Nov 30 13:39:16 2002
@@ -22,14 +22,14 @@
class IBindingAware(Interface):
def bound(name):
- """
+ """Inform a service components that it's providing a service
Called when an immediately-containing service manager binds
this object to perform the named service.
"""
def unbound(name):
- """
+ """Inform a service components that it's no longer providing a service
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.4 => 1.5 ===
--- Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/IServiceManager.py:1.4 Thu Jul 11 14:21:32 2002
+++ Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/IServiceManager.py Sat Nov 30 13:39:16 2002
@@ -16,12 +16,11 @@
$Id$
"""
from Zope.ComponentArchitecture.IServiceService import IServiceService
-
+from Zope.App.OFS.Services.ConfigurationInterfaces import IConfigurable
from IComponentManager import IComponentManager
-
from Interface.Attribute import Attribute
-class IServiceManager(IServiceService, IComponentManager):
+class IServiceManager(IServiceService, IComponentManager, IConfigurable):
"""Service Managers act as containers for Services.
If a Service Manager is asked for a service, it checks for those it
@@ -33,39 +32,12 @@
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 queryConfigurations(service_type):
+ """Return an IConfigurationRegistry for a service type
"""
- 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 createConfigurationsFor(configuration):
+ """Create and return an IConfigurationRegistry a service type
"""
def getBoundService(name):
@@ -73,11 +45,10 @@
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
+ None is returned if the named service isn't bound locally.
"""
def getBoundServiceTypes():
"""Get a sequence of the bound service types"""
+
=== Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/ServiceManager.py 1.9 => 1.10 ===
--- Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/ServiceManager.py:1.9 Tue Nov 19 14:10:07 2002
+++ Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/ServiceManager.py Sat Nov 30 13:39:17 2002
@@ -20,6 +20,8 @@
$Id$
"""
+import sys
+
from Zope.Exceptions import NotFoundError, ZopeError
from Zope.App.ComponentArchitecture.IServiceManagerContainer \
@@ -38,29 +40,34 @@
from Zope.App.OFS.Container.BTreeContainer import BTreeContainer
from Zope.Proxy.ProxyIntrospection import removeAllProxies
-from IBindingAware import IBindingAware
from Packages import Packages
-from Package import Package
from IServiceManager import IServiceManager
+from Zope.App.OFS.Services.Configuration import ConfigurationRegistry
+
from Persistence.Module import PersistentModuleRegistry
+from Persistence.Module import PersistentModuleRegistry, PersistentModule
+from INameResolver import INameResolver
+
+ModuleType = type(INameResolver)
+ModuleType = ModuleType, PersistentModule
+
class ServiceManager(PersistentModuleRegistry):
__implements__ = (IServiceManager, ISimpleReadContainer,
- PersistentModuleRegistry.__implements__)
+ PersistentModuleRegistry.__implements__,
+ INameResolver)
def __init__(self):
super(ServiceManager, self).__init__()
+
self.__bindings = {}
# Bindings is of the form:
#
- # {service_type -> [directives]}
- #
- # Where the first directive is always the active directive.
+ # {service_type -> ConfigurationRegistry}
self.Packages = Packages()
- self.Packages.setObject('default', Package())
def getServiceDefinitions(self):
@@ -88,31 +95,32 @@
def getService(self, name):
"See Zope.ComponentArchitecture.IServiceService.IServiceService"
-
- service = self.__bindings.get(name)
- if service:
- service = service[0] # Get the active service directive
- if service is not None: # not disabled
- service = service.getService(self) # get the service
- return service
+ # This is rather tricky. Normally, getting a service requires
+ # the use of other services, like the adapter service. We
+ # need to be careful not to get into an infinate recursion by
+ # getting out getService to be called while looking up
+ # services, so we'll
+
+ if name == 'Services':
+ return self # We are the service service
+
+ if not getattr(self, '_v_calling', 0):
+
+ self._v_calling = 1
+ try:
+ service = self.getBoundService(name)
+ if service:
+ return service
+
+ finally:
+ self._v_calling = 0
return getNextService(self, name)
getService = ContextMethod(getService)
- def getBoundService(self, name):
- "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():
@@ -123,141 +131,50 @@
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:
- service = directives[0].getService(self)
- aware_service = queryAdapter(service, IBindingAware)
- if aware_service is not None:
- aware_service.unbound(service_type)
- directives.insert(0, None)
- self._p_changed = 1
-
- disableService = ContextMethod(disableService)
-
- 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)
+ def queryConfigurationsFor(self, configuration, default=None):
+ return self.queryConfigurations(configuration.serviceType, default)
- self._p_changed = 1
-
- service = directive.getService(self)
- aware_service = queryAdapter(service, IBindingAware)
- if aware_service is not None:
- aware_service.bound(service_type)
-
- enableService = ContextMethod(enableService)
-
-
- 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]
- else:
-
- old_service = queryAdapter(
- directives[0].getService(self), IBindingAware)
- if old_service is not None:
- # unbind old service, if necessary
- old_service.unbound(service_type)
-
- _disableFirstBeforeEnable = ContextMethod(
- _disableFirstBeforeEnable)
+ queryConfigurationsFor = ContextMethod(queryConfigurationsFor)
- def bindService(self, directive):
- "See "
- "Zope.App.OFS.Services.ServiceManager.IServiceManager.IServiceManager"
- service = directive.getService(self)
- service_type = directive.service_type
+ def queryConfigurations(self, service_type, default=None):
+ registry = self.__bindings.get(service_type, default)
+ return ContextWrapper(registry, self)
- interface = self.getInterfaceFor(service_type)
+ queryConfigurations = ContextMethod(queryConfigurations)
- if not interface.isImplementedBy(service):
- raise InvalidService(service_type, directive, interface)
- self._disableFirstBeforeEnable(service_type)
+ def createConfigurationsFor(self, configuration):
+ return self.createConfigurations(configuration.serviceType)
- bindings = self.__bindings
- if service_type not in bindings:
- bindings[service_type] = [directive]
- else:
- directives = bindings[service_type]
- directives.insert(0, directive)
+ createConfigurationsFor = ContextMethod(createConfigurationsFor)
+ def createConfigurations(self, service_type):
+ registry = ConfigurationRegistry()
+ self.__bindings[service_type] = registry
self._p_changed = 1
-
- aware_service = queryAdapter(service, IBindingAware)
- if aware_service is not None:
- aware_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
-
- interface = self.getInterfaceFor(service_type)
-
- if not interface.isImplementedBy(service):
- raise InvalidService(service_type, directive, interface)
+ return registry
- bindings = self.__bindings
- if service_type not in bindings:
- bindings[service_type] = []
- bindings[service_type].append(directive)
+ createConfigurations = ContextMethod(createConfigurations)
- self._p_changed = 1
-
- if len(bindings) == 1:
- aware_service = queryAdapter(service, IBindingAware)
- if aware_service is not None:
- aware_service.bound(service_type)
-
- addService = ContextMethod(addService)
-
- def unbindService(self, directive):
- "See Zope.App.OFS.Services.ServiceManager.IServiceManager.IServiceManager"
- service = directive.getService(self) # must be before unwrapping self
- self = removeAllProxies(self)
- service_type = directive.service_type
-
- directives = self.__bindings[service_type]
- if directive not in directives:
- raise KeyError(directive)
-
- aware_service = queryAdapter(service, IBindingAware)
- if aware_service is not None:
- aware_service.unbound(service_type)
+ def getBoundService(self, name):
+ "See Zope.App.OFS.Services.ServiceManager.IServiceManager."
- self.__bindings[service_type] = [d for d in directives
- if d != directive]
+ registry = self.queryConfigurations(name)
+ if registry:
+ configuration = registry.active()
+ if configuration is not None:
+ service = configuration.getService()
+ return service
+
+ return None
- self._p_changed = 1
-
- unbindService = ContextMethod(unbindService)
+ getBoundService = ContextMethod(getBoundService)
- def getDirectives(self, service_type):
+ def getBoundServiceTypes(self):
"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()
+ return self.__bindings.keys()
############################################################
# Implementation methods for interface
@@ -306,7 +223,7 @@
def findModule(self, name):
# override to pass call up to next service manager
- mod = super(ServiceManager, self).findModule(name)
+ mod = super(ServiceManager, removeAllProxies(self)).findModule(name)
if mod is not None:
return mod
@@ -319,3 +236,50 @@
# direct way to ask if sm is the global service manager.
return None
return findModule(name)
+
+ findModule = ContextMethod(findModule)
+
+ def __import(self, module_name):
+
+ mod = self.findModule(module_name)
+ if mod is None:
+ mod = sys.modules.get(module_name)
+ if mod is None:
+ raise ImportError(module_name)
+
+ return mod
+
+ __import = ContextMethod(__import)
+
+ def resolve(self, name):
+
+ name = name.strip()
+
+ if name.endswith('.') or name.endswith('+'):
+ name = name[:-1]
+ repeat = 1
+ else:
+ repeat = 0
+
+ names=name.split('.')
+ last=names[-1]
+ mod='.'.join(names[:-1])
+
+ if not mod:
+ return self.__import(name)
+
+ while 1:
+ m = self.__import(mod)
+ try:
+ a=getattr(m, last)
+ except AttributeError:
+ if not repeat:
+ return self.__import(name)
+
+ else:
+ if not repeat or (not isinstance(a, ModuleType)):
+ return a
+ mod += '.' + last
+
+ resolve = ContextMethod(resolve)
+
=== Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/configure.zcml 1.6 => 1.7 ===
--- Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/configure.zcml:1.6 Wed Oct 2 18:18:01 2002
+++ Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/configure.zcml Sat Nov 30 13:39:17 2002
@@ -10,6 +10,7 @@
<require
permission="Zope.ManageServices"
interface="Zope.App.OFS.Services.ServiceManager.IServiceManager." />
+ <implements interface="Zope.App.OFS.Annotation.IAttributeAnnotatable." />
</content>
<content class=".Packages.">
@@ -22,6 +23,7 @@
<require
permission="Zope.ManageServices"
interface=".IComponentManager." />
+
</content>
<content class=".Package.">
@@ -31,22 +33,52 @@
<require
permission="Zope.ManageServices"
interface="Zope.App.OFS.Container.IContainer.IWriteContainer" />
+
+ </content>
+
+ <content class=".ConfigurationManager.">
+ <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"
+ attributes="arrange_object remove_objects" />
+ <factory
+ id = "Zope.App.OFS.Services.ServiceManager.ConfigurationManager"
+ permission = "Zope.ManageServices"
+ title = "Configuration Manager" />
</content>
<content class=".Module.Manager.">
<require
permission="Zope.ManageCode"
interface="Persistence.IPersistentModuleManager." />
+ <implements interface="Zope.App.OFS.Annotation.IAttributeAnnotatable." />
</content>
- <content class=".ServiceDirective.">
+
+ <content class=".ServiceConfiguration.">
<require
permission="Zope.ManageServices"
- interface=".IServiceDirective." />
- </content>
-
-
+ interface=".IServiceConfiguration."
+ set_attributes="serviceType componentPath"
+ set_schema=
+ "Zope.App.OFS.Services.ConfigurationInterfaces.IConfiguration"
+ />
+ <require
+ permission="Zope.ManageServices"
+ interface="Zope.App.OFS.Container.IAddNotifiable."
+ />
+ <require
+ permission="Zope.ManageServices"
+ interface="Zope.App.OFS.Container.IDeleteNotifiable."
+ />
- <include package="Zope.App.OFS.Services.ServiceManager.Views" />
+ </content>
+
+ <include package="Zope.App.OFS.Services.ServiceManager.Browser" />
</zopeConfigure>
=== Removed File Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/IServiceDirective.py ===
=== Removed File Zope3/lib/python/Zope/App/OFS/Services/ServiceManager/ServiceDirective.py ===