Tres Seaver wrote:

I think I'll be able to review and merge it this week.

That's fine, although they might end up getting merged at the "same
time" if you get the second patch in before I get to reviewing the first.

Who needs sleep, ey.... I've done the second patch (pasted below for your inspection) and added it to the collector at http://www.zope.org/Collectors/CMF/461.

Comments welcome! Hopefully both of these should be ready for merge now.

Martin

Index: interfaces/__init__.py
===================================================================
--- interfaces/__init__.py      (revision 71665)
+++ interfaces/__init__.py      (working copy)
@@ -17,6 +17,7 @@

 from _content import *
 from _tools import *
+from _events import *

 import CachingPolicyManager
 import Contentish
Index: interfaces/_events.py
===================================================================
--- interfaces/_events.py       (revision 0)
+++ interfaces/_events.py       (revision 0)
@@ -0,0 +1,30 @@
+from zope.interface import Attribute
+from zope.component.interfaces import IObjectEvent
+
+
+class IWorkflowActionEvent(IObjectEvent):
+
+    """Base interface for events around workflow action invocation
+    """
+
+    workflow = Attribute("The workflow definition object")
+    action = Attribute("The name of the action being invoked")
+
+class IActionWillBeInvokedEvent(IWorkflowActionEvent):
+
+    """Event fired immediately before a workflow action is invoked
+    """
+
+class IActionRaisedExceptionEvent(IWorkflowActionEvent):
+
+    """Event fired when a workflow action raised an exception
+    """
+
+    exc = Attribute("The exception info for the exception raised")
+
+class IActionSucceededEvent(IWorkflowActionEvent):
+
+    """Event fired when a workflow action succeeded
+    """
+
+    result = Attribute("The result of the workflow action")
\ No newline at end of file
Index: WorkflowTool.py
===================================================================
--- WorkflowTool.py     (revision 71665)
+++ WorkflowTool.py     (working copy)
@@ -25,6 +25,7 @@
 from OFS.Folder import Folder
 from OFS.ObjectManager import IFAwareObjectManager
 from zope.interface import implements
+from zope.event import notify

 from ActionProviderBase import ActionProviderBase
 from interfaces import IConfigurableWorkflowTool
@@ -39,8 +40,10 @@
 from WorkflowCore import ObjectDeleted
 from WorkflowCore import ObjectMoved
 from WorkflowCore import WorkflowException
+from WorkflowCore import ActionWillBeInvokedEvent
+from WorkflowCore import ActionRaisedExceptionEvent
+from WorkflowCore import ActionSucceededEvent

-
 _marker = []  # Create a new marker object.


@@ -293,6 +296,7 @@
         wfs = self.getWorkflowsFor(ob)
         for wf in wfs:
             wf.notifyBefore(ob, action)
+            notify(ActionWillBeInvokedEvent(ob, wf, action))

     security.declarePrivate('notifySuccess')
     def notifySuccess(self, ob, action, result=None):
@@ -301,6 +305,7 @@
         wfs = self.getWorkflowsFor(ob)
         for wf in wfs:
             wf.notifySuccess(ob, action, result)
+            notify(ActionSucceededEvent(ob, wf, action, result))

     security.declarePrivate('notifyException')
     def notifyException(self, ob, action, exc):
@@ -309,6 +314,7 @@
         wfs = self.getWorkflowsFor(ob)
         for wf in wfs:
             wf.notifyException(ob, action, exc)
+            notify(ActionRaisedExceptionEvent(ob, wf, action, exc))

     security.declarePrivate('getHistoryOf')
     def getHistoryOf(self, wf_id, ob):
@@ -516,6 +522,7 @@
         reindex = 1
         for w in wfs:
             w.notifyBefore(ob, action)
+            notify(ActionWillBeInvokedEvent(ob, w, action))
         try:
             res = func(*args, **kw)
         except ObjectDeleted, ex:
@@ -529,11 +536,13 @@
             try:
                 for w in wfs:
                     w.notifyException(ob, action, exc)
+                    notify(ActionRaisedExceptionEvent(ob, w, action, exc))
                 raise exc[0], exc[1], exc[2]
             finally:
                 exc = None
         for w in wfs:
             w.notifySuccess(ob, action, res)
+            notify(ActionSucceededEvent(ob, w, action, res))
         if reindex:
             self._reindexWorkflowVariables(ob)
         return res
Index: tests/test_WorkflowTool.py
===================================================================
--- tests/test_WorkflowTool.py  (revision 71665)
+++ tests/test_WorkflowTool.py  (working copy)
@@ -20,6 +20,10 @@

 from OFS.SimpleItem import SimpleItem

