|
1 # |
|
2 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 # All rights reserved. |
|
4 # This component and the accompanying materials are made available |
|
5 # under the terms of "Eclipse Public License v1.0" |
|
6 # which accompanies this distribution, and is available |
|
7 # at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 # |
|
9 # Initial Contributors: |
|
10 # Nokia Corporation - initial contribution. |
|
11 # |
|
12 # Contributors: |
|
13 # |
|
14 # Description: |
|
15 # |
|
16 |
|
17 import logging |
|
18 |
|
19 import cone.validation.common |
|
20 |
|
21 class ValidationContext(object): |
|
22 def __init__(self, configuration): |
|
23 #: The configuration being validated |
|
24 self.configuration = configuration |
|
25 |
|
26 self._dview = None |
|
27 #: The list of validation problems |
|
28 self.problems = [] |
|
29 #: The list of fixes executed in the context |
|
30 self.fixes = [] |
|
31 |
|
32 |
|
33 @property |
|
34 def dview(self): |
|
35 """ |
|
36 The configuration's default view |
|
37 """ |
|
38 if not self._dview: |
|
39 self._dview = self.configuration.get_default_view() |
|
40 return self._dview |
|
41 |
|
42 @property |
|
43 def feature_dict(self): |
|
44 """ |
|
45 All the configuration's features as a ref -> feature dictionary. |
|
46 """ |
|
47 if not hasattr(self, '_feature_dict'): |
|
48 self._feature_dict = {} |
|
49 for fea in self.dview.get_features('**'): |
|
50 self._feature_dict[fea.fqr] = fea |
|
51 return self._feature_dict |
|
52 |
|
53 class ValidatorBase(object): |
|
54 #: Types of the problems this validator produces |
|
55 PROBLEM_TYPES = None |
|
56 |
|
57 def __init__(self, context): |
|
58 self.context = context |
|
59 |
|
60 def validate(self): |
|
61 """ |
|
62 Method called to validate a configuration. |
|
63 """ |
|
64 raise NotImplementedError() |
|
65 |
|
66 class FixerBase(object): |
|
67 def fix(self, context): |
|
68 """ |
|
69 The fix functions takes ValidationContext that is expected to contain a |
|
70 list of Problem objects that it will traverse through and it will try to |
|
71 fix any problem that matches its category. |
|
72 @param context: The ValidationContext object from which problems should be fixed. |
|
73 """ |
|
74 raise NotImplementedError() |
|
75 |
|
76 def filter_problems(self, problems, problem_type): |
|
77 """ |
|
78 A filtering function that returns a list of problems that match to the |
|
79 given problem_type. |
|
80 @param problems: a list of api.Problem objects |
|
81 @param problem_type: a string that represents the problem name. e |
|
82 .g. 'model.confml.duplicate.setting'. |
|
83 """ |
|
84 return [problem for problem in problems if problem.type == problem_type] |
|
85 |
|
86 def get_validator_classes(problem_type_filter=None): |
|
87 """ |
|
88 Return a list of all ConfML validator classes that match the given |
|
89 problem type filter (i.e. all validator classes that yield problems |
|
90 that will not be filtered out). |
|
91 |
|
92 @param problem_type_filter: The filter, if None, all validator |
|
93 classes will be returned. |
|
94 """ |
|
95 classes = [] |
|
96 |
|
97 # Validators from plug-in entry points |
|
98 classes.extend(cone.validation.common.load_plugin_classes( |
|
99 'cone.plugins.confmlvalidators', |
|
100 ValidatorBase)) |
|
101 |
|
102 # Built-in validators |
|
103 from cone.validation.builtinvalidators.confml import VALIDATOR_CLASSES |
|
104 classes.extend(VALIDATOR_CLASSES) |
|
105 |
|
106 return cone.validation.common.filter_classes(classes, problem_type_filter) |
|
107 |
|
108 def get_fixer_classes(problem_type_filter=None): |
|
109 """ |
|
110 Return a list of all ConfML fixer classes that match the given |
|
111 problem type filter (i.e. all fixer classes that yield problems |
|
112 that will not be filtered out). |
|
113 |
|
114 @param problem_type_filter: The filter, if None, all fixer |
|
115 classes will be returned. |
|
116 """ |
|
117 classes = [] |
|
118 |
|
119 # Validators from plug-in entry points |
|
120 classes.extend(cone.validation.common.load_plugin_classes( |
|
121 'cone.plugins.confmlfixers', |
|
122 FixerBase)) |
|
123 |
|
124 # Built-in validators |
|
125 from cone.validation.builtinvalidators.confml import FIXER_CLASSES |
|
126 classes.extend(FIXER_CLASSES) |
|
127 |
|
128 return cone.validation.common.filter_classes(classes, problem_type_filter) |
|
129 |
|
130 def validate_configuration(configuration, validator_classes=None): |
|
131 """ |
|
132 Validate the given configuration. |
|
133 @param configuration: The configuration to validate. |
|
134 @param validator_classes: The validator classes to use for the validation. |
|
135 If None, all validator classes will be used. |
|
136 @return: A ValidationContext objects, which contains a list of Problem objects in |
|
137 member variable problems. |
|
138 """ |
|
139 |
|
140 if validator_classes is None: |
|
141 validator_classes = get_validator_classes() |
|
142 |
|
143 context = ValidationContext(configuration) |
|
144 validators = [vc(context) for vc in validator_classes] |
|
145 for validator in validators: |
|
146 try: |
|
147 validator.validate() |
|
148 except Exception, e: |
|
149 from cone.public import utils |
|
150 utils.log_exception(logging.getLogger('cone'), |
|
151 "Error validating configuration: %s: %s" \ |
|
152 % (e.__class__.__name__, e)) |
|
153 return context |
|
154 |
|
155 def fix_configuration(configuration, context=None, fixer_classes=None): |
|
156 """ |
|
157 Validate the given configuration. |
|
158 @param configuration: The configuration to validate. |
|
159 @param context: The ValidationContext if it has been alread created. With value None |
|
160 The ValidationContext will be created and validated fisrt |
|
161 @param fixer_classes: The fixer classes to use for the validation. |
|
162 If None, all fixer classes will be used. |
|
163 @return: A ValidationContext objects, which contains a list of messaages of fixes that |
|
164 were executed. |
|
165 """ |
|
166 |
|
167 try: |
|
168 conf = configuration.get_configuration('duplicate_settings1.confml') |
|
169 data1 = conf.data |
|
170 except Exception: |
|
171 pass |
|
172 if context is None: |
|
173 context = validate_configuration(configuration) |
|
174 if fixer_classes is None: |
|
175 fixer_classes = get_fixer_classes() |
|
176 |
|
177 try: |
|
178 conf = configuration.get_configuration('duplicate_settings1.confml') |
|
179 data2 = conf.data |
|
180 except Exception: |
|
181 pass |
|
182 for fixer in fixer_classes: |
|
183 try: |
|
184 fixer().fix(context) |
|
185 except Exception, e: |
|
186 from cone.public import utils |
|
187 utils.log_exception(logging.getLogger('cone'), |
|
188 "Error fixing configuration: %s: %s" \ |
|
189 % (e.__class__.__name__, e)) |
|
190 return context |