[Zope-Checkins] CVS: Zope3/lib/python/Zope/App/ZopePublication - ZopePublication.py:1.1.2.26

Jim Fulton jim@zope.com
Fri, 8 Feb 2002 08:09:51 -0500


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

Modified Files:
      Tag: Zope-3x-branch
	ZopePublication.py 
Log Message:
Added logic to handle name parameters. We should remove this logic
from traversers.


=== Zope3/lib/python/Zope/App/ZopePublication/ZopePublication.py 1.1.2.25 => 1.1.2.26 ===
 from Zope.Publisher.Browser.IBrowserPublisher import IBrowserPublisher
 
+class DuplicateNamespaces(Exception):
+    """More than one namespave was specified in a request"""
+    
+class UnknownNamespace(Exception):
+    """A parameter specified an unknown namespace"""
+
 class BrowserPublication(ZopePublication):
     """Web browser (HTTP) publication handling."""
 
     def traverseName(self, request, ob, name, check_auth=1):
 
-        # check for skin specification
-        # XXX: replace that by a regex
+        nm = name # the name to look up the object with
 
-        if name.find(';skin=') > -1:
-            l1 = name.find(';skin=')
-            l2 = name.find(';', l1+1)
-            if l2 < 0:
-                l2 = len(name)
-           
-            request.setViewSkin( name[ l1+6: l2] )
-            name = name[ :l1 ]   + name[ l2: ] 
-            
+        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)
+
+                return traverse(request, ob, nm)
+            elif not nm:
+                # Just set params, so skip
+                return ob
 
+                
         if IBrowserPublisher.isImplementedBy(ob):
-            ob2 = ob.browser_traverse(request, name)
+            ob2 = ob.browser_traverse(request, nm)
         else:
-            adapter = getRequestView(ob, '_traverse', request)
-            if adapter is not None:
-                ob2 =  adapter.browser_traverse(request, name)
+            adapter = getRequestView(ob, '_traverse', request, self # marker
+                                     ) 
+
+            if adapter is not self:
+                ob2 =  adapter.browser_traverse(request, nm)
             else:
                 raise NotFound(ob, name, request)
 
         wrapped = wrapper.Wrapper(ob2, ob, name=name)
-        getSecurityManager().validate(name, wrapped)
+        getSecurityManager().validate(nm, wrapped)
         return wrapped
 
+    def _parameterSetskin(self, pname, pval, request):
+        request.setViewSkin(pval)
+
+    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 _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)
+        
+
     def getDefaultTraversal(self, request, ob):
 
         r = ()
@@ -202,3 +268,7 @@
         getSecurityManager().validate(None, wrapped)
         return (wrapped, r[1])
 
+
+class ExcessiveWrapping(NotFound):
+    """Too many levels of acquisition wrapping. We don't beleive them."""
+