[Zope3-checkins] CVS: Zope3/src/zope/app/services - adapter.py:1.10 auth.py:1.13 cache.py:1.5 configuration.py:1.8 configure.zcml:1.16 connection.py:1.6 errorr.py:1.7 event.py:1.15 hub.py:1.5 principalannotation.py:1.3 role.py:1.3 service.py:1.9 session.py:1.8 view.py:1.8

Guido van Rossum guido@python.org
Mon, 3 Mar 2003 18:16:44 -0500


Update of /cvs-repository/Zope3/src/zope/app/services
In directory cvs.zope.org:/tmp/cvs-serv7820/src/zope/app/services

Modified Files:
	adapter.py auth.py cache.py configuration.py configure.zcml 
	connection.py errorr.py event.py hub.py principalannotation.py 
	role.py service.py session.py view.py 
Log Message:
Merge from use-config-branch.  (A joint production by Jim, Tim and Guido.)

- Refactor the service creation and configuration code, making the UI
  for creating and configuring services much more pleasant.

- Add a new marker interface, IUseConfigurable, which is used to say
  that an object records dependencies between it and its
  configurations.  (This applies to other configurable objects besides
  services.)  Another marker interface, IAttributeUseConfigurable,
  says that these dependencies are stored as annotations.  And finally
  IUseConfiguration defines the actual interface for discussing these
  dependencies; implementing IUseConfigurable is a promise that such
  an adapter exists (and implementing IAttributeUseConfigurable is one
  way of making this promise come true :-).

- Add a new view tab for services, called "Configurations", which
  displays links to its configurations with summary information.  (Try
  it for the Events service, which has two configurations by default.)

- Add a new interface, ILocalService, which all local services must
  implement.  Also add ISimpleService, which extends ILocalService
  with IAttributeUseConfigurable.  All existing local service
  implementations implement this.

- Some miscellaneous cleanup (e.g. made the browser namespace the
  default namespace in zope/app/browser/services/configure.zcml).


=== Zope3/src/zope/app/services/adapter.py 1.9 => 1.10 ===
--- Zope3/src/zope/app/services/adapter.py:1.9	Tue Feb 11 21:17:34 2003
+++ Zope3/src/zope/app/services/adapter.py	Mon Mar  3 18:16:13 2003
@@ -31,6 +31,7 @@
 from zope.proxy.context import ContextMethod
 from zope.app.services.configuration import ConfigurationStatusProperty
 from zope.app.component.nextservice import getNextService
+from zope.app.interfaces.services.interfaces import ISimpleService
 
 from zope.app.interfaces.services.interfaces import IAdapterConfiguration
 
@@ -42,7 +43,7 @@
 
 class AdapterService(Persistent):
 
-    __implements__ = IAdapterService, IConfigurable
+    __implements__ = IAdapterService, IConfigurable, ISimpleService
 
     def __init__(self):
         self._byName = PersistentDict()


=== Zope3/src/zope/app/services/auth.py 1.12 => 1.13 ===
--- Zope3/src/zope/app/services/auth.py:1.12	Tue Feb 11 21:17:34 2003
+++ Zope3/src/zope/app/services/auth.py	Mon Mar  3 18:16:13 2003
@@ -37,6 +37,7 @@
 from zope.app.security.grants.principalrole import principalRoleManager
 from zope.app.component.nextservice import getNextService
 from zope.proxy.context import ContextMethod
+from zope.app.interfaces.services.interfaces import ISimpleService
 
 
 class DuplicateLogin(Exception):
@@ -48,7 +49,7 @@
 
 class AuthenticationService(Persistent):
 
-    __implements__ = IAuthenticationService, IContainer
+    __implements__ = IAuthenticationService, IContainer, ISimpleService
 
     def __init__(self):
         self._usersbylogin = OOBTree()


