Beispiel #1
0
    def draw_reachability_graph(self, rg_graph):
        '''draw the reachability graph
        '''
        states_dict = rg_graph.states_dict
        edges_dict = rg_graph.edges_dict

        G = pgv.AGraph(directed=True, strict=False)

        for state_id in states_dict:
            state = states_dict[state_id]
            if state.reachability:
                G.add_node(state_id, shape="circle")
            else:
                G.add_node(state_id, shape="circle", color='blue')
        for edge_id in edges_dict:
            edge = edges_dict[edge_id]
            source = edge.source
            target = edge.target
            edge_label = edge.label
            if edge.reachability:
                G.add_edge(source, target, label=edge_label)
            else:
                G.add_edge(source, target, label=edge_label, color='blue')
        # print G.string()  # print dot file to standard output
        png_name = self.get_png_name()
        # G.write("Rg"+png_name + ".dot")
        G.layout('dot')  # layout with dot
        G.draw("Rg" + "_" + rg_graph.name + png_name + ".png")  # write to file
        # G.draw("Rg" + png_name + ".bmp")  # write to file
        log.show_info("the Reachability Diagram is created." + " name:" +
                      rg_graph.name)
 def get_parallel_process(self, activity):
     '''get the parallel process (action and object node) in the fork and join.
     '''
     nodes_dict = activity.nodes_dict
     num = 0
     for node_id in nodes_dict:
         node = nodes_dict[node_id]
         # if it is fork
         if node.xmi_type == uml_element.Types.FORK_NODE:
             num += 1
             # set the parallel_num of fork
             node.parallel_num = num
             # change the name of fork
             node.name = "parallel" + str(num)
             actions, objects = self._get_actions_objects(
                 node, num, activity, False)
             # set the parallel as True and the parallel_num
             for action in actions:
                 action.parallel = True
                 action.parallel_num = num
                 log.show_info(
                     "the action:%s is in parallel_num:%d process" %
                     (action.name, num))
             for object_node in objects:
                 object_node.parallel = True
                 object_node.parallel_num = num
                 log.show_info(
                     "the object node:%s is in parallel_num:%d process" %
                     (object_node.name, num))
    def get_tokens_num(self, merge, activity):
        '''first, judge if the incomings of the merge from the different parallel_num,
        if yes set the tokens to the number of the incomings.
        '''
        edges_dict = activity.edges_dict
        # the number of the place's tokens
        tokens_num = 1
        # the number of the parallel
        parallel_num = 0

        # for the edge, which edge.parallel is True
        edges = []
        for incoming in merge.incomings:
            edge_id = incoming.xmi_idref
            edge = edges_dict[edge_id]
            if edge.parallel:
                edges.append(edge)
            else:
                log.show_warn("the merge in the fork has a incoming," + \
                "but the incoming is not from the fork, the incoming comes from the outside")

        if len(edges) > 1:
            first_edge = edges[0]
            parallel_num = first_edge.parallel_num

        for edge in edges:
            # the edges come from the same fork, but different parallels
            if edge.parallel_num != parallel_num:
                tokens_num += 1

        if tokens_num > 1:
            self.set_tokens(merge, tokens_num)
            log.show_info("the merge has %d tokens. name:%s, id:%s" %
                          (tokens_num, str(merge.name), str(merge.xmi_id)))
Beispiel #4
0
    def draw_reachability_graph(self, rg_graph):
        '''draw the reachability graph
        '''
        states_dict = rg_graph.states_dict
        edges_dict = rg_graph.edges_dict

        G = pgv.AGraph(directed=True, strict=False)

        for state_id in states_dict:
            state = states_dict[state_id]
            if state.reachability:
                G.add_node(state_id, shape="circle")
            else:
                G.add_node(state_id, shape="circle", color='blue')
        for edge_id in edges_dict:
            edge = edges_dict[edge_id]
            source = edge.source
            target = edge.target
            edge_label = edge.label
            if edge.reachability:
                G.add_edge(source, target, label=edge_label)
            else:
                G.add_edge(source, target, label=edge_label, color='blue')
        # print G.string()  # print dot file to standard output
        png_name = self.get_png_name()
        # G.write("Rg"+png_name + ".dot")
        G.layout('dot')  # layout with dot
        G.draw("Rg" + "_" + rg_graph.name + png_name + ".png")  # write to file
        # G.draw("Rg" + png_name + ".bmp")  # write to file
        log.show_info("the Reachability Diagram is created." + " name:" + rg_graph.name)
 def action_has_more_outgoings(self, activity):
     """ if a action has more than one outgoing. if yes, create one decision after the action.
     yes: return True
     no:  return False
     """
     nodes_dict = activity.nodes_dict
     edges_dict = activity.edges_dict
     ret = False
     ids = []
     for node_id in nodes_dict:
         node = nodes_dict[node_id]
         if isinstance(node, uml_element.ExecutableNode):
             # the control flow number incomings
             control_flow_num = 0
             outgoings = node.outgoings
             # judge it is a control flow or a object flow
             for outgoing in outgoings:
                 edge_id = outgoing.xmi_idref
                 edge = edges_dict[edge_id]
                 # it is control flow
                 if edge.xmi_type == uml_element.Types.CONTROL_FLOW:
                     control_flow_num += 1
             if control_flow_num > 1:
                 log.show_info(
                     "the action name:%s,id:%s has %d control flow outgoings"
                     % (str(node.name), node.xmi_id, control_flow_num)
                 )
                 ids.append(node_id)
                 ret = True
     if ret:
         for node_id in ids:
             self._create_decision(node_id, activity)
     return ids
    def get_tokens_num(self, merge, activity):
        """first, judge if the incomings of the merge from the different parallel_num,
        if yes set the tokens to the number of the incomings.
        """
        edges_dict = activity.edges_dict
        # the number of the place's tokens
        tokens_num = 1
        # the number of the parallel
        parallel_num = 0

        # for the edge, which edge.parallel is True
        edges = []
        for incoming in merge.incomings:
            edge_id = incoming.xmi_idref
            edge = edges_dict[edge_id]
            if edge.parallel:
                edges.append(edge)
            else:
                log.show_warn(
                    "the merge in the fork has a incoming,"
                    + "but the incoming is not from the fork, the incoming comes from the outside"
                )

        if len(edges) > 1:
            first_edge = edges[0]
            parallel_num = first_edge.parallel_num

        for edge in edges:
            # the edges come from the same fork, but different parallels
            if edge.parallel_num != parallel_num:
                tokens_num += 1

        if tokens_num > 1:
            self.set_tokens(merge, tokens_num)
            log.show_info("the merge has %d tokens. name:%s, id:%s" % (tokens_num, str(merge.name), str(merge.xmi_id)))
 def action_has_more_outgoings(self, activity):
     ''' if a action has more than one outgoing. if yes, create one decision after the action.
     yes: return True
     no:  return False
     '''
     nodes_dict = activity.nodes_dict
     edges_dict = activity.edges_dict
     ret = False
     ids = []
     for node_id in nodes_dict:
         node = nodes_dict[node_id]
         if isinstance(node, uml_element.ExecutableNode):
             # the control flow number incomings
             control_flow_num = 0
             outgoings = node.outgoings
             # judge it is a control flow or a object flow
             for outgoing in outgoings:
                 edge_id = outgoing.xmi_idref
                 edge = edges_dict[edge_id]
                 # it is control flow
                 if edge.xmi_type == uml_element.Types.CONTROL_FLOW:
                     control_flow_num += 1
             if control_flow_num > 1:
                 log.show_info(
                     "the action name:%s,id:%s has %d control flow outgoings"
                     % (str(node.name), node.xmi_id, control_flow_num))
                 ids.append(node_id)
                 ret = True
     if ret:
         for node_id in ids:
             self._create_decision(node_id, activity)
     return ids
