Total Complexity | 140 |
Total Lines | 548 |
Duplicated Lines | 5.47 % |
Coverage | 98.47% |
Changes | 0 |
Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like graph.oval_graph often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
1 | ''' |
||
2 | Modules form my lib and for create ID |
||
3 | ''' |
||
4 | 1 | import graph.xml_parser |
|
5 | 1 | import graph.evaluate |
|
6 | 1 | import uuid |
|
7 | 1 | import collections |
|
8 | 1 | import re |
|
9 | |||
10 | ''' |
||
11 | This module contains methods and classes for |
||
12 | constructing and controlling an oval tree. |
||
13 | ''' |
||
14 | |||
15 | |||
16 | 1 | class OvalNode(): |
|
17 | ''' |
||
18 | The OvalNode object is one node of oval graph. |
||
19 | |||
20 | Args: |
||
21 | node_id (str|int): identifies node |
||
22 | input_node_type (str): type of node (value or operator) |
||
23 | input_value (str): value of node |
||
24 | children ([OvalNode]): array of children of node |
||
25 | |||
26 | Attributes: |
||
27 | node_id (str): id of node |
||
28 | node_type (str): type node |
||
29 | value (str): value of node for operator and, |
||
30 | or, one etc... and for value true, false, error etc... |
||
31 | children ([OvalNode]): children of node |
||
32 | ''' |
||
33 | |||
34 | 1 | def __init__( |
|
35 | self, |
||
36 | node_id, |
||
37 | input_node_type, |
||
38 | input_value, |
||
39 | input_negation, |
||
40 | comment, |
||
41 | children=None): |
||
42 | 1 | self.comment = comment |
|
43 | 1 | self.node_id = node_id |
|
44 | 1 | if isinstance(input_negation, bool): |
|
45 | 1 | self.negation = input_negation |
|
46 | else: |
||
47 | 1 | raise ValueError("err- negation is bool (only True or False)") |
|
48 | 1 | value = input_value.lower() |
|
49 | 1 | node_type = input_node_type.lower() |
|
50 | 1 | if node_type == "value" or node_type == "operator": |
|
51 | 1 | self.node_type = node_type |
|
52 | else: |
||
53 | 1 | raise ValueError("err- unknown type") |
|
54 | 1 | allowed_operators = [ |
|
55 | "or", |
||
56 | "and", |
||
57 | "one", |
||
58 | "xor"] |
||
59 | 1 | allowed_values = [ |
|
60 | "true", |
||
61 | "false", |
||
62 | "error", |
||
63 | "unknown", |
||
64 | "noteval", |
||
65 | "notappl"] |
||
66 | 1 | if self.node_type == "value": |
|
67 | 1 | if value in allowed_values: |
|
68 | 1 | self.value = value |
|
69 | else: |
||
70 | 1 | raise ValueError("err- unknown value") |
|
71 | 1 | if self.node_type == "operator": |
|
72 | 1 | if value in allowed_operators: |
|
73 | 1 | self.value = value |
|
74 | else: |
||
75 | 1 | raise ValueError("err- unknown operator") |
|
76 | 1 | self.children = [] |
|
77 | 1 | if children is not None: |
|
78 | 1 | for child in children: |
|
79 | 1 | self.add_child(child) |
|
80 | else: |
||
81 | 1 | if self.node_type == "operator": |
|
82 | 1 | raise ValueError('err- Operator node has child!') |
|
83 | |||
84 | 1 | def __repr__(self): |
|
85 | 1 | return self.value |
|
86 | |||
87 | 1 | def add_child(self, node): |
|
88 | 1 | if self.node_type == "operator": |
|
89 | 1 | assert isinstance(node, OvalNode) |
|
90 | 1 | self.children.append(node) |
|
91 | else: |
||
92 | 1 | self.children = None |
|
93 | 1 | raise ValueError( |
|
94 | "err- Value node don't has any child!") |
||
95 | |||
96 | 1 | def _get_result_counts(self): |
|
97 | 1 | result = { |
|
98 | 'true_cnt': 0, |
||
99 | 'false_cnt': 0, |
||
100 | 'error_cnt': 0, |
||
101 | 'unknown_cnt': 0, |
||
102 | 'noteval_cnt': 0, |
||
103 | 'notappl_cnt': 0 |
||
104 | } |
||
105 | |||
106 | 1 | for child in self.children: |
|
107 | 1 | if child.value == 'true': |
|
108 | 1 | result['true_cnt'] += 1 |
|
109 | 1 | elif child.value == 'false': |
|
110 | 1 | result['false_cnt'] += 1 |
|
111 | 1 | elif child.value == 'error': |
|
112 | 1 | result['error_cnt'] += 1 |
|
113 | 1 | elif child.value == 'unknown': |
|
114 | 1 | result['unknown_cnt'] += 1 |
|
115 | 1 | elif child.value == 'noteval': |
|
116 | 1 | result['noteval_cnt'] += 1 |
|
117 | 1 | elif child.value == 'notappl': |
|
118 | 1 | result['notappl_cnt'] += 1 |
|
119 | else: |
||
120 | 1 | if self.node_type == "operator": |
|
121 | 1 | result[child.evaluate_tree() + "_cnt"] += 1 |
|
122 | 1 | return result |
|
123 | |||
124 | 1 | def evaluate_tree(self): |
|
125 | 1 | result = self._get_result_counts() |
|
126 | 1 | out_result = None |
|
127 | 1 | if graph.evaluate.is_notapp_result(result): |
|
128 | 1 | out_result = "notappl" |
|
129 | else: |
||
130 | 1 | if self.value == "or": |
|
131 | 1 | out_result = graph.evaluate.oval_operator_or(result) |
|
132 | 1 | elif self.value == "and": |
|
133 | 1 | out_result = graph.evaluate.oval_operator_and(result) |
|
134 | 1 | elif self.value == "one": |
|
135 | 1 | out_result = graph.evaluate.oval_operator_one(result) |
|
136 | 1 | elif self.value == "xor": |
|
137 | 1 | out_result = graph.evaluate.oval_operator_xor(result) |
|
138 | |||
139 | 1 | if out_result == 'true' and self.negation: |
|
140 | 1 | out_result = 'false' |
|
141 | 1 | elif out_result == 'false' and self.negation: |
|
142 | 1 | out_result = 'true' |
|
143 | |||
144 | 1 | return out_result |
|
145 | |||
146 | 1 | def save_tree_to_dict(self): |
|
147 | 1 | if not self.children: |
|
148 | 1 | return { |
|
149 | 'node_id': self.node_id, |
||
150 | 'type': self.node_type, |
||
151 | 'value': self.value, |
||
152 | 'negation': self.negation, |
||
153 | 'comment': self.comment, |
||
154 | 'child': None |
||
155 | } |
||
156 | 1 | return { |
|
157 | 'node_id': self.node_id, |
||
158 | 'type': self.node_type, |
||
159 | 'value': self.value, |
||
160 | 'negation': self.negation, |
||
161 | 'comment': self.comment, |
||
162 | 'child': [child.save_tree_to_dict() for child in self.children] |
||
163 | } |
||
164 | |||
165 | 1 | def _get_node_icon(self): |
|
166 | 1 | value = self.evaluate_tree() |
|
167 | 1 | icon = None |
|
168 | 1 | View Code Duplication | if value is None: |
|
|||
169 | 1 | if self._is_negated_boolean('true', self.value): |
|
170 | icon = 'false' |
||
171 | 1 | elif self._is_negated_boolean('false', self.value): |
|
172 | icon = 'true' |
||
173 | else: |
||
174 | 1 | icon = self.value |
|
175 | 1 | icon, value = self.value, icon |
|
176 | else: |
||
177 | 1 | if self._is_negated_boolean('true', value): |
|
178 | icon = 'false' |
||
179 | 1 | elif self._is_negated_boolean('false', value): |
|
180 | icon = 'true' |
||
181 | else: |
||
182 | 1 | icon = value |
|
183 | |||
184 | 1 | VALUE_TO_COLOR = { |
|
185 | "true": "text-success", |
||
186 | "false": "text-danger", |
||
187 | "error": "text-dark", |
||
188 | "unknown": "text-dark", |
||
189 | "noteval": "text-dark", |
||
190 | "notappl": "text-dark" |
||
191 | } |
||
192 | |||
193 | 1 | VALUE_TO_ICON = { |
|
194 | "true": "glyphicon glyphicon-ok", |
||
195 | "false": "glyphicon glyphicon-remove", |
||
196 | "error": "glyphicon glyphicon-question-sign", |
||
197 | "unknown": "glyphicon glyphicon-question-sign", |
||
198 | "noteval": "glyphicon glyphicon-question-sign", |
||
199 | "notappl": "glyphicon glyphicon-question-sign" |
||
200 | } |
||
201 | |||
202 | 1 | return dict( |
|
203 | color=VALUE_TO_COLOR[value], |
||
204 | icon=VALUE_TO_ICON[icon]) |
||
205 | |||
206 | 1 | def get_comment(self): |
|
207 | 1 | if self.comment is not None: |
|
208 | 1 | return str(self.comment) |
|
209 | 1 | return "" |
|
210 | |||
211 | 1 | def to_JsTree_dict(self): |
|
212 | 1 | icons = self._get_node_icon() |
|
213 | 1 | out = { |
|
214 | 'text': '<strong><span class="' + icons['color'] + '">' + |
||
215 | self._get_label() + '</span></strong>' + |
||
216 | ' <i>' + self.get_comment() + '</i>', |
||
217 | "icon": icons['icon'] + ' ' + icons['color'], |
||
218 | "state": { |
||
219 | "opened": True}} |
||
220 | 1 | if self.children: |
|
221 | 1 | out['children'] = [child.to_JsTree_dict() |
|
222 | for child in self.children] |
||
223 | 1 | return out |
|
224 | |||
225 | 1 | def find_node_with_ID(self, node_id): |
|
226 | 1 | if self.node_id == node_id: |
|
227 | 1 | return self |
|
228 | else: |
||
229 | 1 | for child in self.children: |
|
230 | 1 | if child.node_id == node_id: |
|
231 | 1 | return child |
|
232 | 1 | for child in self.children: |
|
233 | 1 | if child.children != []: |
|
234 | 1 | return child.find_node_with_ID(node_id) |
|
235 | |||
236 | 1 | def add_to_tree(self, node_id, newNode): |
|
237 | 1 | self.find_node_with_ID(node_id).add_child(newNode) |
|
238 | |||
239 | 1 | def change_tree_value(self, node_id, value): |
|
240 | 1 | self.find_node_with_ID(node_id).value = value |
|
241 | |||
242 | # Methods for interpreting oval tree with SigmaJS |
||
243 | |||
244 | 1 | def _get_label(self): |
|
245 | 1 | if self.node_type == 'value': |
|
246 | 1 | return re.sub( |
|
247 | '(oval:ssg-test_|oval:ssg-)|(:def:1|:tst:1)', '', str(self.node_id)) |
||
248 | else: |
||
249 | 1 | if str(self.node_id).startswith('xccdf_org'): |
|
250 | 1 | return re.sub( |
|
251 | '(xccdf_org.ssgproject.content_)', '', str( |
||
252 | self.node_id)) |
||
253 | 1 | return self.value |
|
254 | |||
255 | 1 | def _is_negated_boolean(self, boolean, value): |
|
256 | 1 | if value == boolean and self.negation: |
|
257 | 1 | return True |
|
258 | 1 | return False |
|
259 | |||
260 | 1 | def _get_node_colors(self): |
|
261 | 1 | value = self.evaluate_tree() |
|
262 | 1 | borderValue = None |
|
263 | 1 | View Code Duplication | if value is None: |
264 | 1 | if self._is_negated_boolean('true', self.value): |
|
265 | 1 | borderValue = 'false' |
|
266 | 1 | elif self._is_negated_boolean('false', self.value): |
|
267 | 1 | borderValue = 'true' |
|
268 | else: |
||
269 | 1 | borderValue = self.value |
|
270 | 1 | borderValue, value = self.value, borderValue |
|
271 | else: |
||
272 | 1 | if self._is_negated_boolean('true', value): |
|
273 | 1 | borderValue = 'false' |
|
274 | 1 | elif self._is_negated_boolean('false', value): |
|
275 | 1 | borderValue = 'true' |
|
276 | else: |
||
277 | 1 | borderValue = value |
|
278 | 1 | VALUE_TO_COLOR = { |
|
279 | "true": "#00ff00", |
||
280 | "false": "#ff0000", |
||
281 | "error": "#000000", |
||
282 | "unknown": "#000000", |
||
283 | "noteval": "#000000", |
||
284 | "notappl": "#000000" |
||
285 | } |
||
286 | 1 | return dict( |
|
287 | color=VALUE_TO_COLOR[value], |
||
288 | borderColor=VALUE_TO_COLOR[borderValue]) |
||
289 | |||
290 | 1 | def _get_node_title(self): |
|
291 | 1 | value = self.evaluate_tree() |
|
292 | 1 | if value is None: |
|
293 | 1 | value = self.value |
|
294 | 1 | if value == 'true' or value == 'false': |
|
295 | 1 | return self.node_id |
|
296 | 1 | return str(self.node_id) + ' ' + self.value |
|
297 | |||
298 | 1 | def _create_node(self, x, y): |
|
299 | # print(self.evaluate_tree(),self.value) |
||
300 | 1 | colors = self._get_node_colors() |
|
301 | 1 | return { |
|
302 | 'id': self.node_id, |
||
303 | 'label': self._get_label(), |
||
304 | 'url': 'null', |
||
305 | 'text': self.comment, |
||
306 | 'title': self._get_node_title(), |
||
307 | "x": x, |
||
308 | "y": y, |
||
309 | "size": 3, |
||
310 | "color": colors['color'], |
||
311 | "type": "circle", |
||
312 | "borderColor": colors['borderColor']} |
||
313 | |||
314 | 1 | def _create_edge(self, id_source, id_target, target_node): |
|
315 | 1 | return { |
|
316 | "id": str(uuid.uuid4()), |
||
317 | "source": id_source, |
||
318 | "target": id_target, |
||
319 | "color": self._get_color_edge(target_node) |
||
320 | } |
||
321 | |||
322 | 1 | def _get_color_edge(self, target_node): |
|
323 | 1 | return target_node['color'] |
|
324 | |||
325 | 1 | def create_list_of_id(self, array_of_ids=None): |
|
326 | 1 | if array_of_ids is None: |
|
327 | 1 | array_of_ids = [] |
|
328 | 1 | array_of_ids.append(self.node_id) |
|
329 | 1 | for child in self.children: |
|
330 | 1 | if child.node_type != "operator": |
|
331 | 1 | array_of_ids.append(child.node_id) |
|
332 | else: |
||
333 | 1 | array_of_ids.append(child.node_id) |
|
334 | 1 | child.create_list_of_id(array_of_ids) |
|
335 | 1 | return array_of_ids |
|
336 | |||
337 | 1 | def _remove_Duplication(self, graph_data): |
|
338 | 1 | array_of_ids = self.create_list_of_id() |
|
339 | 1 | out = dict(nodes=[], edges=graph_data['edges']) |
|
340 | 1 | duplicate_ids = [item for item, count in collections.Counter( |
|
341 | array_of_ids).items() if count > 1] |
||
342 | |||
343 | 1 | for node in graph_data['nodes']: |
|
344 | 1 | if node['id'] not in duplicate_ids: |
|
345 | 1 | out['nodes'].append(node) |
|
346 | |||
347 | 1 | for id in duplicate_ids: |
|
348 | 1 | for node in graph_data['nodes']: |
|
349 | 1 | if node['id'] == id: |
|
350 | 1 | out['nodes'].append(node) |
|
351 | 1 | break |
|
352 | 1 | return out |
|
353 | |||
354 | 1 | def _fix_graph(self, preprocessed_graph_data): |
|
355 | 1 | for node in preprocessed_graph_data['nodes']: |
|
356 | 1 | for node1 in preprocessed_graph_data['nodes']: |
|
357 | 1 | if node['x'] == node1['x'] and node['y'] == node1['y']: |
|
358 | 1 | node['x'] = node['x'] - 1 |
|
359 | 1 | return preprocessed_graph_data |
|
360 | |||
361 | 1 | def _help_to_sigma_dict(self, x, y, preprocessed_graph_data=None): |
|
362 | 1 | if preprocessed_graph_data is None: |
|
363 | 1 | preprocessed_graph_data = dict(nodes=[], edges=[]) |
|
364 | 1 | preprocessed_graph_data['nodes'].append(self._create_node(x, y)) |
|
365 | 1 | y_row = y + 1 |
|
366 | 1 | x_row = x |
|
367 | 1 | for node in self.children: |
|
368 | 1 | preprocessed_graph_data['nodes'].append( |
|
369 | node._create_node(x_row, y_row)) |
||
370 | 1 | preprocessed_graph_data['edges'].append(node._create_edge( |
|
371 | self.node_id, node.node_id, preprocessed_graph_data['nodes'][-1])) |
||
372 | 1 | x_row = x_row + 1 |
|
373 | 1 | if node.children is not None: |
|
374 | 1 | preprocessed_graph_data = node._help_to_sigma_dict( |
|
375 | x_row + 1, y_row + 1, preprocessed_graph_data) |
||
376 | 1 | return self._fix_graph(preprocessed_graph_data) |
|
377 | |||
378 | 1 | def _count_max_y(self, out): |
|
379 | 1 | max_y = 0 |
|
380 | |||
381 | 1 | for node in out['nodes']: |
|
382 | 1 | if max_y < node['y']: |
|
383 | 1 | max_y = node['y'] |
|
384 | 1 | return max_y |
|
385 | |||
386 | 1 | def _create_nodes_in_rows(self, rows): |
|
387 | 1 | nodes_in_rows = dict() |
|
388 | |||
389 | 1 | for i in range(rows + 1): |
|
390 | 1 | nodes_in_rows[i] = [] |
|
391 | 1 | return nodes_in_rows |
|
392 | |||
393 | 1 | def _push_nodes_to_nodes_in_row(self, out, nodes_in_rows): |
|
394 | 1 | for node in out['nodes']: |
|
395 | 1 | nodes_in_rows[node['y']].append(node) |
|
396 | |||
397 | 1 | def _remove_empty_rows(self, nodes_in_rows, max_y): |
|
398 | 1 | for row in range(max_y + 1): |
|
399 | 1 | if not nodes_in_rows[row]: |
|
400 | 1 | del nodes_in_rows[row] |
|
401 | |||
402 | 1 | def _move_rows(self, nodes_in_rows): |
|
403 | 1 | count = 0 |
|
404 | 1 | nodes_in_rows1 = dict() |
|
405 | |||
406 | 1 | for row in nodes_in_rows: |
|
407 | 1 | nodes_in_rows1[count] = nodes_in_rows[row] |
|
408 | 1 | for node in nodes_in_rows1[count]: |
|
409 | 1 | node['y'] = count |
|
410 | 1 | count += 1 |
|
411 | 1 | return nodes_in_rows1 |
|
412 | |||
413 | 1 | def _create_positions(self, nodes_in_rows): |
|
414 | 1 | positions = [] |
|
415 | 1 | for row in nodes_in_rows: |
|
416 | 1 | len_of_row = len(nodes_in_rows[row]) |
|
417 | 1 | if len_of_row > 1: |
|
418 | 1 | if (len_of_row % 2) == 1: |
|
419 | 1 | len_of_row += 1 |
|
420 | |||
421 | 1 | for i in range((int(-(len_of_row / 2))) * 2, |
|
422 | (int(+(len_of_row / 2)) + 1) * 2, 2): |
||
423 | 1 | positions.append(i) |
|
424 | |||
425 | 1 | if len_of_row == 2: |
|
426 | 1 | positions.remove(0) |
|
427 | |||
428 | 1 | if len(nodes_in_rows[row]) < len(positions): |
|
429 | 1 | positions.pop() |
|
430 | 1 | if len(nodes_in_rows[row]) < len(positions): |
|
431 | 1 | positions.pop(0) |
|
432 | |||
433 | 1 | count = 0 |
|
434 | |||
435 | 1 | for pos in positions: |
|
436 | 1 | nodes_in_rows[row][count]['x'] = pos |
|
437 | 1 | count += 1 |
|
438 | 1 | positions = [] |
|
439 | else: |
||
440 | 1 | nodes_in_rows[row][0]['x'] = 0 |
|
441 | |||
442 | 1 | return positions |
|
443 | |||
444 | 1 | def _convert_nodes_in_rows_to_nodes(self, nodes_in_rows): |
|
445 | 1 | nodes = [] |
|
446 | 1 | for row in nodes_in_rows: |
|
447 | 1 | for node in nodes_in_rows[row]: |
|
448 | 1 | nodes.append(node) |
|
449 | 1 | return nodes |
|
450 | |||
451 | 1 | def _change_position(self, nodes_in_rows): |
|
452 | 1 | x = 0.6 |
|
453 | 1 | up_and_down = True |
|
454 | 1 | down = False |
|
455 | 1 | down_row = False |
|
456 | 1 | save_x = 0 |
|
457 | 1 | continue_move = False |
|
458 | |||
459 | 1 | for row in nodes_in_rows: |
|
460 | 1 | for node in nodes_in_rows[row]: |
|
461 | 1 | if (len(node['label']) > 6 |
|
462 | and len(node['label']) < 40 |
||
463 | or continue_move): |
||
464 | 1 | if up_and_down: |
|
465 | 1 | node['y'] = node['y'] + (0.6 * x) |
|
466 | 1 | up_and_down = False |
|
467 | else: |
||
468 | 1 | up_and_down = True |
|
469 | 1 | continue_move = True |
|
470 | 1 | elif len(node['label']) > 30: |
|
471 | 1 | node['y'] = node['y'] + (0.6 * x) |
|
472 | 1 | x += 0.6 |
|
473 | 1 | save_x = x |
|
474 | 1 | down = True |
|
475 | else: |
||
476 | 1 | if down: |
|
477 | 1 | node['y'] = node['y'] + (0.6 * save_x) |
|
478 | |||
479 | 1 | if down_row: |
|
480 | 1 | node['y'] = node['y'] + (0.6 * save_x) - 0.7 |
|
481 | 1 | if down: |
|
482 | 1 | down = False |
|
483 | 1 | down_row = True |
|
484 | 1 | continue_move = False |
|
485 | 1 | x = 0.6 |
|
486 | |||
487 | 1 | def _sort(self, array): |
|
488 | 1 | less = [] |
|
489 | 1 | equal = [] |
|
490 | 1 | greater = [] |
|
491 | |||
492 | 1 | if len(array) > 1: |
|
493 | 1 | pivot = array[0]['x'] |
|
494 | 1 | for node in array: |
|
495 | 1 | if node['x'] < pivot: |
|
496 | less.append(node) |
||
497 | 1 | if node['x'] == pivot: |
|
498 | 1 | equal.append(node) |
|
499 | 1 | if node['x'] > pivot: |
|
500 | 1 | greater.append(node) |
|
501 | 1 | return self._sort(less) + equal + self._sort(greater) |
|
502 | else: |
||
503 | 1 | return array |
|
504 | |||
505 | 1 | def _sort_nodes(self, nodes_in_rows): |
|
506 | 1 | for row in nodes_in_rows: |
|
507 | 1 | nodes_in_rows[row] = self._sort(nodes_in_rows[row]) |
|
508 | |||
509 | 1 | def _center_graph(self, out): |
|
510 | 1 | max_y = self._count_max_y(out) |
|
511 | 1 | nodes_in_rows = self._create_nodes_in_rows(max_y) |
|
512 | 1 | self._push_nodes_to_nodes_in_row(out, nodes_in_rows) |
|
513 | 1 | self._remove_empty_rows(nodes_in_rows, max_y) |
|
514 | 1 | nodes_in_rows = self._move_rows(nodes_in_rows) |
|
515 | 1 | self._sort_nodes(nodes_in_rows) |
|
516 | 1 | self._create_positions(nodes_in_rows) |
|
517 | 1 | self._change_position(nodes_in_rows) |
|
518 | 1 | out['nodes'] = self._convert_nodes_in_rows_to_nodes(nodes_in_rows) |
|
519 | 1 | return out |
|
520 | |||
521 | 1 | def to_sigma_dict(self, x, y): |
|
522 | 1 | return self._center_graph( |
|
523 | self._remove_Duplication( |
||
524 | self._help_to_sigma_dict( |
||
525 | x, y))) |
||
526 | |||
527 | |||
528 | 1 | def build_nodes_form_xml(xml_src, rule_id): |
|
529 | 1 | parser = graph.xml_parser.xml_parser(xml_src) |
|
530 | 1 | return parser.get_oval_graph(rule_id) |
|
531 | |||
532 | |||
533 | 1 | def restore_dict_to_tree(dict_of_tree): |
|
534 | 1 | if dict_of_tree["child"] is None: |
|
535 | 1 | return OvalNode( |
|
536 | dict_of_tree["node_id"], |
||
537 | dict_of_tree["type"], |
||
538 | dict_of_tree["value"], |
||
539 | dict_of_tree["negation"], |
||
540 | dict_of_tree['comment']) |
||
541 | 1 | return OvalNode( |
|
542 | dict_of_tree["node_id"], |
||
543 | dict_of_tree["type"], |
||
544 | dict_of_tree["value"], |
||
545 | dict_of_tree["negation"], |
||
546 | dict_of_tree['comment'], |
||
547 | [restore_dict_to_tree(i) for i in dict_of_tree["child"]]) |
||
548 |