[Zope3-checkins] SVN: Zope3/branches/ajung-tarek-request-publication-branch/src/zope/app/publication/ finished implementation of solution 1

Tarek Ziadé tziade at nuxeo.com
Fri Oct 7 04:51:13 EDT 2005


Log message for revision 38844:
  finished implementation of solution 1

Changed:
  U   Zope3/branches/ajung-tarek-request-publication-branch/src/zope/app/publication/httpfactory.py
  U   Zope3/branches/ajung-tarek-request-publication-branch/src/zope/app/publication/interfaces.py
  U   Zope3/branches/ajung-tarek-request-publication-branch/src/zope/app/publication/publicationfactories.py
  U   Zope3/branches/ajung-tarek-request-publication-branch/src/zope/app/publication/tests/test_httpfactory.py
  U   Zope3/branches/ajung-tarek-request-publication-branch/src/zope/app/publication/tests/test_publicationfactories.py

-=-
Modified: Zope3/branches/ajung-tarek-request-publication-branch/src/zope/app/publication/httpfactory.py
===================================================================
--- Zope3/branches/ajung-tarek-request-publication-branch/src/zope/app/publication/httpfactory.py	2005-10-07 08:50:21 UTC (rev 38843)
+++ Zope3/branches/ajung-tarek-request-publication-branch/src/zope/app/publication/httpfactory.py	2005-10-07 08:51:13 UTC (rev 38844)
@@ -29,32 +29,52 @@
 from zope.app.publication.browser import BrowserPublication, setDefaultSkin
 from zope.app.publication.xmlrpc import XMLRPCPublication
 from zope.app.publication.soap import SOAPPublication
+from zope.app.zapi import getUtility, getSiteManager
 
+from zope.component.adapter import GlobalAdapterService
+from zope.component.exceptions import ComponentLookupError
 
-def chooseClasses(method, environment):
-    if method in ('GET', 'POST', 'HEAD'):
-        content_type = environment.get('CONTENT_TYPE', '')
-        if method == 'POST' and content_type.startswith('text/xml'):
-            soap_req = component.queryUtility(interfaces.ISOAPRequestFactory)
-            if environment.get('HTTP_SOAPACTION') and soap_req is not None:
-                request_class = soap_req
-                publication_class = SOAPPublication
-            else:
-                request_class = component.queryUtility(
-                    interfaces.IXMLRPCRequestFactory, default=XMLRPCRequest)
-                publication_class = XMLRPCPublication
-        else:
-            request_class = component.queryUtility(
-                interfaces.IBrowserRequestFactory, default=BrowserRequest)
-            publication_class = BrowserPublication
-    else:
-        request_class = component.queryUtility(
-            interfaces.IHTTPRequestFactory, default=HTTPRequest)
-        publication_class = HTTPPublication
+from zope.app.publication.publicationfactories import HTTPFactory, BrowserFactory
 
-    return request_class, publication_class
 
+def chooseClasses(method, environment, context=None):
+    """ see README.txt """
+    def _byname(chooser1, chooser2):
+        """ reverse sorting """
+        return cmp(chooser2.getSortKey(), chooser1.getSortKey())
 
+    try:
+        method_interface = getUtility(interfaces.IMethodBase, method)
+    except ComponentLookupError:
+        # unhandled method, returns http publisher
+        return HTTPFactory()()
+
+    content_type = environment.get('CONTENT_TYPE', '')
+
+    try:
+        content_type_interface = getUtility(interfaces.IMimetypeBase, content_type)
+    except ComponentLookupError:
+        # unhandled mimetype, returns browser publisher
+        return BrowserFactory()()
+
+    # do a lookup here, returns a list callables
+    adapters = getSiteManager(context).adapters
+
+    choosers = adapters.lookupAll(required=(method_interface,
+                                            content_type_interface),
+                                  provided=interfaces.IRequestPublicationFactory)
+
+    # choose a chooser here
+    # chooser sorting, to sort from most specialized to less
+    choosers = [chooser[1] for chooser in list(choosers)]
+    choosers.sort(_byname)
+
+    for chooser in choosers:
+        if chooser.canHandle(environment):
+            return chooser()
+
+    return BrowserFactory()() 
+
 class HTTPPublicationRequestFactory(object):
     interface.implements(interfaces.IPublicationRequestFactory)
 
@@ -79,7 +99,7 @@
 
 
         method = env.get('REQUEST_METHOD', 'GET').upper()
