[Zope3-checkins] CVS: Packages3/workflow/stateful - definition.py:1.8 instance.py:1.12 xmlimportexport.py:1.6
Ulrich Eck
ueck@net-labs.de
Fri, 28 Mar 2003 13:17:08 -0500
Update of /cvs-repository/Packages3/workflow/stateful
In directory cvs.zope.org:/tmp/cvs-serv4403/stateful
Modified Files:
definition.py instance.py xmlimportexport.py
Log Message:
added script support for Transitions (condition and script need to evaluate
to True that the transition can be fired)
cleaned up some parts of the import/export (unittests will follow next week)
added unittest for transition-script-support
=== Packages3/workflow/stateful/definition.py 1.7 => 1.8 ===
--- Packages3/workflow/stateful/definition.py:1.7 Thu Mar 27 11:26:13 2003
+++ Packages3/workflow/stateful/definition.py Fri Mar 28 13:16:37 2003
@@ -57,11 +57,12 @@
__implements__ = ITransition
def __init__(self, source=None, destination=None, condition=None,
- permission=None, triggerMode=None):
+ script=None, permission=None, triggerMode=None):
super(Transition, self).__init__()
self.__source = source
self.__destination = destination
self.__condition = condition or None
+ self.__script = script or None
self.__permission = permission or None
self.__triggerMode = triggerMode
@@ -84,6 +85,12 @@
def setCondition(self, condition):
self.__condition = condition or None
+ def getScript(self):
+ return self.__script
+
+ def setScript(self, script):
+ self.__script = script or None
+
def getPermission(self):
return self.__permission
@@ -105,6 +112,9 @@
condition = property(getCondition, setCondition, None,
"Condition for Transition.")
+
+ script = property(getScript, setScript, None,
+ "Script for Transition.")
permission = property(getPermission, setPermission, None,
"Permission for Transition.")
=== Packages3/workflow/stateful/instance.py 1.11 => 1.12 ===
--- Packages3/workflow/stateful/instance.py:1.11 Thu Mar 27 10:12:40 2003
+++ Packages3/workflow/stateful/instance.py Fri Mar 28 13:16:37 2003
@@ -29,7 +29,7 @@
from zope.component import getServiceManager
from zope.proxy.introspection import removeAllProxies
-from zope.proxy.context import ContextMethod
+from zope.proxy.context import ContextMethod, getWrapperContainer
from zope.proxy.context import ContextWrapper,ContextAware
from zope.security.management import getSecurityManager
@@ -103,6 +103,7 @@
return self._outgoingTransitions(clean_pd)
getOutgoingTransitions = ContextMethod(getOutgoingTransitions)
+
def fireTransition(self, id):
pd = self._getProcessDefinition()
clean_pd = removeAllProxies(pd)
@@ -127,28 +128,44 @@
_getProcessDefinition = ContextMethod(_getProcessDefinition)
-
- def _getContext(self, transition):
+ def _getContext(self):
ctx = {}
# data should be readonly for condition-evaluation
ctx['data'] = self.data
ctx['principal'] = getSecurityManager().getPrincipal()
+ ctx['content'] = getWrapperContainer(self)
+ return ctx
+ _getContext = ContextMethod(_getContext)
+
+
+ def _extendContext(self, transition, ctx={}):
ctx['state_change'] = StateChangeInfo(transition)
return ctx
- def _evaluateCondition(self, transition):
+
+ def _evaluateCondition(self, transition, contexts):
"""Evaluate a condition in context of relevant-data.
"""
if not transition.condition:
return True
expr = Engine.compile(transition.condition)
- return expr(Engine.getContext( contexts=self._getContext(transition) ))
+ return expr(Engine.getContext( contexts=contexts ))
+
+
+ def _evaluateScript(self, transition, contexts):
+ script = transition.script
+ if not script:
+ return True
+ if type(script) in StringTypes:
+ sm = getServiceManager(self)
+ script = sm.resolve(script)
+ return script(contexts)
+ _evaluateScript = ContextMethod(_evaluateScript)
def _buildRelevantData(self, schema):
"""Create a new data object and initialize with Schema defaults.
"""
-
data = RelevantData()
data.__implements__ = schema
if schema is not None:
@@ -160,6 +177,8 @@
def _outgoingTransitions(self, clean_pd):
sm = getSecurityManager()
ret = []
+ contexts = self._getContext()
+
for name, trans in clean_pd.transitions.items():
if self.status == trans.sourceState:
# check permissions
@@ -169,25 +188,36 @@
and not sm.checkPermission(permission, self)
):
continue
-
+
+ ctx = self._extendContext(trans, contexts)
# evaluate conditions
if trans.condition is not None:
try:
- include = self._evaluateCondition(trans)
+ include = self._evaluateCondition(trans, ctx)
+ except Unauthorized:
+ include = 0
+ if not include:
+ continue
+
+ if trans.script is not None:
+ try:
+ include = self._evaluateScript(trans, ctx)
except Unauthorized:
include = 0
if not include:
continue
-
+
# append transition name
ret.append(name)
return ret
+ _outgoingTransitions = ContextMethod(_outgoingTransitions)
def _checkAndFireAuto(self, clean_pd):
outgoing_transitions = self.getOutgoingTransitions()
for name in outgoing_transitions:
trans = clean_pd.transitions[name]
+ # XXX Use Constants instead of strings
if trans.triggerMode == 'Automatic':
self.fireTransition(name)
return
=== Packages3/workflow/stateful/xmlimportexport.py 1.5 => 1.6 ===
--- Packages3/workflow/stateful/xmlimportexport.py:1.5 Thu Mar 27 11:26:13 2003
+++ Packages3/workflow/stateful/xmlimportexport.py Fri Mar 28 13:16:37 2003
@@ -33,8 +33,9 @@
from zope.app.workflow.stateful.definition import State, Transition
class XMLStatefulImporter(ContentHandler):
- def __init__(self, context):
+ def __init__(self, context, encoding='latin-1'):
self.context = context
+ self.encoding = encoding
def startElement(self, name, attrs):
handler = getattr(self, 'start' + name.title().replace('-', ''), None)
@@ -55,40 +56,38 @@
startTransitions = noop
def startWorkflow(self, attrs):
- title = attrs['title'].encode('latin-1')
- getAdapter(self.context, IZopeDublinCore).setQualifiedTitles([('',title)])
+ dc = getAdapter(self.context, IZopeDublinCore)
+ dc.title = attrs.get('title', u'')
def startSchema(self, attrs):
- name = attrs['name'].encode('latin-1')
+ name = attrs['name'].encode(self.encoding)
self.context.setRelevantDataSchema(name)
def startState(self, attrs):
- title = attrs.get('title', '').encode('latin-1')
- name = attrs['name'].encode('latin-1')
+ encoding = self.encoding
+ name = attrs['name'].encode(encoding)
if name == 'INITIAL':
state = self.context.getState('INITIAL')
- getAdapter(state, IZopeDublinCore).setQualifiedTitles([('',title)])
+ dc = getAdapter(state, IZopeDublinCore)
+ dc.title = attrs.get('title', u'')
else:
state = State()
- getAdapter(state, IZopeDublinCore).setQualifiedTitles([('',title)])
+ dc = getAdapter(state, IZopeDublinCore)
+ dc.title = attrs.get('title', u'')
self.context.addState(name, state)
def startTransition(self, attrs):
- title = attrs.get('title', '').encode('latin-1')
- source = attrs['sourceState'].encode('latin-1')
- dest = attrs['destinationState'].encode('latin-1')
- condi = attrs.get('condition', '').encode('latin-1')
- permi = attrs.get('permission', '').encode('latin-1')
- triggM = attrs['triggerMode'].encode('latin-1')
- name = attrs['name'].encode('latin-1')
- trans = Transition(source = source,
- destination = dest,
- condition = condi,
- permission = permi,
- triggerMode = triggM)
- getAdapter(trans, IZopeDublinCore).setQualifiedTitles([('',title)])
+ encoding = self.encoding
+ name = attrs['name'].encode(encoding)
+ 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),
+ triggerMode = attrs['triggerMode'].encode(encoding))
+ dc = getAdapter(trans, IZopeDublinCore)
+ dc.title = attrs.get('title', u'')
self.context.addTransition(name, trans)
-
@@ -100,6 +99,7 @@
return True
def doImport(self, context, data):
+ # XXX Manually clean ProcessDefinition ??
context.clear()
if not hasattr(data, "read"):
data = StringIO(data)
@@ -124,13 +124,4 @@
def getDublinCore(self, obj):
return getAdapter(obj, IZopeDublinCore)
-
-# not working, schema-class should be in an filesystem based module
-# which gets imported separately
-## def getSchemaClass(self):
-## schema = self.process_definition.getRelevantDataSchema()
-## if type(schema) in StringTypes:
-## sm = getServiceManager(self.context)
-## schema = sm.resolve(schema)
-## return schema