[Zope-CVS] CVS: Packages3/workflow/stateful - configure.zcml:1.4 contentworkflow.py:1.2 instance.py:1.5

Ulrich Eck ueck@net-labs.de
Fri, 7 Feb 2003 16:51:23 -0500


Update of /cvs-repository/Packages3/workflow/stateful
In directory cvs.zope.org:/tmp/cvs-serv15434/stateful

Modified Files:
	configure.zcml contentworkflow.py instance.py 
Log Message:
First usable state of Stateful Workflow :)
- Implemented ProcessInstanceContainer/Adapter + Views
- Implemented Dummy ContentWorkflowsUtility
- updated Readme
- fixed some bugs
 --> read the README for a small tutorial of what works


=== Packages3/workflow/stateful/configure.zcml 1.3 => 1.4 ===
--- Packages3/workflow/stateful/configure.zcml:1.3	Fri Feb  7 10:29:29 2003
+++ Packages3/workflow/stateful/configure.zcml	Fri Feb  7 16:50:52 2003
@@ -90,7 +90,7 @@
       />
 </content>
 
-<!-- ContentWorkflowsUtility
+<!-- ContentWorkflowsUtility -->
 
 <content class="zope.app.workflow.stateful.contentworkflow.ContentWorkflowsUtility">
   <require
@@ -98,11 +98,9 @@
     interface="zope.app.interfaces.workflow.stateful.IContentWorkflowsUtility"
     />
   <factory
-    id="zope.app.workflow.stateful.contentworkflow.ContentWorkflowsUtility"
+    id="ContentWorkflowsUtility"
     permission="zope.ManageServices"
     />
 </content>
-
--->
 
 </zopeConfigure>


=== Packages3/workflow/stateful/contentworkflow.py 1.1 => 1.2 ===
--- Packages3/workflow/stateful/contentworkflow.py:1.1	Tue Feb  4 16:42:18 2003
+++ Packages3/workflow/stateful/contentworkflow.py	Fri Feb  7 16:50:52 2003
@@ -24,14 +24,15 @@
 from zope.component import getService, queryAdapter
 from zope.component.exceptions import ComponentLookupError
 from zope.proxy.context import ContextMethod
+from zope.proxy.introspection import removeAllProxies
 
 from zope.app.interfaces.event import ISubscriber
-from zope.app.interfaces.services.hub import IRegistrationHubEvent
-from zope.app.interfaces.services.hub import IObjectRegisteredHubEvent
-from zope.app.interfaces.services.hub import IObjectUnregisteredHubEvent
+from zope.app.interfaces.event import IObjectCreatedEvent
+from zope.component.servicenames import Events, Workflows
 
 from zope.app.interfaces.workflow import IProcessInstanceContainer
-from zope.app.interfaces.workflow import IContentWorkflowsUtility
+from zope.app.interfaces.workflow import IProcessInstanceContainerAdaptable
+from zope.app.interfaces.workflow.stateful import IContentWorkflowsUtility
 
 
 
@@ -41,39 +42,45 @@
 
     def __init__(self):
         super(ContentWorkflowsUtility, self).__init__()
-        self._names = () # _names should be a TypeRegistry
+        self._names = ('default',) # _names should be a TypeRegistry
 
     # ISubscriber
 
     def notify(self, event):
         """An event occured. Perhaps register this object with the hub."""
-        pi_container = queryAdapter(event.object, IProcessInstanceContainer)
+        obj = event.object
+
+        # XXX Do i need to removeAllProxies somewhere in here ???
+        
+        # check if it implements IProcessInstanceContainerAdaptable
+        if not IProcessInstanceContainerAdaptable.isImplementedBy(obj):
+            return
+        
+        pi_container = queryAdapter(obj, IProcessInstanceContainer)
         # 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 IObjectRegisteredHubEvent.isImplementedBy(event):
-            wfs = getService(self, "Workflows")
+        
+        if IObjectCreatedEvent.isImplementedBy(event):
+            wfs = getService(self, Workflows)
 
             # 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._names:
+                
+                if pd_name in pi_container.keys():
+                    continue
                 try:
                     pi = wfs.createProcessInstance(pd_name)
+                    print "CREATED PROCESSINSTANCE:", str(pi)
                 except KeyError:
                     # No registered PD with that name..
                     continue
-                # XXX What happens if there's already a pi with that name?
-                container[pd_name] = pi
-        elif IObjectUnregisteredHubEvent.isImplementedBy(event):
-            for pd_name in self._names:
-                if pd_name in container:
-                    # give the pi a chanche to know that it's going
-                    # to be deleted ??
-                    del container[pd_name]
+                pi_container.setObject(pd_name, pi)
+                
     notify = ContextMethod(notify)
 
     # IContentWorkflowsUtility
