[Zope-Checkins] CVS: Zope3/lib/python/Zope/App/ZopePublication - IPublicationTraverse.py:1.1.4.1 ITraverser.py:1.1.4.1 PublicationTraverse.py:1.1.2.4 Traversers.py:1.1.2.12 ZopePublication.py:1.1.2.31 __init__.py:1.1.2.3 zopepublication.zcml:1.1.2.2

Stephan Richter srichter@cbu.edu
Wed, 27 Mar 2002 10:05:38 -0500


Update of /cvs-repository/Zope3/lib/python/Zope/App/ZopePublication
In directory cvs.zope.org:/tmp/cvs-serv32058

Modified Files:
      Tag: Zope-3x-branch
	PublicationTraverse.py Traversers.py ZopePublication.py 
	__init__.py zopepublication.zcml 
Added Files:
      Tag: Zope-3x-branch
	IPublicationTraverse.py ITraverser.py 
Log Message:
- XML-RPC support
- security
- ZCML cleanup


=== Added File Zope3/lib/python/Zope/App/ZopePublication/IPublicationTraverse.py ===
##############################################################################
#
# 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.0 (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
# 
##############################################################################
"""

$Id: IPublicationTraverse.py,v 1.1.4.1 2002/03/27 15:05:07 srichter Exp $
"""

from Zope.Publisher.Browser.IBrowserPublisher import IBrowserPublisher
from Zope.ComponentArchitecture import getRequestView
from Zope.App.Security.SecurityManagement import getSecurityManager
from Zope.Publisher.Exceptions import NotFound
from types import StringTypes
from Zope.ContextWrapper import wrapper

class DuplicateNamespaces(Exception):
    """More than one namespave was specified in a request"""
    
class UnknownNamespace(Exception):
    """A parameter specified an unknown namespace"""

class ExcessiveWrapping(NotFound):
    """Too many levels of acquisition wrapping. We don't beleive them."""

class PublicationTraverse:

    def traverseName(self, request, ob, name):

        nm = name # the name to look up the object with

        if name.find(';'):
            # Process URI segment parameters. It makes sense to centralize
            # this here. Later it may be abstracted and distributed again,
            # but, if so it will be distributed to various path
            # traversers, rather than to traversal adapters/views.
            ns = ''
            parts = name.split(';')
            nm = parts[:1]
            for param in parts[1:]:
                l = param.find('=')
                if l >= 0:
                    pname = param[:l]
                    pval = param[l+1:]
                    if pname == 'ns':
                        if ns:
                            raise DuplicateNamespaces(name)
                        ns = pval
                    else:
                        pset = getattr(self, "_parameterSet%s" % pname,
                                       self # marker
                                       )
                        if pset is self:
                            # We don't know about this one, so leave it in the
                            # name
                            nm.append(param)
                        else:
                            pset(pname, pval, request)
                else:
                    if ns:
                        raise DuplicateNamespaces(name)
                    ns = param

            nm = ';'.join(nm)
            if ns:
                traverse = getattr(self, "_traverse%s" % ns,
                                   self # marker
                                   )
                if traverse is self:
                    raise UnknownNamespace(ns, name)

                ob2 = traverse(request, ob, nm)
                return self._wrap(ob2, ob, name, nm)
            elif not nm:
                # Just set params, so skip
                return ob

        if nm == '.':
            return ob
                
        if IBrowserPublisher.isImplementedBy(ob):
            ob2 = ob.browser_traverse(request, nm)
        else:
            adapter = getRequestView(ob, '_traverse', request, self # marker
                                     ) 

            if adapter is not self:
                ob2 =  adapter.browser_traverse(request, nm)
            else:
                raise NotFound(ob, name, request)

        return self._wrap(ob2, ob, name, nm)

    def _wrap(self, ob, parent, name, nm):
        wrapped = wrapper.Wrapper(ob, parent, name=name)
        getSecurityManager().validate(nm, wrapped)
        return wrapped

    def _traverseview(self, request, ob, name):
        # use self as marker
        r = getRequestView(ob, name, request, self)
        if r is self: 
            raise NotFound(ob, name, request)
        return r

    def _traverseetc(self, request, ob, name):
        # XXX
        
        # This is here now to allow us to get service managers from a
        # separate namespace from the content. We add and etc
        # namespace to allow us to handle misc objects.  We'll apply
        # YAGNI for now and hard code this. We'll want something more
        # general later. We were thinking of just calling "get"
        # methods, but this is probably too magic. In particular, we
        # will treat returned objects as sub-objects wrt security and
        # not all get methods may satisfy this assumption. It might be
        # best to introduce some sort of etc registry.

        if name != 'Services':
            raise NotFound(ob, name, request)
            
        
        method_name = "getServiceManager"
        method = getattr(ob, method_name, self)
        if method is self: 
            raise NotFound(ob, name, request)
        # Check access
        self._wrap(method, ob, name, name)

        return method()

    def _traverseacquire(self, request, ob, name):
        i = 0
        while i < 200:
            i = i + 1
            r = getattr(ob, name, self)
            if r is not self:
                return r
            r = getcontext(ob)
            if r is None:
                raise NotFound(ob, name, request)
        raise ExcessiveWrapping(ob, name, request)

