[Zope3-checkins] SVN: Zope3/trunk/src/zope/app/ Changed the way ContentWorkflowsManagers are notified that objects are

Jim Fulton jim at zope.com
Sun May 23 12:21:33 EDT 2004


Log message for revision 24906:

Changed the way ContentWorkflowsManagers are notified that objects are
created. We no-longer use a local event service. Rather, there is a
global subscriber that updates the object using all the
ContentWorkflowsManagers it can find.




-=-
Modified: Zope3/trunk/src/zope/app/tests/setup.py
===================================================================
--- Zope3/trunk/src/zope/app/tests/setup.py	2004-05-23 14:13:30 UTC (rev 24905)
+++ Zope3/trunk/src/zope/app/tests/setup.py	2004-05-23 16:21:33 UTC (rev 24906)
@@ -172,7 +172,8 @@
 
     This utility is useful for tests that need to set up utilities.
     """
-    folder_name = name + suffix
+    
+    folder_name = (name or (iface.__name__ + 'Utility')) + suffix
     default = zapi.traverse(servicemanager, 'default')
     default[folder_name] = utility
     path = "%s/default/%s" % (zapi.getPath(servicemanager), folder_name)

Modified: Zope3/trunk/src/zope/app/workflow/stateful/browser/configure.zcml
===================================================================
--- Zope3/trunk/src/zope/app/workflow/stateful/browser/configure.zcml	2004-05-23 14:13:30 UTC (rev 24905)
+++ Zope3/trunk/src/zope/app/workflow/stateful/browser/configure.zcml	2004-05-23 16:21:33 UTC (rev 24906)
@@ -129,14 +129,6 @@
   <page
       name="index.html"
       for="zope.app.workflow.stateful.interfaces.IContentWorkflowsManager"
-      class=".contentworkflow.ContentWorkflowsManagerView"
-      permission="zope.ManageServices"
-      template="contentworkflow_index.pt"
-      menu="zmi_views" title="Overview"/>
-
-  <page
-      name="registry.html"
-      for="zope.app.workflow.stateful.interfaces.IContentWorkflowsManager"
       class=".contentworkflow.ManageContentProcessRegistry"
       permission="zope.ManageServices"
       template="contentworkflow_registry.pt"

Modified: Zope3/trunk/src/zope/app/workflow/stateful/browser/contentworkflow.py
===================================================================
--- Zope3/trunk/src/zope/app/workflow/stateful/browser/contentworkflow.py	2004-05-23 14:13:30 UTC (rev 24905)
+++ Zope3/trunk/src/zope/app/workflow/stateful/browser/contentworkflow.py	2004-05-23 16:21:33 UTC (rev 24906)
@@ -28,12 +28,6 @@
 from zope.security.proxy import trustedRemoveSecurityProxy 
 from zope.app.workflow.interfaces import IProcessDefinition
 
-class ContentWorkflowsManagerView(object):
- 
-    def getName(self):
-        return """I'm a ContentWorkflows Utility"""
-
-
 class IContentProcessMapping(Interface):
 
     iface = List(

Deleted: Zope3/trunk/src/zope/app/workflow/stateful/browser/contentworkflow_index.pt
===================================================================
--- Zope3/trunk/src/zope/app/workflow/stateful/browser/contentworkflow_index.pt	2004-05-23 14:13:30 UTC (rev 24905)
+++ Zope3/trunk/src/zope/app/workflow/stateful/browser/contentworkflow_index.pt	2004-05-23 16:21:33 UTC (rev 24906)
@@ -1,36 +0,0 @@
-<html metal:use-macro="views/standard_macros/view">
- <head>
-  <title metal:fill-slot="title" i18n:translate="">
-    Registration "Service" Control Page
-  </title>
-</head>
-
-<body>
-<div metal:fill-slot="body">
- 
-  <h1 i18n:translate="">Subscription control</h1>
-
-  <!-- XXX: Too much logic for a template --> 
-  <span tal:condition="request/callSubscribe|nothing" tal:omit-tag="">
-    <span tal:define="dummy context/subscribe" tal:omit-tag=""/>
-  </span>
-  <span tal:condition="request/callUnsubscribe|nothing" tal:omit-tag="">
-    <span tal:define="dummy context/unsubscribe" tal:omit-tag=""/>
-  </span>
-
-  <form action="" method="post">
-    <span tal:condition="context/isSubscribed" tal:omit-tag="">
-      <span i18n:translate="">Subscription state: ON</span>
-      <input type="submit" value="Unsubscribe" name="callUnsubscribe" 
-             i18n:attributes="value unsubscribe-button"/>
-     </span>
-     <span tal:condition="not:context/isSubscribed" tal:omit-tag="">
-       <span i18n:translate="">Subscription state: OFF</span>
-       <input type="submit" value="Subscribe" name="callSubscribe"
-              i18n:attributes="value unsubscribe-button"/>
-     </span>
-  </form>
- 
-</div>
-</body>
-</html>
\ No newline at end of file

Modified: Zope3/trunk/src/zope/app/workflow/stateful/browser/ftests/test_contentworkflowsmanager.py
===================================================================
--- Zope3/trunk/src/zope/app/workflow/stateful/browser/ftests/test_contentworkflowsmanager.py	2004-05-23 14:13:30 UTC (rev 24905)
+++ Zope3/trunk/src/zope/app/workflow/stateful/browser/ftests/test_contentworkflowsmanager.py	2004-05-23 16:21:33 UTC (rev 24906)
@@ -69,34 +69,13 @@
         pd_id = rm.addRegistration(registration)
         zapi.traverse(rm, pd_id).status = ActiveStatus
 
-    def test_subscribe(self):
+    def test_registry(self):
         response = self.publish(
             self.basepath + '/mgr/index.html',
             basic='mgr:mgrpw')
 
         self.assertEqual(response.getStatus(), 200)
         body = ' '.join(response.getBody().split())
-        self.assert_(body.find("Subscription state: OFF") >= 0)        
-
-        response = self.publish(
-            self.basepath + '/mgr/index.html',
-            basic='mgr:mgrpw',
-            form={'callSubscribe':'Subscribe'})
-
-        self.assertEqual(response.getStatus(), 200)
-        body = ' '.join(response.getBody().split())
-        self.assert_(body.find("Subscription state: ON") >= 0)        
-        root = self.getRootFolder()
-        mgr = zapi.traverse(root, self.basepath+'/mgr')
-        self.assert_(mgr.isSubscribed())
-
-    def test_registry(self):
-        response = self.publish(
-            self.basepath + '/mgr/registry.html',
-            basic='mgr:mgrpw')
-
-        self.assertEqual(response.getStatus(), 200)
-        body = ' '.join(response.getBody().split())
         self.assert_(body.find(
             '<option value="zope.app.folder.interfaces.IFolder">'
             ) >= 0)        
@@ -105,7 +84,7 @@
             ) >= 0)        
 
         response = self.publish(
-            self.basepath + '/mgr/registry.html',
+            self.basepath + '/mgr/index.html',
             basic='mgr:mgrpw',
             form={
             'field.iface':['zope.app.folder.interfaces.IFolder',
@@ -130,7 +109,7 @@
         self.assertEqual(len(ifaces), 2)
 
         response = self.publish(
-            self.basepath + '/mgr/registry.html',
+            self.basepath + '/mgr/index.html',
             basic='mgr:mgrpw',
             form={
             'mappings': ['dummy-definition:zope.app.folder.interfaces.IFolder',

Modified: Zope3/trunk/src/zope/app/workflow/stateful/configure.zcml
===================================================================
--- Zope3/trunk/src/zope/app/workflow/stateful/configure.zcml	2004-05-23 14:13:30 UTC (rev 24905)
+++ Zope3/trunk/src/zope/app/workflow/stateful/configure.zcml	2004-05-23 16:21:33 UTC (rev 24906)
@@ -1,6 +1,4 @@
-<configure
-   xmlns="http://namespaces.zope.org/zope"
-   xmlns:workflow="http://namespaces.zope.org/workflow" >
+<configure xmlns="http://namespaces.zope.org/zope">
 
 <!-- Stateful ProcessDefintion -->
 
@@ -128,6 +126,18 @@
    factory=".xmlimportexport.XMLImportHandler"
    />
 
+
+<subscriber
+   for="..interfaces.IProcessInstanceContainerAdaptable
+        zope.app.event.objectevent.IObjectCreatedEvent"
+   provides="zope.app.event.interfaces.ISubscriber"
+   factory=".contentworkflow.NewObjectProcessInstanceCreator"
+   >
+
+   Cause workflow instances to be added to content objects when they
+   are created.
+</subscriber>
+
 <!-- Test Object for testing Stateful Workflows -->
 <!--include file="testobject.zcml"/-->
 

Modified: Zope3/trunk/src/zope/app/workflow/stateful/contentworkflow.py
===================================================================
--- Zope3/trunk/src/zope/app/workflow/stateful/contentworkflow.py	2004-05-23 14:13:30 UTC (rev 24905)
+++ Zope3/trunk/src/zope/app/workflow/stateful/contentworkflow.py	2004-05-23 16:21:33 UTC (rev 24906)
@@ -33,75 +33,51 @@
 from zope.app.container.contained import Contained
 
 
-class ContentWorkflowsManager(Persistent, Contained):
+class NewObjectProcessInstanceCreator(object):
+    implements(ISubscriber)
+    
+    __used_for__ = (IProcessInstanceContainerAdaptable, IObjectCreatedEvent)
 
-    implements(IContentWorkflowsManager, ISubscriber)
+    __slots__ = ('event', )
 
-    currentlySubscribed = False # Default subscription state
+    def __init__(self, obj, event):
+        self.event = event
 
-    def __init__(self):
-        super(ContentWorkflowsManager, self).__init__()
-        self._registry = PersistentDict()
-
-    def notify(self, event):
+    def notify(self, ignored_event):
         """See zope.app.event.interfaces.ISubscriber"""
+        event = self.event
         obj = event.object
 
-        # check if it implements IProcessInstanceContainerAdaptable
-        # This interface ensures that the object can store process
-        # instances.
-        if not IProcessInstanceContainerAdaptable.providedBy(obj):
-            return
+        pi_container = IProcessInstanceContainer(obj)
 
-        pi_container = IProcessInstanceContainer(obj, None)
-        # probably need to adapt to IZopeContainer to use pi_container with
-        # context.
-        if pi_container is None:
-            # Object can't have associated PIs.
-            return
-
-        if IObjectCreatedEvent.providedBy(event):
+        for (ignored, cwf) in zapi.getUtilitiesFor(IContentWorkflowsManager):
             # here we will lookup the configured processdefinitions
             # for the newly created compoent. For every pd_name
             # returned we will create a processinstance.
-            for pd_name in self.getProcessDefinitionNamesForObject(obj):
 
+            # Note that we use getUtilitiesFor rather than getAllUtilitiesFor
+            # so that we don't use overridden content-workflow managers.
+            
+            for pd_name in cwf.getProcessDefinitionNamesForObject(obj):
+
                 if pd_name in pi_container.keys():
                     continue
                 try:
-                    pi = createProcessInstance(self, pd_name)
+                    pi = createProcessInstance(cwf, pd_name)
                 except KeyError:
                     # No registered PD with that name..
                     continue
                 pi_container[pd_name] = pi
+        
 
+class ContentWorkflowsManager(Persistent, Contained):
 
+    implements(IContentWorkflowsManager)
 
-    def subscribe(self):
-        """See interfaces.workflows.stateful.IContentWorkflowsManager"""
-        if self.currentlySubscribed:
-            raise ValueError, "already subscribed; please unsubscribe first"
-        channel = self._getChannel(None)
-        channel.subscribe(self, IObjectCreatedEvent)
-        self.currentlySubscribed = True
+    def __init__(self):
+        super(ContentWorkflowsManager, self).__init__()
+        self._registry = PersistentDict()
 
-    def unsubscribe(self):
-        """See interfaces.workflows.stateful.IContentWorkflowsManager"""
-        if not self.currentlySubscribed:
-            raise ValueError, "not subscribed; please subscribe first"
-        channel = self._getChannel(None)
-        channel.unsubscribe(self, IObjectCreatedEvent)
-        self.currentlySubscribed = False
-
-    def isSubscribed(self):
-        """See interfaces.workflows.stateful.IContentWorkflowsManager"""
-        return self.currentlySubscribed
-
-    def _getChannel(self, channel):
-        if channel is None:
-            channel = zapi.getService(self, EventSubscription)
-        return channel
-
     def getProcessDefinitionNamesForObject(self, object):
         """See interfaces.workflows.stateful.IContentWorkflowsManager"""
         names = ()
@@ -109,6 +85,17 @@
             names += self.getProcessNamesForInterface(iface)
         return names
 
+    def getProcessNamesForInterface(self, iface):
+        """See zope.app.workflow.interfacess.stateful.IContentProcessRegistry"""
+        return self._registry.get(iface, ())
+
+    def getInterfacesForProcessName(self, name):
+        ifaces = []
+        for iface, names in self._registry.items():
+            if name in names:
+                ifaces.append(iface)
+        return tuple(ifaces)
+
     def register(self, iface, name):
         """See zope.app.workflow.interfacess.stateful.IContentProcessRegistry"""
         if iface not in self._registry.keys():
@@ -123,14 +110,3 @@
             del self._registry[iface]
         else:
             self._registry[iface] = tuple(names)
-
-    def getProcessNamesForInterface(self, iface):
-        """See zope.app.workflow.interfacess.stateful.IContentProcessRegistry"""
-        return self._registry.get(iface, ())
-
-    def getInterfacesForProcessName(self, name):
-        ifaces = []
-        for iface, names in self._registry.items():
-            if name in names:
-                ifaces.append(iface)
-        return tuple(ifaces)

Modified: Zope3/trunk/src/zope/app/workflow/stateful/interfaces.py
===================================================================
--- Zope3/trunk/src/zope/app/workflow/stateful/interfaces.py	2004-05-23 14:13:30 UTC (rev 24905)
+++ Zope3/trunk/src/zope/app/workflow/stateful/interfaces.py	2004-05-23 16:21:33 UTC (rev 24906)
@@ -246,15 +246,6 @@
     It associates content objects with some workflow process definitions.
     """
 
-    def subscribe():
-        """Subscribe to the prevailing object hub service."""
-
-    def unsubscribe():
-        """Unsubscribe from the object hub service."""
-
-    def isSubscribed():
-        """Return whether we are currently subscribed."""
-
     def getProcessDefinitionNamesForObject(object):
         """Get the process definition names for a particular object.
 

Modified: Zope3/trunk/src/zope/app/workflow/stateful/tests/test_contentworkflow.py
===================================================================
--- Zope3/trunk/src/zope/app/workflow/stateful/tests/test_contentworkflow.py	2004-05-23 14:13:30 UTC (rev 24905)
+++ Zope3/trunk/src/zope/app/workflow/stateful/tests/test_contentworkflow.py	2004-05-23 16:21:33 UTC (rev 24906)
@@ -27,9 +27,7 @@
 from zope.app.event.tests.placelesssetup import eventPublisher, EventRecorder
 from zope.app.event.tests.placelesssetup import clearEvents
 from zope.app.annotation.interfaces import IAnnotatable, IAttributeAnnotatable
-from zope.app.event.interfaces import IObjectCreatedEvent, ISubscriptionService
-from zope.app.event.localservice import EventService
-from zope.app.servicenames import EventSubscription
+from zope.app.event.interfaces import IObjectCreatedEvent, ISubscriber
 from zope.app.utility import UtilityRegistration
 from zope.app.utility.interfaces import ILocalUtility
 from zope.app.registration.interfaces import ActiveStatus
@@ -40,6 +38,8 @@
 from zope.app.workflow.stateful.interfaces import IContentWorkflowsManager
 from zope.app.workflow.instance import ProcessInstanceContainerAdapter
 from zope.app.workflow.stateful.contentworkflow import ContentWorkflowsManager
+from zope.app.workflow.stateful.contentworkflow \
+     import NewObjectProcessInstanceCreator
 from zope.app.workflow.tests.workflowsetup import WorkflowSetup
 
 from zope.app.tests import ztapi, setup
@@ -89,12 +89,6 @@
 
     def setUp(self):
         WorkflowSetup.setUp(self)
-        sm = zapi.getGlobalServices()
-        sm.defineService(EventSubscription, ISubscriptionService)
-        self.events = EventService()
-        setup.addService(self.sm, EventSubscription, self.events)
-        clearEvents()
-        eventPublisher.globalSubscribe(EventRecorder)
         ztapi.provideAdapter(IAnnotatable, IProcessInstanceContainer,
                              ProcessInstanceContainerAdapter)
 
@@ -107,32 +101,6 @@
         self.default['manager'] = manager
         return zapi.traverse(self.default, 'manager')
 
-    def test_subscribe(self):
-        manager = self.getManager()
-        self.assertEqual(manager.currentlySubscribed, False)
-        manager.subscribe()
-        self.assertEqual(manager.currentlySubscribed, True)
-        self.assertEqual(self.events._registry._reg.keys()[0],
-                         IObjectCreatedEvent)
-        self.assertEqual(self.events._registry._reg.values()[0][0][0],
-                         u'/++etc++site/default/manager')
-
-    def test_unsubscribe(self):
-        manager = self.getManager()
-        self.assertEqual(manager.currentlySubscribed, False)
-        manager.subscribe()
-        manager.unsubscribe()
-        self.assertEqual(manager.currentlySubscribed, False)
-        self.assertEqual(len(self.events._registry._reg.values()), 0)
-
-    def test_isSubscribed(self):
-        manager = self.getManager()
-        self.assertEqual(manager.isSubscribed(), False)
-        manager.subscribe()
-        self.assertEqual(manager.isSubscribed(), True)
-        manager.unsubscribe()
-        self.assertEqual(manager.isSubscribed(), False)
-
     def test_getProcessDefinitionNamesForObject(self):
         manager = self.getManager()
         self.assertEqual(
@@ -179,25 +147,22 @@
 
     def test_notify(self):
         # setup ProcessDefinitions
-        self.default['pd1'] = DummyProcessDefinition(1)
-        self.default['pd2'] = DummyProcessDefinition(2)
 
-        id = self.cm.addRegistration(
-            UtilityRegistration('definition1', IProcessDefinition,
-                                '/++etc++site/default/pd1'))
-        zapi.traverse(self.default.getRegistrationManager(),
-                      id).status = ActiveStatus
-        id = self.cm.addRegistration(
-            UtilityRegistration('definition2', IProcessDefinition,
-                                '/++etc++site/default/pd2'))
-        zapi.traverse(self.default.getRegistrationManager(),
-                      id).status = ActiveStatus
+        setup.addUtility(self.sm, 'definition1', IProcessDefinition,
+                         DummyProcessDefinition(1))
+        setup.addUtility(self.sm, 'definition2', IProcessDefinition,
+                         DummyProcessDefinition(2))
+
         manager = self.getManager()
         manager._registry = {IFace1: ('definition1',),
                              IFace2: ('definition1', 'definition2')}
+        setup.addUtility(self.sm, '', IContentWorkflowsManager,
+                         manager)
 
         obj = TestObject2()
-        manager.notify(ObjectCreatedEvent(obj))
+        event = ObjectCreatedEvent(obj)
+        subscriber = NewObjectProcessInstanceCreator(obj, event)
+        subscriber.notify(event)
         pi = obj.__annotations__['zope.app.worfklow.ProcessInstanceContainer']
         self.assertEqual(pi.keys(), ['definition2', 'definition1'])
 




More information about the Zope3-Checkins mailing list