예제 #1
0
def process_node_end_event(p: Process, xml_node) -> None:
    """ Create an end event from the process """
    node_name = normalize_name(xml_node.get("name"))

    task = EndEvent(parent_process=p, id=xml_node.get("id"), name=node_name)

    p.add_end_event(task)
예제 #2
0
def process_parallel_gateway(p: Process, xml_node) -> None:
    """ Create an end event from the process """
    node_name = normalize_name(xml_node.get("name"))
    task = ParallelGateway(parent_process=p,
                           id=xml_node.get("id"),
                           name=node_name)

    p.add_task(task)
예제 #3
0
def process_exclusive_gateway(p: Process, xml_node) -> None:
    """ Create an exclusive gateway from the process """
    node_name = normalize_name(xml_node.get("name"))
    task = ExclusiveGateway(parent_process=p,
                            id=xml_node.get("id"),
                            name=node_name)

    p.add_task(task)
예제 #4
0
def process_usertask(p: Process, xml_node) -> None:
    """ Create a HumanTask element from the process """
    node_name = normalize_name(xml_node.get("name"))
    task = UserTask(parent_process=p, id=xml_node.get("id"), name=node_name)

    task = process_potential_loop(task, xml_node)

    p.add_task(task)
예제 #5
0
def process_node_sequence_flow(p: Process, xml_node) -> None:
    edge = Edge(
        id=xml_node.get("id"),
        source_id=xml_node.get("sourceRef"),
        target_id=xml_node.get("targetRef"),
    )

    condition_node = find_node(xml_node, "conditionExpression")

    if condition_node is not None:
        edge.condition = textwrap.dedent(condition_node.text)

    p.add_edge(edge)
예제 #6
0
def read_process(parent_process: Optional[Process], process) -> Process:
    node_ns, node_name = parse_tag(process)

    if "process" == node_name:
        result = Process(id=process.get("id"))
    elif "subProcess" == node_name:
        assert parent_process
        result = SubProcess(
            parent_process=parent_process,
            id=process.get("id"),
            name=normalize_name(process.get("name")),
        )
    else:
        raise Exception(f"Unknown process node: {process.tag}")

    # we read first the nodes, then the boundary events,
    # then only the edges so they are findable
    # when adding the edges by id.
    for node in list(process):
        process_node(result, node)

    for node in list(process):
        process_boundary_event(result, node)

    for node in list(process):
        process_edge(result, node)

    for node in list(process):
        process_lane_set(result, node)

    for task_id, task in result.tasks.items():
        if not isinstance(task, ProcessTask):
            continue

        if result.has_incoming_edges(task):
            continue

        result.start_events[task.id] = task

    for task_id, task in result.tasks.items():
        if not result.has_outgoing_edges(task):
            if not isinstance(task, EndEvent) and not isinstance(
                    task, ProcessTask):
                raise Exception(
                    f"Executable node {task} has no outgoing connections, but can't "
                    f"be used as ae end task.")

            result.end_events[task.id] = task

    return result
예제 #7
0
    def route_single_output(process: Process, gateway: Gateway,
                            event: ActiveEvent) -> List[Edge]:

        default_edge = None
        result_edge = None

        edges = process.get_outgoing_edges(gateway.id)

        for edge in edges:
            if not edge.condition:
                if default_edge is not None:
                    raise Exception(
                        f"Duplicate default edge for gateway {gateway.id}.")

                default_edge = edge
                continue

            if eval_edge(edge.condition, event):
                if result_edge is not None:
                    raise Exception(
                        f"Duplicate output edge for gateway {gateway.id}")

                result_edge = edge
                continue

        if result_edge is None and default_edge is not None:
            result_edge = default_edge

        if not result_edge:
            raise Exception(f"No branch matches on gateway {gateway.id}")

        return [result_edge]
예제 #8
0
    def __init__(
        self,
        parent_builder: Optional["ProcessBuilder"],
        _build: Optional[Callable] = None,
        name: Optional[str] = None,
    ):
        self.parent_builder = parent_builder

        if self.parent_builder is None:
            self.process = Process(
                id=next_id(), name="<process>" if name is None else name
            )
        else:
            self.process = SubProcess(
                id=next_id(),
                name="<sub-process>" if name is None else name,
                parent_process=self.parent_builder.process,
            )

        self.current_task: WiredNode = StartEvent(
            parent_process=self.process, id=next_id(), name="<start>"
        )
        self.pre_current_when_task: WiredNode = self.current_task

        self.process.add_start_event(self.current_task)

        self.nested_branches: List[BranchGroup] = list()
        self._build = _build
