[Zope3-checkins] CVS: Zope3/src/zope/app/publisher/xmlrpc - meta.zcml:1.4 metaconfigure.py:1.13 metadirectives.py:1.2

Stephan Richter srichter at cosmos.phy.tufts.edu
Mon Aug 4 20:19:46 EDT 2003


Update of /cvs-repository/Zope3/src/zope/app/publisher/xmlrpc
In directory cvs.zope.org:/tmp/cvs-serv1822/src/zope/app/publisher/xmlrpc

Modified Files:
	meta.zcml metaconfigure.py metadirectives.py 
Log Message:
After wanting to fix XML-RPC for over a year, I finally got around to do
it. You can now specify view names, create default views and of course you
do not have access to the object's methods directly anymore.

Added some tests for all of this.

Updated XML-RPC directives. Made them also a bit more consistent with the 
browser ones.

This should make the XML-RPC code ready for the beta.


=== Zope3/src/zope/app/publisher/xmlrpc/meta.zcml 1.3 => 1.4 ===
--- Zope3/src/zope/app/publisher/xmlrpc/meta.zcml:1.3	Sun Aug  3 19:47:47 2003
+++ Zope3/src/zope/app/publisher/xmlrpc/meta.zcml	Mon Aug  4 19:19:10 2003
@@ -2,16 +2,16 @@
     xmlns:meta="http://namespaces.zope.org/meta"
     xmlns="http://namespaces.zope.org/zope">
   
-  <meta:complexDirective 
+  <meta:directive 
        namespace="http://namespaces.zope.org/xmlrpc"
        name="view" 
        schema=".metadirectives.IViewDirective"
-       handler=".metaconfigure.view">
+       handler=".metaconfigure.view" />
 
-     <meta:subdirective 
-         name="method" 
-         schema=".metadirectives.IMethodDirective" /> 
-
-  </meta:complexDirective>
+  <meta:directive
+      namespace="http://namespaces.zope.org/xmlrpc"
+      name="defaultView"
+      schema=".metadirectives.IDefaultViewDirective"
+      handler=".metaconfigure.defaultView" />
 
 </configure>


=== Zope3/src/zope/app/publisher/xmlrpc/metaconfigure.py 1.12 => 1.13 ===
--- Zope3/src/zope/app/publisher/xmlrpc/metaconfigure.py:1.12	Sun Aug  3 19:47:47 2003
+++ Zope3/src/zope/app/publisher/xmlrpc/metaconfigure.py	Mon Aug  4 19:19:10 2003
@@ -23,130 +23,71 @@
 from zope.security.checker import CheckerPublic, NamesChecker, Checker
 
 
-class view(object):
-    '''This view class handles the directives for the XML-RPC Presentation'''
+def view(_context, name, class_=None, for_=None, layer=None,
+         permission=None, allowed_interface=None, allowed_attributes=None):
 