Beispiel #8
0
    def draw_petri_net(self, petri_net):
        '''draw Petri Net from the 3 dicts
        '''
        places_dict = petri_net.places_dict
        transitions_dict = petri_net.transitions_dict
        arcs_dict = petri_net.arcs_dict
        # G=pgv.AGraph(directed=True,strict=True,splines="polyline")
        # G = pgv.AGraph(directed=True, strict=True, splines=False)
        G = pgv.AGraph(directed=True, strict=True)
        G.graph_attr['label'] = petri_net.label + petri_net.probs

        for pt_id in places_dict:
            place = places_dict[pt_id]
            place_xlabel = place.xlabel
            G.add_node(pt_id, shape="circle", label="", xlabel=place_xlabel)
        for pt_id in transitions_dict:
            transition = transitions_dict[pt_id]
            # get the max number of the incomings and outgoings
            number = max(len(transition.incomings), len(transition.outgoings))
            transition_width = 0.5 * number
            transition_xlabel = transition.xlabel

            transition_type = transition.transition_type
            # Deterministic transitions are drawn as black filled rectangles.
            if transition_type == petri_net_element.TransitionTypes.DETERMINISTIC_TRANSITION:
                G.add_node(pt_id, shape="box", style="filled", label="", \
                            xlabel=transition_xlabel, height=0.3, \
                            width=transition_width, fillcolor="#000000")  # color:black
            # Exponential transitions are drawn as empty rectangles.
            elif transition_type == petri_net_element.TransitionTypes.EXPONENTIAL_TRANSITION:
                G.add_node(pt_id, shape="box", label="",
                           xlabel=transition_xlabel, height=0.3,
                           width=transition_width, fillcolor="#000000")  # color:black
            # Immediate transitions are drawn as thin bars.
            elif transition_type == petri_net_element.TransitionTypes.IMMEDIATE_TRANSITION:
                G.add_node(pt_id, shape="box", style="filled", label="",
                           xlabel=transition_xlabel, height=0.08,
                           width=transition_width, fillcolor="#000000")  # color:black
            else:
                log.show_error("the transition type is not defined")
        for pt_id in arcs_dict:
            arc = arcs_dict[pt_id]
            source = arc.source
            target = arc.target
            G.add_edge(source, target)
            # draw the arc with probability
            # if arc.prob == 1:
            #    G.add_edge(source, target)
            # else:
            #    G.add_edge(source, target, label=arc.prob)

        # print G.string()  # print dot file to standard output
        png_name = self.get_png_name()
        # G.write("Pt"+png_name + ".dot")
        G.layout('dot')  # layout with dot
        G.draw("Pt" + "_" + petri_net.name + png_name + ".png")  # write to file
        log.show_info("the Petri Net Diagram is created.name:%s" % petri_net.name)
    def get_matrix(self, petri_net):
        '''get the net matrix of the Petri-Net.
        the way to change the number of a matrix in numpy
        matrix[0][0] = 1 or matrix[0,0] = 1
        '''

        places_dict = petri_net.places_dict
        transitions_dict = petri_net.transitions_dict
        arcs_dict = petri_net.arcs_dict

        p_num = len(places_dict)
        t_num = len(transitions_dict)
        # create the matrix
        matrix = np.zeros((p_num, t_num))
        for p_id in places_dict:
            # "s1"-->1, "s12"-->12
            row_str = p_id[1:]
            # if it is "p1", also id_changed is True, the place can be enabled
            if row_str.isdigit():
                row = int(row_str)
                place = places_dict[p_id]
                incomings = place.incomings
                for incoming in incomings:
                    arc_id = incoming
                    arc = arcs_dict[arc_id]
                    source = arc.source
                    t_id = source
                    col_str = t_id[1:]
                    # if it is "t1", also id_changed is True, the transition can fire
                    if col_str.isdigit():
                        col = int(col_str)
                        matrix[row - 1, col - 1] = 1
                outgoings = place.outgoings
                for outgoing in outgoings:
                    arc_id = outgoing
                    arc = arcs_dict[arc_id]
                    target = arc.target
                    t_id = target
                    # if it is "t1", also id_changed is True, the transition can fire
                    col_str = t_id[1:]
                    if col_str.isdigit():
                        col = int(col_str)
                        matrix[row - 1, col - 1] = -1
        log.show_info("the matrix of the Petri-Net, see below." + " name:" + petri_net.name)
        petri_net.matrix = matrix
        print matrix
        return matrix
 def _add_control_flow(self, node1, node2, activity):
     """add one control flow from node1 to node2.
     """
     edges_dict = activity.edges_dict
     # get the edge_id, and create a edge
     edge_id = self._get_new_id("edge", edges_dict)
     edge = uml_element.ControlFlow(
         edge_id, uml_element.Types.CONTROL_FLOW, edge_id, node2.xmi_id, node1.xmi_id, None
     )
     # node1.outgoings and node2.incomings
     outgoing = uml_element.Outgoing(edge_id)
     node1.outgoings.append(outgoing)
     incoming = uml_element.Incoming(edge_id)
     node2.incomings.append(incoming)
     # put the edge to the edge_dict
     edges_dict[edge_id] = edge
     # shwo info
     log.show_info("one control flow is created from %s to %s." % (str(node1.name), str(node2.name)))
 def activity_analyse(self):
     '''start analyze
     '''
     activity_analyser = ActivityDiagramAnalyser()
     activitys_dict = self.model.activitys_dict
     num = len(activitys_dict)
     log.show_info("the model has %d activities" % num)
     for activity in activitys_dict.values():
         activity_analyser.show_activity_details(activity, show=False)
         activity_analyser.get_init_final_num(activity)
         activity_analyser.check_names(activity)
         activity_analyser.analyze_object_flow(activity)
         activity_analyser.action_has_more_incomings(activity)
         activity_analyser.action_has_more_outgoings(activity)
         activity_analyser.get_parallel_edges(activity)
         activity_analyser.fork_has_more_incomings(activity)
         activity_analyser.check_probability(activity)
         activity_analyser.get_parallel_process(activity)
         activity_analyser.show_activity_details(activity, show=False)
 def activity_analyse(self):
     '''start analyze
     '''
     activity_analyser = ActivityDiagramAnalyser()
     activitys_dict = self.model.activitys_dict
     num = len(activitys_dict)
     log.show_info("the model has %d activities" % num)
     for activity in  activitys_dict.values():
         activity_analyser.show_activity_details(activity, show=False)
         activity_analyser.get_init_final_num(activity)
         activity_analyser.check_names(activity)
         activity_analyser.analyze_object_flow(activity)
         activity_analyser.action_has_more_incomings(activity)
         activity_analyser.action_has_more_outgoings(activity)
         activity_analyser.get_parallel_edges(activity)
         activity_analyser.fork_has_more_incomings(activity)
         activity_analyser.check_probability(activity)
         activity_analyser.get_parallel_process(activity)
         activity_analyser.show_activity_details(activity, show=False)
 def _add_control_flow(self, node1, node2, activity):
     '''add one control flow from node1 to node2.
     '''
     edges_dict = activity.edges_dict
     # get the edge_id, and create a edge
     edge_id = self._get_new_id("edge", edges_dict)
     edge = uml_element.ControlFlow(edge_id, uml_element.Types.CONTROL_FLOW,
                                    edge_id, node2.xmi_id, node1.xmi_id,
                                    None)
     # node1.outgoings and node2.incomings
     outgoing = uml_element.Outgoing(edge_id)
     node1.outgoings.append(outgoing)
     incoming = uml_element.Incoming(edge_id)
     node2.incomings.append(incoming)
     # put the edge to the edge_dict
     edges_dict[edge_id] = edge
     # shwo info
     log.show_info("one control flow is created from %s to %s." %
                   (str(node1.name), str(node2.name)))