+from zope.component import adapter, provideHandler
+from Products.CMFCore.interfaces import IActionWillBeInvokedEvent
+from Products.CMFCore.interfaces import IActionRaisedExceptionEvent
+from Products.CMFCore.interfaces import IActionSucceededEvent

 class Dummy( SimpleItem ):

@@ -98,7 +102,18 @@
     def notifyException( self, ob, action, exc ):
         self.notified( 'exception' ).append( ( ob, action, exc ) )

[EMAIL PROTECTED](IActionWillBeInvokedEvent)
+def notifyBeforeHandler(evt):
+ evt.workflow.notified( 'before-evt' ).append( (evt.object, evt.action) )
+
[EMAIL PROTECTED](IActionSucceededEvent)
+def notifySuccessHandler(evt):
+ evt.workflow.notified( 'success-evt' ).append( (evt.object, evt.action, evt.result ) )

[EMAIL PROTECTED](IActionRaisedExceptionEvent)
+def notifyExceptionHandler(evt):
+ evt.workflow.notified( 'exception-evt' ).append( (evt.object, evt.action, evt.exc) )
+
 class DummyContent( Dummy ):

     meta_type = 'Dummy'
@@ -328,6 +343,8 @@

     def test_notifyBefore( self ):

+        provideHandler(notifyBeforeHandler)
+
         tool = self._makeWithTypesAndChain()

         ob = DummyContent( 'dummy' )
@@ -337,9 +354,15 @@
             notified = wf.notified( 'before' )
             self.assertEqual( len( notified ), 1 )
             self.assertEqual( notified[0], ( ob, 'action' ) )
+
+            notified = wf.notified( 'before-evt' )
+            self.assertEqual( len( notified ), 1 )
+            self.assertEqual( notified[0], ( ob, 'action' ) )

     def test_notifySuccess( self ):

+        provideHandler(notifySuccessHandler)
+
         tool = self._makeWithTypesAndChain()

         ob = DummyContent( 'dummy' )
@@ -349,9 +372,15 @@
             notified = wf.notified( 'success' )
             self.assertEqual( len( notified ), 1 )
             self.assertEqual( notified[0], ( ob, 'action', None ) )
+
+            notified = wf.notified( 'success-evt' )
+            self.assertEqual( len( notified ), 1 )
+            self.assertEqual( notified[0], ( ob, 'action', None ) )

     def test_notifyException( self ):

+        provideHandler(notifyExceptionHandler)
+
         tool = self._makeWithTypesAndChain()

         ob = DummyContent( 'dummy' )
@@ -361,6 +390,10 @@
             notified = wf.notified( 'exception' )
             self.assertEqual( len( notified ), 1 )
             self.assertEqual( notified[0], ( ob, 'action', 'exception' ) )
+
+            notified = wf.notified( 'exception-evt' )
+            self.assertEqual( len( notified ), 1 )
+            self.assertEqual( notified[0], ( ob, 'action', 'exception' ) )

     def xxx_test_updateRoleMappings( self ):
         """
Index: WorkflowCore.py
===================================================================
--- WorkflowCore.py     (revision 71665)
+++ WorkflowCore.py     (working copy)
@@ -15,12 +15,20 @@
 $Id$
 """

+from zope.interface import implements
+from zope.component.interfaces import ObjectEvent
+
+from Products.CMFCore.interfaces import IWorkflowActionEvent
+from Products.CMFCore.interfaces import IActionWillBeInvokedEvent
+from Products.CMFCore.interfaces import IActionRaisedExceptionEvent
+from Products.CMFCore.interfaces import IActionSucceededEvent
+
 class WorkflowException( Exception ):

     """ Exception while invoking workflow.
     """
+

-
 class ObjectDeleted( Exception ):

     """ Raise to tell the workflow tool that the object has been deleted.
@@ -49,3 +57,31 @@

     def getNewObject(self):
         return self._ob
+
+# Events
+
+class WorkflowActionEvent(ObjectEvent):
+    implements(IWorkflowActionEvent)
+
+    def __init__(self, object, workflow, action):
+        ObjectEvent.__init__(self, object)
+        self.workflow = workflow
+        self.action = action
+
+class ActionWillBeInvokedEvent(WorkflowActionEvent):
+    implements(IActionWillBeInvokedEvent)
+
+
+class ActionRaisedExceptionEvent(WorkflowActionEvent):
+    implements(IActionRaisedExceptionEvent)
+
+    def __init__(self, object, workflow, action, exc):
+        WorkflowActionEvent.__init__(self, object, workflow, action)
+        self.exc = exc
+
+class ActionSucceededEvent(WorkflowActionEvent):
+    implements(IActionSucceededEvent)
+
+    def __init__(self, object, workflow, action, result):
+        WorkflowActionEvent.__init__(self, object, workflow, action)
+        self.result = result
\ No newline at end of file

_______________________________________________
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests

Reply via email to