[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