[Zope3-checkins] CVS: Zope3/src/zope/app/component - classfactory.py:1.3.4.1 configure.zcml:1.6.2.1 contentdirective.py:1.1.4.1 globalinterfaceservice.py:1.10.2.1 hooks.py:1.5.10.1 interfacefield.py:1.8.2.1 meta.zcml:1.3.4.1 metaconfigure.py:1.10.10.1 nextservice.py:1.3.18.1

Grégoire Weber zope@i-con.ch
Sun, 22 Jun 2003 10:24:28 -0400


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

Modified Files:
      Tag: cw-mail-branch
	classfactory.py configure.zcml contentdirective.py 
	globalinterfaceservice.py hooks.py interfacefield.py meta.zcml 
	metaconfigure.py nextservice.py 
Log Message:
Synced up with HEAD

=== Zope3/src/zope/app/component/classfactory.py 1.3 => 1.3.4.1 ===
--- Zope3/src/zope/app/component/classfactory.py:1.3	Sat May  3 12:32:41 2003
+++ Zope3/src/zope/app/component/classfactory.py	Sun Jun 22 10:22:54 2003
@@ -13,7 +13,7 @@
 ##############################################################################
 "$Id$"
 
-from zope.interface import implements
+from zope.interface import implements, implementedBy
 from zope.component.interfaces import IFactory
 
 class ClassFactory:
@@ -28,6 +28,6 @@
         return self._class(*args, **kwargs)
 
     def getInterfaces(self):
-        return getattr(self._class, '__implements__', None)
+        return tuple(implementedBy(self._class))
 
 __doc__ = "%s\n\n%s" % (ClassFactory.__doc__, __doc__)


=== Zope3/src/zope/app/component/configure.zcml 1.6 => 1.6.2.1 ===
--- Zope3/src/zope/app/component/configure.zcml:1.6	Tue May 20 11:46:38 2003
+++ Zope3/src/zope/app/component/configure.zcml	Sun Jun 22 10:22:54 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/contentdirective.py 1.1 => 1.1.4.1 ===
--- Zope3/src/zope/app/component/contentdirective.py:1.1	Mon May 12 12:32:39 2003
+++ Zope3/src/zope/app/component/contentdirective.py	Sun Jun 22 10:22:54 2003
@@ -17,7 +17,7 @@
 """
 from zope.interface import classProvides
 from types import ModuleType
-from zope.interface.implements import implements
+from zope.interface import implements, classImplements
 from zope.configuration.interfaces import INonEmptyDirective
 from zope.configuration.interfaces import ISubdirectiveHandler
 from zope.component import getService
@@ -51,7 +51,7 @@
 class ContentDirective:
 
     classProvides(INonEmptyDirective)
-    __implements__ = ISubdirectiveHandler
+    implements(ISubdirectiveHandler)
 
     def __init__(self, _context, class_):
         self.__id = class_
@@ -70,11 +70,10 @@
             resolved_interface = resolveInterface(_context, interface)
             r += [
                 Action(
-                    discriminator = ('ContentDirective', self.__class, object()),
-                    callable = implements,
-                    # the last argument is check=1, which causes implements
-                    # to verify that the class does implement the interface
-                    args = (self.__class, resolved_interface, 1),
+                    discriminator = (
+                        'ContentDirective', self.__class, object()),
+                    callable = classImplements,
+                    args = (self.__class, resolved_interface),
                     ),
                 Action(
                    discriminator = None,


=== Zope3/src/zope/app/component/globalinterfaceservice.py 1.10 => 1.10.2.1 ===
--- Zope3/src/zope/app/component/globalinterfaceservice.py:1.10	Tue May 20 15:43:25 2003
+++ Zope3/src/zope/app/component/globalinterfaceservice.py	Sun Jun 22 10:22:54 2003
@@ -19,9 +19,10 @@
 
 from zope.component.exceptions import ComponentLookupError
 from zope.app.interfaces.component import IGlobalInterfaceService
+from zope.interface import implements
 
 class InterfaceService:
-    __implements__ = IGlobalInterfaceService
+    implements(IGlobalInterfaceService)
 
     def __init__(self, data=None):
         if data is None:


=== Zope3/src/zope/app/component/hooks.py 1.5 => 1.5.10.1 ===
--- Zope3/src/zope/app/component/hooks.py:1.5	Thu May  1 15:35:07 2003
+++ Zope3/src/zope/app/component/hooks.py	Sun Jun 22 10:22:54 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.app.context import ContextWrapper
+from zope.context import getWrapperContainer, isWrapper, getWrapperData
 from zope.component.service import serviceManager
-from zope.proxy.introspection import removeAllProxies
+from zope.proxy 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)


=== Zope3/src/zope/app/component/interfacefield.py 1.8 => 1.8.2.1 ===
--- Zope3/src/zope/app/component/interfacefield.py:1.8	Tue May 13 13:08:33 2003
+++ Zope3/src/zope/app/component/interfacefield.py	Sun Jun 22 10:22:54 2003
@@ -16,14 +16,14 @@
 """
 
 from zope.schema import Enumerated, Field, Tuple