class PublicationTraverser(PublicationTraverse):    

    def traversePath(self, request, ob, path):

        if isinstance(path, StringTypes):
            path = path.split('/')
            if len(path) > 1 and not path[-1]:
                # Remove trailing slash
                path.pop()
        else:
            path = list(path)

        # Remove dingle dots
        path = [x for x in path if x != '.']

        path.reverse()

        # Remove double dots
        while '..' in path:
            l = path.index('..')
            if l < 0 or l+2 > len(path):
                break
            del path[l:l+2]
                     
        pop = path.pop

        while path:
            name = pop()
            ob = self.traverseName(request, ob, name)

        return ob


=== Added File Zope3/lib/python/Zope/App/ZopePublication/ITraverser.py ===


=== Zope3/lib/python/Zope/App/ZopePublication/PublicationTraverse.py 1.1.2.3 => 1.1.2.4 ===
 """
 
-from Zope.Publisher.Browser.IBrowserPublisher import IBrowserPublisher
 from Zope.ComponentArchitecture import getRequestView
 from Zope.App.Security.SecurityManagement import getSecurityManager
 from Zope.Publisher.Exceptions import NotFound
 from types import StringTypes
-from Zope.ContextWrapper import wrapper
+from Zope.ContextWrapper import Wrapper
 
 class DuplicateNamespaces(Exception):
     """More than one namespave was specified in a request"""
@@ -85,13 +84,12 @@
 
         if nm == '.':
             return ob
-                
-        if IBrowserPublisher.isImplementedBy(ob):
+
+        if request.getViewType().isImplementedBy(ob):
             ob2 = ob.publishTraverse(request, nm)
         else:
             adapter = getRequestView(ob, '_traverse', request, self # marker
                                      ) 
-
             if adapter is not self:
                 ob2 =  adapter.publishTraverse(request, nm)
             else:
@@ -100,7 +98,7 @@
         return self._wrap(ob2, ob, name, nm)
 
     def _wrap(self, ob, parent, name, nm):
-        wrapped = wrapper.Wrapper(ob, parent, name=name)
+        wrapped = Wrapper(ob, parent, name=name)
         getSecurityManager().validate(nm, wrapped)
         return wrapped
 


=== Zope3/lib/python/Zope/App/ZopePublication/Traversers.py 1.1.2.11 => 1.1.2.12 ===
 from Zope.Publisher.Exceptions import Unauthorized, NotFound, DebugError
 from Zope.Publisher.Browser.IBrowserPublisher import IBrowserPublisher
+from Zope.Publisher.XMLRPC.IXMLRPCPublisher import IXMLRPCPublisher
 from Zope.ComponentArchitecture \
      import getRequestView, getRequestDefaultViewName
 
 class DefaultTraverser:
     """
     """
-    __implements__ = IBrowserPublisher
+    __implements__ = IBrowserPublisher, IXMLRPCPublisher
 
     def __init__(self, target):
         self.target = target
@@ -36,6 +37,7 @@
 
     def publishTraverse(self, request, name):
         """ """
+
         # TODO:  Look for default view
         ob = self.target
         if name.startswith('_'):


=== Zope3/lib/python/Zope/App/ZopePublication/ZopePublication.py 1.1.2.30 => 1.1.2.31 ===
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors. 
+# All Rights Reserved.
 # 
 # This software is subject to the provisions of the Zope Public License,
-# Version 1.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# Version 2.0 (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.
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE
+# 
+##############################################################################
+"""
+
+$Id$
+"""
 
 import sys
 from types import StringType, ClassType
 
-from zLOG import LOG, ERROR, INFO
-from Zope.ComponentArchitecture import getRequestView
+from zLOG import LOG, INFO
 from Zope.Publisher.DefaultPublication import DefaultPublication
 from Zope.Publisher.mapply import mapply
 from Zope.Publisher.Exceptions import Retry
@@ -21,11 +29,7 @@
 from Zope.Exceptions import Unauthorized
 
 from ZODB.POSException import ConflictError
-from Zope.App.OFS.Folder.RootFolder import RootFolder
-from Zope.ContextWrapper import wrapper
-from PublicationTraverse import PublicationTraverse
 
-from Zope.Publisher.Browser.IBrowserPublisher import IBrowserPublisher
 
 class RequestContainer:
     # TODO: add security assertion declaring access to REQUEST
@@ -39,7 +43,8 @@
         self.__del__ = f
 
 
-try: get_transaction
+try:
+    get_transaction
 except NameError:
     class get_transaction:
         def abort(self): pass
@@ -47,7 +52,7 @@
         def commit(self): pass
 
 
-class ZopePublication(PublicationTraverse, DefaultPublication):
+class ZopePublication(DefaultPublication):
     """Base Zope publication specification."""
 
     version_cookie = 'Zope-Version'
@@ -57,6 +62,7 @@
         # db is a ZODB.DB.DB object.
         self.db = db
 
+
     def beforeTraversal(self, request):
         id = prin_reg.authenticate(request)
         if id is None:
@@ -66,10 +72,12 @@
         newSecurityManager(id)
         get_transaction().begin()
 
+
     def openedConnection(self, conn):
         # Hook for auto-refresh
         pass
 
+
     def getApplication(self, request):
         # Open the database.
         version = request.get(self.version_cookie, '')
@@ -89,6 +97,7 @@
 
         return app
 
+
     def callTraversalHooks(self, request, ob):
         # Call __before_publishing_traverse__ hooks
         pass
@@ -96,16 +105,20 @@
     def getDefaultTraversal(self, request, ob):
         return ob, None
 
+
     def afterTraversal(self, request, ob):
         #recordMetaData(object, request)
         pass
 
+
     def callObject(self, request, ob):
         return mapply(ob, request.getPositionalArguments(), request)
 
+
     def afterCall(self, request):
         get_transaction().commit()
 
+
     def handleException(self, request, exc_info, retry_allowed=1):
         try:
             # Abort the transaction.
@@ -120,7 +133,6 @@
                 prin_reg.unauthorized(id, request) # May issue challenge
                 request.getResponse().handleException(exc_info)
                 return
-
 
             # XXX This is wrong. Should use getRequstView:
             # 


=== Zope3/lib/python/Zope/App/ZopePublication/__init__.py 1.1.2.2 => 1.1.2.3 ===
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors. 
+# All Rights Reserved.
+# 
 # This software is subject to the provisions of the Zope Public License,
-# Version 1.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# Version 2.0 (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.
-
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE
+# 
+##############################################################################
 """
 Zope publication package.
+
+$Id$
 """


=== Zope3/lib/python/Zope/App/ZopePublication/zopepublication.zcml 1.1.2.1 => 1.1.2.2 ===
    xmlns='http://namespaces.zope.org/zope'
    xmlns:security='http://namespaces.zope.org/security'
-   xmlns:zmi='http://namespaces.zope.org/zmi'
    xmlns:browser='http://namespaces.zope.org/browser'
+   xmlns:xmlrpc='http://namespaces.zope.org/xmlrpc'
 >
 
-<browser:view name="_traverse" 
- factory="Zope.App.ZopePublication.Traversers.DefaultTraverser." />
+  <browser:view name="_traverse" 
+   factory=".Traversers.DefaultTraverser." />
+
+  <xmlrpc:view name="_traverse" 
+   factory=".Traversers.DefaultTraverser." />
 
 </zopeConfigure>