[Checkins] SVN: z3c.jsonrpc/trunk/ Fix:

Roger Ineichen roger at projekt01.ch
Fri Feb 27 19:53:25 EST 2009


Log message for revision 97361:
  Fix:
  - The default skin didn't get applied based on the inherited concept give
    from the zope.publisher.browser implementation because our JSON-RPC request
    doesn't provide IBrowserRequest. Added a workaround which will apply a given
    IDefaultSkin during request instance creation.
  - Added tests
  

Changed:
  U   z3c.jsonrpc/trunk/CHANGES.txt
  U   z3c.jsonrpc/trunk/src/z3c/jsonrpc/interfaces.py
  U   z3c.jsonrpc/trunk/src/z3c/jsonrpc/publication.py
  U   z3c.jsonrpc/trunk/src/z3c/jsonrpc/publisher.py
  U   z3c.jsonrpc/trunk/src/z3c/jsonrpc/zcml.py
  U   z3c.jsonrpc/trunk/src/z3c/jsonrpc/zcml.txt

-=-
Modified: z3c.jsonrpc/trunk/CHANGES.txt
===================================================================
--- z3c.jsonrpc/trunk/CHANGES.txt	2009-02-27 21:17:40 UTC (rev 97360)
+++ z3c.jsonrpc/trunk/CHANGES.txt	2009-02-28 00:53:24 UTC (rev 97361)
@@ -5,7 +5,10 @@
 Version 0.5.3dev (unreleased)
 -----------------------------
 
-- ...
+- Fix: The default skin didn't get applied based on the inherited concept give
+  from the zope.publisher.browser implementation because our JSON-RPC request
+  doesn't provide IBrowserRequest. Added a workaround which will apply a given
+  IDefaultSkin during request instance creation. 
 
 
 Version 0.5.2 (2009-02-24)

Modified: z3c.jsonrpc/trunk/src/z3c/jsonrpc/interfaces.py
===================================================================
--- z3c.jsonrpc/trunk/src/z3c/jsonrpc/interfaces.py	2009-02-27 21:17:40 UTC (rev 97360)
+++ z3c.jsonrpc/trunk/src/z3c/jsonrpc/interfaces.py	2009-02-28 00:53:24 UTC (rev 97361)
@@ -59,3 +59,17 @@
     """JSON-RPC request."""
 
     jsonID = zope.interface.Attribute("""JSON-RPC ID for the request""")
+
+
+class IDefaultSkin(zope.interface.Interface):
+    """Any component providing this interface must be a skin.
+
+    This is a marker interface, so that we can register the default skin as an
+    adapter from the presentation type to `IDefaultSkin`.
+    """
+
+
+class ISkinChangedEvent(zope.interface.Interface):
+    """Event that gets triggered when the skin of a request is changed."""
+
+    request = zope.interface.Attribute("The request for which the skin was changed.")

Modified: z3c.jsonrpc/trunk/src/z3c/jsonrpc/publication.py
===================================================================
--- z3c.jsonrpc/trunk/src/z3c/jsonrpc/publication.py	2009-02-27 21:17:40 UTC (rev 97360)
+++ z3c.jsonrpc/trunk/src/z3c/jsonrpc/publication.py	2009-02-28 00:53:24 UTC (rev 97361)
@@ -20,9 +20,12 @@
 import zope.component
 from zope.app.publication.http import BaseHTTPPublication
 from zope.app.publication.interfaces import IRequestPublicationFactory
+from zope.app.publication.interfaces import IPublicationRequestFactory
+from zope.app.publication.requestpublicationregistry import factoryRegistry
 
 from z3c.jsonrpc import interfaces
 from z3c.jsonrpc.publisher import JSONRPCRequest
+from z3c.jsonrpc.publisher import setDefaultSkin
 
 
 class JSONRPCPublication(BaseHTTPPublication):

Modified: z3c.jsonrpc/trunk/src/z3c/jsonrpc/publisher.py
===================================================================
--- z3c.jsonrpc/trunk/src/z3c/jsonrpc/publisher.py	2009-02-27 21:17:40 UTC (rev 97360)
+++ z3c.jsonrpc/trunk/src/z3c/jsonrpc/publisher.py	2009-02-28 00:53:24 UTC (rev 97361)
@@ -22,9 +22,9 @@
 
 import zope.interface
 import zope.component
+import zope.event
 from zope.location.location import Location
 from zope.i18n.interfaces import IUserPreferredCharsets
-from zope.publisher.interfaces.browser import IDefaultSkin
 from zope.publisher.http import HTTPRequest
 from zope.publisher.http import HTTPResponse
 from zope.publisher.http import getCharsetUsingRequest
@@ -46,14 +46,34 @@
     return int(item[0])
 
 
