[Zope3-checkins] CVS: Zope3/src/zope/app/component - configure.zcml:1.7 hooks.py:1.6

Jim Fulton jim@zope.com
Fri, 23 May 2003 13:52:33 -0400


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

Modified Files:
	configure.zcml hooks.py 
Log Message:
Changed the getServiceManager_hook to cache service managers in
wrapper dictionaries.

Added a getNamedAdapter hook that caches the adapter service in
wrapper dictionaries.


=== Zope3/src/zope/app/component/configure.zcml 1.6 => 1.7 ===
--- Zope3/src/zope/app/component/configure.zcml:1.6	Tue May 20 11:46:38 2003
+++ Zope3/src/zope/app/component/configure.zcml	Fri May 23 13:52:33 2003
@@ -42,6 +42,10 @@
 <hook module="zope.component"
       name="getServiceManager"
       implementation="zope.app.component.hooks.getServiceManager_hook" />
+         
+<hook module="zope.component"
+      name="queryNamedAdapter"
+      implementation="zope.app.component.hooks.queryNamedAdapter" />
 
 <serviceType
     id='Interfaces'


=== Zope3/src/zope/app/component/hooks.py 1.5 => 1.6 ===
--- Zope3/src/zope/app/component/hooks.py:1.5	Thu May  1 15:35:07 2003
+++ Zope3/src/zope/app/component/hooks.py	Fri May 23 13:52:33 2003
@@ -15,35 +15,97 @@
 
 $Id$
 """
+
+from zope.component import getService
 from zope.component.interfaces import IServiceService
+from zope.component.exceptions import ComponentLookupError
+from zope.component.servicenames import Adapters
 from zope.app.interfaces.services.service import IServiceManagerContainer
 from zope.proxy.context import getWrapperContainer, ContextWrapper
+from zope.proxy.context import isWrapper, getWrapperData
 from zope.component.service import serviceManager
 from zope.proxy.introspection import removeAllProxies
 from zope.security.proxy import trustedRemoveSecurityProxy
 from zope.app.traversing import IContainmentRoot
 
-def getServiceManager_hook(context, local=False):
-    """
-    context based lookup, with fallback to component architecture
-    service manager if no service manager found within context
-    """
-    while context is not None:
-        clean_context = removeAllProxies(context)
-
-        # if the context is actually a service or service manager...
-        if IServiceService.isImplementedBy(clean_context):
-            return trustedRemoveSecurityProxy(context)
-
-        if (IServiceManagerContainer.isImplementedBy(clean_context) and
-            clean_context.hasServiceManager()
-            ):
-            return ContextWrapper(
-                trustedRemoveSecurityProxy(context.getServiceManager()),
-                context,
-                name="++etc++site",
-                )
+## alog=open('alog','w')
+## slog=open('slog','w')
+## swlog=open('swlog','w')
+## sulog=open('sulog','w')
+## sutblog=open('sutblog','w')
+## nlog=open('nlog','w')
+
+## import sys, traceback
+
+
+
+
+def getServiceManager_hook(context, local=False, recurse=False):
+
+    
+    # XXX Uh, there's this special case for context being none. :(
+    if context is None:
+##         if not recurse:
+##             slog.write('n')
+##             nlog.write('\n')
+##             f = sys._getframe(1)
+##             nlog.write("%s\n" % context.__class__)
+##             nlog.write(''.join(traceback.format_stack(sys._getframe(1),
+##                                                          5)))
+##             nlog.write("\n")
+
+        return serviceManager
+
 
+    data = None
+    wrapped = isWrapper(context)
+    if wrapped:
+        data = getWrapperData(context, create=True)
+##         unwrapped = removeAllProxies(context)
+##         oid = id(unwrapped)
+##         did = id(data)
+##         if not recurse:
+##             swlog.write("%s %s %s\n" %
+##                         (context.__class__.__name__, oid, did))
+        cached = data.get('zope.app.component.hooks.sm')
+        if cached is not None:
+##             if not recurse:
+##                 slog.write('h')
+            return cached
+##         else:
+##             if not recurse:
+##                 slog.write('m')
+##     else:
+##         if not recurse:
+##             sulog.write("%s.%s\n" %
+##                         (context.__class__.__module__,
+##                          context.__class__.__name__))
+##             f = sys._getframe(1)
+##             avoid = "src/zope/app/component/hooks.py"
+##             if (1 or f.f_back.f_code.co_filename != avoid
+##                 ):
+##                 sutblog.write("%s\n" % context.__class__)
+##                 sutblog.write(''.join(traceback.format_stack(sys._getframe(1),
+##                                                              5)))
+##                 sutblog.write("\n")
+##             slog.write('u')
+        
+
+    clean_context = removeAllProxies(context)
+
+    # if the context is actually a service or service manager...
+    if IServiceService.isImplementedBy(clean_context):
+        sm = trustedRemoveSecurityProxy(context)
+
+    elif (IServiceManagerContainer.isImplementedBy(clean_context) and
+        clean_context.hasServiceManager()
+        ):
+        sm = ContextWrapper(
+            trustedRemoveSecurityProxy(context.getServiceManager()),
+            context,
+            name="++etc++site",
+            )
+    else:
         container = getWrapperContainer(context)
         if container is None:
             if local:
@@ -52,8 +114,48 @@
                 if not IContainmentRoot.isImplementedBy(context):
                     raise TypeError("Not enough context to get next "
                                     "service manager")
-                break
-            
-        context = container
 
-    return serviceManager
+            # Fall back to global:
+            sm = serviceManager
+        else:
+            # We have a container, so context is a wrapper.  We still
+            # don't have a service manager, so try again, recursively:
+            sm = getServiceManager_hook(container, local, True)
+
+    # Now cache what we found, cause we might look for it again:
+    if wrapped:
+        data['zope.app.component.hooks.sm'] = sm
+
+    return sm
+
+def queryNamedAdapter(object, interface, name, default=None, context=None):
+    if context is None:
+        context = object
+
+    wrapped = isWrapper(context)
+##     alog.write("%s %s.%s %s.%s\n" % (wrapped,
+##                                context.__class__.__module__,
+##                                context.__class__.__name__,
+##                                interface.__module__,
+##                                interface.__name__,
+##                                ))
+    if wrapped:
+        data = getWrapperData(context, create=True)
+        adapters = data.get('zope.app.component.hooks.adapters')
+        if adapters is None:
+            try:
+                adapters = getService(context, Adapters)
+            except ComponentLookupError:
+                # Oh blast, no adapter service. We're probably just
+                # running from a test
+                return default
+            data['zope.app.component.hooks.adapters'] = adapters
+    else:
+        try:
+            adapters = getService(context, Adapters)
+        except ComponentLookupError:
+            # Oh blast, no adapter service. We're probably just
+            # running from a test
+            return default
+
+    return adapters.queryNamedAdapter(object, interface, name, default)