Beispiel #14
0
    def _get_cf_prob_from_text(self, guard):
        """get the cf_prob from text of guard.
        for example: 
        [...prob:0.25]
        [...prob=0.25]
        [...pro:0.25]
        [...pro=0.25]
        [...pr:0.25]
        [...pr=0.25]
        """
        prob = 1
        if guard is None:
            # cf_prob is default 1, also edge.prob =1
            return 1
        # delete the " "
        guard_body = guard.body.replace(" ", "")
        possibles = ["prob:", "prob=", "pro:", "pro=", "pr:", "pr="]
        index = -1
        for possible_str in possibles:
            # find it from right
            index = guard_body.rfind(possible_str)
            if index != -1:
                # the length
                num = len(possible_str)
                break

        if index != -1:
            # find the number_str, such as "0.5"
            prob_str = guard_body[(index + num) :]
            try:
                # str to float
                prob = float(prob_str)
            except ValueError:
                log.show_error("the prob is invalid,Please modify it " + prob_str)
            # if it is less than 0 or more than one
            if (prob <= 0.0) or (prob > 1.0):
                log.show_error("the prob should be a number between 0 and 1")
            # if it is not default one
            if prob != 1:
                # show info
                log.show_info("the guard:%s, has cf_prob:%f" % (guard_body, prob))
        return prob
