[Zope3-checkins] SVN: Zope3/trunk/ Merged from ZopeX3-3.0 branch:

Jim Fulton jim at zope.com
Fri Aug 27 19:01:44 EDT 2004


Log message for revision 27315:
  Merged from ZopeX3-3.0 branch:
  
    r27308 | jim | 2004-08-27 16:41:19 -0400 (Fri, 27 Aug 2004) | 2 lines
  
    Added code to clean up views registered by the test.
  
    ------------------------------------------------------------------------
    r27307 | jim | 2004-08-27 16:13:49 -0400 (Fri, 27 Aug 2004) | 18 lines
  
    Made a number of related changes:
  
    - Finished the README.txt, explaining how to create named XML-RPC
      views.
  
    - Moved MethodPublisher to zope.app.publisher.xmlrpc
  
    - Now subclasses Location, so that it can acquire security grants
  
    - Now provides traversal via an adapter so that attribute accesses
        are mediated by security.
  
    - MethodPublisher is now pretty much configuration, so needs no unit
        tests.  (It is tested vie README.txt.)
  
    - Got rid of DefaultPublisher, which was only used (and isn't used any
      more) by MethodPublisher.
  
    ------------------------------------------------------------------------
    r27305 | jim | 2004-08-27 16:13:45 -0400 (Fri, 27 Aug 2004) | 3 lines
  
    Removed the scant zope.app.xmlrpc package, moving it's
    configuration (all it was) to zope.app.publisher.xmlrpc.
  
  


Changed:
  D   Zope3/trunk/package-includes/xmlrpc-configure.zcml
  U   Zope3/trunk/releases/ZopeX3/DEPENDENCIES.cfg
  U   Zope3/trunk/src/bugtracker/xmlrpc.py
  U   Zope3/trunk/src/zope/app/publisher/configure.zcml
  U   Zope3/trunk/src/zope/app/publisher/xmlrpc/README.txt
  U   Zope3/trunk/src/zope/app/publisher/xmlrpc/__init__.py
  A   Zope3/trunk/src/zope/app/publisher/xmlrpc/configure.zcml
  U   Zope3/trunk/src/zope/app/publisher/xmlrpc/ftests.py
  D   Zope3/trunk/src/zope/app/xmlrpc/
  U   Zope3/trunk/src/zope/publisher/http.py
  D   Zope3/trunk/src/zope/publisher/tests/test_xmlrpcmethodpublisher.py
  U   Zope3/trunk/src/zope/publisher/xmlrpc.py


-=-
Deleted: Zope3/trunk/package-includes/xmlrpc-configure.zcml
===================================================================
--- Zope3/trunk/package-includes/xmlrpc-configure.zcml	2004-08-27 21:28:57 UTC (rev 27314)
+++ Zope3/trunk/package-includes/xmlrpc-configure.zcml	2004-08-27 23:01:44 UTC (rev 27315)
@@ -1 +0,0 @@
-<include package="zope.app.xmlrpc"/>

Modified: Zope3/trunk/releases/ZopeX3/DEPENDENCIES.cfg
===================================================================
--- Zope3/trunk/releases/ZopeX3/DEPENDENCIES.cfg	2004-08-27 21:28:57 UTC (rev 27314)
+++ Zope3/trunk/releases/ZopeX3/DEPENDENCIES.cfg	2004-08-27 23:01:44 UTC (rev 27315)
@@ -22,5 +22,4 @@
 zope.app.sqlscript
 zope.app.tree
 zope.app.undo
-zope.app.xmlrpc
 zope.app.zptpage

Modified: Zope3/trunk/src/bugtracker/xmlrpc.py
===================================================================
--- Zope3/trunk/src/bugtracker/xmlrpc.py	2004-08-27 21:28:57 UTC (rev 27314)
+++ Zope3/trunk/src/bugtracker/xmlrpc.py	2004-08-27 23:01:44 UTC (rev 27315)
@@ -20,7 +20,7 @@
 import base64
 
 from zope.event import notify
-from zope.publisher.xmlrpc import MethodPublisher
+from zope.app.publisher.xmlrpc import MethodPublisher
 from zope.schema.vocabulary import getVocabularyRegistry
 
 from zope.app import zapi

