kota
initial commit
e60e568
raw
history blame
5.64 kB
'''
This file is part of PM4Py (More Info: https://pm4py.fit.fraunhofer.de).
PM4Py is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
PM4Py 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with PM4Py. If not, see <https://www.gnu.org/licenses/>.
'''
import copy
import uuid
from lxml import etree
from pm4py.objects.process_tree.obj import ProcessTree
from pm4py.objects.process_tree.obj import Operator
from pm4py.util import constants, exec_utils
from enum import Enum
class Parameters(Enum):
ENCODING = "encoding"
def get_list_nodes_from_tree(tree, parameters=None):
"""
Gets the list of nodes from a process tree
Parameters
---------------
tree
Process tree
parameters
Parameters
Returns
---------------
list_nodes
List of nodes of the process tree
"""
if parameters is None:
parameters = {}
list_nodes = []
to_visit = [tree]
while len(to_visit) > 0:
node = to_visit.pop(0)
for child in node.children:
to_visit.append(child)
list_nodes.append(node)
return list_nodes
def export_ptree_tree(tree, parameters=None):
"""
Exports the XML tree from a process tree
Parameters
-----------------
tree
Process tree
parameters
Parameters of the algorithm
Returns
-----------------
xml_tree
XML tree object
"""
tree = copy.deepcopy(tree)
if parameters is None:
parameters = {}
nodes = get_list_nodes_from_tree(tree, parameters=parameters)
nodes_dict = {(id(x), x): str(uuid.uuid4()) for x in nodes}
# make sure that in the exporting, loops have 3 children
# (for ProM compatibility)
# just add a skip as third child
for node in nodes:
if node.operator == Operator.LOOP and len(node.children) < 3:
third_children = ProcessTree(operator=None, label=None)
third_children.parent = node
node.children.append(third_children)
nodes_dict[(id(third_children), third_children)] = str(uuid.uuid4())
# repeat twice (structure has changed)
nodes = get_list_nodes_from_tree(tree, parameters=parameters)
nodes_dict = {(id(x), x): str(uuid.uuid4()) for x in nodes}
root = etree.Element("ptml")
processtree = etree.SubElement(root, "processTree")
processtree.set("name", str(uuid.uuid4()))
processtree.set("root", nodes_dict[(id(tree), tree)])
processtree.set("id", str(uuid.uuid4()))
for node in nodes:
nk = nodes_dict[(id(node), node)]
child = None
if node.operator is None:
if node.label is None:
child = etree.SubElement(processtree, "automaticTask")
child.set("name", "")
else:
child = etree.SubElement(processtree, "manualTask")
child.set("name", node.label)
else:
if node.operator is Operator.SEQUENCE:
child = etree.SubElement(processtree, "sequence")
elif node.operator is Operator.XOR:
child = etree.SubElement(processtree, "xor")
elif node.operator is Operator.PARALLEL:
child = etree.SubElement(processtree, "and")
elif node.operator is Operator.OR:
child = etree.SubElement(processtree, "or")
elif node.operator is Operator.LOOP:
child = etree.SubElement(processtree, "xorLoop")
child.set("name", "")
child.set("id", nk)
for node in nodes:
if not node == tree:
child = etree.SubElement(processtree, "parentsNode")
child.set("id", str(uuid.uuid4()))
child.set("sourceId", nodes_dict[(id(node.parent), node.parent)])
child.set("targetId", nodes_dict[(id(node), node)])
tree = etree.ElementTree(root)
return tree
def export_tree_as_string(tree, parameters=None):
"""
Exports a process tree as a string
Parameters
---------------
tree
Process tree
parameters
Parameters
Returns
---------------
stri
XML string describing the process tree
"""
if parameters is None:
parameters = {}
encoding = exec_utils.get_param_value(Parameters.ENCODING, parameters, constants.DEFAULT_ENCODING)
# gets the XML tree
tree = export_ptree_tree(tree, parameters=parameters)
return etree.tostring(tree, xml_declaration=True, encoding=encoding)
def apply(tree, output_path, parameters=None):
"""
Exports the process tree to a XML (.PTML) file
Parameters
----------------
tree
Process tree
output_path
Output path
parameters
Parameters
"""
if parameters is None:
parameters = {}
encoding = exec_utils.get_param_value(Parameters.ENCODING, parameters, constants.DEFAULT_ENCODING)
# gets the XML tree
tree = export_ptree_tree(tree, parameters=parameters)
# exports the tree to a file
F = open(output_path, "wb")
tree.write(F, pretty_print=True, xml_declaration=True, encoding=encoding)
F.close()
return tree