15 |
15 |
16 ''' |
16 ''' |
17 Ruleml eval extension to check is passed ref changed on given layer(range). |
17 Ruleml eval extension to check is passed ref changed on given layer(range). |
18 ''' |
18 ''' |
19 |
19 |
20 from cone.public import api |
20 from cone.public import api, plugin |
21 |
21 |
22 import logging |
22 import logging |
|
23 import re |
23 |
24 |
24 logger = logging.getLogger('cone.ruleplugin.evals.layer_utils') |
25 logger = logging.getLogger('cone.ruleplugin.evals.layer_utils') |
|
26 |
|
27 |
|
28 def layers_used(config, layers_or_regex, impl_tags): |
|
29 """ |
|
30 Return True if matching layers are used by any implementation with given tag. |
|
31 @param config: The configuration. |
|
32 @param layers_or_regex: List of layer objects to check against, or regular |
|
33 expression (string) for resolving the list of layers. |
|
34 @param impl_tags: Implementation tags to use. |
|
35 """ |
|
36 # Resolve layer list |
|
37 if isinstance(layers_or_regex, basestring): |
|
38 layers = [] |
|
39 for lay in config.list_configurations(): |
|
40 if re.search(layers_or_regex, lay): |
|
41 layers.append(config.get_configuration(lay)) |
|
42 else: |
|
43 layers = layers_or_regex |
|
44 |
|
45 impls = plugin.filtered_impl_set(config).filter_implementations(tags=impl_tags) |
|
46 context = plugin.GenerationContext(tags=impl_tags, |
|
47 configuration=config) |
|
48 for impl in impls: |
|
49 if impl.uses_layers(layers, context) == True: |
|
50 return True |
|
51 return False |
|
52 |
|
53 |
|
54 def get_all_layers(feat): |
|
55 """ |
|
56 Returns all layers. |
|
57 """ |
|
58 |
|
59 root_conf = feat.get_root_configuration() |
|
60 result = [] |
|
61 |
|
62 for i in range(0, len(root_conf.list_configurations())): |
|
63 result.append(root_conf.get_configuration_by_index(i)) |
|
64 return result |
25 |
65 |
26 def give_changed_layers(feat): |
66 def give_changed_layers(feat): |
27 """ |
67 """ |
28 Returns a list of booleans where True means that feature is changed in that layer. Index is |
68 Returns a list of booleans where True means that feature is changed in that layer. Index is |
29 same than in configuration root's get_configuration_by_index(). |
69 same than in configuration root's get_configuration_by_index(). |
31 |
71 |
32 logger.debug('Checking feature: %s' % feat.fqr) |
72 logger.debug('Checking feature: %s' % feat.fqr) |
33 |
73 |
34 root_conf = feat.get_root_configuration() |
74 root_conf = feat.get_root_configuration() |
35 nro_of_layers = len(root_conf.list_configurations()) |
75 nro_of_layers = len(root_conf.list_configurations()) |
36 result = [False] * nro_of_layers |
76 result = [] |
37 |
|
38 for i in range(0, nro_of_layers): |
77 for i in range(0, nro_of_layers): |
39 conf = root_conf.get_configuration_by_index(i) |
78 result.append(_changed_on_layer(feat, root_conf.get_configuration_by_index(i))) |
40 logger.debug("Traversing data from configuration: %s" % conf.get_path()) |
|
41 datas = conf._traverse(type=api.Data, filters=[lambda d: d.fqr==feat.fqr]) |
|
42 for data in datas: |
|
43 try: |
|
44 if data.get_value() != None: |
|
45 logger.debug("Feature '%s' is changed in layer %s with data '%s'" % (feat.fqr, i, data.get_value())) |
|
46 result[i] = True |
|
47 except Exception, e: |
|
48 logger.debug("Failed to check Feature '%s' data in layer %s:", (e,i)) |
|
49 if result[i] == False: |
|
50 logger.debug("Feature '%s' is not changed in layer: %s" % (feat.fqr, i)) |
|
51 logger.debug("Feature '%s' is changed in layers: %s" % (feat.fqr, result)) |
|
52 return result |
79 return result |
53 |
80 |
54 def changed_on_last_layer(feat): |
81 def changed_on_last_layer(feat): |
55 """ |
82 """ |
56 Returns True if feature is changed in the last layer. |
83 Returns True if feature is changed in the last layer. |
57 """ |
84 """ |
58 |
85 |
59 root_conf = feat.get_root_configuration() |
86 root_conf = feat.get_root_configuration() |
60 conf = root_conf.get_configuration_by_index(-2)#autoconfig layer is ignored |
87 conf = root_conf.get_configuration_by_index(-2)#autoconfig layer is ignored |
61 |
88 return _changed_on_layer(feat, conf) |
62 def check(node): |
|
63 if isinstance(node, api.Data) and node.fqr == feat.fqr: |
|
64 return True |
|
65 for obj in node._objects(): |
|
66 if check(obj): |
|
67 return True |
|
68 |
|
69 if check(conf): |
|
70 return True |
|
71 else: |
|
72 return False |
|
73 |
89 |
74 def changed_on_autoconfig_layer(feat): |
90 def changed_on_autoconfig_layer(feat): |
75 """ |
91 """ |
76 Returns True if feature is changed in the autoconfig layer. |
92 Returns True if feature is changed in the autoconfig layer. |
77 """ |
93 """ |
78 |
94 |
79 root_conf = feat.get_root_configuration() |
95 root_conf = feat.get_root_configuration() |
80 conf = root_conf.get_configuration_by_index(-1) |
96 conf = root_conf.get_configuration_by_index(-1) |
81 |
97 return _changed_on_layer(feat, conf) |
82 def check(node): |
|
83 if isinstance(node, api.Data) and node.fqr == feat.fqr: |
|
84 return True |
|
85 for obj in node._objects(): |
|
86 if check(obj): |
|
87 return True |
|
88 |
|
89 if check(conf): |
|
90 return True |
|
91 else: |
|
92 return False |
|
93 |
98 |
94 def changed_on_layer(feat, layer): |
99 def changed_on_layer(feat, layer): |
95 """ |
100 """ |
96 Returns True if feature is changed in the given layer. |
101 Returns True if feature is changed in the given layer. |
97 """ |
102 """ |
98 try: |
103 try: |
99 return give_changed_layers(feat)[layer] |
104 return give_changed_layers(feat)[layer] |
100 except IndexError, e: |
105 except IndexError: |
101 logger.warning("Given layer is not found: %s" % (layer)) |
106 logger.warning("Given layer is not found: %s" % (layer)) |
102 return False |
107 return False |
|
108 |
|
109 def _changed_on_layer(feature, layer_obj): |
|
110 """ |
|
111 Return whether the given feature is changed on the given layer. |
|
112 """ |
|
113 # Check recursively if the layer contains any data objects with |
|
114 # the same FQR as the feature |
|
115 def check(node): |
|
116 if isinstance(node, api.Data) and node.fqr == feature.fqr: |
|
117 return True |
|
118 for obj in node._objects(): |
|
119 if check(obj): |
|
120 return True |
|
121 return False |
|
122 |
|
123 return check(layer_obj) |
103 |
124 |
104 def changed_on_layers(feat, findex, tindex): |
125 def changed_on_layers(feat, findex, tindex): |
105 """ |
126 """ |
106 Returns True if feature is changed in layer of given range. |
127 Returns True if feature is changed in layer of given range. |
107 """ |
128 """ |
108 layers = give_changed_layers(feat) |
129 root_conf = feat.get_root_configuration() |
|
130 nro_of_layers = len(root_conf.list_configurations()) |
109 |
131 |
110 if findex == tindex: |
132 # Convert negative indices to positive |
111 return changed_on_layer(feat, findex) |
133 def neg_index_to_pos(index): |
|
134 if index < 0: return nro_of_layers + index |
|
135 else: return index |
|
136 begin = neg_index_to_pos(findex) |
|
137 end = neg_index_to_pos(tindex) |
112 |
138 |
113 for i in range(findex, tindex): |
139 if end == begin: |
114 if i > len(layers): |
140 return changed_on_layer(feat, begin) |
|
141 |
|
142 # Check the layers inside the range |
|
143 if end > begin: index_range = xrange(begin, end) |
|
144 else: index_range = xrange(end, begin) |
|
145 for i in index_range: |
|
146 if i < 0 or i >= nro_of_layers: |
115 continue |
147 continue |
116 if layers != None and layers[i] != None and layers[i]: |
148 |
|
149 layer = root_conf.get_configuration_by_index(i) |
|
150 if _changed_on_layer(feat, layer): |
117 return True |
151 return True |
118 return False |
152 return False |
119 |
153 |
|
154 def changed_on_layers_regex(feat, regex): |
|
155 """ |
|
156 Return whether the given feature is changed on any layer that matches |
|
157 the given regular expression. |
|
158 """ |
|
159 pattern = re.compile(regex) |
|
160 root_conf = feat.get_root_configuration() |
|
161 for config_path in root_conf.list_configurations(): |
|
162 if pattern.search(config_path): |
|
163 layer = root_conf.get_configuration(config_path) |
|
164 if _changed_on_layer(feat, layer): |
|
165 return True |
|
166 return False |
|
167 |
|
168 def changed_on_custvariant_layer(feat): |
|
169 """ |
|
170 Return whether the given feature is changed on any of the custvariant layers |
|
171 (layers that match the regex '/custvariant(_.*)?/'). |
|
172 """ |
|
173 return changed_on_layers_regex(feat, r'/custvariant(_.*)?/') |