[Zope3-checkins] CVS: Packages3/workflow/stateful - instance.py:1.14 xmlimportexport.py:1.9 exportimport.py:NONE

Ulrich Eck ueck@net-labs.de
Thu, 8 May 2003 12:03:49 -0400


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

Modified Files:
	instance.py xmlimportexport.py 
Removed Files:
	exportimport.py 
Log Message:
last steps before merging workflow-package into zope3-head



=== Packages3/workflow/stateful/instance.py 1.13 => 1.14 ===
--- Packages3/workflow/stateful/instance.py:1.13	Thu May  1 11:47:35 2003
+++ Packages3/workflow/stateful/instance.py	Thu May  8 12:03:18 2003
@@ -11,9 +11,7 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-"""Content Workflows Utility
-
-Associates content objects with some workflow process definitions.
+"""Stateful Process Instance
 
 $Id$
 """
@@ -22,6 +20,7 @@
 from types import StringTypes
 from persistence import Persistent
 from zope.schema import getFields
+from zope.interface import directlyProvides
 
 from zope.exceptions import Unauthorized
 
@@ -34,6 +33,13 @@
 
 from zope.security.management import getSecurityManager
 from zope.security.checker import CheckerPublic
+
+# XXX Needed for WfrData Permission checking
+# commented out for now
+#from zope.security.checker import CheckerPublic, selectChecker
+#from zope.security.checker import Checker
+#from zope.security.proxy import getChecker, Proxy
+
 from zope.app.security.permission import checkPermission
 
 from zope.tales.engine import Engine
@@ -41,9 +47,37 @@
 from zope.app.interfaces.workflow.stateful import IStatefulProcessInstance
 from zope.app.workflow.instance import ProcessInstance
 
+
+
 class RelevantData(ContextAware):
     pass
 
+# XXX Example of how Changes to Workflow Relevant Data would send out Events
+# ToDo:
+# - Define Events:
+#    RelevantDataChangingWorkflowEvent
+#    RelevantDataChangedWorkflowEvent
+#
+# - all this is untested !!!!
+#
+#class RelevantData:
+#
+#    def __setattr__(self, key, value):
+#        is_schema_field = bool(key in getFields(self.__implements__).keys())
+#        if is_schema_field:
+#            # Send an Event bevor RelevantData changes
+#            oldvalue = getattr(self, key, None)
+#            print "send RelevantDataChangingWorkflowEvent(key:%s, old:%s, new:%s) here" \
+#                  % (key, oldvalue, value)
+#
+#        super(RelevantData, self).__setattr__(key, value)
+#
+#        if is_schema_field:
+#            # Send an Event after RelevantData has changed
+#            print "send RelevantDataChangedWorkflowEvent(key:%s, old:%s, new:%s) here" \
+#                  % (key, oldvalue, value)
+
+
 
 
 class StateChangeInfo:
@@ -72,8 +106,35 @@
     # zope.app.interfaces.workflow.IStatefulProcessInstance
 
 
+
     data = property(lambda self: ContextWrapper(self._data, self))
     
+    # XXX this is not entirely tested nor finished
+    #def _getData(self):
+    #    """getter for Workflow Relevant Data."""
+    #    
+    #    data = self._data
+    #    if data is None:
+    #        return
+    #    
+    #    schema = data.__implements__
+    #
+    #    # XXX permissions need to be manageable TTW
+    #    # is this too much overhead ????
+    #    checker_getattr = {}
+    #    checker_setattr = {}
+    #    for name in schema.names(all=True):
+    #        
+    #        # XXX Just a dummy implementation for now
+    #        checker_getattr[name] = CheckerPublic
+    #        checker_setattr[name] = CheckerPublic
+    #        
+    #    checker = Checker(checker_getattr.get, checker_setattr.get)
+    #    return Proxy(data, checker)
+    #
+    #data = property(lambda self: ContextWrapper(self._getData(), self))
+
+    
     def initialize(self):
         pd = self._getProcessDefinition()
         clean_pd = removeAllProxies(pd)
@@ -111,7 +172,20 @@
             raise KeyError, 'Invalid Transition Id: %s' % id
         trans = clean_pd.transitions[id]
         # modify relevant-data if needed
+
+        # XXX Implement EventHandling in BaseClass as property ???
+        # send StatusChangingWorkflowEvent
+        #print "send StatusChangingWorkflowEvent(old:%s, new:%s) here" \
+        #      % (self._status, trans.destinationState)
+        
+        # change status
         self._status = trans.destinationState
+
+        # send StatusChangedWorkflowEvent
+        #print "send StatusChangedWorkflowEvent(old:%s, new:%s) here" \
+        #      % (trans.sourceState, self._status)
+
+
         # check for automatic transitions
         self._checkAndFireAuto(clean_pd)
     fireTransition = ContextMethod(fireTransition)
@@ -119,7 +193,7 @@
     #
     ############################################################
     
-    # XXX expose this method in the interface (without _)
+    # XXX expose this method in the interface (without _) ???
     def _getProcessDefinition(self):
         """Get the ProcessDefinition object from WorkflowService.
         """
@@ -128,13 +202,38 @@
     _getProcessDefinition = ContextMethod(_getProcessDefinition)
 
 
+
+    # XXX this is not entirely tested
     def _getContext(self):
         ctx = {}
         # data should be readonly for condition-evaluation
         ctx['data'] = self.data
         ctx['principal'] = getSecurityManager().getPrincipal()
-        ctx['content'] = getWrapperContainer(self)
+
+        # XXX This needs to be discussed:
+        # how can we know if this ProcessInstance is annotated
+        # to a Content-Object and provide secure ***READONLY***
+        # Access to it for evaluating Transition Conditions ???
+        
+        #content = getWrapperContainer(self)
+
+        # XXX How can i make shure that nobody modifies content
+        # while the condition scripts/conditions are evaluated ????
+        # this hack only prevents from directly setting an attribute
+        # using a setter-method directly is not protected :((
+        #try:
+        #    checker = getChecker(content)
+        #    checker._setattr_permission_func = lambda x: None
+        #except TypeError:
+        #    # got object without Security Proxy
+        #    checker = selectChecker(content)
+        #    checker._setattr_permission_func = lambda x: None
+        #    content = Proxy(content, checker)
+
+        #ctx['content'] = content
+        
         return ctx
+
     _getContext = ContextMethod(_getContext)
 
 
@@ -167,8 +266,9 @@
         """Create a new data object and initialize with Schema defaults.
         """
         data = RelevantData()
-        data.__implements__ = schema
         if schema is not None:
+            # set schema to RelevantData Instance
+            directlyProvides(data, schema)
             for name, field in getFields(schema).items():
                 setattr(data, name, field.default)
         return data
@@ -183,8 +283,9 @@
             if self.status == trans.sourceState:
                 # check permissions
                 permission = trans.permission
+                # 
                 if (permission is not None
-                    and permission != 'zope.Public'
+                    and permission is not CheckerPublic
                     and not sm.checkPermission(permission, self)
                     ):
                     continue


=== Packages3/workflow/stateful/xmlimportexport.py 1.8 => 1.9 ===
--- Packages3/workflow/stateful/xmlimportexport.py:1.8	Wed Apr  9 14:35:30 2003
+++ Packages3/workflow/stateful/xmlimportexport.py	Thu May  8 12:03:18 2003
@@ -105,11 +105,14 @@
     def startTransition(self, attrs):
         encoding = self.encoding
         name   = attrs['name'].encode(encoding)
+        permission = attrs.get('permission', '').encode(encoding)
+        if permission == 'zope.Public':
+            permission = CheckerPublic
         trans = Transition(source = attrs['sourceState'].encode(encoding),
                            destination = attrs['destinationState'].encode(encoding),
                            condition = attrs.get('condition', '').encode(encoding),
                            script = attrs.get('script', '').encode(encoding),
-                           permission = attrs.get('permission', '').encode(encoding),
+                           permission = permission,
                            triggerMode = attrs['triggerMode'].encode(encoding))
         dc = getAdapter(trans, IZopeDublinCore)
         dc.title = attrs.get('title', u'')

=== Removed File Packages3/workflow/stateful/exportimport.py ===