[CMF-checkins] SVN: CMF/trunk/CMF - replaced _recurseOpaques calls by dispatchToOpaqueItems and handleOpaqueItemEvent subscribers

Yvo Schubbe y.2006_ at wcm-solutions.de
Wed May 24 16:30:01 EDT 2006


Log message for revision 68268:
  - replaced _recurseOpaques calls by dispatchToOpaqueItems and handleOpaqueItemEvent subscribers
  
  (this is just one step, more refactoring is necessary to get rid of the ICallableOpaqueItemEvents manage_* methods)

Changed:
  U   CMF/trunk/CMFCore/CMFCatalogAware.py
  U   CMF/trunk/CMFCore/event.zcml
  U   CMF/trunk/CMFDefault/DiscussionItem.py
  U   CMF/trunk/CMFDefault/tests/test_Discussions.py

-=-
Modified: CMF/trunk/CMFCore/CMFCatalogAware.py
===================================================================
--- CMF/trunk/CMFCore/CMFCatalogAware.py	2006-05-24 17:01:05 UTC (rev 68267)
+++ CMF/trunk/CMFCore/CMFCatalogAware.py	2006-05-24 20:30:00 UTC (rev 68268)
@@ -26,6 +26,7 @@
 from OFS.interfaces import IObjectWillBeMovedEvent
 from zope.app.container.interfaces import IObjectAddedEvent
 from zope.app.container.interfaces import IObjectMovedEvent
+from zope.component import subscribers
 
 from permissions import AccessContentsInformation
 from permissions import ManagePortal
@@ -205,21 +206,6 @@
             self.manage_delLocalRoles(local_role_holders)
             self.manage_setLocalRoles(current_user.getId(), ['Owner'])
 
-    def _recurseOpaques(self, name, container=None):
-        """
-            Recurse in both opaque subobjects.
-        """
-        for opaque in self.opaqueValues():
-            s = getattr(opaque, '_p_changed', 0)
-            if hasattr(aq_base(opaque), name):
-                if container is None:
-                    getattr(opaque, name)(opaque)
-                else:
-                    getattr(opaque, name)(opaque, container)
-            else:
-                if s is None:
-                    opaque._p_deactivate()
-
     # ZMI
     # ---
 
@@ -266,28 +252,49 @@
 InitializeClass(CMFCatalogAware)
 
 
-def handleObjectEvent(ob, event):
+def handleContentishEvent(ob, event):
     """ Event subscriber for (IContentish, IObjectEvent) events.
-
-    o XXX:  the nasty '_recurseOpaques' propagates notification to opaque
-            items, which are ignored by the stock ObjectManager propagation.
     """
     if IObjectAddedEvent.providedBy(event):
         if event.newParent is not None:
             ob.indexObject()
-            ob._recurseOpaques('manage_afterAdd', ob)
 
     elif IObjectClonedEvent.providedBy(event):
         ob.notifyWorkflowCreated()
         ob._clearLocalRolesAfterClone()
-        ob._recurseOpaques('manage_afterClone')
 
     elif IObjectMovedEvent.providedBy(event):
         if event.newParent is not None:
             ob.reindexObject()
-            ob._recurseOpaques('manage_afterAdd', ob)
 
     elif IObjectWillBeMovedEvent.providedBy(event):
         if event.oldParent is not None:
             ob.unindexObject()
-            ob._recurseOpaques('manage_beforeDelete', ob)
+
+def dispatchToOpaqueItems(ob, event):
+    """Dispatch an event to opaque sub-items of a given object.
+    """
+    for opaque in ob.opaqueValues():
+        s = getattr(opaque, '_p_changed', 0)
+        for ignored in subscribers((opaque, event), None):
+            pass # They do work in the adapter fetch
+        if s is None:
+            opaque._p_deactivate()
+
+def handleOpaqueItemEvent(ob, event):
+    """ Event subscriber for (ICallableOpaqueItemEvents, IObjectEvent) events.
+    """
+    if IObjectAddedEvent.providedBy(event):
+        if event.newParent is not None:
+            ob.manage_afterAdd(ob, event.newParent)
+
+    elif IObjectClonedEvent.providedBy(event):
+        ob.manage_afterClone(ob)
+
+    elif IObjectMovedEvent.providedBy(event):
+        if event.newParent is not None:
+            ob.manage_afterAdd(ob, event.newParent)
+
+    elif IObjectWillBeMovedEvent.providedBy(event):
+        if event.oldParent is not None:
+            ob.manage_beforeDelete(ob, event.oldParent)