Beispiel #15
0
    def _get_cf_prob_from_text(self, guard):
        '''get the cf_prob from text of guard.
        for example: 
        [...prob:0.25]
        [...prob=0.25]
        [...pro:0.25]
        [...pro=0.25]
        [...pr:0.25]
        [...pr=0.25]
        '''
        prob = 1
        if guard is None:
            # cf_prob is default 1, also edge.prob =1
            return 1
        # delete the " "
        guard_body = guard.body.replace(' ', '')
        possibles = ["prob:", "prob=", "pro:", "pro=", "pr:", "pr="]
        index = -1
        for possible_str in possibles:
            # find it from right
            index = guard_body.rfind(possible_str)
            if index != -1:
                # the length
                num = len(possible_str)
                break

        if index != -1:
            # find the number_str, such as "0.5"
            prob_str = guard_body[(index + num):]
            try:
            # str to float
                prob = float(prob_str)
            except ValueError:
                log.show_error("the prob is invalid,Please modify it " + prob_str)
            # if it is less than 0 or more than one
            if (prob <= 0.0) or (prob > 1.0):
                log.show_error("the prob should be a number between 0 and 1")
            # if it is not default one
            if prob != 1:
                # show info
                log.show_info("the guard:%s, has cf_prob:%f" % (guard_body, prob))
        return prob
Beispiel #16
0
 def set_time(self, str_time, base_element, time_type, model):
     '''set the time property of action
     '''
     for activity_id in model.activitys_dict:
         activity = model.activitys_dict[activity_id]
         nodes_dict = activity.nodes_dict
         if base_element in nodes_dict:
             node = nodes_dict[base_element]
             time = self.get_time(str_time)
             # it is not immediate
             node.immediate = False
             if time_type == "const":
                 node.deterministic = True
             elif time_type == "exp":
                 node.exponential = True
             else:
                 log.show_warn("the type of the time is not defined.type:%s" % time_type)
                 # set it to default deterministic
                 node.deterministic = True
             node.time = time
             log.show_info("the action has time property.name:%s,id:%s,time:%s" % 
                           (str(node.name), node.xmi_id, str_time))
             break
Beispiel #17
0
 def set_time(self, str_time, base_element, time_type, model):
     """set the time property of action
     """
     for activity_id in model.activitys_dict:
         activity = model.activitys_dict[activity_id]
         nodes_dict = activity.nodes_dict
         if base_element in nodes_dict:
             node = nodes_dict[base_element]
             time = self.get_time(str_time)
             # it is not immediate
             node.immediate = False
             if time_type == "const":
                 node.deterministic = True
             elif time_type == "exp":
                 node.exponential = True
             else:
                 log.show_warn("the type of the time is not defined.type:%s" % time_type)
                 # set it to default deterministic
                 node.deterministic = True
             node.time = time
             log.show_info(
                 "the action has time property.name:%s,id:%s,time:%s" % (str(node.name), node.xmi_id, str_time)
             )
             break
 def get_parallel_process(self, activity):
     """get the parallel process (action and object node) in the fork and join.
     """
     nodes_dict = activity.nodes_dict
     num = 0
     for node_id in nodes_dict:
         node = nodes_dict[node_id]
         # if it is fork
         if node.xmi_type == uml_element.Types.FORK_NODE:
             num += 1
             # set the parallel_num of fork
             node.parallel_num = num
             # change the name of fork
             node.name = "parallel" + str(num)
             actions, objects = self._get_actions_objects(node, num, activity, False)
             # set the parallel as True and the parallel_num
             for action in actions:
                 action.parallel = True
                 action.parallel_num = num
                 log.show_info("the action:%s is in parallel_num:%d process" % (action.name, num))
             for object_node in objects:
                 object_node.parallel = True
                 object_node.parallel_num = num
                 log.show_info("the object node:%s is in parallel_num:%d process" % (object_node.name, num))
    def analyze_object_flow(self, activity):
        """analyze the object flow between node1 and node2.
        """
        log.show_info("object flow analyze starts...")

        edges_dict = activity.edges_dict
        # object flow number
        num = 0
        # dictionary changed size during iteration
        for edge in edges_dict.values():
            # if it is object flow
            if edge.xmi_type == uml_element.Types.OBJECT_FLOW:
                num += 1
                # get the node1, node2 from the edge
                node1, node2 = self._get_nodes_from_edge(edge, activity)
                # anylyse the node1 and node2
                self._analyse_nodes(node1, node2, activity)
        # show the number of object edge
        log.show_info("the activity diagram has %d object flow" % num)
        log.show_info("object flow analyze completed.")
    def analyze_object_flow(self, activity):
        '''analyze the object flow between node1 and node2.
        '''
        log.show_info("object flow analyze starts...")

        edges_dict = activity.edges_dict
        # object flow number
        num = 0
        # dictionary changed size during iteration
        for edge in edges_dict.values():
            # if it is object flow
            if edge.xmi_type == uml_element.Types.OBJECT_FLOW:
                num += 1
                # get the node1, node2 from the edge
                node1, node2 = self._get_nodes_from_edge(edge, activity)
                # anylyse the node1 and node2
                self._analyse_nodes(node1, node2, activity)
        # show the number of object edge
        log.show_info("the activity diagram has %d object flow" % num)
        log.show_info("object flow analyze completed.")
Beispiel #21
0
start_time = time.clock()
# the path of the xml
xml_path = examples.get_xml_path()
# create the main object
act_to_pt = ActivityDiagramToPetriNet()
# load xml and parsing
act_to_pt.load_xml(xml_path)
# start activity_analyse
act_to_pt.activity_analyse()
# transform_to_pt to Petri net
act_to_pt.transform_to_pt()

act_to_pt.petri_net_analyse()
# draw PT net and reachability_graph_element
act_to_pt.create_diagram()

# control, getReachabilityGraph
act_to_pt.get_reachability_graph()
# start petri_net_reachability_analyse
act_to_pt.petri_net_reachability_analyse()
# show .reachability_graph details
act_to_pt.reachability_graph_analyse()
# draw PT net and reachability_graph_element
act_to_pt.create_diagram()

act_to_pt.show_summary(True)