Modified: Zope3/trunk/src/zope/app/publisher/configure.zcml
===================================================================
--- Zope3/trunk/src/zope/app/publisher/configure.zcml	2004-08-27 21:28:57 UTC (rev 27314)
+++ Zope3/trunk/src/zope/app/publisher/configure.zcml	2004-08-27 23:01:44 UTC (rev 27315)
@@ -1,5 +1,6 @@
 <configure xmlns='http://namespaces.zope.org/zope' >
   <include package=".browser" />
+  <include package=".xmlrpc" />
   <include file="http.zcml" />
 
   <interface

Modified: Zope3/trunk/src/zope/app/publisher/xmlrpc/README.txt
===================================================================
--- Zope3/trunk/src/zope/app/publisher/xmlrpc/README.txt	2004-08-27 21:28:57 UTC (rev 27314)
+++ Zope3/trunk/src/zope/app/publisher/xmlrpc/README.txt	2004-08-27 23:01:44 UTC (rev 27315)
@@ -124,13 +124,119 @@
   <BLANKLINE>
 
 
-Now let's look at views that have their own methods.  Views that have
-their own methods have names that appear in URLs and they get
-traversed to get to their methods, as in::
+Now let's look at views that have their own methods or other
+subobjects.  Views that have their own methods have names that appear
+in URLs and they get traversed to get to their methods, as in::
 
    .../somefolder/listing/contents
 
 To make this possible, the view has to support traversal, so that,
-when it is traversed, it traverses to it's attributes.
+when it is traversed, it traverses to it's attributes.  To supplot
+traversal, you can implement or provide an adapter to
+`zope.publisher.interfaces.IPublishTraverse`. It's actually better to
+provide an adapter so that accesses to attributes during traversal are
+mediated by the security machinery.  (Object methods are always bound
+to unproxied objects, but adapters are bound to proxied objects unless
+they are trusted adapters.)
 
-XXX: need to finish
+The 'zope.app.publisher.xmlrpc' package provides a base class,
+`MethodPublisher`,  that provides the necessary traversal support.  In
+particulat, it has an adapter that simply traverses to attributes. 
+
+If an XML-RPC view isn't going to be public, then it also has to
+implement 'zope.app.location.ILocation' so that security grants can be
+acquired for it, at least with Zope's default security policy. The
+`MethodPublisher` class does that too.
+
+Let's modify our view class to use `MethodPublisher`:
+
+  >>> from zope.app.publisher.xmlrpc import MethodPublisher
+
+  >>> class FolderListing(MethodPublisher):
+  ...
+  ...     def contents(self):
+  ...         return list(self.context.keys())
+
+Note that `MethodPublisher` also provides a suitable `__init__`
+method, so we don't need one any more.  This time, we'll register it
+as as a named view:
+
+  >>> ignored = xmlconfig.string("""
+  ... <configure 
+  ...     xmlns="http://namespaces.zope.org/zope"
+  ...     xmlns:xmlrpc="http://namespaces.zope.org/xmlrpc"
+  ...     >
+  ...   <!-- We only need to do this include in this example, 
+  ...        Normally the include has already been done for us. -->
+  ...   <include package="zope.app.publisher.xmlrpc" file="meta.zcml" />
+  ...
+  ...   <xmlrpc:view
+  ...       name="listing"
+  ...       for="zope.app.folder.folder.IFolder"
+  ...       methods="contents"
+  ...       class="zope.app.publisher.xmlrpc.README.FolderListing"
+  ...       permission="zope.ManageContent"
+  ...       />
+  ... </configure>
+  ... """)
+
+Now, when we access the `contents`, we do so through the listing view:
+
+  >>> print http(r"""
+  ... POST /listing/ HTTP/1.0
+  ... Authorization: Basic bWdyOm1ncnB3
+  ... Content-Length: 102
+  ... Content-Type: text/xml
+  ... 
+  ... <?xml version='1.0'?>
+  ... <methodCall>
+  ... <methodName>contents</methodName>
+  ... <params>
+  ... </params>
+  ... </methodCall>
+  ... """, handle_errors=False)
+  HTTP/1.0 200 Ok
+  Content-Length: 208
+  Content-Type: text/xml;charset=utf-8
+  <BLANKLINE>
+  <?xml version='1.0'?>
+  <methodResponse>
+  <params>
+  <param>
+  <value><array><data>
+  <value><string>f1</string></value>
+  <value><string>f2</string></value>
+  </data></array></value>
+  </param>
+  </params>
+  </methodResponse>
+  <BLANKLINE>
+
+as before, we will get an error if we don't supply credentials:
+
+  >>> print http(r"""
+  ... POST /listing/ HTTP/1.0
+  ... Content-Length: 102
+  ... Content-Type: text/xml
+  ... 
+  ... <?xml version='1.0'?>
+  ... <methodCall>
+  ... <methodName>contents</methodName>
+  ... <params>
+  ... </params>
+  ... </methodCall>
+  ... """)
+  HTTP/1.0 401 Unauthorized
+  Content-Length: 126
+  Content-Type: text/xml;charset=utf-8
+  Www-Authenticate: basic realm='Zope'
+  <BLANKLINE>
+  <?xml version='1.0'?>
+  <methodResponse>
+  <params>
+  <param>
+  <value><string></string></value>
+  </param>
+  </params>
+  </methodResponse>
+  <BLANKLINE>