-from zope.interface import Interface
+from zope.interface import Interface, implements
 from zope.interface.interfaces import IInterface
 from zope.schema.interfaces import ValidationError
 from zope.app.interfaces.component import IInterfaceField, IInterfacesField
 
 class InterfaceField(Enumerated, Field):
     __doc__ = IInterfaceField.__doc__
-    __implements__ = IInterfaceField
+    implements(IInterfaceField)
 
     # This is the most base basetype.
     # This isn't the default value. See the 'basetype' arg of __init__ for
@@ -56,7 +56,7 @@
 
 class InterfacesField(Tuple):
     __doc__ = IInterfacesField.__doc__
-    __implements__ = IInterfacesField
+    implements(IInterfacesField)
 
     # This is the most base basetype.
     # This isn't the default value. See the 'basetype' arg of __init__ for


=== Zope3/src/zope/app/component/meta.zcml 1.3 => 1.3.4.1 ===
--- Zope3/src/zope/app/component/meta.zcml:1.3	Mon May 12 12:32:39 2003
+++ Zope3/src/zope/app/component/meta.zcml	Sun Jun 22 10:22:54 2003
@@ -11,7 +11,7 @@
     <directive name="utility" attributes="component provides permission name"
        handler="zope.app.component.metaconfigure.utility" />
 
-    <directive name="factory" attributes="component id"
+    <directive name="factory" attributes="component id permission"
        handler="zope.app.component.metaconfigure.factory" />
 
     <directive 
@@ -39,127 +39,203 @@
     <directive name="service" attributes="serviceType component permission"
        handler="zope.app.component.metaconfigure.service" />
 
-  </directives>
-
-<directives namespace="http://namespaces.zope.org/zope">
-
-  <directive
-      name="content"
-      handler="zope.app.component.contentdirective.ContentDirective"
-      description="Make a component available as a content object type"
-      >
-    <attribute
-        name="class"
-        required="yes"
-        description="resolvable name of a class" 
-        />
-
-    <subdirective name="implements">
-
-      <description>
-            Declare that the class given by the content
-            directive's class attribute implements a given interface
-        </description>
-
+    <directive
+        name="content"
+        handler="zope.app.component.contentdirective.ContentDirective"
+        description="Make a component available as a content object type"
+        >
       <attribute
-          name="interface"
+          name="class"
           required="yes"
-          description="resolvable name of an Interface" 
+          description="resolvable name of a class" 
           />
-    </subdirective>
 
-    <subdirective name="require">
-      <description>
-          Indicate that the a specified list of names or the
-          names in a given Interface require a given permission for
-          access.
-        </description>
+      <subdirective name="implements">
 
-      <attribute
-          name="permission"
-          required="yes"
-          description="a permission id" 
-          />
+        <description>
+              Declare that the class given by the content
+              directive's class attribute implements a given interface
+          </description>
 
-      <attribute
-          name="attributes"
-          description="space-separated list of attribute names" 
-          />
+        <attribute
+            name="interface"
+            required="yes"
+            description="resolvable name of an Interface" 
+            />
+      </subdirective>
 
-      <attribute
-          name="interface"
-          description="the resolvable name of an interface" 
-          />
+      <subdirective name="require">
+        <description>
+            Indicate that the a specified list of names or the
+            names in a given Interface require a given permission for
+            access.
+          </description>
 
-      <attribute name="like_class">
+        <attribute
+            name="permission"
+            required="yes"
+            description="a permission id" 
+            />
+
+        <attribute
+            name="attributes"
+            description="space-separated list of attribute names" 
+            />
+
+        <attribute
+            name="interface"
+            description="the resolvable name of an interface" 
+            />
+
+        <attribute name="like_class">
+          <description>
+                a class on which the security requirements
+                for this class will be based 
+              </description>
+          </attribute>
+
+      </subdirective>
+
+      <subdirective name="allow">
         <description>
