[CMF-checkins] CVS: CMF - DCWorkflow.py:1.4 Expression.py:1.3
shane@digicool.com
shane@digicool.com
Tue, 12 Jun 2001 22:06:21 -0400 (EDT)
Update of /cvs-repository/CMF/DCWorkflow
In directory korak.digicool.com:/tmp/cvs-serv3181
Modified Files:
DCWorkflow.py Expression.py
Log Message:
- Role mappings were being updated before the state changed. Fixed.
- DCWorkflow is now aware of ObjectDeleted and ObjectMoved messages.
- getObjectContainer() added to expressions.
- What is passed to scripts is now an object whose attributes are from
the expression namespace.
--- Updated File DCWorkflow.py in package CMF --
--- DCWorkflow.py 2001/06/11 20:36:35 1.3
+++ DCWorkflow.py 2001/06/13 02:06:20 1.4
@@ -105,7 +105,8 @@
from DocumentTemplate.DT_Util import TemplateDict
# CMFCore
-from Products.CMFCore.WorkflowCore import WorkflowException
+from Products.CMFCore.WorkflowCore import WorkflowException, \
+ ObjectDeleted, ObjectMoved
from Products.CMFCore.WorkflowTool import addWorkflowFactory
from Products.CMFCore.CMFCorePermissions import ManagePortal
from Products.CMFCore.utils import getToolByName
@@ -125,7 +126,19 @@
raise ValueError, 'Illegal ID'
return 1
+class NamespaceAccessor:
+ __allow_access_to_unprotected_subobjects__ = 1
+ def __init__(self, md):
+ self._getitem = md.getitem
+ def __getattr__(self, name):
+ try:
+ return self._getitem(name, 0)
+ except KeyError:
+ raise AttributeError, name
+ def __getitem__(self, name):
+ return self._getitem(name, 0)
+
class DCWorkflowDefinition (WorkflowUIMixin, Folder):
'''
This class is the workflow engine and the container for the
@@ -378,7 +391,15 @@
if not self._checkTransitionGuard(tdef, ob):
raise Unauthorized
res = apply(func, args, kw)
- self._changeStateOf(ob, tdef)
+ try:
+ self._changeStateOf(ob, tdef)
+ except ObjectDeleted:
+ # Re-raise with a different result.
+ raise ObjectDeleted(res)
+ except ObjectMoved, ex:
+ # Re-raise with a different result.
+ raise ObjectMoved(ex.getNewObject(), res)
+ return res
security.declarePrivate('isInfoSupported')
def isInfoSupported(self, ob, name):
@@ -423,7 +444,11 @@
Notifies this workflow after an object has been created
and put in its new place.
'''
- self._changeStateOf(ob, None)
+ try:
+ self._changeStateOf(ob, None)
+ except ObjectDeleted, ObjectMoved:
+ # Swallow.
+ pass
security.declarePrivate('notifyBefore')
def notifyBefore(self, ob, action):
@@ -501,6 +526,7 @@
Private method.
Puts object in a new state.
'''
+ moved = 0
if tdef is None:
state = self.initial_state
former_status = {}
@@ -518,7 +544,12 @@
# Pass lots of info to the script in a single parameter.
md = exprNamespace(ob, self, former_status,
action, state, kwargs)
- script(md) # May throw an exception.
+ accessor = NamespaceAccessor(md)
+ try:
+ script(accessor) # May throw an exception.
+ except ObjectMoved, ex:
+ ob = ex.getNewObject()
+ moved = 1
sdef = self.states.get(state, None)
if sdef is None:
raise WorkflowException, 'Destination state undefined: ' + state
@@ -547,12 +578,16 @@
status[id] = value
# Update state.
status[self.state_var] = state
+ tool = aq_parent(aq_inner(self))
+ tool.setStatusOf(self.id, ob, status)
# Update role to permission assignments.
self.updateRoleMappingsFor(ob)
- tool = aq_parent(aq_inner(self))
- tool.setStatusOf(self.id, ob, status)
- return sdef
+ if moved:
+ # Re-raise.
+ raise ObjectMoved(ob)
+ else:
+ return sdef
Globals.InitializeClass(DCWorkflowDefinition)
--- Updated File Expression.py in package CMF --
--- Expression.py 2001/06/11 20:18:14 1.2
+++ Expression.py 2001/06/13 02:06:20 1.3
@@ -94,6 +94,8 @@
from AccessControl import getSecurityManager, ClassSecurityInfo
from DocumentTemplate.DT_Util import TemplateDict, InstanceDict, Eval
+from Products.CMFCore.WorkflowCore import ObjectDeleted, ObjectMoved
+
try:
# Zope 2.3.x
from DocumentTemplate.DT_Util import expr_globals
@@ -175,6 +177,8 @@
'''
Provides names that are more expensive to compute.
'''
+ ObjectDeleted = ObjectDeleted
+ ObjectMoved = ObjectMoved
def __init__(self, ob, wf):
self._ob = ob
@@ -200,3 +204,6 @@
while ob is not None and not getattr(ob, '_isPortalRoot', 0):
ob = aq_parent(aq_inner(ob))
return ob
+
+ def getObjectContainer(self):
+ return aq_parent(aq_inner(self._ob))