burnettk 92bfe2e659 Squashed 'SpiffWorkflow/' changes from 01a25fc3..0adfc8cb
0adfc8cb update spiff signal event
52d65dfc Merge pull request #346 from sartography/bugfix/update-split-task-inputs
23ca808c make sure tasks with boundary events are connected properly
de427431 remove pointless parser attribute and variable
3236b5b9 change subprocess start event validation error message text
a5ad0672 Merge pull request #344 from sartography/bugfix/gateway-in-loop
6b22a195 allow event definitions without refs
bb843873 clean up inclusive gateway a little
a7d81c02 prevent parallel gateways from waiting on descendants
802352a2 move test to proper location
ebcdde95 Merge pull request #343 from sartography/feature/event-payloads
87636472 add an additional test for boundary event parent removal
41423168 add escalation event test
26c5a9bb fix message event catch check
9bd018e5 Add test case for call activities in sub processes, fixed bug (#342)
546923b4 add serialization migration for boundary events
46d41e20 add spiff payload extensions + base spec improvements
a0f5fc2a remove boundary event parent
56277ff1 add event class
6de6fb2b reorganize event definitions
7db65566 fix subprocess cancel
442535ae do not allow the task trace to infinitely loop to get the trace w/ burnettk
dbe41c8e Merge pull request #339 from sartography/improvement/better-subworkflow-management
6c61f20a update parent attribute name
ea0a7bf4 update correlations when catching external messages
f511e2dd remove unneeded method from tests
953fa63c clean up workflow methods
efcdcf54 Merge pull request #338 from sartography/bugfix/triggered-multiinstance-tasks
11b78ce7 prevent errors synching children of MI tasks
bbb79e05 miscellaneous improvements
3f8e8d84 split bpmn workflow into two classes
61e01201 clean up workflow attributes & methods

git-subtree-dir: SpiffWorkflow
git-subtree-split: 0adfc8cbaec80d36f98a4136434e960f666fcfe2
2023-08-09 16:14:27 -04:00

337 lines
9.8 KiB
Python

# Copyright (C) 2023 Sartography
#
# This file is part of SpiffWorkflow.
#
# SpiffWorkflow is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 3.0 of the License, or (at your option) any later version.
#
# SpiffWorkflow is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301 USA
from SpiffWorkflow.bpmn.specs.bpmn_task_spec import _BpmnCondition
from SpiffWorkflow.bpmn.specs.control import (
BpmnStartTask,
_EndJoin,
BoundaryEventSplit,
BoundaryEventJoin,
SimpleBpmnTask
)
from SpiffWorkflow.bpmn.specs.defaults import (
UserTask,
ManualTask,
NoneTask,
ScriptTask,
ExclusiveGateway,
InclusiveGateway,
ParallelGateway,
StandardLoopTask,
SequentialMultiInstanceTask,
ParallelMultiInstanceTask,
CallActivity,
TransactionSubprocess,
SubWorkflowTask,
StartEvent,
EndEvent,
IntermediateCatchEvent,
IntermediateThrowEvent,
BoundaryEvent,
EventBasedGateway,
SendTask,
ReceiveTask,
)
from .helpers.spec import TaskSpecConverter
class BpmnTaskSpecConverter(TaskSpecConverter):
def to_dict(self, spec):
dct = self.get_default_attributes(spec)
return dct
def from_dict(self, dct):
return self.task_spec_from_dict(dct)
class SimpleBpmnTaskConverter(BpmnTaskSpecConverter):
def __init__(self, registry):
super().__init__(SimpleBpmnTask, registry)
class BpmnStartTaskConverter(BpmnTaskSpecConverter):
def __init__(self, registry):
super().__init__(BpmnStartTask, registry)
class EndJoinConverter(BpmnTaskSpecConverter):
def __init__(self, registry):
super().__init__(_EndJoin, registry)
class NoneTaskConverter(BpmnTaskSpecConverter):
def __init__(self, registry):
super().__init__(NoneTask, registry)
class UserTaskConverter(BpmnTaskSpecConverter):
def __init__(self, registry):
super().__init__(UserTask, registry)
class ManualTaskConverter(BpmnTaskSpecConverter):
def __init__(self, registry):
super().__init__(ManualTask, registry)
class ScriptTaskConverter(BpmnTaskSpecConverter):
def __init__(self, registry):
super().__init__(ScriptTask, registry)
def to_dict(self, spec):
dct = self.get_default_attributes(spec)
dct['script'] = spec.script
return dct
class StandardLoopTaskConverter(BpmnTaskSpecConverter):
def __init__(self, registry):
super().__init__(StandardLoopTask, registry)
def to_dict(self, spec):
dct = self.get_default_attributes(spec)
dct.update(self.get_standard_loop_attributes(spec))
return dct
class MultiInstanceTaskConverter(BpmnTaskSpecConverter):
def to_dict(self, spec):
dct = self.get_default_attributes(spec)
dct['task_spec'] = spec.task_spec
dct['cardinality'] = spec.cardinality
dct['data_input'] = self.registry.convert(spec.data_input)
dct['data_output'] = self.registry.convert(spec.data_output)
dct['input_item'] = self.registry.convert(spec.input_item)
dct['output_item'] = self.registry.convert(spec.output_item)
dct['condition'] = spec.condition
return dct
def from_dict(self, dct):
dct['data_input'] = self.registry.restore(dct['data_input'])
dct['data_output'] = self.registry.restore(dct['data_output'])
dct['input_item'] = self.registry.restore(dct['input_item'])
dct['output_item'] = self.registry.restore(dct['output_item'])
return self.task_spec_from_dict(dct)
class ParallelMultiInstanceTaskConverter(MultiInstanceTaskConverter):
def __init__(self, registry):
super().__init__(ParallelMultiInstanceTask, registry)
class SequentialMultiInstanceTaskConverter(MultiInstanceTaskConverter):
def __init__(self, registry):
super().__init__(SequentialMultiInstanceTask, registry)
class BoundaryEventSplitConverter(BpmnTaskSpecConverter):
def __init__(self, registry):
super().__init__(BoundaryEventSplit, registry)
class BoundaryEventJoinConverter(BpmnTaskSpecConverter):
def __init__(self, registry):
super().__init__(BoundaryEventJoin, registry)
def to_dict(self, spec):
dct = super().to_dict(spec)
dct.update(self.get_join_attributes(spec))
return dct
class SubWorkflowConverter(BpmnTaskSpecConverter):
def __init__(self, cls, registry):
super().__init__(cls, registry)
def to_dict(self, spec):
dct = super().to_dict(spec)
dct.update(self.get_subworkflow_attributes(spec))
return dct
def from_dict(self, dct):
dct['subworkflow_spec'] = dct.pop('spec')
return self.task_spec_from_dict(dct)
class SubprocessTaskConverter(SubWorkflowConverter):
def __init__(self, registry):
super().__init__(SubWorkflowTask, registry)
class CallActivityTaskConverter(SubWorkflowConverter):
def __init__(self, registry):
super().__init__(CallActivity, registry)
class TransactionSubprocessTaskConverter(SubWorkflowConverter):
def __init__(self, registry):
super().__init__(TransactionSubprocess, registry)
class ConditionalGatewayConverter(BpmnTaskSpecConverter):
def to_dict(self, spec):
dct = super().to_dict(spec)
dct['cond_task_specs'] = [ self.bpmn_condition_to_dict(cond) for cond in spec.cond_task_specs ]
dct['choice'] = spec.choice
return dct
def from_dict(self, dct):
conditions = dct.pop('cond_task_specs')
spec = self.task_spec_from_dict(dct)
spec.cond_task_specs = [ self.bpmn_condition_from_dict(cond) for cond in conditions ]
return spec
def bpmn_condition_from_dict(self, dct):
return (_BpmnCondition(dct['condition']) if dct['condition'] is not None else None, dct['task_spec'])
def bpmn_condition_to_dict(self, condition):
expr, task_spec = condition
return {
'condition': expr.args[0] if expr is not None else None,
'task_spec': task_spec
}
class ExclusiveGatewayConverter(ConditionalGatewayConverter):
def __init__(self, registry):
super().__init__(ExclusiveGateway, registry)
def to_dict(self, spec):
dct = super().to_dict(spec)
dct['default_task_spec'] = spec.default_task_spec
return dct
def from_dict(self, dct):
default_task_spec = dct.pop('default_task_spec')
spec = super().from_dict(dct)
spec.default_task_spec = default_task_spec
return spec
class InclusiveGatewayConverter(ConditionalGatewayConverter):
def __init__(self, registry):
super().__init__(InclusiveGateway, registry)
class ParallelGatewayConverter(BpmnTaskSpecConverter):
def __init__(self, registry):
super().__init__(ParallelGateway, registry)
def to_dict(self, spec):
dct = super().to_dict(spec)
dct.update(self.get_join_attributes(spec))
return dct
def from_dict(self, dct):
return self.task_spec_from_dict(dct)
class EventConverter(BpmnTaskSpecConverter):
def __init__(self, spec_class, registry):
super().__init__(spec_class, registry)
def to_dict(self, spec):
dct = super().to_dict(spec)
dct['event_definition'] = self.registry.convert(spec.event_definition)
return dct
def from_dict(self, dct):
dct['event_definition'] = self.registry.restore(dct['event_definition'])
return self.task_spec_from_dict(dct)
class StartEventConverter(EventConverter):
def __init__(self, registry):
super().__init__(StartEvent, registry)
class EndEventConverter(EventConverter):
def __init__(self, registry):
super().__init__(EndEvent, registry)
class IntermediateCatchEventConverter(EventConverter):
def __init__(self, registry):
super().__init__(IntermediateCatchEvent, registry)
class ReceiveTaskConverter(EventConverter):
def __init__(self, registry):
super().__init__(ReceiveTask, registry)
class IntermediateThrowEventConverter(EventConverter):
def __init__(self, registry):
super().__init__(IntermediateThrowEvent, registry)
class SendTaskConverter(EventConverter):
def __init__(self, registry):
super().__init__(SendTask, registry)
class BoundaryEventConverter(EventConverter):
def __init__(self, registry):
super().__init__(BoundaryEvent, registry)
def to_dict(self, spec):
dct = super().to_dict(spec)
dct['cancel_activity'] = spec.cancel_activity
return dct
class EventBasedGatewayConverter(EventConverter):
def __init__(self, registry):
super().__init__(EventBasedGateway, registry)
DEFAULT_TASK_SPEC_CONVERTER_CLASSES = [
SimpleBpmnTaskConverter,
BpmnStartTaskConverter,
EndJoinConverter,
NoneTaskConverter,
UserTaskConverter,
ManualTaskConverter,
ScriptTaskConverter,
StandardLoopTaskConverter,
ParallelMultiInstanceTaskConverter,
SequentialMultiInstanceTaskConverter,
SubprocessTaskConverter,
CallActivityTaskConverter,
TransactionSubprocessTaskConverter,
StartEventConverter,
EndEventConverter,
SendTaskConverter,
ReceiveTaskConverter,
IntermediateCatchEventConverter,
IntermediateThrowEventConverter,
EventBasedGatewayConverter,
BoundaryEventConverter,
BoundaryEventSplitConverter,
BoundaryEventJoinConverter,
ParallelGatewayConverter,
ExclusiveGatewayConverter,
InclusiveGatewayConverter,
]