end_time = time.clock()
log.show_info("completed in " + str(end_time - start_time) + "s")
 def _analyse_nodes(self, node1, node2, activity):
     """for example:
     situation:
     1. action1(with(out) pout)-->action2 (with(out) pin)
     2. action1-->object-->action2(or control)
     3. action1 with pin-->control node #pass
     4. control node(fork,decision,merge)-->action2 with pin #pass
     5. control node(fork,decision,merge)-->object-->action2(or control)
     6. control node-->control node #pass
     7. object node-->... #pass
     if action1 has no control flow, add one control flow between action1 and action2.
     """
     # if node1 and node2 are actions
     # 1.situation
     if isinstance(node1, uml_element.ExecutableNode) and isinstance(node2, uml_element.ExecutableNode):
         log.show_info("1.situation: action to action")
         # if node1 has no control flow
         if not self._has_outgoing_control_flow(node1, activity):
             # add one control flow from action1 to action2
             self._add_control_flow(node1, node2, activity)
     # if node1 is a action, and node2 is a object_node
     # 2.situation
     elif isinstance(node1, uml_element.ExecutableNode) and isinstance(node2, uml_element.ObjectNode):
         log.show_info("2.situation: action to object node")
         # if node1 has no control flow
         if not self._has_outgoing_control_flow(node1, activity):
             node3 = self._get_object_next_node(node2, activity)
             # if node3 not None
             if node3:
                 self._add_control_flow(node1, node3, activity)
     # if node1 is a action with pout, and node2 is a control
     # 3.situation
     elif isinstance(node1, uml_element.ExecutableNode) and isinstance(node2, uml_element.ControlNode):
         log.show_info("3.situation: action to control node")
         # pass
     # if node1 is control_node, node2 is a action with pin
     # 4.situation
     elif isinstance(node1, uml_element.ControlNode) and isinstance(node2, uml_element.ExecutableNode):
         log.show_info("4.situation: control node to action")
         # pass
     # if node1 is control_node, node2 is object_node
     # 5.situation
     elif isinstance(node1, uml_element.ControlNode) and isinstance(node2, uml_element.ObjectNode):
         log.show_info("5.situation: control node to object node")
         node3 = self._get_object_next_node(node2, activity)
         if node3:
             # add one control flow from node1 to node3
             self._add_control_flow(node1, node3, activity)
     # if node1 is control_node, node2 is control_node
     # 6.situation
     elif isinstance(node1, uml_element.ControlNode) and isinstance(node2, uml_element.ControlNode):
         log.show_info("6.situation: control node to control node")
         # TODO
         # pass
     # if node1 is object node
     # 7.situation
     elif isinstance(node1, uml_element.ObjectNode):
         pass
     else:
         log.show_warn("a object flow from node1 to node2," "but the 2 nodes's situation are not defined")
Beispiel #23
0
    def xml_parse(self, xml_path):
        '''start the parsing
        @param xml_path: the path of the xml
        @attention: the different between windows and Linux
        '''
        # use minidom to open the xml
        try:
            DOMTree = minidom.parse(xml_path)
            # collection = DOMTree.documentElement
        except IOError:
            log.show_error("the xml is wrong")

        # get the root tag of the xml
        root = DOMTree.documentElement

        # get the tag: <xmi:Documentation>
        # get the exporter(Magic Draw or EA) and exporterVersion
        documentation = self.get_child_nodes(root, "xmi:Documentation")[0]
        exporter, export_version = self.get_exporter_version(documentation)

        log.show_info("exporter:" + exporter + ".exportVersion:" + export_version)

        # get <uml:Model  />
        model_node = self.get_child_nodes(root, "uml:Model")[0]
        # the 4 parameters: xmi_id, xmi_type, name, activitys_dict
        xmi_id, name, xmi_type = self.get_id_name_type(model_node)

        activitys_dict = {}
        # create the model
        model = uml_element.Model(xmi_id, xmi_type, name, activitys_dict)
        # get <packagedElement>
        # packaged_elements = self.get_child_nodes(model_node, "packagedElement")
        packaged_elements = model_node.getElementsByTagName("packagedElement")


        InstanceSpecification_nodes = []
        activity_id = None
        for packaged_element in packaged_elements:
            xmi_id, name, xmi_type = self.get_id_name_type(packaged_element)
            # get the activity diagram "uml:Activity"
            if xmi_type == uml_element.Types.ACTIVITY:
                # xmi_id:ActivityNode (class UmlActivityDiagramElement.ActivityNode)
                nodes_dict = {}
                # xmi_id:ActivityEdge (class uml_activity_diagram_element.ActivityEdge)
                edges_dict = {}
                # Result and Argument
                pins_dict = {}
                # create activity
                activity = uml_element.Activity(xmi_id, xmi_type, name,
                                                nodes_dict, edges_dict, pins_dict)
                # put it in the activitys_dict
                activitys_dict[xmi_id] = activity
                # activity_id
                activity_id = xmi_id
                # get all the nodes
                nodes = self.get_child_nodes(packaged_element, "node")
                # get every node
                for node in nodes:
                    # get the id, name, type of the node
                    xmi_id, name, xmi_type = self.get_id_name_type(node)
                    # get behavior
                    behavior = self.get_behavior(node)
                    # get incomings of the node
                    incomings = self.get_incomings(node)
                    # get outgoings of the node
                    outgoings = self.get_outgoings(node)
                    # get the results of the node
                    results = self.get_results(node, xmi_id)
                    # get the arguments of the node
                    arguments = self.get_arguments(node, xmi_id)
                    # create node object
                    self.create_node_object(nodes_dict, xmi_id, xmi_type, name, \
                                           incomings, outgoings, results, arguments, behavior)
                    # put all the results and arguments in the pins_dict
                    # if not all empty
                    if (results or arguments):
                        self.__set_pins_dict(pins_dict, results, arguments)
                # get all the edges
                edges = self.get_child_nodes(packaged_element, "edge")
                # get every node
                for edge in edges:
                    # get the id,name,type of the edge
                    xmi_id, name, xmi_type = self.get_id_name_type(edge)
                    # get the target, source of the edge
                    target, source = self.get_target_source(edge)
                    # get the guard of the edge
                    guard = self.get_guard(edge)
                    # create edge object
                    self.create_edge_object(edges_dict, xmi_id, xmi_type, name, \
                                           target, source, guard)
            # <packagedElement name="UserData" xmi:type="uml:InstanceSpecification" xmi:id="EAID_C3D4C"/>
            elif xmi_type == "uml:InstanceSpecification":
                InstanceSpecification_node = uml_element.InstanceSpecification_node(xmi_id, xmi_type, name, [], [])
                InstanceSpecification_nodes.append(InstanceSpecification_node)
        
        for InstanceSpecification_node in InstanceSpecification_nodes:
            model.activitys_dict[activity_id].nodes_dict[InstanceSpecification_node.xmi_id] = InstanceSpecification_node
        
        if exporter == "MagicDraw UML":
            # time parser
            data_times = self.get_child_nodes(root, "Data:Time")
            for data_time in data_times:
                str_time, base_element , time_type = self.get_time_base_element(data_time)
                self.set_time(str_time, base_element, time_type, model)

            # for from EA imported xml
            thecustomprofile_times = self.get_child_nodes(root, "thecustomprofile:time")
            for thecustomprofile_time in thecustomprofile_times:
                str_time, base_element, time_type = self.get_time_base_element(thecustomprofile_time)
                self.set_time(str_time, base_element, time_type, model)

        elif exporter == "Enterprise Architect":
            # get the tag "time" for EA
            extension = self.get_child_nodes(root, "xmi:Extension")[0]
            elements = self.get_child_nodes(extension, "elements")[0]
            element_tags = self.get_child_nodes(elements, "element")
            for element in element_tags:
                tags = self.get_child_nodes(element, "tags")
                if len(tags) > 0:
                    tags = tags[0]
                    tag_elements = self.get_child_nodes(tags, "tag")
                    for tag in tag_elements:
                        if tag.hasAttribute("name"):
                            name = tag.getAttribute("name")
                            if name == "time":
                                if tag.hasAttribute("value"):
                                    str_time = tag.getAttribute("value")
                                    base_element = element.getAttribute("xmi:idref")
                                    # TODO 
                                    self.set_time(str_time, base_element, "exp", model)
        else:
            log.show_error("the exporter is not supported in the code")

        return model