Modified: Zope3/trunk/src/zope/app/publisher/xmlrpc/__init__.py
===================================================================
--- Zope3/trunk/src/zope/app/publisher/xmlrpc/__init__.py	2004-08-27 21:28:57 UTC (rev 27314)
+++ Zope3/trunk/src/zope/app/publisher/xmlrpc/__init__.py	2004-08-27 23:01:44 UTC (rev 27315)
@@ -17,15 +17,40 @@
 
 $Id$
 """
-from zope.interface import implements
-from zope.app.publisher.interfaces.xmlrpc import IXMLRPCView
+import zope.interface
+import zope.app.location
+import zope.app.publisher.interfaces.xmlrpc
 
 class XMLRPCView(object):
     """A base XML-RPC view that can be used as mix-in for XML-RPC views.""" 
 
-    implements(IXMLRPCView)
+    zope.interface.implements(zope.app.publisher.interfaces.xmlrpc.IXMLRPCView)
 
     def __init__(self, context, request):
         self.context = context
         self.request = request
 
+
+class IMethodPublisher(zope.interface.Interface):
+    """Marker interface for an object that wants to publish methods
+    """
+
+class MethodPublisher(XMLRPCView, zope.app.location.Location):
+    """Base class for very simple XML-RPC views that publish methods
+
+    This class is meant to be more of an example than a standard base class. 
+
+    This example is explained in the README.txt file for this package
+    """
+
+    zope.interface.implements(IMethodPublisher)
+
+class MethodTraverser(object):
+
+    __used_for__ = IMethodPublisher
+
+    def __init__(self, context, request):
+        self.context = context
+        
+    def publishTraverse(self, request, name):
+        return getattr(self.context, name)

Copied: Zope3/trunk/src/zope/app/publisher/xmlrpc/configure.zcml (from rev 27307, Zope3/branches/ZopeX3-3.0/src/zope/app/publisher/xmlrpc/configure.zcml)


Property changes on: Zope3/trunk/src/zope/app/publisher/xmlrpc/configure.zcml
___________________________________________________________________
Name: cvs2svn:cvs-rev
   + 1.4
Name: svn:eol-style
   + native

Modified: Zope3/trunk/src/zope/app/publisher/xmlrpc/ftests.py
===================================================================
--- Zope3/trunk/src/zope/app/publisher/xmlrpc/ftests.py	2004-08-27 21:28:57 UTC (rev 27314)
+++ Zope3/trunk/src/zope/app/publisher/xmlrpc/ftests.py	2004-08-27 23:01:44 UTC (rev 27315)
@@ -16,6 +16,10 @@
 $Id$
 """
 import sys
+import zope.interface
+import zope.app.folder.folder
+import zope.publisher.interfaces.xmlrpc
+from zope.app.tests import ztapi
 
 # Evil hack to make pickling work with classes defined in doc tests
 class NoCopyDict(dict):
@@ -40,6 +44,26 @@
     sys.modules[name] = FakeModule(globs)
 
 def tearDown():
+    # clean up the views we registered:
+    
+    # we use the fact that registering None unregisters whatever is
+    # registered. We can't use an unregistration call because that
+    # requires the object that was registered and we don't have that handy.
+    # (OK, we could get it if we want. Maybe later.)
+
+    ztapi.provideView(zope.app.folder.folder.IFolder,
+                        zope.publisher.interfaces.xmlrpc.IXMLRPCRequest,
+                        zope.interface,
+                        'contents',
+                        None,
+                        )
+    ztapi.provideView(zope.app.folder.folder.IFolder,
+                        zope.publisher.interfaces.xmlrpc.IXMLRPCRequest,
+                        zope.interface,
+                        'contents',
+                        None,
+                        )
+    
     globs.clear()
     del sys.modules[name]
 