@@ -86,7 +93,7 @@
         if self.currentlySubscribed:
             raise ValueError, "already subscribed; please unsubscribe first"
         channel = self._getChannel(None)
-        channel.subscribe(self, IRegistrationHubEvent)
+        channel.subscribe(self, IObjectCreatedEvent)
         self.currentlySubscribed = True
     subscribe = ContextMethod(subscribe)
 
@@ -94,7 +101,7 @@
         if not self.currentlySubscribed:
             raise ValueError, "not subscribed; please subscribe first"
         channel = self._getChannel(None)
-        channel.unsubscribe(self, IRegistrationHubEvent)
+        channel.unsubscribe(self, IObjectCreatedEvent)
         self.currentlySubscribed = False
     unsubscribe = ContextMethod(unsubscribe)
 
@@ -103,7 +110,7 @@
 
     def _getChannel(self, channel):
         if channel is None:
-            channel = getService(self, "ObjectHub")
+            channel = getService(self, Events)
         return channel
     _getChannel = ContextMethod(_getChannel)
 


=== Packages3/workflow/stateful/instance.py 1.4 => 1.5 ===
--- Packages3/workflow/stateful/instance.py:1.4	Fri Feb  7 10:29:30 2003
+++ Packages3/workflow/stateful/instance.py	Fri Feb  7 16:50:52 2003
@@ -28,6 +28,7 @@
 from zope.component import getService
 from zope.component import getServiceManager
 
+from zope.proxy.introspection import removeAllProxies
 from zope.proxy.context import ContextMethod
 from zope.proxy.context import ContextWrapper,ContextAware
 
@@ -40,6 +41,10 @@
 from zope.app.interfaces.workflow.stateful import IStatefulProcessInstance
 from zope.app.workflow.instance import ProcessInstance
 
+class RelevantData(ContextAware):
+    pass
+
+
 
 class StateChangeInfo:
     """Immutable StateChangeInfo.
@@ -71,10 +76,11 @@
     
     def initialize(self):
         pd = self._getProcessDefinition()
-        self._status = pd.getInitialStateName()
+        clean_pd = removeAllProxies(pd)
+        self._status = clean_pd.getInitialStateName()
 
         # resolve schema class 
-        schema = pd.getRelevantDataSchema()
+        schema = clean_pd.getRelevantDataSchema()
         if type(schema) in StringTypes:
             sm = getServiceManager(self)
             schema =  sm.resolve(schema)
@@ -89,20 +95,21 @@
     def getOutgoingTransitions(self):
         ret = []
         pd = self._getProcessDefinition()
+        clean_pd = removeAllProxies(pd)
         sm = getSecurityManager()
         
-        for name, trans in pd.transitions.items():
+        for name, trans in clean_pd.transitions.items():
             if self.status == trans.sourceState:
                 # check permissions
-                if trans.permission is not None:
-                    if trans.permission == 'zope.Public':
-                        permission = CheckerPublic
-                    else:
-                        permission = checkPermission(self, trans.permission)
+                #if trans.permission is not None:
+                    #if trans.permission == 'zope.Public':
+                    #    permission = CheckerPublic
+                    #else:
+                    #    permission = checkPermission(self, trans.permission)
                         
-                    print str(permission), trans.permission, name
-                    if not sm.checkPermission(permission, self):
-                        continue
+                    #if not sm.checkPermission(permission, self):
+                    #    continue
+                    
 
                 # evaluate conditions
                 if trans.condition is not None:
@@ -120,9 +127,10 @@
 
     def fireTransition(self, id):
         pd = self._getProcessDefinition()
+        clean_pd = removeAllProxies(pd)
         if not id in self.getOutgoingTransitions():
             raise KeyError, 'Invalid Transition Id: %s' % id
-        trans = pd.transitions[id]
+        trans = clean_pd.transitions[id]
         # modify relevant-data if needed
         self._status = trans.destinationState
     fireTransition = ContextMethod(fireTransition)
@@ -158,10 +166,9 @@
     def _buildRelevantData(self, schema):
         """Create a new data object and initialize with Schema defaults.
         """
-        class RelevantData(ContextAware):
-            __implements__ = schema
 
         data = RelevantData()
+        data.__implements__ = schema
         if schema is not None:
             for name, field in getFields(schema).items():
                 setattr(data, name, field.default)