[Checkins] SVN: z3c.jsonrpc/trunk/ Fix: reflect skin lookup changes in zope.publisher.

Roger Ineichen roger at projekt01.ch
Mon Mar 9 23:17:55 EDT 2009


Log message for revision 97775:
  Fix: reflect skin lookup changes in zope.publisher.
  Use the new skinnable concept. Skip dependency to browser part of zope.publisher.

Changed:
  U   z3c.jsonrpc/trunk/CHANGES.txt
  U   z3c.jsonrpc/trunk/src/z3c/jsonrpc/configure.zcml
  U   z3c.jsonrpc/trunk/src/z3c/jsonrpc/error.zcml
  U   z3c.jsonrpc/trunk/src/z3c/jsonrpc/interfaces.py
  U   z3c.jsonrpc/trunk/src/z3c/jsonrpc/namespace.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-03-10 03:14:47 UTC (rev 97774)
+++ z3c.jsonrpc/trunk/CHANGES.txt	2009-03-10 03:17:54 UTC (rev 97775)
@@ -5,6 +5,9 @@
 Version 0.5.3dev (unreleased)
 -----------------------------
 
+- Fix: reflect skin lookup changes in zope.publisher. Use the new skinnable
+  concept.
+
 - 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

Modified: z3c.jsonrpc/trunk/src/z3c/jsonrpc/configure.zcml
===================================================================
--- z3c.jsonrpc/trunk/src/z3c/jsonrpc/configure.zcml	2009-03-10 03:14:47 UTC (rev 97774)
+++ z3c.jsonrpc/trunk/src/z3c/jsonrpc/configure.zcml	2009-03-10 03:17:54 UTC (rev 97775)
@@ -1,14 +1,12 @@
 <configure
     xmlns="http://namespaces.zope.org/zope"
-    i18n_domain="zope">
+    i18n_domain="z3c">
 
-
   <interface
       interface="z3c.jsonrpc.layer.IJSONRPCLayer"
-      type="zope.publisher.interfaces.browser.IBrowserSkinType"
+      type="z3c.jsonrpc.interfaces.IJSONRPCSkinType"
       />
 
-
   <!-- JSON-RPC server -->
   <publisher
       name="Z3C JSONRPC"
@@ -51,15 +49,28 @@
       permission="zope.Public"
       />
 
+  <!-- Be careful and register the skin namespace for our request and layer.
+       This will prevents that we can simply get the wrong skin namespace
+       based on the __iro__ order of our layer and request interfaces.
+       Note, if we don't choose carefully our layer and request interfaces
+       for our skin, it's possible that we get the skin namespace registered
+       for the browser request -->
+  <adapter
+      name="skin"
+      factory=".namespace.skin"
+      for="zope.interface.Interface
+           z3c.jsonrpc.layer.IJSONRPCLayer"
+      provides="zope.traversing.interfaces.ITraversable"
+      />
 
-  <!-- skin namespace -->
-  <view
-      name="skin" type="z3c.jsonrpc.interfaces.IJSONRPCRequest"
-      provides="zope.traversing.interfaces.ITraversable" for="*"
+  <adapter
+      name="skin"
       factory=".namespace.skin"
+      for="zope.interface.Interface
+           z3c.jsonrpc.interfaces.IJSONRPCRequest"
+      provides="zope.traversing.interfaces.ITraversable"
       />
 
-
   <include file="error.zcml" />
 
 </configure>

Modified: z3c.jsonrpc/trunk/src/z3c/jsonrpc/error.zcml
===================================================================
--- z3c.jsonrpc/trunk/src/z3c/jsonrpc/error.zcml	2009-03-10 03:14:47 UTC (rev 97774)
+++ z3c.jsonrpc/trunk/src/z3c/jsonrpc/error.zcml	2009-03-10 03:17:54 UTC (rev 97775)
@@ -1,7 +1,7 @@
 <configure
     xmlns:zope="http://namespaces.zope.org/zope"
     xmlns="http://namespaces.zope.org/browser"
-    i18n_domain="zope">
+    i18n_domain="z3c">
 
   <!-- implement error views for this exceptions
        The error views should return a 1i8n aware error message as result

Modified: z3c.jsonrpc/trunk/src/z3c/jsonrpc/interfaces.py
===================================================================
--- z3c.jsonrpc/trunk/src/z3c/jsonrpc/interfaces.py	2009-03-10 03:14:47 UTC (rev 97774)
+++ z3c.jsonrpc/trunk/src/z3c/jsonrpc/interfaces.py	2009-03-10 03:17:54 UTC (rev 97775)
@@ -17,13 +17,14 @@
 __docformat__ = "reStructuredText"
 
 import zope.interface
-from zope.interface.interfaces import IInterface
+from zope.publisher.interfaces import IPublication
 from zope.publisher.interfaces import IPublishTraverse
+from zope.publisher.interfaces import ISkinnable
+from zope.publisher.interfaces import ISkinType
 from zope.publisher.interfaces.http import IHTTPApplicationRequest
 from zope.publisher.interfaces.http import IHTTPCredentials
-from zope.publisher.interfaces import IPublication
-from zope.app.publication.interfaces import IRequestFactory
 from zope.publisher.interfaces.http import IHTTPRequest
+from zope.app.publication.interfaces import IRequestFactory
 
 JSON_CHARSETS = ('utf-8','utf-16', 'utf-32')
 
@@ -46,7 +47,7 @@
     """Publication for JOSN-RPC-based protocol."""
 
 
-class IJSONRPCSkinType(IInterface):
+class IJSONRPCSkinType(ISkinType):
     """A skin is a set of layers."""
 
 
@@ -55,21 +56,7 @@
 
 
 class IJSONRPCRequest(IJSONRPCApplicationRequest, IHTTPCredentials,
-    IHTTPRequest):
+    IHTTPRequest, ISkinnable):
     """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/namespace.py
===================================================================
--- z3c.jsonrpc/trunk/src/z3c/jsonrpc/namespace.py	2009-03-10 03:14:47 UTC (rev 97774)
+++ z3c.jsonrpc/trunk/src/z3c/jsonrpc/namespace.py	2009-03-10 03:17:54 UTC (rev 97775)
@@ -1,32 +1,22 @@
 import zope.component
 import zope.interface
 import zope.traversing.namespace
+from zope.location.interfaces import LocationError
+from zope.publisher.skinnable import applySkin
 from zope.component.interfaces import ComponentLookupError
 from zope.traversing.interfaces import TraversalError
 
 from z3c.jsonrpc import interfaces
 
 
-def applySkin(request, skin, skin_type):
-       """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 skin_type.providedBy(iface)]
-       # Add the new skin.
-       ifaces.append(skin)
-       zope.interface.directlyProvides(request, *ifaces)
+class skin(zope.traversing.namespace.view):
+    """JSONRPC skin namespace"""
 
-
-class skin(zope.traversing.namespace.skin):
-    """JSONRPC skin type interface."""
-
-    skin_type = interfaces.IJSONRPCSkinType
-
     def traverse(self, name, ignored):
         self.request.shiftNameToApplication()
         try:
-            skin = zope.component.getUtility(self.skin_type, name)
+            skin = zope.component.getUtility(interfaces.IJSONRPCSkinType, name)
         except ComponentLookupError:
-            raise TraversalError("++skin++%s" % name)
-        applySkin(self.request, skin, self.skin_type)
+            raise LocationError("++skin++%s" % name)
+        applySkin(self.request, skin)
         return self.context

Modified: z3c.jsonrpc/trunk/src/z3c/jsonrpc/publication.py
===================================================================
--- z3c.jsonrpc/trunk/src/z3c/jsonrpc/publication.py	2009-03-10 03:14:47 UTC (rev 97774)
+++ z3c.jsonrpc/trunk/src/z3c/jsonrpc/publication.py	2009-03-10 03:17:54 UTC (rev 97775)
@@ -25,7 +25,6 @@
 
 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-03-10 03:14:47 UTC (rev 97774)
+++ z3c.jsonrpc/trunk/src/z3c/jsonrpc/publisher.py	2009-03-10 03:17:54 UTC (rev 97775)
@@ -34,7 +34,6 @@
 from z3c.json.interfaces import IJSONWriter
 from z3c.json.converter import premarshal
 from z3c.jsonrpc import interfaces
-from z3c.jsonrpc.interfaces import JSON_CHARSETS
 
 JSON_RPC_VERSION = '2.0'
 
@@ -46,34 +45,6 @@
     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),),