Modified: Zope3/trunk/src/zope/publisher/http.py
===================================================================
--- Zope3/trunk/src/zope/publisher/http.py	2004-08-27 21:28:57 UTC (rev 27314)
+++ Zope3/trunk/src/zope/publisher/http.py	2004-08-27 23:01:44 UTC (rev 27315)
@@ -928,14 +928,6 @@
         return text
 
 
-class DefaultPublisher(object):
-    implements(IHTTPPublisher)
-
-    def publishTraverse(self, request, name):
-        'See IHTTPPublisher'
-
-        return getattr(self, name)
-
 def sort_charsets(x, y):
     if y[1] == 'utf-8':
         return 1

Deleted: Zope3/trunk/src/zope/publisher/tests/test_xmlrpcmethodpublisher.py
===================================================================
--- Zope3/trunk/src/zope/publisher/tests/test_xmlrpcmethodpublisher.py	2004-08-27 21:28:57 UTC (rev 27314)
+++ Zope3/trunk/src/zope/publisher/tests/test_xmlrpcmethodpublisher.py	2004-08-27 23:01:44 UTC (rev 27315)
@@ -1,62 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (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.
-#
-##############################################################################
-"""XML-RPC Method Publisher tests
-
-$Id$
-"""
-import unittest
-
-from zope.publisher.xmlrpc import MethodPublisher, TestRequest
-from zope.publisher.interfaces.xmlrpc import IXMLRPCPublisher
-
-from zope.interface.verify import verifyClass
-from zope.interface import implementedBy
-
-class ContentStub(object):
-    pass
-
-class Presentation(MethodPublisher):
-    index = 'index'
-    action = 'action'
-    foo = 'foo'
-
-
-class TestMethodPublisher(unittest.TestCase):
-    def setUp(self):
-        self.pres = Presentation(ContentStub(), TestRequest())
-
-    def testImplementsIXMLRPCPublisher(self):
-        self.failUnless(IXMLRPCPublisher.providedBy(self.pres))
-
-    def testInterfacesVerify(self):
-        for interface in implementedBy(Presentation):
-            verifyClass(interface, Presentation)
-
-    def testXMLRPCTraverseIndex(self):
-        self.assertEquals(self.pres.publishTraverse(None, 'index'), 'index')
-
-    def testXMLRPCTraverseAction(self):
-        self.assertEquals(self.pres.publishTraverse(None, 'action'), 'action')
-
-    def testXMLRPCTraverseNotFound(self):
-        self.failUnlessRaises(AttributeError, self.pres.publishTraverse,
-            None, 'bar')
-
-
-def test_suite():
-    loader = unittest.TestLoader()
-    return loader.loadTestsFromTestCase(TestMethodPublisher)
-
-if __name__ == '__main__':
-    unittest.TextTestRunner().run(test_suite())

Modified: Zope3/trunk/src/zope/publisher/xmlrpc.py
===================================================================
--- Zope3/trunk/src/zope/publisher/xmlrpc.py	2004-08-27 21:28:57 UTC (rev 27314)
+++ Zope3/trunk/src/zope/publisher/xmlrpc.py	2004-08-27 23:01:44 UTC (rev 27315)
@@ -13,7 +13,7 @@
 ##############################################################################
 """XML-RPC Publisher
 
-This module contains the MethodPublisher, XMLRPCRequest and XMLRPCResponse
+This module contains the XMLRPCRequest and XMLRPCResponse
 
 $Id$
 """
@@ -26,21 +26,8 @@
 from zope.publisher.interfaces.xmlrpc import IXMLRPCRequest
 
 from zope.publisher.http import HTTPRequest, HTTPResponse
-from zope.publisher.http import DefaultPublisher
 from zope.proxy import removeAllProxies
 
-
-class MethodPublisher(DefaultPublisher):
-    """Simple XML-RPC publisher that is identical to the HTTP Default Publisher
-       except that it implements the IXMLRPCPublisher interface."""
-
-    implements(IXMLRPCPublisher)
-
-    def __init__(self, context, request):
-        self.context = context
-        self.request = request
-
-
 class XMLRPCRequest(HTTPRequest):
     implements(IXMLRPCRequest)
 



More information about the Zope3-Checkins mailing list