appy.gen: workflows are now implemented as full Appy worlflows. Plone (DC) workflow are not generated anymore. From the Appy user point of view (=developer), no change has occurred: it is a pure implementation concern. This is one more step towards Appy independence from Plone.

This commit is contained in:
Gaetan Delannay 2011-07-26 22:15:04 +02:00
parent 93eb16670b
commit ddec7cd62c
14 changed files with 378 additions and 806 deletions

View file

@ -89,141 +89,9 @@ class ClassDescriptor(Descriptor):
class WorkflowDescriptor(Descriptor):
'''This class gives information about an Appy workflow.'''
def _getWorkflowElements(self, elemType):
res = []
for attrName in dir(self.klass):
attrValue = getattr(self.klass, attrName)
condition = False
if elemType == 'states':
condition = isinstance(attrValue, State)
elif elemType == 'transitions':
condition = isinstance(attrValue, Transition)
elif elemType == 'all':
condition = isinstance(attrValue, State) or \
isinstance(attrValue, Transition)
if condition:
res.append(attrValue)
return res
def getStates(self):
return self._getWorkflowElements('states')
def getTransitions(self):
return self._getWorkflowElements('transitions')
def getStateNames(self, ordered=False):
res = []
attrs = dir(self.klass)
allAttrs = attrs
if ordered:
attrs = self.orderedAttributes
allAttrs = dir(self.klass)
for attrName in attrs:
attrValue = getattr(self.klass, attrName)
if isinstance(attrValue, State):
res.append(attrName)
# Complete the list with inherited states. For the moment, we are unable
# to sort inherited states.
for attrName in allAttrs:
attrValue = getattr(self.klass, attrName)
if isinstance(attrValue, State) and (attrName not in attrs):
res.insert(0, attrName)
return res
def getInitialStateName(self):
res = None
for attrName in dir(self.klass):
attrValue = getattr(self.klass, attrName)
if isinstance(attrValue, State) and attrValue.initial:
res = attrName
break
return res
def getTransitionNamesOf(self, transitionName, transition,
limitToFromState=None):
'''Appy p_transition may correspond to several transitions of the
concrete workflow engine used. This method returns in a list the
name(s) of the "concrete" transition(s) corresponding to
p_transition.'''
res = []
if transition.isSingle():
res.append(transitionName)
else:
for fromState, toState in transition.states:
if not limitToFromState or \
(limitToFromState and (fromState == limitToFromState)):
fromStateName = self.getNameOf(fromState)
toStateName = self.getNameOf(toState)
res.append('%s%s%sTo%s%s' % (transitionName,
fromStateName[0].upper(), fromStateName[1:],
toStateName[0].upper(), toStateName[1:]))
return res
def getTransitionNames(self, limitToTransitions=None, limitToFromState=None,
withLabels=False):
'''Returns the name of all "concrete" transitions corresponding to the
Appy transitions of this worlflow. If p_limitToTransitions is not
None, it represents a list of Appy transitions and the result is a
list of the names of the "concrete" transitions that correspond to
those transitions only. If p_limitToFromState is not None, it
represents an Appy state; only transitions having this state as start
state will be taken into account. If p_withLabels is True, the method
returns a list of tuples (s_transitionName, s_transitionLabel); the
label being the name of the Appy transition.'''
res = []
for attrName in dir(self.klass):
attrValue = getattr(self.klass, attrName)
if isinstance(attrValue, Transition):
# We encountered a transition.
t = attrValue
tName = attrName
if not limitToTransitions or \
(limitToTransitions and t in limitToTransitions):
# We must take this transition into account according to
# param "limitToTransitions".
if (not limitToFromState) or \
(limitToFromState and \
t.hasState(limitToFromState, isFrom=True)):
# We must take this transition into account according
# to param "limitToFromState"
tNames = self.getTransitionNamesOf(
tName, t, limitToFromState)
if not withLabels:
res += tNames
else:
for tn in tNames:
res.append((tn, tName))
return res
def getEndStateName(self, transitionName):
'''Returns the name of the state where the "concrete" transition named
p_transitionName ends.'''
res = None
for attrName in dir(self.klass):
attrValue = getattr(self.klass, attrName)
if isinstance(attrValue, Transition):
# We got a transition.
t = attrValue
tName = attrName
if t.isSingle():
if transitionName == tName:
endState = t.states[1]
res = self.getNameOf(endState)
else:
transNames = self.getTransitionNamesOf(tName, t)
if transitionName in transNames:
endState = t.states[transNames.index(transitionName)][1]
res = self.getNameOf(endState)
return res
def getNameOf(self, stateOrTransition):
'''Gets the Appy name of a p_stateOrTransition.'''
res = None
for attrName in dir(self.klass):
attrValue = getattr(self.klass, attrName)
if attrValue == stateOrTransition:
res = attrName
break
return res
@staticmethod
def getWorkflowName(klass):
'''Returns the name of this workflow.'''
res = klass.__module__.replace('.', '_') + '_' + klass.__name__
return res.lower()
# ------------------------------------------------------------------------------