configurationengine/source/cone/validation/confmlvalidation.py
changeset 3 e7e0ae78773e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/confmlvalidation.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,190 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import logging
+
+import cone.validation.common
+
+class ValidationContext(object):
+    def __init__(self, configuration):
+        #: The configuration being validated
+        self.configuration = configuration
+        
+        self._dview = None
+        #: The list of validation problems
+        self.problems = []
+        #: The list of fixes executed in the context
+        self.fixes = []
+        
+
+    @property
+    def dview(self):
+        """ 
+        The configuration's default view 
+        """
+        if not self._dview:
+            self._dview = self.configuration.get_default_view()
+        return self._dview
+        
+    @property
+    def feature_dict(self):
+        """
+        All the configuration's features as a ref -> feature dictionary. 
+        """
+        if not hasattr(self, '_feature_dict'):
+            self._feature_dict = {}
+            for fea in self.dview.get_features('**'):
+                self._feature_dict[fea.fqr] = fea
+        return self._feature_dict
+
+class ValidatorBase(object):
+    #: Types of the problems this validator produces
+    PROBLEM_TYPES = None
+    
+    def __init__(self, context):
+        self.context = context
+    
+    def validate(self):
+        """
+        Method called to validate a configuration.
+        """
+        raise NotImplementedError()
+
+class FixerBase(object):
+    def fix(self, context):
+        """
+        The fix functions takes ValidationContext that is expected to contain a 
+        list of Problem objects that it will traverse through and it will try to 
+        fix any problem that matches its category.
+        @param context: The ValidationContext object from which problems should be fixed.  
+        """
+        raise NotImplementedError()
+
+    def filter_problems(self, problems, problem_type):
+        """
+        A filtering function that returns a list of problems that match to the 
+        given problem_type.
+        @param problems: a list of api.Problem objects
+        @param problem_type: a string that represents the problem name. e
+        .g. 'model.confml.duplicate.setting'.
+        """
+        return [problem for problem in problems if problem.type == problem_type]
+
+def get_validator_classes(problem_type_filter=None):
+    """
+    Return a list of all ConfML validator classes that match the given
+    problem type filter (i.e. all validator classes that yield problems
+    that will not be filtered out).
+    
+    @param problem_type_filter: The filter, if None, all validator
+        classes will be returned.
+    """
+    classes = []
+    
+    # Validators from plug-in entry points
+    classes.extend(cone.validation.common.load_plugin_classes(
+        'cone.plugins.confmlvalidators',
+        ValidatorBase))
+    
+    # Built-in validators
+    from cone.validation.builtinvalidators.confml import VALIDATOR_CLASSES
+    classes.extend(VALIDATOR_CLASSES)
+    
+    return cone.validation.common.filter_classes(classes, problem_type_filter)
+
+def get_fixer_classes(problem_type_filter=None):
+    """
+    Return a list of all ConfML fixer classes that match the given
+    problem type filter (i.e. all fixer classes that yield problems
+    that will not be filtered out).
+    
+    @param problem_type_filter: The filter, if None, all fixer
+        classes will be returned.
+    """
+    classes = []
+    
+    # Validators from plug-in entry points 
+    classes.extend(cone.validation.common.load_plugin_classes(
+        'cone.plugins.confmlfixers',
+        FixerBase))
+    
+    # Built-in validators 
+    from cone.validation.builtinvalidators.confml import FIXER_CLASSES
+    classes.extend(FIXER_CLASSES)
+    
+    return cone.validation.common.filter_classes(classes, problem_type_filter)
+
+def validate_configuration(configuration, validator_classes=None):
+    """
+    Validate the given configuration.
+    @param configuration: The configuration to validate.
+    @param validator_classes: The validator classes to use for the validation.
+        If None, all validator classes will be used.
+    @return: A ValidationContext objects, which contains a list of Problem objects in 
+    member variable problems.
+    """
+    
+    if validator_classes is None:
+        validator_classes = get_validator_classes()
+    
+    context = ValidationContext(configuration)
+    validators = [vc(context) for vc in validator_classes]
+    for validator in validators:
+        try:
+            validator.validate()
+        except Exception, e:
+            from cone.public import utils
+            utils.log_exception(logging.getLogger('cone'),
+                                "Error validating configuration: %s: %s" \
+                                % (e.__class__.__name__, e))
+    return context
+
+def fix_configuration(configuration, context=None, fixer_classes=None):
+    """
+    Validate the given configuration.
+    @param configuration: The configuration to validate.
+    @param context:  The ValidationContext if it has been alread created. With value None
+        The ValidationContext will be created and validated fisrt
+    @param fixer_classes: The fixer classes to use for the validation.
+        If None, all fixer classes will be used.
+    @return:  A ValidationContext objects, which contains a list of messaages of fixes that
+    were executed.
+    """
+    
+    try:
+        conf = configuration.get_configuration('duplicate_settings1.confml')
+        data1 = conf.data
+    except Exception:
+        pass
+    if context is None:
+        context = validate_configuration(configuration)
+    if fixer_classes is None:
+        fixer_classes = get_fixer_classes()
+
+    try:
+        conf = configuration.get_configuration('duplicate_settings1.confml')
+        data2 = conf.data
+    except Exception:
+        pass
+    for fixer in fixer_classes:
+        try:
+            fixer().fix(context)
+        except Exception, e:
+            from cone.public import utils
+            utils.log_exception(logging.getLogger('cone'),
+                                "Error fixing configuration: %s: %s" \
+                                % (e.__class__.__name__, e))
+    return context