-    type = IXMLRPCPresentation
-
-    def __init__(self, _context, name=None, factory=None, for_=None,
-                 permission=None, allowed_interface=None,
-                 allowed_methods=None):
-
-        self.for_ = for_
-
-        if ((allowed_methods or allowed_interface)
-            and ((name is None) or not permission)):
-            raise ConfigurationError(
-                "Must use name attribute with allowed_interface or "
-                "allowed_methods"
-                )
-
-        self._context = _context
-        self.factory = factory
-        self.name = name
-        self.permission = permission
-        self.allowed_methods = allowed_methods
-        self.allowed_interface = allowed_interface
-        self.methods = 0
-
-
-    def method(self, _context, name, attribute, permission=None):
-        permission = permission or self.permission
-        # make a copy of the factory sequence, since we might modify it
-        # specifically for this method.
-        factory = self.factory[:]
-
-        # if a specific permission was specified for this method we have to
-        # apply a new proxy.
-        if permission:
-            if permission == 'zope.Public':
-                permission = CheckerPublic
-
-            def methodView(context, request, factory=factory[-1],
-                           attribute=attribute, permission=permission):
-
-                return Proxy(getattr(factory(context, request), attribute),
-                             NamesChecker(__call__ = permission))
-        else:
-
-            def methodView(context, request, factory=factory[-1],
-                           attribute=attribute):
-                return getattr(factory(context, request), attribute)
-
-        factory[-1] = methodView
-
-        self.methods += 1
-
-        _context.action(
-            discriminator = ('view', self.for_, name, self.type),
-            callable = handler,
-            args = ('Views', 'provideView', self.for_, name, self.type, factory)
+    if layer is not None:
+        raise ConfigurationError("Layers are not supported for XML-RPC.")
+    
+    if name is None:
+        raise ConfigurationError("You must specify a view name.") 
+    
+    if ((allowed_attributes or allowed_interface)
+        and ((name is None) or not permission)):
+        raise ConfigurationError(
+            "Must use name attribute with allowed_interface or "
+            "allowed_attributes"
             )
-
-
-    def _proxyFactory(self, factory, checker):
-        factory = factory[:]
-
-        def proxyView(context, request, factory=factory[-1], checker=checker):
-
-            view = factory(context, request)
-
+    
+    allowed_interface = allowed_interface or []
+    allowed_attributes = allowed_attributes or []
+
+    # If there were special permission settings provided, then use them
+    if permission:
+        if permission == 'zope.Public':
+            permission = CheckerPublic
+    
+        require = {}
+        for attr_name in allowed_attributes:
+            require[attr_name] = permission
+    
+        if allowed_interface:
+            for iface in allowed_interface:
+                for field_name in iface:
+                    require[field_name] = permission
+    
+        checker = Checker(require.get)
+    
+        def proxyView(context, request, class_=class_, checker=checker):
+            view = class_(context, request)
             # We need this in case the resource gets unwrapped and
             # needs to be rewrapped
             view.__Security_checker__ = checker
-
             return view
+    
+        class_ =  proxyView
 
-        factory[-1] =  proxyView
-
-        return factory
+    # Register the new view.
+    _context.action(
+        discriminator = ('view', for_, name, IXMLRPCPresentation),
+        callable = handler,
+        args = ('Views', 'provideView', for_, name,
+                IXMLRPCPresentation, [class_]) )
 
-
-    def __call__(self):
-        if self.name is None:
-            return
-
-        permission = self.permission
-        allowed_interface = self.allowed_interface or []
-        allowed_methods = self.allowed_methods or []
-        factory = self.factory[:]
-
-
-        if permission:
-            if permission == 'zope.Public':
-                permission = CheckerPublic
-
-            require = {}
-            for name in allowed_methods:
-                require[name] = permission
-
-            if allowed_interface:
-                for iface in allowed_interface:
-                    for name in iface:
-                        require[name] = permission
-
-            checker = Checker(require.get)
-
-            def proxyView(context, request,
-                          factory=factory[-1], checker=checker):
-                view = factory(context, request)
-                # We need this in case the resource gets unwrapped and
-                # needs to be rewrapped
-                view.__Security_checker__ = checker
-                return view
-
-            factory[-1] =  proxyView
-
-        self._context.action(
-            discriminator = ('view', self.for_, self.name, self.type),
+    # Register the used interfaces with the interface service
+    if for_ is not None:
+        _context.action(
+            discriminator = None,
             callable = handler,
-            args = ('Views', 'provideView', self.for_, self.name,
-                    self.type, factory) )
+            args = (Interfaces, 'provideInterface',
+                    for_.__module__+'.'+for_.__name__, for_)
+            )
+
 
-        if self.for_ is not None:
-            self._context.action(
-                discriminator = None,
-                callable = handler,
-                args = (Interfaces, 'provideInterface',
-                        self.for_.__module__+'.'+self.for_.__name__, self.for_)
-                )
+def defaultView(_context, name, for_=None):
+    """Declare the view having the passed name as the default view."""
+    _context.action(
+        discriminator = ('defaultViewName', for_, IXMLRPCPresentation, name),
+        callable = handler,
+        args = ('Views', 'setDefaultViewName', for_, IXMLRPCPresentation, name)
+        )


=== Zope3/src/zope/app/publisher/xmlrpc/metadirectives.py 1.1 => 1.2 ===
--- Zope3/src/zope/app/publisher/xmlrpc/metadirectives.py:1.1	Sun Aug  3 19:47:47 2003
+++ Zope3/src/zope/app/publisher/xmlrpc/metadirectives.py	Mon Aug  4 19:19:10 2003
@@ -15,11 +15,12 @@
 
 $Id$
 """
+from zope.app.component.metadirectives import IBasicViewInformation
+from zope.configuration.fields import GlobalObject
 from zope.interface import Interface
-from zope.configuration.fields import GlobalObject, Tokens, PythonIdentifier
-from zope.schema import TextLine, Id
+from zope.schema import TextLine
 
-class IViewDirective(Interface):
+class IViewDirective(IBasicViewInformation):
     """View Directive for XML-RPC methods."""
 
     name = TextLine(
@@ -27,65 +28,29 @@
         description=u"The name shows up in URLs/paths. For example 'foo'.",
         required=False)
 
-    factory = Tokens(
-        title=u"Factory",
-        description=u"Specifies a component that is used to provide the "\
-                    u"methods.",
-        value_type=GlobalObject(),
-        required=False)
 
-    for_ = GlobalObject(
-        title=u"The interface this view applies to.",
-        description=u"""
-        The view will be for all objects that implement this
-        interface. If this is not supplied, the view applies to all
-        objects.""",
-        required=False)
+class IDefaultViewDirective(Interface):
+    """
+    The name of the view that should be the default.
+              
+    This name refers to view that should be the
+    view used by default (if no view name is supplied
+    explicitly).
+    """
 
-    permission = Id(
-        title=u"Permission",
-        description=u"The permission needed to use the view.",
-        required=False)
-
-    allowed_interface = Tokens(
-        title=u"Interface that is also allowed if user has permission.",
+    name = TextLine(
+        title=u"The name of the view that should be the default.",
         description=u"""
-        By default, 'permission' only applies to viewing the view and
-        any possible sub views. By specifying this attribute, you can
-        make the permission also apply to everything described in the
-        supplied interface.
-
-        Multiple interfaces can be provided, separated by
-        whitespace.""",
-        required=False,
-        value_type=GlobalObject() )
+        This name refers to view that should be the view used by
+        default (if no view name is supplied explicitly).""",
+        required=True
+        )
 
-    allowed_methods = Tokens(
-        title=u"View attributes that are also allowed if user has permission.",
+    for_ = GlobalObject(
+        title=u"The interface this view is the default for.",
         description=u"""
-        By default, 'permission' only applies to viewing the view and
-        any possible sub views. By specifying 'allowed_methods',
-        you can make the permission also apply to the extra attributes
-        on the view object.""",
-        required=False,
-        value_type=PythonIdentifier() )
-
-
-class IMethodDirective(Interface):
-    """This is the method subdirective."""
-
-    name = TextLine(
-        title=u"The name of the view.",
-        description=u"The name shows up in URLs/paths. For example 'foo'.",
-        required=True)
-
-    permission = Id(
-        title=u"Permission",
-        description=u"The permission needed to use the view.",
-        required=False)
-
-    attribute = PythonIdentifier(
-        title=u"Attribute",
-        description=u"The attribute that describes the method that will be "\
-                    u"known as 'name'",
-        required=False)
+        The view is the default view for the supplied interface. If
+        this is not supplied, the view applies to all objects (XXX
+        this ought to change).""",
+        required=False
+        )




More information about the Zope3-Checkins mailing list