-        request_class, publication_class = chooseClasses(method, env)
+        request_class, publication_class = chooseClasses(method, env, self._db)
 
         publication = self._publication_cache.get(publication_class)
         if publication is None:

Modified: Zope3/branches/ajung-tarek-request-publication-branch/src/zope/app/publication/interfaces.py
===================================================================
--- Zope3/branches/ajung-tarek-request-publication-branch/src/zope/app/publication/interfaces.py	2005-10-07 08:50:21 UTC (rev 38843)
+++ Zope3/branches/ajung-tarek-request-publication-branch/src/zope/app/publication/interfaces.py	2005-10-07 08:51:13 UTC (rev 38844)
@@ -85,28 +85,36 @@
 
 
 # marker interfaces for request-publication factories
+class IMethodBase(interface.interfaces.IInterface):
+    """ interface for all request-publication factories """
+
 class IMethodPOST(interface.Interface):
     """Marker interface for request-publication factories able to deal
        with POST requests.
     """
+interface.directlyProvides(IMethodPOST, IMethodBase)
 
 class IMethodGET(interface.Interface):
     """Marker interface for request-publication factories able to deal
        with GET requests.
     """
+interface.directlyProvides(IMethodGET, IMethodBase)
 
 class IMethodHEAD(interface.Interface):
     """Marker interface for request-publication factories able to deal
        with HEAD requests.
     """
-    
+interface.directlyProvides(IMethodHEAD, IMethodBase)
+
+# marker interfaces for request-chooser factories
+class IMimetypeBase(interface.interfaces.IInterface):
+    """Base interface for all request-choosers """
+
 class IMimetypeTextXML(interface.Interface):
     """ request-chooser able to deal with text/html """
+interface.directlyProvides(IMimetypeTextXML, IMimetypeBase)
 
-class IMimetypesAll(interface.Interface):
-    """ request-chooser able to deal with any mimetypes """
-
-class IRequestPublicationFactory(interface.Interface):
+class IRequestPublicationFactory(IMimetypeBase):
     """ request-publication factory """
 
     def canHandle(environment):
@@ -117,3 +125,10 @@
 
     def __call__():
         """ returns a tuple (request, publication) """
+
+    def getSortKey():
+        """ returns a string that is used to sort the factories
+            when several factories can handle the request.
+
+            After a sort, the highest one gets picked
+        """

Modified: Zope3/branches/ajung-tarek-request-publication-branch/src/zope/app/publication/publicationfactories.py
===================================================================
--- Zope3/branches/ajung-tarek-request-publication-branch/src/zope/app/publication/publicationfactories.py	2005-10-07 08:50:21 UTC (rev 38843)
+++ Zope3/branches/ajung-tarek-request-publication-branch/src/zope/app/publication/publicationfactories.py	2005-10-07 08:51:13 UTC (rev 38844)
@@ -37,13 +37,16 @@
     implements(IRequestPublicationFactory)
 
     def canHandle(self, environment):
-        self.soap_req = component.queryUtility(interfaces.ISOAPRequestFactory)
-        return bool(environment.get('HTTP_SOAPACTION') and self.soap_req)
+        soap_req = component.queryUtility(interfaces.ISOAPRequestFactory)
+        return bool(environment.get('HTTP_SOAPACTION') and soap_req)
 
+    def getSortKey(self):
+        return '1'
+
     def __call__(self):
-        return self.soap_req, SOAPPublication
+        soap_req = component.queryUtility(interfaces.ISOAPRequestFactory)
+        return soap_req, SOAPPublication
 
-
 class XMLRPCFactory(object):
 
     implements(IRequestPublicationFactory)
@@ -56,6 +59,8 @@
             interfaces.IXMLRPCRequestFactory, default=XMLRPCRequest)
         return request_class, XMLRPCPublication
 
+    def getSortKey(self):
+        return '0'
 
 class HTTPFactory(object):
 
@@ -64,6 +69,9 @@
     def canHandle(self, environment):
         return True
 
+    def getSortKey(self):
+        return '0'
+
     def __call__(self):
         request_class = component.queryUtility(
             interfaces.IHTTPRequestFactory, default=HTTPRequest)
@@ -81,3 +89,5 @@
                 interfaces.IBrowserRequestFactory, default=BrowserRequest)
         return request_class, BrowserPublication
 
+    def getSortKey(self):
+        return '0'

