[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