예제 #9
0
def process_node_start_event(p: Process, xml_node) -> None:
    """ Create a start event from the process """
    node_name = normalize_name(xml_node.get("name"))

    message_event_node = find_node(xml_node, "messageEventDefinition")

    if message_event_node is not None:
        message_event = MessageEvent(parent_process=p,
                                     id=xml_node.get("id"),
                                     name=node_name)

        p.add_message_event(message_event)
        return

    task = StartEvent(parent_process=p, id=xml_node.get("id"), name=node_name)

    p.add_start_event(task)
예제 #10
0
def process_script_task(p: Process, xml_node) -> None:
    """ Create a ScriptTask element from the process """
    node_name = normalize_name(xml_node.get("name"))
    language = xml_node.get("scriptFormat")

    script_node = find_node(xml_node, "script")

    task = ScriptTask(
        parent_process=p,
        id=xml_node.get("id"),
        name=node_name,
        language=language,
        script=textwrap.dedent(script_node.text),
    )

    task = process_potential_loop(task, xml_node)

    p.add_task(task)
예제 #11
0
def process_boundary_task(p: Process, boundary_event_node) -> None:
    """ Create a Task element from the process """
    for node in list(boundary_event_node):
        node_ns, node_name = parse_tag(node)

        if node_name in boundary_ignored_elements:
            continue

        # node is not ignored, we either found the type
        # or we die with exception.
        task_name = normalize_name(boundary_event_node.get("name"))

        if node_name == "errorEventDefinition":
            boundary_task = ErrorBoundaryEvent(
                parent_process=p,
                id=boundary_event_node.get("id"),
                name=task_name)

            boundary_task.attached_task_id = boundary_event_node.get(
                "attachedToRef", default="not attached")

            boundary_task.cancel_activity = get_boolean(
                boundary_event_node, "cancelActivity", True)
            boundary_task.parallel_multiple = get_boolean(
                boundary_event_node, "parallelMultiple", True)

            p.add_boundary_event(boundary_task)

            return

        if node_name == "timerEventDefinition":
            read_timer_event_definition(
                process=p,
                boundary_event_node=boundary_event_node,
                timer_event_definition_node=node,
                task_name=task_name,
            )
            return

    raise Exception(
        "Unable to find the type of the boundary event. Only "
        "<errorEventDefinition>, and <timerEventDefinition> are supported.")
예제 #12
0
def process_lane(process: Process, lane_node) -> None:
    """ Create a lane object """
    lane_node_ns, lane_node_name = parse_tag(lane_node)

    lane = Lane(id=lane_node.get("id"),
                name=lane_node.get("name"),
                parent_process=process)

    process.add_lane(lane)

    for node in list(lane_node):
        node_ns, node_name = parse_tag(node)

        if node_name in boundary_ignored_elements:
            continue

        if node_name == "flowNodeRef":
            process_lane_task(process, lane, node)
            continue

        raise Exception(
            f"Unknown node <{node_name}> inside a <{lane_node_name}>.")
예제 #13
0
    def route_all_outputs(process: Process, task: ProcessTask,
                          event: ActiveEvent) -> List[Edge]:

        result_edges = []
        edges = process.get_outgoing_edges(task.id)

        for edge in edges:
            # if we have no condition on the edge, we create an event for it
            if edge.condition and not eval_edge(edge.condition, event):
                continue

            result_edges.append(edge)

        return result_edges
예제 #14
0
    def __init__(self, id: str) -> None:
        self.lane_definitions: List[ExecutionLane] = []
        self.task_definitions: List[ExecutionTask] = []
        self.user_task_definitions: List[ExecutionUserTask] = []
        self.message_definitions: List[ExecutionMessageEvent] = []
        self.message_callback_definitions: List[
            ExecutionMessageCallbackEvent] = []

        self.chained_task_definitions: List[Union[ExecutionTask,
                                                  ExecutionUserTask]] = []

        self.process: Process = Process(id=id)

        # map from lane key, to actual lane
        self.lanes: Dict[str, AdhesiveLane] = dict()
예제 #15
0
def process_node_sub_process(p: Process, xml_node) -> None:
    task = cast(SubProcess, read_process(p, xml_node))
    task = process_potential_loop(task, xml_node)

    p.add_task(task)
예제 #16
0
def process_lane_task(process: Process, lane: Lane, xml_node) -> None:
    """
    Binds the task for the lane.
    """
    task_id = textwrap.dedent(xml_node.text)
    process.add_task_to_lane(lane, task_id)