-              a class on which the security requirements
-              for this class will be based 
-            </description>
-        </attribute>
+              Declare a part of the class to be publicly
+              viewable (that is, requires the zope.Public
+              permission).  Only one of the following two
+              attributes may be used.
+           </description>
+
+        <attribute
+            name="attributes"
+            description="space-separated list of attribute names" 
+            />
+
+        <attribute
+            name="interface"
+            description="the resolvable name of an interface" 
+            />
 
-    </subdirective>
+      </subdirective>
 
-    <subdirective name="allow">
-      <description>
-            Declare a part of the class to be publicly
-            viewable (that is, requires the zope.Public
-            permission).  Only one of the following two
-            attributes may be used.
-         </description>
+      <subdirective name="factory">
 
-      <attribute
-          name="attributes"
-          description="space-separated list of attribute names" 
-          />
+        <description>
+              Specify the factory used to create this
+              content object
+          </description>
+
+        <attribute name="permission">
+          <description>
+                permission id required to use this factory.
+                Although optional, this attribute should normally
+                be specified. 
+                </description>
+          </attribute>
+
+        <attribute name="id">
+          <description>
+                the identifier for this factory in the
+                ZMI factory identification scheme.  If not given, defaults
+                to the literal string given as the content directive's
+                'class' attribute.
+              </description>
+          </attribute>
+
+        <attribute name="title">
+          <description>
+                text suitable for use in the 'add content' menu of
+                a management interface
+              </description>
+          </attribute>
 
+        <attribute name="description">
+          <description>
+                longer narrative description of what this
+                factory does
+            </description>
+          </attribute>
+
+      </subdirective>
+    </directive>
+
+    <directive
+        name="class"
+        handler="zope.app.component.contentdirective.ContentDirective"
+        description="Make statements about a class"
+        >
       <attribute
-          name="interface"
-          description="the resolvable name of an interface" 
+          name="class"
+          required="yes"
+          description="resolvable name of a class" 
           />
 
-    </subdirective>
+      <subdirective name="implements">
 
-    <subdirective name="factory">
+        <description>
+              Declare that the class given by the content
+              directive's class attribute implements a given interface
+          </description>
 
-      <description>
-            Specify the factory used to create this
-            content object
-        </description>
+        <attribute
+            name="interface"
+            required="yes"
+            description="resolvable name of an Interface" 
+            />
+      </subdirective>
 
-      <attribute name="permission">
+      <subdirective name="require">
         <description>
-              permission id required to use this factory.
-              Although optional, this attribute should normally
-              be specified. 
+            Indicate that the a specified list of names or the
+            names in a given Interface require a given permission for
+            access.
+          </description>
+
+        <attribute
+            name="permission"
+            required="yes"
+            description="a permission id" 
+            />
+
+        <attribute
+            name="attributes"
+            description="space-separated list of attribute names" 
+            />
+
+        <attribute
+            name="interface"
+            description="the resolvable name of an interface" 
+            />
+
+        <attribute name="like_class">
+          <description>
+                a class on which the security requirements
+                for this class will be based 
               </description>
-        </attribute>
+          </attribute>
 
-      <attribute name="id">
-        <description>
-              the identifier for this factory in the
-              ZMI factory identification scheme.  If not given, defaults
-              to the literal string given as the content directive's
-              'class' attribute.
-            </description>
-        </attribute>
+      </subdirective>
 
-      <attribute name="title">
+      <subdirective name="allow">
         <description>
-              text suitable for use in the 'add content' menu of
-              a management interface
-            </description>
-        </attribute>
+              Declare a part of the class to be publicly
+              viewable (that is, requires the zope.Public
+              permission).  Only one of the following two
+              attributes may be used.
+           </description>
+
+        <attribute
+            name="attributes"
+            description="space-separated list of attribute names" 
+            />
+
+        <attribute
+            name="interface"
+            description="the resolvable name of an interface" 
+            />
 
-      <attribute name="description">
-        <description>
-              longer narrative description of what this
-              factory does
-          </description>
-        </attribute>
+      </subdirective>
 
-    </subdirective>
-  </directive>
-</directives>
+    </directive>
+
+  </directives>
 
 </zopeConfigure>


