Merge "Remove dependency of impl on onf-extensions"
[openflowplugin.git] / test-scripts / openvswitch / parser_tools.py
1 '''
2 Created on Jan 24, 2014
3
4 @author: vdemcak
5 '''
6
7 import re
8 from xml.etree import ElementTree as ET
9
10 from convertor_tools import ConvertorTools
11
12
13 class ParseTools(): 
14
15     @staticmethod
16     def get_element_alias_by_key(element,key_dict):
17         return key_dict.get(element.tag) if (key_dict.get(element.tag, None) > None) else None
18
19     @staticmethod
20     def sort_ordered_dict_to_array(x_dict=None):
21         if (x_dict > None):
22             out_put = []
23             for val in map(lambda val: x_dict.get(val), sorted(x_dict.keys())) : 
24                 out_put.append(val)
25 #                 if (out_put > None) :
26 #                     out_put += ', %s' %val
27 #                 else :
28 #                     out_put = val
29             return ', '.join(out_put)
30         return
31
32     @staticmethod
33     def get_element_value(element):
34         return (re.sub('[\s]+', '', element.text, count=1)).lower() if element.text > None else ''
35
36     @staticmethod
37     def __parse_ordered_tags_from_xml(element, kwd, p_elm_n=None, ikwd=None, ord_value=None):
38         a_dict = {}
39         if (element > None) :
40             elm_n = ParseTools.get_element_alias_by_key(element, kwd)
41             if ((element.getchildren() > None) & (len(element.getchildren()) > 0)) :
42                 sub_dict ={}
43                 for child in element.getchildren() :
44                     if (child.tag == 'order') :
45                         ord_value = ParseTools.get_element_value(child)
46                     else :
47                         sub_dict.update(ParseTools.__parse_ordered_tags_from_xml(child, kwd, p_elm_n, ikwd))
48                         
49                 a_value = ParseTools.sort_ordered_dict_to_array(sub_dict)
50                 if (ord_value > None) :
51                     order = ord_value if (len(ord_value) > 0) else '0'
52                 else :
53                     order = '0'
54                 a_dict[order]=a_value
55                 
56             else :
57                 if (ord_value > None) :
58                     order = ord_value if ((len(ord_value) > 0)) else '0'
59                 else :
60                     order = '0'
61                 a_val = elm_n if elm_n > None else element.tag
62                 a_dict[order] = a_val
63                 
64         return a_dict
65
66     @staticmethod
67     def __parse_tags_from_xml(element, flow_dict, kwd, p_elm_n=None, ikwd=None):
68         if element > None :
69             # find and translate element.tag in key_word_dictionary
70             elm_n = ParseTools.get_element_alias_by_key(element, kwd)
71             if ((element.getchildren() > None) & (len(element.getchildren()) > 0)) :
72                 for child in element.getchildren() :
73                     new_p_elm_n = elm_n if elm_n > None else p_elm_n
74                     ParseTools.__parse_tags_from_xml(child, flow_dict, kwd, new_p_elm_n, ikwd)
75             else :
76                 # prefer parent element_name before elment_name and element_name before element.tag
77                 a_key = elm_n if elm_n > None else p_elm_n if (p_elm_n > None) else element.tag
78                 a_value = ParseTools.get_element_value(element)
79                 # Don't continue for ignore tags
80                 if (ikwd > None) :
81                     if (ikwd.get(a_key, None) > None) :
82                         # TODO add check for cookie_mask (mask has to have same or more length as cookie if is more as 0)
83                         return
84                 flow_dict[a_key] = ConvertorTools.base_tag_values_conversion(a_key, a_value)
85
86     @staticmethod
87     def get_switchflow_from_xml(xml_string, key_dict=None, action_key_dict=None, match_key_dict=None, ignore_key_dict=None):
88         if xml_string > None :
89             # remove namespace
90             xml_string = re.sub(' xmlns="[^"]+"', '', xml_string, count=1)
91             tree = ET.fromstring(xml_string)
92             
93         flow_dict = {}
94         
95         if (tree > None) :
96             if (tree.getchildren() > None) :
97                 for child in tree.getchildren() :
98                     if (child.tag == 'match') :
99                         ParseTools.__parse_tags_from_xml(child, flow_dict, match_key_dict, ikwd=ignore_key_dict)
100                     elif (child.tag == 'instructions') : 
101                         x_dict = ParseTools.__parse_ordered_tags_from_xml(child, action_key_dict, ikwd=ignore_key_dict)
102                         flow_dict['actions'] = ParseTools.sort_ordered_dict_to_array(x_dict)
103                     else :
104                         ParseTools.__parse_tags_from_xml(child, flow_dict, key_dict, ikwd=ignore_key_dict) 
105
106         return flow_dict
107         
108         # TODO VD remove this method
109 #     @staticmethod
110 #     def get_switchflow_dict(switch_dict, ignore_key_dict=None):
111 #         x_dict={}
112 #         for sw_key in switch_dict.keys() :
113 #             if (ignore_key_dict.get(sw_key,None) is None):
114 #                 x_dict[sw_key] = switch_dict.get(sw_key)
115 #             
116 #         return x_dict
117     
118     @staticmethod
119     def all_nodes(xml_root):
120         """
121         Generates every non-text nodes.
122         """
123         current_nodes = [xml_root]
124         next_nodes = []
125
126         while len(current_nodes) > 0:
127             for node in current_nodes:
128                 if node.nodeType != xml_root.TEXT_NODE:
129                     yield node
130                     next_nodes.extend(node.childNodes)
131
132             current_nodes, next_nodes = next_nodes, []
133
134     @staticmethod
135     def get_values(node, *tags):
136         result = dict((tag, None) for tag in tags)
137 #         result = {tag: None for tag in tags}
138         for node in ParseTools.all_nodes(node):
139             if node.nodeName in result and len(node.childNodes) > 0:
140                 result[node.nodeName] = node.childNodes[0].nodeValue
141         return result
142
143     @staticmethod
144     def dump_string_to_dict(dump_string):
145         dump_list = ParseTools.dump_string_to_list(dump_string)
146         return ParseTools.dump_list_to_dict(dump_list)
147
148     @staticmethod
149     def dump_string_to_list(dump_string):
150         out_list = []
151         for item in dump_string.split():
152             out_list.extend(item.rstrip(',').split(','))
153
154         return out_list
155
156     @staticmethod
157     def dump_list_to_dict(dump_list):
158         out_dict = {}
159         for item in dump_list:
160             parts = item.split('=')
161             if len(parts) == 1:
162                 parts.append(None)
163             out_dict[parts[0]] = parts[1]
164
165         return out_dict