+class SkinChangedEvent(object):
+
+    zope.interface.implements(interfaces.ISkinChangedEvent)
+
+    def __init__(self, request):
+        self.request = request
+
+
 def setDefaultSkin(request):
     """Sets the default skin for the JONS-RPC request."""
     adapters = zope.component.getSiteManager().adapters
-    skin = adapters.lookup((zope.interface.providedBy(request),), IDefaultSkin, '')
+    skin = adapters.lookup((zope.interface.providedBy(request),),
+        interfaces.IDefaultSkin, '')
     if skin is not None:
         zope.interface.directlyProvides(request, skin)
 
 
+def applySkin(request, skin):
+    """Change the presentation skin for this request."""
+    # Remove all existing skin declarations (commonly the default skin).
+    ifaces = [iface for iface in zope.interface.directlyProvidedBy(request)
+              if not interfaces.IJSONRPCSkinType.providedBy(iface)]
+    # Add the new skin.
+    ifaces.append(skin)
+    zope.interface.directlyProvides(request, *ifaces)
+    zope.event.notify(SkinChangedEvent(request))
+
+
 class MethodPublisher(Location):
     """Base class for JSON-RPC views that publish methods
        like zope.app.publisher.xmlrpc.MethodPublisher
@@ -123,6 +143,12 @@
         self._args = ()
         self.charsets = None
         super(JSONRPCRequest, self).__init__(body_instream, environ, response)
+        # set the default skin. This is a workaround which allows us to set a
+        # default skin. The real concept used in the class
+        # HTTPPublicationRequestFactory does this before setPublication is
+        # called. We don't have any chance to hook into the existing concept.
+        # Let's just do it here.
+        setDefaultSkin(self)
 
     def _createResponse(self):
         """return a response"""

Modified: z3c.jsonrpc/trunk/src/z3c/jsonrpc/zcml.py
===================================================================
--- z3c.jsonrpc/trunk/src/z3c/jsonrpc/zcml.py	2009-02-27 21:17:40 UTC (rev 97360)
+++ z3c.jsonrpc/trunk/src/z3c/jsonrpc/zcml.py	2009-02-28 00:53:24 UTC (rev 97361)
@@ -226,7 +226,7 @@
     """Set the default skin."""
     skin = zope.component.getUtility(interfaces.IJSONRPCSkinType, name=name)
     handler('registerAdapter', skin, (interfaces.IJSONRPCRequest,),
-        IDefaultSkin, '', info),
+        interfaces.IDefaultSkin, '', info),
 
 
 def defaultJSONRPCSkin(_context, name):

Modified: z3c.jsonrpc/trunk/src/z3c/jsonrpc/zcml.txt
===================================================================
--- z3c.jsonrpc/trunk/src/z3c/jsonrpc/zcml.txt	2009-02-27 21:17:40 UTC (rev 97360)
+++ z3c.jsonrpc/trunk/src/z3c/jsonrpc/zcml.txt	2009-02-28 00:53:24 UTC (rev 97361)
@@ -78,20 +78,34 @@
 setDefaultJSONRPCSkin
 ---------------------
 
-  >>> from zope.interface import directlyProvides
-  >>> from zope.publisher.interfaces.browser import IDefaultSkin
   >>> from z3c.jsonrpc import interfaces
   >>> import z3c.jsonrpc.zcml
 
-  >>> class Skin: pass
-  >>> directlyProvides(Skin, interfaces.IJSONRPCSkinType)
+  >>> class IMySkin(zope.interface.Interface):
+  ...     pass
+  >>> zope.interface.directlyProvides(IMySkin, interfaces.IJSONRPCSkinType)
 
-  >>> zope.component.provideUtility(Skin, interfaces.IJSONRPCSkinType,
+  >>> zope.component.provideUtility(IMySkin, interfaces.IJSONRPCSkinType,
   ...     name='JSONRPC')
   >>> z3c.jsonrpc.zcml.setDefaultJSONRPCSkin('JSONRPC')
   >>> adapters = zope.component.getSiteManager().adapters
 
 Lookup the default skin for a request that has the
 
-  >>> adapters.lookup((interfaces.IJSONRPCRequest,), IDefaultSkin, '') is Skin
+  >>> adapters.lookup((interfaces.IJSONRPCRequest,),
+  ...     interfaces.IDefaultSkin, '') is IMySkin
   True
+
+Let's test if our request instance will provide this IDefaultSkin after we
+create an instance. The old request shoud not provide taht skin since we
+created the request instance before we registered the default skin:
+
+  >>> IMySkin.providedBy(request)
+  False
+
+But since we have a default skin utility registered as a skin type for our 
+request, a new request instance should provide the default skin:
+
+  >>> request = TestRequest()
+  >>> IMySkin.providedBy(request)
+  True



More information about the Checkins mailing list