Beispiel #24
0
'''
Created on 27.11.2015

@author: Kai
'''
from activity_diagram_to_ptnet import ActivityDiagramToPetriNet
import log
import examples
import time

start = time.clock()
# the path of the xml
xml_path = examples.get_xml_path()
# create the main object
act_to_pt = ActivityDiagramToPetriNet()
# load xml and parsing
act_to_pt.load_xml(xml_path)
# start activity_analyse
act_to_pt.activity_analyse()
# transform_to_pt to Petri net
act_to_pt.transform_to_epf()

end = time.clock()
log.show_info("completed in " + str(end - start) + "s")
Beispiel #25
0
    def draw_petri_net(self, petri_net):
        '''draw Petri Net from the 3 dicts
        '''
        places_dict = petri_net.places_dict
        transitions_dict = petri_net.transitions_dict
        arcs_dict = petri_net.arcs_dict
        # G=pgv.AGraph(directed=True,strict=True,splines="polyline")
        # G = pgv.AGraph(directed=True, strict=True, splines=False)
        G = pgv.AGraph(directed=True, strict=True)
        G.graph_attr['label'] = petri_net.label + petri_net.probs

        for pt_id in places_dict:
            place = places_dict[pt_id]
            place_xlabel = place.xlabel
            G.add_node(pt_id, shape="circle", label="", xlabel=place_xlabel)
        for pt_id in transitions_dict:
            transition = transitions_dict[pt_id]
            # get the max number of the incomings and outgoings
            number = max(len(transition.incomings), len(transition.outgoings))
            transition_width = 0.5 * number
            transition_xlabel = transition.xlabel

            transition_type = transition.transition_type
            # Deterministic transitions are drawn as black filled rectangles.
            if transition_type == petri_net_element.TransitionTypes.DETERMINISTIC_TRANSITION:
                G.add_node(pt_id, shape="box", style="filled", label="", \
                            xlabel=transition_xlabel, height=0.3, \
                            width=transition_width, fillcolor="#000000")  # color:black
            # Exponential transitions are drawn as empty rectangles.
            elif transition_type == petri_net_element.TransitionTypes.EXPONENTIAL_TRANSITION:
                G.add_node(pt_id,
                           shape="box",
                           label="",
                           xlabel=transition_xlabel,
                           height=0.3,
                           width=transition_width,
                           fillcolor="#000000")  # color:black
            # Immediate transitions are drawn as thin bars.
            elif transition_type == petri_net_element.TransitionTypes.IMMEDIATE_TRANSITION:
                G.add_node(pt_id,
                           shape="box",
                           style="filled",
                           label="",
                           xlabel=transition_xlabel,
                           height=0.08,
                           width=transition_width,
                           fillcolor="#000000")  # color:black
            else:
                log.show_error("the transition type is not defined")
        for pt_id in arcs_dict:
            arc = arcs_dict[pt_id]
            source = arc.source
            target = arc.target
            G.add_edge(source, target)
            # draw the arc with probability
            # if arc.prob == 1:
            #    G.add_edge(source, target)
            # else:
            #    G.add_edge(source, target, label=arc.prob)

        # print G.string()  # print dot file to standard output
        png_name = self.get_png_name()
        # G.write("Pt"+png_name + ".dot")
        G.layout('dot')  # layout with dot
        G.draw("Pt" + "_" + petri_net.name + png_name +
               ".png")  # write to file
        log.show_info("the Petri Net Diagram is created.name:%s" %
                      petri_net.name)
    def get_petri_type(self, petri_net):
        '''get the type of Petri-Net
        @see: http://www.informatik.uni-hamburg.de/TGI/PetriNets/classification/
        -Place/Transition (P/T) Nets
            *(Ordinary) Petri Nets (PN)
                ~1-safe Net Systems
                ~Free Choice Nets: @1
                    S-Systems
                        State Machines (SM): @2
                    T-System
                        Marked Graphs (MG): @3
                    Structural Free Choice Extensions:
        ps:
        1: A Free Choice Net is an ordinary Petri Net such that every arc from a place is
        either a unique outgoing arc or a unique incoming arc to a transition
            1a.if two transitions share a common input place then they have no other input places
            1b.If two places share a common transition then they have no other transition
            --here algorithm
        2: A State Machine is a Petri Net where every transition has only
        one input place and one output place
        3: A Marked Graph is a pure (ordinary) Petri Net system where every place has only
        one input transition and one output transition
        '''
        petri_type = []

        places_dict = petri_net.places_dict
        transitions_dict = petri_net.transitions_dict
        arcs_dict = petri_net.arcs_dict

        free_choice = True
        state_machines = True
        marked_graphs = True

        for t_id in transitions_dict:
            transition = transitions_dict[t_id]
            incomings = transition.incomings
            outgoings = transition.outgoings
            in_num = len(incomings)
            out_num = len(outgoings)
            if in_num > 1:
                state_machines = False
                # if it is free_choice
                for incoming in incomings:
                    arc = arcs_dict[incoming]
                    p_id = arc.source
                    place = places_dict[p_id]
                    if len(place.outgoings) > 1:
                        # the place has another transition
                        free_choice = False
                        marked_graphs = False
                        break
                # if not free_choice,break. it is neither state_machines nor marked_graphs
                if not free_choice:
                    break
            elif out_num > 1:
                state_machines = False

        # it is free_choice, see if it is marked_graphs
        if free_choice:
            for p_id in places_dict:
                place = places_dict[p_id]
                incomings = place.incomings
                outgoings = place.outgoings
                in_num = len(incomings)
                out_num = len(outgoings)
                if in_num > 1 or out_num > 1:
                    marked_graphs = False
                    break

        if free_choice:
            if state_machines and marked_graphs:
                petri_type.append(petri_net_element.PetriNetTypes.STATE_MACHINES)
                petri_type.append(petri_net_element.PetriNetTypes.MARKED_GRAPHS)
                log.show_info("the type of the transformed Petri-Net is state_machines, "\
                "and also marked_graphs. name:%s" % petri_net.name)
            elif state_machines and not marked_graphs:
                petri_type.append(petri_net_element.PetriNetTypes.STATE_MACHINES)
                log.show_info("the type of the transformed Petri-Net is state_machines."\
                               + " name:%s" % petri_net.name)
            elif not state_machines and marked_graphs:
                petri_type.append(petri_net_element.PetriNetTypes.MARKED_GRAPHS)
                log.show_info("the type of the transformed Petri-Net is marked_graphs."\
                              + " name:%s" % petri_net.name)
            else:
                petri_type.append(petri_net_element.PetriNetTypes.FREE_CHOICE)
                log.show_info("the type of the transformed Petri-Net is free_choice, "\
                              "it is neither state_machines nor marked_graphs."\
                               + " name:%s" % petri_net.name)
        else:
            petri_type.append(petri_net_element.PetriNetTypes.NOT_FREE_CHOICE)
            log.show_info("the type of the transformed Petri-Net is not free_choice."\
                           + " name:%s" % petri_net.name)

        return petri_type