=== Zope3/src/zope/app/component/metaconfigure.py 1.10 => 1.10.10.1 ===
--- Zope3/src/zope/app/component/metaconfigure.py:1.10	Thu May  1 15:35:07 2003
+++ Zope3/src/zope/app/component/metaconfigure.py	Sun Jun 22 10:22:54 2003
@@ -13,16 +13,19 @@
 ##############################################################################
 
 from zope.configuration.exceptions import ConfigurationError
-from zope.security.proxy import Proxy
+from zope.security.proxy import Proxy, ProxyFactory
 from zope.component import getService, getServiceManager
 from zope.app.services.servicenames import Adapters, Interfaces, Skins
 from zope.app.services.servicenames import Views, Resources, Factories
 from zope.app.component.globalinterfaceservice import interfaceService
 from zope.configuration.action import Action
-from zope.security.checker import InterfaceChecker, CheckerPublic, Checker
+from zope.security.checker import InterfaceChecker, CheckerPublic, \
+     Checker, NamesChecker
 from zope.app.security.registries.permissionregistry import permissionRegistry
 from zope.component.service import UndefinedService
 
+PublicPermission = 'zope.Public'
+
 # 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
@@ -68,7 +71,7 @@
     elif not for_:
         raise ValueError(
             "A for interface must be provided. Use * for all objects.")
-        
+
     if for_:
         for_ = resolveInterface(_context, for_)
 
@@ -76,7 +79,7 @@
     factory = map(_context.resolve, factory.split())
 
     if permission is not None:
-        if permission == 'zope.Public':
+        if permission == PublicPermission:
             permission = CheckerPublic
         checker = InterfaceChecker(provides, permission)
         factory.append(lambda c: Proxy(c, checker))
@@ -119,7 +122,7 @@
         component = _context.resolve(component)
 
     if permission is not None:
-        if permission == 'zope.Public':
+        if permission == PublicPermission:
             permission = CheckerPublic
         checker = InterfaceChecker(provides, permission)
 
@@ -141,7 +144,7 @@
         ]
 
 
-def factory(_context, component, id=None):
+def factory(_context, component, id=None, permission=None):
     if id is None:
         id = component
 
@@ -150,16 +153,33 @@
     return [
         Action(
             discriminator = ('factory', id),
-            callable = handler,
-            args = (Factories, 'provideFactory', id, component),
+            callable = provideFactory,
+            args = (id, component, permission),
             )
         ]
 
+def provideFactory(name, factory, permission):
+    # make sure the permission is defined
+    if permission is not None:
+        permissionRegistry.ensurePermissionDefined(permission)
+
+    if permission == PublicPermission:
+        permission = CheckerPublic
+
+    if permission:
+        # XXX should getInterfaces be public, as below?
+        factory = ProxyFactory(factory,
+                               NamesChecker(('getInterfaces',),
+                                            __call__=permission))
+
+    getService(None, Factories).provideFactory(name, factory)
+
+
 def _checker(_context, permission, allowed_interface, allowed_attributes):
     if (not allowed_attributes) and (not allowed_interface):
         allowed_attributes = "__call__"
 
-    if permission == 'zope.Public':
+    if permission == PublicPermission:
         permission = CheckerPublic
 
     require={}
@@ -344,7 +364,7 @@
         else:
             raise UndefinedService(serviceType)
 
-        if permission == 'zope.Public':
+        if permission == PublicPermission:
             permission = CheckerPublic
 
         checker = InterfaceChecker(interface, permission)


=== Zope3/src/zope/app/component/nextservice.py 1.3 => 1.3.18.1 ===
--- Zope3/src/zope/app/component/nextservice.py:1.3	Tue Mar 11 16:08:40 2003
+++ Zope3/src/zope/app/component/nextservice.py	Sun Jun 22 10:22:54 2003
@@ -18,8 +18,8 @@
 
 from zope.component.exceptions import ComponentLookupError
 from zope.component.service import serviceManager
-from zope.proxy.context import getWrapperContainer
-from zope.proxy.introspection import removeAllProxies
+from zope.context import getWrapperContainer
+from zope.proxy import removeAllProxies
 from zope.app.interfaces.services.service import IServiceManagerContainer
 from zope.app.component.hooks import getServiceManager_hook
 
@@ -74,5 +74,8 @@
     # But we have to make sure we haven't got the same object..
     while (context is not None) and (context == container):
         context = getWrapperContainer(context)
+
+    if context is None:
+        return serviceManager
 
     return getServiceManager_hook(context, local=True)