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:
parent
93eb16670b
commit
ddec7cd62c
14 changed files with 378 additions and 806 deletions
|
@ -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()
|
||||
# ------------------------------------------------------------------------------
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue