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