Beispiel #27
0
    def xml_parse(self, xml_path):
        """start the parsing
        @param xml_path: the path of the xml
        @attention: the different between windows and Linux
        """
        # use minidom to open the xml
        try:
            DOMTree = minidom.parse(xml_path)
            # collection = DOMTree.documentElement
        except IOError:
            log.show_error("the xml is wrong")

        # get the root tag of the xml
        root = DOMTree.documentElement

        # get the tag: <xmi:Documentation>
        # get the exporter(Magic Draw or EA) and exporterVersion
        documentation = self.get_child_nodes(root, "xmi:Documentation")[0]
        exporter, export_version = self.get_exporter_version(documentation)

        log.show_info("exporter:" + exporter + ".exportVersion:" + export_version)

        # get <uml:Model  />
        model_node = self.get_child_nodes(root, "uml:Model")[0]
        # the 4 parameters: xmi_id, xmi_type, name, activitys_dict
        xmi_id, name, xmi_type = self.get_id_name_type(model_node)

        activitys_dict = {}
        # create the model
        model = uml_element.Model(xmi_id, xmi_type, name, activitys_dict)
        # get <packagedElement>
        # packaged_elements = self.get_child_nodes(model_node, "packagedElement")
        packaged_elements = model_node.getElementsByTagName("packagedElement")

        InstanceSpecification_nodes = []
        activity_id = None
        for packaged_element in packaged_elements:
            xmi_id, name, xmi_type = self.get_id_name_type(packaged_element)
            # get the activity diagram "uml:Activity"
            if xmi_type == uml_element.Types.ACTIVITY:
                # xmi_id:ActivityNode (class UmlActivityDiagramElement.ActivityNode)
                nodes_dict = {}
                # xmi_id:ActivityEdge (class uml_activity_diagram_element.ActivityEdge)
                edges_dict = {}
                # Result and Argument
                pins_dict = {}
                # create activity
                activity = uml_element.Activity(xmi_id, xmi_type, name, nodes_dict, edges_dict, pins_dict)
                # put it in the activitys_dict
                activitys_dict[xmi_id] = activity
                # activity_id
                activity_id = xmi_id
                # get all the nodes
                nodes = self.get_child_nodes(packaged_element, "node")
                # get every node
                for node in nodes:
                    # get the id, name, type of the node
                    xmi_id, name, xmi_type = self.get_id_name_type(node)
                    # get behavior
                    behavior = self.get_behavior(node)
                    # get incomings of the node
                    incomings = self.get_incomings(node)
                    # get outgoings of the node
                    outgoings = self.get_outgoings(node)
                    # get the results of the node
                    results = self.get_results(node, xmi_id)
                    # get the arguments of the node
                    arguments = self.get_arguments(node, xmi_id)
                    # create node object
                    self.create_node_object(
                        nodes_dict, xmi_id, xmi_type, name, incomings, outgoings, results, arguments, behavior
                    )
                    # put all the results and arguments in the pins_dict
                    # if not all empty
                    if results or arguments:
                        self.__set_pins_dict(pins_dict, results, arguments)
                # get all the edges
                edges = self.get_child_nodes(packaged_element, "edge")
                # get every node
                for edge in edges:
                    # get the id,name,type of the edge
                    xmi_id, name, xmi_type = self.get_id_name_type(edge)
                    # get the target, source of the edge
                    target, source = self.get_target_source(edge)
                    # get the guard of the edge
                    guard = self.get_guard(edge)
                    # create edge object
                    self.create_edge_object(edges_dict, xmi_id, xmi_type, name, target, source, guard)
            # <packagedElement name="UserData" xmi:type="uml:InstanceSpecification" xmi:id="EAID_C3D4C"/>
            elif xmi_type == "uml:InstanceSpecification":
                InstanceSpecification_node = uml_element.InstanceSpecification_node(xmi_id, xmi_type, name, [], [])
                InstanceSpecification_nodes.append(InstanceSpecification_node)

        for InstanceSpecification_node in InstanceSpecification_nodes:
            model.activitys_dict[activity_id].nodes_dict[InstanceSpecification_node.xmi_id] = InstanceSpecification_node

        if exporter == "MagicDraw UML":
            # time parser
            data_times = self.get_child_nodes(root, "Data:Time")
            for data_time in data_times:
                str_time, base_element, time_type = self.get_time_base_element(data_time)
                self.set_time(str_time, base_element, time_type, model)

            # for from EA imported xml
            thecustomprofile_times = self.get_child_nodes(root, "thecustomprofile:time")
            for thecustomprofile_time in thecustomprofile_times:
                str_time, base_element, time_type = self.get_time_base_element(thecustomprofile_time)
                self.set_time(str_time, base_element, time_type, model)

        elif exporter == "Enterprise Architect":
            # get the tag "time" for EA
            extension = self.get_child_nodes(root, "xmi:Extension")[0]
            elements = self.get_child_nodes(extension, "elements")[0]
            element_tags = self.get_child_nodes(elements, "element")
            for element in element_tags:
                tags = self.get_child_nodes(element, "tags")
                if len(tags) > 0:
                    tags = tags[0]
                    tag_elements = self.get_child_nodes(tags, "tag")
                    for tag in tag_elements:
                        if tag.hasAttribute("name"):
                            name = tag.getAttribute("name")
                            if name == "time":
                                if tag.hasAttribute("value"):
                                    str_time = tag.getAttribute("value")
                                    base_element = element.getAttribute("xmi:idref")
                                    # TODO
                                    self.set_time(str_time, base_element, "exp", model)
        else:
            log.show_error("the exporter is not supported in the code")

        return model
 def _analyse_nodes(self, node1, node2, activity):
     '''for example:
     situation:
     1. action1(with(out) pout)-->action2 (with(out) pin)
     2. action1-->object-->action2(or control)
     3. action1 with pin-->control node #pass
     4. control node(fork,decision,merge)-->action2 with pin #pass
     5. control node(fork,decision,merge)-->object-->action2(or control)
     6. control node-->control node #pass
     7. object node-->... #pass
     if action1 has no control flow, add one control flow between action1 and action2.
     '''
     # if node1 and node2 are actions
     # 1.situation
     if (isinstance(node1, uml_element.ExecutableNode) and \
         isinstance(node2, uml_element.ExecutableNode)):
         log.show_info("1.situation: action to action")
         # if node1 has no control flow
         if not self._has_outgoing_control_flow(node1, activity):
             # add one control flow from action1 to action2
             self._add_control_flow(node1, node2, activity)
     # if node1 is a action, and node2 is a object_node
     # 2.situation
     elif (isinstance(node1, uml_element.ExecutableNode)
           and isinstance(node2, uml_element.ObjectNode)):
         log.show_info("2.situation: action to object node")
         # if node1 has no control flow
         if not self._has_outgoing_control_flow(node1, activity):
             node3 = self._get_object_next_node(node2, activity)
             # if node3 not None
             if node3:
                 self._add_control_flow(node1, node3, activity)
     # if node1 is a action with pout, and node2 is a control
     # 3.situation
     elif (isinstance(node1, uml_element.ExecutableNode)
           and isinstance(node2, uml_element.ControlNode)):
         log.show_info("3.situation: action to control node")
         # pass
     # if node1 is control_node, node2 is a action with pin
     # 4.situation
     elif (isinstance(node1, uml_element.ControlNode)
           and isinstance(node2, uml_element.ExecutableNode)):
         log.show_info("4.situation: control node to action")
         # pass
     # if node1 is control_node, node2 is object_node
     # 5.situation
     elif (isinstance(node1, uml_element.ControlNode)
           and isinstance(node2, uml_element.ObjectNode)):
         log.show_info("5.situation: control node to object node")
         node3 = self._get_object_next_node(node2, activity)
         if node3:
             # add one control flow from node1 to node3
             self._add_control_flow(node1, node3, activity)
     # if node1 is control_node, node2 is control_node
     # 6.situation
     elif (isinstance(node1, uml_element.ControlNode)
           and isinstance(node2, uml_element.ControlNode)):
         log.show_info("6.situation: control node to control node")
         # TODO
         # pass
     # if node1 is object node
     # 7.situation
     elif isinstance(node1, uml_element.ObjectNode):
         pass
     else:
         log.show_warn("a object flow from node1 to node2,"
                       "but the 2 nodes's situation are not defined")