[Zope-Checkins] CVS: Zope3/lib/python/Zope/App/ZopePublication - IPublicationTraverse.py:1.1.2.1 ITraverser.py:1.1.2.1 ZopePublication.py:1.1.2.27.2.1 __init__.py:1.1.2.2.4.1 zopepublication.zcml:1.1.2.1.2.1 PublicationTraverse.py:NONE Traversers.py:NONE

Stephan Richter srichter@cbu.edu
Mon, 4 Mar 2002 00:07:37 -0500


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

Modified Files:
      Tag: srichter-OFS_Formulator-branch
	ZopePublication.py __init__.py zopepublication.zcml 
Added Files:
      Tag: srichter-OFS_Formulator-branch
	IPublicationTraverse.py ITraverser.py 
Removed Files:
      Tag: srichter-OFS_Formulator-branch
	PublicationTraverse.py Traversers.py 
Log Message:
This package got a major revamp, so here is what I have done:

- reorganized the package in a way that it becomes multiple-protocol 
  firendly, like the Publisher.

- Separated generic code from Browser code

- Removed Traversers.py and PublicationTraverse.py for the above reason

- Refactor Browser{Publication|PublicationTraverse|Traversers}

- Same as above with XML-RPC


ToDo:

- Write tests.

- Update interfaces



=== 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.2.1 2002/03/04 05:07: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/ZopePublication.py 1.1.2.27 => 1.1.2.27.2.1 ===
+##############################################################################
+#
+# 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,6 +52,7 @@
         def commit(self): pass
 
 
+
 class ZopePublication(DefaultPublication):
     """Base Zope publication specification."""
 
@@ -57,6 +63,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 +73,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,26 +98,33 @@
 
         return app
 
+
     def callTraversalHooks(self, request, ob):
         # Call __before_publishing_traverse__ hooks
         pass
 
+
     def traverseName(self, request, ob, name, check_auth=1):
         raise NotImplementedError('This method must be overridden.')
 
+
     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.args, request)
 
+
     def afterCall(self, request):
         get_transaction().commit()
 
+
     def handleException(self, request, exc_info, retry_allowed=1):
         try:
             # Abort the transaction.
@@ -128,7 +144,7 @@
             traversed = request.traversed
             if traversed:
                 context = traversed[-1]
-                #handler = getExceptionHandler(context, t, IBrowserPublisher)
+                # handler = getExceptionHandler(context, t, IBrowserPublisher)
                 handler = None  # no getExceptionHandler() exists yet.
                 if handler is not None:
                     handler(request, exc_info)
@@ -149,31 +165,3 @@
         finally:
             # Avoid leaking
             exc_info = 0
-
-
-class BrowserPublication(PublicationTraverse, ZopePublication):
-    """Web browser (HTTP) publication handling."""
-        
-
-    def _parameterSetskin(self, pname, pval, request):
-        request.setViewSkin(pval)
-        
-
-    def getDefaultTraversal(self, request, ob):
-
-        r = ()
-
-        if IBrowserPublisher.isImplementedBy(ob):
-            r = ob.browser_default(request)
-        else:
-            adapter = getRequestView(ob, '_traverse', request , None)
-            if adapter is not None:
-                r = adapter.browser_default(request)
-            else:
-                return (ob, None)
-
-        if r[0] is ob: return r
-        
-        wrapped = wrapper.Wrapper(r[0], ob, name=None)
-        getSecurityManager().validate(None, wrapped)
-        return (wrapped, r[1])


=== Zope3/lib/python/Zope/App/ZopePublication/__init__.py 1.1.2.2 => 1.1.2.2.4.1 ===
+#
+# 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.1.2.1 ===
    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'
 >
 
-<browser:view name="_traverse" 
- factory="Zope.App.ZopePublication.Traversers.DefaultTraverser." />
+  <include package="Zope.App.ZopePublication.Browser" 
+    file="browser.zcml" />
+
+  <include package="Zope.App.ZopePublication.XMLRPC" 
+    file="xmlrpc.zcml" />
 
 </zopeConfigure>

=== Removed File Zope3/lib/python/Zope/App/ZopePublication/PublicationTraverse.py ===

=== Removed File Zope3/lib/python/Zope/App/ZopePublication/Traversers.py ===