=== Zope3/src/zope/app/services/cache.py 1.4 => 1.5 ===
--- Zope3/src/zope/app/services/cache.py:1.4	Thu Jan 23 04:53:28 2003
+++ Zope3/src/zope/app/services/cache.py	Mon Mar  3 18:16:13 2003
@@ -27,6 +27,7 @@
 from zope.proxy.context import ContextMethod
 from zope.app.interfaces.services.event import IEventChannel
 from zope.app.interfaces.event import IObjectModifiedEvent
+from zope.app.interfaces.services.interfaces import ISimpleService
 
 
 class ILocalCachingService(ICachingService, IEventChannel,
@@ -37,6 +38,7 @@
 class CachingService(ServiceSubscriberEventChannel, NameComponentConfigurable):
 
     __implements__ = (ILocalCachingService,
+                      ISimpleService,
                       ServiceSubscriberEventChannel.__implements__)
 
     _subscribeToServiceInterface = IObjectModifiedEvent


=== Zope3/src/zope/app/services/configuration.py 1.7 => 1.8 ===
--- Zope3/src/zope/app/services/configuration.py:1.7	Wed Feb 26 11:11:36 2003
+++ Zope3/src/zope/app/services/configuration.py	Mon Mar  3 18:16:13 2003
@@ -18,28 +18,32 @@
 __metaclass__ = type
 
 from persistence import Persistent
+
+from zope.component \
+     import getAdapter, getService, queryService, getServiceManager
+
+from zope.proxy.context import ContextMethod, ContextWrapper
+from zope.proxy.introspection import removeAllProxies
+
+from zope.security.checker import InterfaceChecker
+from zope.security.proxy import Proxy
+
+from zope.app.interfaces.annotation import IAnnotations
+from zope.app.interfaces.container import IAddNotifiable, IDeleteNotifiable
+from zope.app.interfaces.dependable import IDependable, DependencyError
+
 from zope.app.interfaces.services.configuration import IConfigurationRegistry
 from zope.app.interfaces.services.configuration \
-    import INamedComponentConfiguration, INameConfigurable
+     import INameComponentConfigurable, INamedConfiguration, IConfiguration
 from zope.app.interfaces.services.configuration \
-    import INameComponentConfigurable, INamedConfiguration, IConfiguration
-from zope.component import getService, queryService
-from zope.component import getServiceManager
-from zope.component import getAdapter
-from zope.proxy.context import ContextMethod
-from zope.proxy.context import ContextWrapper
-from zope.proxy.introspection import removeAllProxies
-from zope.security.proxy import Proxy
-from zope.security.checker import InterfaceChecker
-from zope.app.interfaces.container import IAddNotifiable
-from zope.app.interfaces.container import IDeleteNotifiable
-from zope.app.interfaces.dependable import IDependable
-from zope.app.interfaces.dependable import DependencyError
-from zope.app.traversing import getPhysicalPathString, traverse
-from zope.app.traversing import getPhysicalRoot
+     import INamedComponentConfiguration, INameConfigurable
+from zope.app.interfaces.services.configuration import IUseConfiguration
 from zope.app.interfaces.services.configuration \
      import Unregistered, Registered, Active
 
+from zope.app.traversing \
+     import getPhysicalRoot, getPhysicalPathString, traverse
+
 
 class ConfigurationStatusProperty:
 
@@ -272,7 +276,7 @@
             try:
                 objectpath = getPhysicalPathString(configuration)
             except: # XXX
-                objectpath = str(configuration) 
+                objectpath = str(configuration)
             raise DependencyError("Can't delete active configuration (%s)"
                                   % objectpath)
         elif objectstatus == Registered:
@@ -285,9 +289,9 @@
 
     __implements__ = INamedConfiguration, SimpleConfiguration.__implements__
 
-    def __init__(self, name, *args, **kw):
+    def __init__(self, name):
         self.name = name
-        super(NamedConfiguration, self).__init__(*args, **kw)
+        super(NamedConfiguration, self).__init__()
 
 
 class NamedComponentConfiguration(NamedConfiguration):
@@ -301,14 +305,12 @@
     __implements__ = (INamedComponentConfiguration,
                       NamedConfiguration.__implements__, IAddNotifiable)
 
-    # XXX is all this '*args, **kw' business the right way to use super?
-
-    def __init__(self, name, component_path, permission=None, *args, **kw):
+    def __init__(self, name, component_path, permission=None):
         self.componentPath = component_path
         if permission == 'zope.Public':
             permission = CheckerPublic
         self.permission = permission
-        super(NamedComponentConfiguration, self).__init__(name, *args, **kw)
+        super(NamedComponentConfiguration, self).__init__(name)
 
     def getComponent(wrapped_self):
         service_manager = getServiceManager(wrapped_self)
@@ -416,3 +418,29 @@
                 return configuration.getComponent()
         return default
     queryActiveComponent = ContextMethod(queryActiveComponent)
+
+
+USE_CONFIG_KEY = 'zope.app.services.configuration.UseConfiguration'
+
+class UseConfiguration:
+    """An adapter."""
+
+    __implements__ = IUseConfiguration
+
+    def __init__(self, context):
+        self.context = context
+
+    def addUsage(self, location):
+        annotations = getAdapter(self.context, IAnnotations)
+        annotations[USE_CONFIG_KEY] = (annotations.get(USE_CONFIG_KEY, ()) +
+                                       (location, ))
+
+    def removeUsage(self, location):
+        annotations = getAdapter(self.context, IAnnotations)
+        locs = [loc for loc in annotations.get(USE_CONFIG_KEY, ())
+                    if loc != location]
+        annotations[USE_CONFIG_KEY] = tuple(locs)
+
+    def usages(self):
+        annotations = getAdapter(self.context, IAnnotations)
+        return annotations.get(USE_CONFIG_KEY, ())


=== Zope3/src/zope/app/services/configure.zcml 1.15 => 1.16 ===
--- Zope3/src/zope/app/services/configure.zcml:1.15	Fri Feb  7 10:52:21 2003
+++ Zope3/src/zope/app/services/configure.zcml	Mon Mar  3 18:16:13 2003
@@ -13,9 +13,6 @@
 <!-- Adapter Service -->
 
 <content class="zope.app.services.adapter.AdapterService">
-  <implements
-      interface="zope.app.interfaces.annotation.IAttributeAnnotatable"
-      />
   <factory
       id="zope.app.services.AdapterService"
       permission="zope.ManageServices"
@@ -42,8 +39,6 @@
 <!-- View Service -->
 
 <content class="zope.app.services.view.ViewService">
-  <implements
-      interface="zope.app.interfaces.annotation.IAttributeAnnotatable" />
   <factory
       id="zope.app.services.ViewService"
       permission="zope.ManageServices"
@@ -102,27 +97,33 @@
       />
 </content>
 
-<adapter 
+<adapter
   for="zope.app.interfaces.services.interfaces.IZPTTemplate"
   provides="zope.app.interfaces.file.IReadFile"
   factory=".zpt.ReadFile"
   permission="zope.ManageServices"
   />
 
-<adapter 
+<adapter
   for="zope.app.interfaces.services.interfaces.IZPTTemplate"
   provides="zope.app.interfaces.file.IWriteFile"
   factory=".zpt.WriteFile"
   permission="zope.ManageServices"
   />
 
-<adapter 
+<adapter
   for="zope.app.interfaces.services.service.IViewPackage"
   provides="zope.app.interfaces.file.IFileFactory"
   factory=".zpt.ZPTFactory"
   permission="zope.ManageServices"
   />
 
+<adapter
+  for="zope.app.interfaces.services.configuration.IUseConfigurable"
+  provides="zope.app.interfaces.services.configuration.IUseConfiguration"
+  factory="zope.app.services.configuration.UseConfiguration"
+  />
+
 <!-- Role Templates -->
 
 <content class="zope.app.services.role.RoleService">
@@ -138,9 +139,6 @@
       permission="zope.ManageServices"
       interface="zope.app.interfaces.container.IContainer"
       />
-  <implements
-      interface="zope.app.interfaces.annotation.IAttributeAnnotatable"
-      />
 </content>
 
 <content class="zope.app.services.role.Role">
@@ -154,7 +152,7 @@
 <!-- Session Templates -->
 
 <serviceType
-    id="Sessions" 
+    id="Sessions"
     interface="zope.app.interfaces.services.session.ISessionService"
     />
 
@@ -167,9 +165,6 @@
       id="ISessionService"
       permission="zope.ManageServices"
       />
-  <implements
-      interface="zope.app.interfaces.annotation.IAttributeAnnotatable"
-      />
 </content>
 
 <!-- Caching Service -->
@@ -184,8 +179,6 @@
       <require
           permission="zope.ManageServices"
           interface="zope.app.interfaces.container.IContainer" />
-      <implements
-          interface="zope.app.interfaces.annotation.IAttributeAnnotatable" />
     </content>
 
   <content class="zope.app.services.cache.CacheConfiguration">
@@ -298,18 +291,15 @@
         permission="zope.ManageCode"
         interface="zodb.code.interfaces.IPersistentModuleManager"
         />
-    <implements
-        interface="zope.app.interfaces.annotation.IAttributeAnnotatable"
-        />
     </content>
 
 <!-- View Packages -->
 
   <content class="zope.app.services.viewpackage.ViewPackage">
     <factory
-      id = "zope.app.services.ViewPackage" 
+      id = "zope.app.services.ViewPackage"
       permission = "zope.ManageServices"
-      title = "View Package" 
+      title = "View Package"
       />
     <require
         permission="zope.View"
@@ -333,10 +323,7 @@
   <content class="zope.app.services.connection.ConnectionService">
     <factory
        id="ConnectionService"
-       permission="zope.ManageServices" 
-       />
-    <implements
-       interface="zope.app.interfaces.annotation.IAttributeAnnotatable" 
+       permission="zope.ManageServices"
        />
     <require
         permission="zope.View"
@@ -351,15 +338,15 @@
         interface=
         "zope.app.interfaces.services.connection.IConnectionConfiguration"
         set_attributes="name componentPath"
-        set_schema="zope.app.interfaces.services.interfaces.IPageConfiguration" 
+        set_schema="zope.app.interfaces.services.interfaces.IPageConfiguration"
         />
     <require
         permission="zope.ManageServices"
-        interface="zope.app.interfaces.container.IAddNotifiable" 
+        interface="zope.app.interfaces.container.IAddNotifiable"
         />
     <require
         permission="zope.ManageServices"
-        interface="zope.app.interfaces.container.IDeleteNotifiable" 
+        interface="zope.app.interfaces.container.IDeleteNotifiable"
         />
     </content>
 
@@ -384,15 +371,12 @@
         id="IPrincipalAnnotationService"
         permission="zope.ManageServices"
         />
-    <implements 
-       interface="zope.app.interfaces.annotation.IAttributeAnnotatable"
-       />
     </content>
 
 <!-- Error reporting service -->
 
   <serviceType
-      id="ErrorReportingService" 
+      id="ErrorReportingService"
       interface="zope.app.interfaces.services.error.IErrorReportingService" />
 
   <content class='zope.app.services.errorr.ErrorReportingService'>
@@ -403,15 +387,12 @@
     <factory
         id='ErrorReportingService'
         permission='zope.Public' />
-    <implements
-        interface="zope.app.interfaces.annotation.IAttributeAnnotatable"
-        />
     </content>
 
 <!-- Object Hub -->
 
   <serviceType
-      id='HubIds' 
+      id='HubIds'
       interface='zope.app.interfaces.services.hub.IObjectHub' />
 
   <content class='zope.app.services.hub.ObjectHub'>
@@ -422,13 +403,11 @@
         permission="zope.View"
 	attributes="notify getHubId getLocation getObject
                     register unregister numRegistrations
-                    getRegistrations" />		   
+                    getRegistrations" />
     <require
         permission="zope.ManageServices"
         attributes="bound unbound subscribe unsubscribe subscribeOnBind
                     unsubscribedFrom subscribedTo" />
-    <implements 
-       interface="zope.app.interfaces.annotation.IAttributeAnnotatable" />
     </content>
 
 <!-- Authentication Service -->
@@ -450,9 +429,6 @@
         permission="zope.ManageServices"
         interface="zope.app.interfaces.container.IContainer" />
 
-    <implements
-       interface="zope.app.interfaces.annotation.IAttributeAnnotatable" />
-
     </content>
 
   <content class="zope.app.services.auth.User">
@@ -481,9 +457,6 @@
       permission="zope.ManageServices"
       attributes="bound unbound subscribe unsubscribe subscribeOnBind
                   unsubscribedFrom subscribedTo"
-      />
-  <implements
-      interface="zope.app.interfaces.annotation.IAttributeAnnotatable."
       />
 </content>
 


=== Zope3/src/zope/app/services/connection.py 1.5 => 1.6 ===
--- Zope3/src/zope/app/services/connection.py:1.5	Thu Jan 23 04:46:30 2003
+++ Zope3/src/zope/app/services/connection.py	Mon Mar  3 18:16:13 2003
@@ -23,6 +23,7 @@
 from zope.app.services.configuration import NameComponentConfigurable
 from zope.app.interfaces.rdb import IConnectionService
 from zope.app.interfaces.rdb import IZopeDatabaseAdapter
+from zope.app.interfaces.services.interfaces import ISimpleService
 
 
 class ILocalConnectionService(IConnectionService, INameComponentConfigurable):
@@ -33,7 +34,7 @@
 
     __doc__ = ILocalConnectionService.__doc__
 
-    __implements__ = ILocalConnectionService
+    __implements__ = ILocalConnectionService, ISimpleService
 
     def getConnection(self, name):
         'See IConnectionService'


=== Zope3/src/zope/app/services/errorr.py 1.6 => 1.7 ===
--- Zope3/src/zope/app/services/errorr.py:1.6	Tue Feb 11 10:59:56 2003
+++ Zope3/src/zope/app/services/errorr.py	Mon Mar  3 18:16:13 2003
@@ -25,8 +25,9 @@
 import logging
 from zope.exceptions.exceptionformatter import format_exception
 from zope.proxy.context import ContextMethod
-from zope.app.interfaces.services.error \
-        import IErrorReportingService
+from zope.app.interfaces.services.error import IErrorReportingService
+from zope.app.interfaces.services.interfaces import ISimpleService
+
 
 #Restrict the rate at which errors are sent to the Event Log
 _rate_restrict_pool = {}
@@ -48,7 +49,7 @@
 class ErrorReportingService(Persistent):
     """Error Reporting Service
     """
-    __implements__ = IErrorReportingService
+    __implements__ = IErrorReportingService, ISimpleService
 
     keep_entries = 20
     copy_to_zlog = 0


=== Zope3/src/zope/app/services/event.py 1.14 => 1.15 ===
--- Zope3/src/zope/app/services/event.py:1.14	Tue Feb 18 10:19:22 2003
+++ Zope3/src/zope/app/services/event.py	Mon Mar  3 18:16:13 2003
@@ -294,11 +294,14 @@
     iterSubscriptions = ContextMethod(iterSubscriptions)
 
 
+from zope.app.interfaces.services.interfaces import ISimpleService
+
 class EventService(ServiceSubscriberEventChannel, ServiceSubscribable):
 
     __implements__ = (
         IEventService,
         ISubscriptionService,
+        ISimpleService,
         ServiceSubscribable.__implements__,
         ServiceSubscriberEventChannel.__implements__
         )


=== Zope3/src/zope/app/services/hub.py 1.4 => 1.5 ===
--- Zope3/src/zope/app/services/hub.py:1.4	Mon Dec 30 09:03:16 2002
+++ Zope3/src/zope/app/services/hub.py	Mon Mar  3 18:16:13 2003
@@ -46,6 +46,7 @@
 from zope.app.interfaces.services.hub import IObjectMovedHubEvent
 from zope.app.interfaces.services.hub import IObjectRemovedHubEvent
 from zope.app.interfaces.traversing import ITraverser
+from zope.app.interfaces.services.interfaces import ISimpleService
 
 class HubEvent:
     """Convenient mix-in for HubEvents"""
@@ -162,6 +163,7 @@
     else:
         return abs
 
+
 class ObjectHub(ServiceSubscriberEventChannel, ):
 
     # this implementation makes the decision to not interact with any
@@ -171,6 +173,7 @@
 
     __implements__ = (
         IObjectHub,
+        ISimpleService,
         ServiceSubscriberEventChannel.__implements__)
 
     def __init__(self):


=== Zope3/src/zope/app/services/principalannotation.py 1.2 => 1.3 ===
--- Zope3/src/zope/app/services/principalannotation.py:1.2	Wed Dec 25 09:13:19 2002
+++ Zope3/src/zope/app/services/principalannotation.py	Mon Mar  3 18:16:13 2003
@@ -28,7 +28,7 @@
 
 # Sibling imports
 from zope.app.interfaces.services.principalannotation import IPrincipalAnnotationService
-
+from zope.app.interfaces.services.interfaces import ISimpleService
 
 class PrincipalAnnotationService(Persistent):
     """Stores IAnnotations for IPrinicipals.
@@ -36,7 +36,8 @@
     The service ID is 'PrincipalAnnotation'.
     """
 
-    __implements__ = IPrincipalAnnotationService, Persistent.__implements__
+    __implements__ = (IPrincipalAnnotationService, Persistent.__implements__,
+                      ISimpleService)
 
     def __init__(self):
         self.annotations = OOBTree()


=== Zope3/src/zope/app/services/role.py 1.2 => 1.3 ===
--- Zope3/src/zope/app/services/role.py:1.2	Wed Dec 25 09:13:19 2002
+++ Zope3/src/zope/app/services/role.py	Mon Mar  3 18:16:13 2003
@@ -17,32 +17,24 @@
 $Id$
 """
 
-from zope.app.security.registries.roleregistry import Role
 from persistence import Persistent
-
-class Role(Role, Persistent):
-    "Persistent Role"
-
-
-
-
-"""
-
-Revision information:
-$Id$
-"""
+from zope.app.security.registries.roleregistry import Role
 from zope.app.container.btree import BTreeContainer
 from zope.app.interfaces.security import IRoleService
 from zope.app.interfaces.container import IContainer
 from zope.proxy.context import ContextMethod
 from zope.app.component.nextservice import getNextService
+from zope.app.interfaces.services.interfaces import ISimpleService
+
+class Role(Role, Persistent):
+    "Persistent Role"
 
 class ILocalRoleService(IRoleService, IContainer):
     """TTW manageable role service"""
 
 class RoleService(BTreeContainer):
 
-    __implements__ = ILocalRoleService
+    __implements__ = ILocalRoleService, ISimpleService
 
     def getRole(wrapped_self, rid):
         '''See interface IRoleService'''
@@ -64,6 +56,3 @@
             roles.extend(roleserv.getRoles())
         return roles
     getRoles = ContextMethod(getRoles)
-
-    #
-    ############################################################


=== Zope3/src/zope/app/services/service.py 1.8 => 1.9 ===
--- Zope3/src/zope/app/services/service.py:1.8	Tue Feb  4 05:26:00 2003
+++ Zope3/src/zope/app/services/service.py	Mon Mar  3 18:16:13 2003
@@ -31,6 +31,7 @@
 from zodb.code.module import PersistentModule
 from zodb.code.module import PersistentModuleRegistry
 
+from zope.component import getAdapter
 from zope.component import getServiceManager
 from zope.component.exceptions import ComponentLookupError
 from zope.component.interfaces import IServiceService
@@ -48,6 +49,7 @@
 from zope.app.interfaces.services.service import IServiceConfiguration
 from zope.app.interfaces.services.service import IServiceManager
 from zope.app.interfaces.services.service import IServiceManagerContainer
+from zope.app.interfaces.services.configuration import IUseConfiguration
 
 ModuleType = type(INameResolver)
 ModuleType = ModuleType, PersistentModule
@@ -56,6 +58,10 @@
 from zope.app.services.configuration import NameComponentConfigurable
 from zope.app.services.configuration import NamedComponentConfiguration
 from zope.app.services.package import Packages
+from zope.app.interfaces.services.configuration import IUseConfigurable
+from zope.app.interfaces.services.interfaces import ILocalService
+
+from zope.app.traversing import getPhysicalPathString
 
 class ServiceManager(PersistentModuleRegistry, NameComponentConfigurable):
 
@@ -256,8 +262,16 @@
 
     label = "Service"
 
-    def __init__(self, *args, **kw):
-        super(ServiceConfiguration, self).__init__(*args, **kw)
+    def __init__(self, name, path, context=None):
+        super(ServiceConfiguration, self).__init__(name, path)
+        if context is not None:
+            # Check that the object implements stuff we need
+            wrapped_self = ContextWrapper(self, context)
+            service = wrapped_self.getComponent()
+            if not ILocalService.isImplementedBy(service):
+                raise TypeError("service %r doesn't implement ILocalService" %
+                                service)
+        # Else, this must be a hopeful test invocation
 
     def getInterface(self):
         service_manager = getServiceManager(self)
@@ -279,3 +293,18 @@
 
     deactivated = ContextMethod(deactivated)
 
+    def afterAddHook(self, configuration, container):
+        NamedComponentConfiguration.afterAddHook(self,
+                                                 configuration,
+                                                 container)
+        service = configuration.getComponent()
+        adapter = getAdapter(service, IUseConfiguration)
+        adapter.addUsage(getPhysicalPathString(configuration))
+
+    def beforeDeleteHook(self, configuration, container):
+        service = configuration.getComponent()
+        adapter = getAdapter(service, IUseConfiguration)
+        adapter.removeUsage(getPhysicalPathString(configuration))
+        NamedComponentConfiguration.beforeDeleteHook(self,
+                                                     configuration,
+                                                     container)


=== Zope3/src/zope/app/services/session.py 1.7 => 1.8 ===
--- Zope3/src/zope/app/services/session.py:1.7	Sun Mar  2 13:09:01 2003
+++ Zope3/src/zope/app/services/session.py	Mon Mar  3 18:16:13 2003
@@ -30,6 +30,7 @@
 # Sibling imports
 from zope.app.interfaces.services.session import ISessionService
 from zope.app.interfaces.services.session import IConfigureSessionService
+from zope.app.interfaces.services.interfaces import ISimpleService
 
 
 cookieSafeTrans = string.maketrans("+/", "-.")
@@ -43,7 +44,7 @@
     """Session service implemented using cookies."""
 
     __implements__ = (Persistent.__implements__, ISessionService,
-                      IConfigureSessionService)
+                      IConfigureSessionService, ISimpleService)
 
     def __init__(self):
         self.dataManagers = PersistentDict()


=== Zope3/src/zope/app/services/view.py 1.7 => 1.8 ===
--- Zope3/src/zope/app/services/view.py:1.7	Fri Feb 21 09:50:04 2003
+++ Zope3/src/zope/app/services/view.py	Mon Mar  3 18:16:13 2003
@@ -44,10 +44,11 @@
 from zope.app.interfaces.services.interfaces import IViewConfiguration, IPageConfiguration
 from zope.app.services.adapter import PersistentAdapterRegistry
 from zope.configuration.exceptions import ConfigurationError
+from zope.app.interfaces.services.interfaces import ISimpleService
 
 class ViewService(Persistent):
 
-    __implements__ = IViewService, IConfigurable
+    __implements__ = IViewService, IConfigurable, ISimpleService
 
     def __init__(self):
         self._layers = PersistentDict()