--- a/schemas/workflow.py Thu Aug 20 17:33:05 2009 +0200
+++ b/schemas/workflow.py Thu Aug 20 17:44:27 2009 +0200
@@ -13,6 +13,29 @@
from cubicweb.schema import RQLConstraint
from cubicweb.schemas import META_ETYPE_PERMS, META_RTYPE_PERMS, HOOKS_RTYPE_PERMS
+class Workflow(EntityType):
+ permissions = META_ETYPE_PERMS
+
+ name = String(required=True, indexed=True, internationalizable=True,
+ maxsize=256)
+ description = RichString(fulltextindexed=True, default_format='text/rest',
+ description=_('semantic description of this workflow'))
+
+ workflow_of = SubjectRelation('CWEType', cardinality='+*',
+ description=_('entity types which may use this workflow'),
+ constraints=[RQLConstraint('O final FALSE')])
+
+ default_workflow_of = SubjectRelation('CWEType', cardinality='*?',
+ description=_('which entity types use this workflow by default'),
+ constraints=[RQLConstraint('O final FALSE')])
+
+ initial_state = SubjectRelation('State', cardinality='?*',
+ # S initial_state O, O state_of S
+ constraints=[RQLConstraint('O state_of S')],
+ description=_('initial state for this workflow'))
+
+# XXX ensure state/transition name is unique in a given workflow
+
class State(EntityType):
"""used to associate simple states to an entity type and/or to define
workflows
@@ -24,23 +47,17 @@
description = RichString(fulltextindexed=True, default_format='text/rest',
description=_('semantic description of this state'))
- state_of = SubjectRelation('CWEType', cardinality='+*',
- description=_('entity types which may use this state'),
- constraints=[RQLConstraint('O final FALSE')])
- allowed_transition = SubjectRelation('Transition', cardinality='**',
- constraints=[RQLConstraint('S state_of ET, O transition_of ET')],
+ state_of = SubjectRelation('Workflow', cardinality='+*',
+ description=_('workflow to which this state belongs'))
+ # XXX should be on BaseTransition w/ AND/OR selectors when we will
+ # implements #345274
+ allowed_transition = SubjectRelation('BaseTransition', cardinality='**',
+ constraints=[RQLConstraint('S state_of WF, O transition_of WF')],
description=_('allowed transitions from this state'))
- initial_state = ObjectRelation('CWEType', cardinality='?*',
- # S initial_state O, O state_of S
- constraints=[RQLConstraint('O state_of S')],
- description=_('initial state for entities of this type'))
-
-class Transition(EntityType):
- """use to define a transition from one or multiple states to a destination
- states in workflow's definitions.
- """
+class BaseTransition(EntityType):
+ """abstract base class for transitions"""
permissions = META_ETYPE_PERMS
name = String(required=True, indexed=True, internationalizable=True,
@@ -57,47 +74,107 @@
require_group = SubjectRelation('CWGroup', cardinality='**',
description=_('group in which a user should be to be '
'allowed to pass this transition'))
- transition_of = SubjectRelation('CWEType', cardinality='+*',
- description=_('entity types which may use this transition'),
- constraints=[RQLConstraint('O final FALSE')])
+ transition_of = SubjectRelation('Workflow', cardinality='+*',
+ description=_('workflow to which this transition belongs'))
+
+
+class Transition(BaseTransition):
+ """use to define a transition from one or multiple states to a destination
+ states in workflow's definitions.
+ """
+ __specializes_schema__ = True
+
destination_state = SubjectRelation('State', cardinality='1*',
- constraints=[RQLConstraint('S transition_of ET, O state_of ET')],
+ constraints=[RQLConstraint('S transition_of WF, O state_of WF')],
description=_('destination state for this transition'))
-class TrInfo(EntityType):
- permissions = META_ETYPE_PERMS
+class WorkflowTransition(BaseTransition):
+ """special transition allowing to go through a sub-workflow"""
+ __specializes_schema__ = True
+
+ subworkflow = SubjectRelation('Workflow', cardinality='1*',
+ constraints=[RQLConstraint('S transition_of WF, WF workflow_of ET, O workflow_of ET')])
+ subworkflow_exit = SubjectRelation('SubWorkflowExitPoint', cardinality='+1',
+ composite='subject')
+
+
+class SubWorkflowExitPoint(EntityType):
+ """define how we get out from a sub-workflow"""
+ subworkflow_state = SubjectRelation('State', cardinality='1*',
+ constraints=[RQLConstraint('T subworkflow_exit S, T subworkflow WF, O state_of WF')],
+ description=_('subworkflow state'))
+ destination_state = SubjectRelation('State', cardinality='1*',
+ constraints=[RQLConstraint('T subworkflow_exit S, T transition_of WF, O state_of WF')],
+ description=_('destination state'))
- from_state = SubjectRelation('State', cardinality='?*')
+
+# XXX should we allow managers to delete TrInfo?
+
+class TrInfo(EntityType):
+ """workflow history item"""
+ # 'add' security actually done by hooks
+ permissions = {
+ 'read': ('managers', 'users', 'guests',), # XXX U has_read_permission O ?
+ 'add': ('managers', 'users', 'guests',),
+ 'delete': (),
+ 'update': ('managers', 'owners',),
+ }
+
+ from_state = SubjectRelation('State', cardinality='1*')
to_state = SubjectRelation('State', cardinality='1*')
+ # make by_transition optional because we want to allow managers to set
+ # entity into an arbitrary state without having to respect wf transition
+ by_transition = SubjectRelation('Transition', cardinality='?*')
comment = RichString(fulltextindexed=True)
# get actor and date time using owned_by and creation_date
+class from_state(RelationType):
+ permissions = HOOKS_RTYPE_PERMS.copy()
+ inlined = True
-class from_state(RelationType):
- permissions = HOOKS_RTYPE_PERMS
+class to_state(RelationType):
+ permissions = {
+ 'read': ('managers', 'users', 'guests',),
+ 'add': ('managers',),
+ 'delete': (),
+ }
inlined = True
-class to_state(RelationType):
- permissions = HOOKS_RTYPE_PERMS
+
+class by_transition(RelationType):
+ # 'add' security actually done by hooks
+ permissions = {
+ 'read': ('managers', 'users', 'guests',),
+ 'add': ('managers', 'users', 'guests',),
+ 'delete': (),
+ }
inlined = True
-class wf_info_for(RelationType):
- """link a transition information to its object"""
- permissions = {
- 'read': ('managers', 'users', 'guests',),# RRQLExpression('U has_read_permission O')),
- 'add': (), # handled automatically, no one should add one explicitly
- 'delete': ('managers',), # RRQLExpression('U has_delete_permission O')
- }
- inlined = True
- composite = 'object'
- fulltext_container = composite
+class workflow_of(RelationType):
+ """link a workflow to one or more entity type"""
+ permissions = META_RTYPE_PERMS
class state_of(RelationType):
- """link a state to one or more entity type"""
+ """link a state to one or more workflow"""
permissions = META_RTYPE_PERMS
+
class transition_of(RelationType):
- """link a transition to one or more entity type"""
+ """link a transition to one or more workflow"""
+ permissions = META_RTYPE_PERMS
+
+class subworkflow(RelationType):
+ """link a transition to one or more workflow"""
permissions = META_RTYPE_PERMS
+ inlined = True
+
+class exit_point(RelationType):
+ """link a transition to one or more workflow"""
+ permissions = META_RTYPE_PERMS
+
+class subworkflow_state(RelationType):
+ """link a transition to one or more workflow"""
+ permissions = META_RTYPE_PERMS
+ inlined = True
class initial_state(RelationType):
"""indicate which state should be used by default when an entity using
@@ -115,16 +192,42 @@
"""allowed transition from this state"""
permissions = META_RTYPE_PERMS
+
+# "abstract" relations, set by WorkflowableEntityType ##########################
+
+class custom_workflow(RelationType):
+ """allow to set a specific workflow for an entity"""
+ permissions = META_RTYPE_PERMS
+
+ cardinality = '?*'
+ constraints = [RQLConstraint('S is ET, O workflow_of ET')]
+ object = 'Workflow'
+
+
+class wf_info_for(RelationType):
+ """link a transition information to its object"""
+ # 'add' security actually done by hooks
+ permissions = {
+ 'read': ('managers', 'users', 'guests',),
+ 'add': ('managers', 'users', 'guests',),
+ 'delete': (),
+ }
+ inlined = True
+
+ cardinality='1*'
+ composite = 'object'
+ fulltext_container = composite
+ subject = 'TrInfo'
+
+
class in_state(RelationType):
"""indicate the current state of an entity"""
+ permissions = HOOKS_RTYPE_PERMS
+
# not inlined intentionnaly since when using ldap sources, user'state
# has to be stored outside the CWUser table
inlined = False
- # add/delete perms given to managers/users, after what most of the job
- # is done by workflow enforcment
- permissions = {
- 'read': ('managers', 'users', 'guests',),
- 'add': ('managers', 'users',), # XXX has_update_perm
- 'delete': ('managers', 'users',),
- }
+ cardinality = '1*'
+ constraints = [RQLConstraint('S is ET, O state_of WF, WF workflow_of ET')]
+ object = 'State'