-        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
@@ -143,12 +114,6 @@
         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"""
@@ -293,27 +258,7 @@
     def __getitem__(self, key):
         return self.get(key)
 
-    def retry(self):
-        """Set default JSONRPC skin if available."""
-        count = getattr(self, '_retry_count', 0)
-        self._retry_count = count + 1
 
-        request = self.__class__(
-            # Use the cache stream as the new input stream.
-            body_instream=self._body_instream.getCacheStream(),
-            environ=self._orig_env,
-            response=self.response.retry(),
-            )
-        # restore the default skin
-        if interfaces.IJSONRPCRequest.providedBy(self):
-            # only browser requests have skins
-            setDefaultSkin(request)
-
-        request.setPublication(self.publication)
-        request._retry_count = self._retry_count
-        return request
-
-
 class JSONRPCResponse(HTTPResponse):
     """JSON-RPC Response"""
 
@@ -357,7 +302,7 @@
         # we've asked json to return unicode; result should be unicode
         encoding = getCharsetUsingRequest(self._request) or 'utf-8'
         enc = encoding.lower()
-        if not enc in JSON_CHARSETS:
+        if not enc in interfaces.JSON_CHARSETS:
             encoding = 'utf-8'
         # encode outgoing boundary.
         if isinstance(result, unicode):

Modified: z3c.jsonrpc/trunk/src/z3c/jsonrpc/zcml.py
===================================================================
--- z3c.jsonrpc/trunk/src/z3c/jsonrpc/zcml.py	2009-03-10 03:14:47 UTC (rev 97774)
+++ z3c.jsonrpc/trunk/src/z3c/jsonrpc/zcml.py	2009-03-10 03:17:54 UTC (rev 97775)
@@ -22,7 +22,7 @@
 import zope.interface
 import zope.schema
 import zope.security.zcml
-from zope.publisher.interfaces.browser import IDefaultSkin
+from zope.publisher.interfaces import IDefaultSkin
 
 from zope.interface import Interface
 from zope.security.checker import CheckerPublic, Checker
@@ -226,7 +226,7 @@
     """Set the default skin."""
     skin = zope.component.getUtility(interfaces.IJSONRPCSkinType, name=name)
     handler('registerAdapter', skin, (interfaces.IJSONRPCRequest,),
-        interfaces.IDefaultSkin, '', info),
+        IDefaultSkin, '', info),
 
 
 def defaultJSONRPCSkin(_context, name):

Modified: z3c.jsonrpc/trunk/src/z3c/jsonrpc/zcml.txt
===================================================================
--- z3c.jsonrpc/trunk/src/z3c/jsonrpc/zcml.txt	2009-03-10 03:14:47 UTC (rev 97774)
+++ z3c.jsonrpc/trunk/src/z3c/jsonrpc/zcml.txt	2009-03-10 03:17:54 UTC (rev 97775)
@@ -85,27 +85,42 @@
   ...     pass
   >>> zope.interface.directlyProvides(IMySkin, interfaces.IJSONRPCSkinType)
 
+Before we setup a default request, we try to set a default request for our
+request:
+
+  >>> from zope.publisher.skinnable import setDefaultSkin
+  >>> setDefaultSkin(request)
+
+Our request should not provide any default kins since we didn't register any:
+
+  >>> IMySkin.providedBy(request)
+  False
+
+Now let's register a default skin:
+
   >>> 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
+We can lookup a default skin from the adapter registry: 
 
-  >>> adapters.lookup((interfaces.IJSONRPCRequest,),
-  ...     interfaces.IDefaultSkin, '') is IMySkin
+  >>> from zope.publisher.interfaces import IDefaultSkin
+  >>> adapters = zope.component.getSiteManager().adapters
+  >>> default = adapters.lookup((interfaces.IJSONRPCRequest,), IDefaultSkin, '')
+  >>> default 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 
+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()
+  >>> setDefaultSkin(request)
   >>> IMySkin.providedBy(request)
   True
+
+We can get the applied default skin by look for our skin type:
+
+  >>> for iface in zope.interface.providedBy(request):
+  ...     if interfaces.IJSONRPCSkinType.providedBy(iface):
+  ...         print "%s" % iface
+  <InterfaceClass README.IMySkin>



More information about the Checkins mailing list