Modified: CMF/trunk/CMFCore/event.zcml
===================================================================
--- CMF/trunk/CMFCore/event.zcml	2006-05-24 17:01:05 UTC (rev 68267)
+++ CMF/trunk/CMFCore/event.zcml	2006-05-24 20:30:00 UTC (rev 68268)
@@ -10,7 +10,19 @@
   <subscriber
       for=".interfaces.IContentish
            zope.app.event.interfaces.IObjectEvent"
-      handler=".CMFCatalogAware.handleObjectEvent"
+      handler=".CMFCatalogAware.handleContentishEvent"
       />
 
+  <subscriber
+      for=".interfaces.IDynamicType
+           zope.app.event.interfaces.IObjectEvent"
+      handler=".CMFCatalogAware.dispatchToOpaqueItems"
+      />
+
+  <subscriber
+      for=".interfaces.ICallableOpaqueItemEvents
+           zope.app.event.interfaces.IObjectEvent"
+      handler=".CMFCatalogAware.handleOpaqueItemEvent"
+      />
+
 </configure>

Modified: CMF/trunk/CMFDefault/DiscussionItem.py
===================================================================
--- CMF/trunk/CMFDefault/DiscussionItem.py	2006-05-24 17:01:05 UTC (rev 68267)
+++ CMF/trunk/CMFDefault/DiscussionItem.py	2006-05-24 20:30:00 UTC (rev 68268)
@@ -24,6 +24,7 @@
 from OFS.Traversable import Traversable
 from zope.interface import implements
 
+from Products.CMFCore.interfaces import ICallableOpaqueItemEvents
 from Products.CMFCore.interfaces import IDiscussable
 from Products.CMFCore.interfaces import IDiscussionResponse
 from Products.CMFCore.interfaces.Discussions \
@@ -158,7 +159,7 @@
         hold the discussion threads.
     """
 
-    implements(IDiscussable)
+    implements(IDiscussable, ICallableOpaqueItemEvents)
     __implements__ = z2IDiscussable
 
     # for the security machinery to allow traversal

Modified: CMF/trunk/CMFDefault/tests/test_Discussions.py
===================================================================
--- CMF/trunk/CMFDefault/tests/test_Discussions.py	2006-05-24 17:01:05 UTC (rev 68267)
+++ CMF/trunk/CMFDefault/tests/test_Discussions.py	2006-05-24 20:30:00 UTC (rev 68268)
@@ -80,20 +80,25 @@
 
 class DiscussionItemContainerTests(unittest.TestCase):
 
+    def _getTargetClass(self):
+        from Products.CMFDefault.DiscussionItem import DiscussionItemContainer
+
+        return DiscussionItemContainer
+
     def test_z2interfaces(self):
         from Interface.Verify import verifyClass
         from Products.CMFCore.interfaces.Discussions \
                 import Discussable as IDiscussable
-        from Products.CMFDefault.DiscussionItem import DiscussionItemContainer
 
-        verifyClass(IDiscussable, DiscussionItemContainer)
+        verifyClass(IDiscussable, self._getTargetClass())
 
     def test_z3interfaces(self):
         from zope.interface.verify import verifyClass
+        from Products.CMFCore.interfaces import ICallableOpaqueItemEvents
         from Products.CMFCore.interfaces import IDiscussable
-        from Products.CMFDefault.DiscussionItem import DiscussionItemContainer
 
-        verifyClass(IDiscussable, DiscussionItemContainer)
+        verifyClass(ICallableOpaqueItemEvents, self._getTargetClass())
+        verifyClass(IDiscussable, self._getTargetClass())
 
 
 class DiscussionTests(SecurityTest):



More information about the CMF-checkins mailing list