Modified: Zope3/branches/ajung-tarek-request-publication-branch/src/zope/app/publication/tests/test_httpfactory.py
===================================================================
--- Zope3/branches/ajung-tarek-request-publication-branch/src/zope/app/publication/tests/test_httpfactory.py	2005-10-07 08:50:21 UTC (rev 38843)
+++ Zope3/branches/ajung-tarek-request-publication-branch/src/zope/app/publication/tests/test_httpfactory.py	2005-10-07 08:51:13 UTC (rev 38844)
@@ -30,7 +30,7 @@
 from zope.app.publication.http import HTTPPublication
 from zope.app.publication.xmlrpc import XMLRPCPublication
 from zope.app.testing import ztapi
-from zope.app.publication import interfaces
+from zope.app.publication import interfaces, publicationfactories
 
 class DummyRequestFactory(object):
     def __call__(self, input_stream, env):
@@ -45,6 +45,31 @@
 
     def setUp(self):
         super(Test, self).setUp()
+
+        ztapi.provideUtility(interfaces.IMethodBase, interfaces.IMethodPOST,
+                             'POST')
+
+        ztapi.provideUtility(interfaces.IMethodBase, interfaces.IMethodGET,
+                             'GET')
+
+        ztapi.provideUtility(interfaces.IMethodBase, interfaces.IMethodHEAD,
+                             'HEAD')
+
+        ztapi.provideUtility(interfaces.IMimetypeBase, interfaces.IMimetypeTextXML,
+                             'text/xml')
+
+        # POST + text/xml -> XMLRPC or Soap
+        ztapi.provideAdapter(required=(interfaces.IMethodPOST, interfaces.IMimetypeTextXML),
+                             provided=interfaces.IRequestPublicationFactory,
+                             name='XMLRPC',
+                             factory=publicationfactories.XMLRPCFactory())
+
+        ztapi.provideAdapter(required=(interfaces.IMethodPOST, interfaces.IMimetypeTextXML),
+                             provided=interfaces.IRequestPublicationFactory,
+                             name='SOAP',
+                             factory=publicationfactories.SOAPFactory())
+
+
         self.__factory = HTTPPublicationRequestFactory(None)
         self.__env =  {
             'SERVER_URL':         'http://127.0.0.1',

Modified: Zope3/branches/ajung-tarek-request-publication-branch/src/zope/app/publication/tests/test_publicationfactories.py
===================================================================
--- Zope3/branches/ajung-tarek-request-publication-branch/src/zope/app/publication/tests/test_publicationfactories.py	2005-10-07 08:50:21 UTC (rev 38843)
+++ Zope3/branches/ajung-tarek-request-publication-branch/src/zope/app/publication/tests/test_publicationfactories.py	2005-10-07 08:51:13 UTC (rev 38844)
@@ -63,8 +63,9 @@
         component.provideUtility(soaprequestfactory)
         env = self.__env
         factory = SOAPFactory()
+        self.assertEquals(factory.getSortKey(), '1')
         self.assertEqual(factory.canHandle(env), False)
-        env['HTTP_SOAPACTION'] = 'server:foo'
+        env['HTTP_SOAPACTION'] = 'server#foo'
         self.assertEqual(factory.canHandle(env), True)
         request, publication = factory()
         self.assertEqual(isinstance(request, DummyRequestFactory), True)
@@ -77,6 +78,7 @@
         component.provideUtility(xmlrpcrequestfactory)
         env = self.__env
         factory = XMLRPCFactory()
+        self.assertEquals(factory.getSortKey(), '0')
         self.assertEqual(factory.canHandle(env), True)
         request, publication = factory()
         self.assertEqual(isinstance(request, DummyRequestFactory), True)
@@ -89,6 +91,7 @@
         component.provideUtility(httprequestfactory)
         env = self.__env
         factory = HTTPFactory()
+        self.assertEquals(factory.getSortKey(), '0')
         self.assertEqual(factory.canHandle(env), True)
         request, publication = factory()
         self.assertEqual(isinstance(request, DummyRequestFactory), True)
@@ -101,6 +104,7 @@
         component.provideUtility(browserrequestfactory)
         env = self.__env
         factory = BrowserFactory()
+        self.assertEquals(factory.getSortKey(), '0')
         self.assertEqual(factory.canHandle(env), True)
         request, publication = factory()
         self.assertEqual(isinstance(request, DummyRequestFactory), True)



More information about the Zope3-Checkins mailing list