configurationengine/source/cone/validation/implmlvalidation.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
from cone.public import api, exceptions, plugin, utils, parsecontext
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    20
from cone.validation.parsecontext import ValidationParseContext
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    21
import cone.validation.common
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    22
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    23
class ValidationContext(object):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    24
    def __init__(self, configuration):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    25
        self.configuration = configuration
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    26
        self.problems = []
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    27
        
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    28
        #: Flat list of all implementations, including containers
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    29
        self.all_impls = []
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    30
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    31
class ValidatorBase(object):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    32
    """
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    33
    Base class for implementation validators.
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    34
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    35
    NOTE THAT THIS CLASS SHOULD NOT BE DIRECTLY SUB-CLASSED.
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    36
    Sub-class either ImplValidatorBase or GlobalValidatorBase
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    37
    instead.
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    38
    """
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    39
    PROBLEM_TYPES = None
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    40
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    41
    def __init__(self, context):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    42
        self.context = context
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    43
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    44
class ImplValidatorBase(ValidatorBase):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    45
    """
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    46
    Base class for validators that validate only a single implementation.
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    47
    """
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    48
    SUPPORTED_IMPL_CLASSES = []
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    49
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    50
    def __init__(self, context, impl):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    51
        self.context = context
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    52
        self.impl = impl
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    53
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    54
    def validate(self):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    55
        """
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    56
        Called to validate an implementation instance.
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    57
        """
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    58
        pass
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    59
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    60
    def check_feature_reference(self, ref, line, problem_type):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    61
        """
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    62
        Check that a feature with the given reference exists, and if
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    63
        not, add a problem.
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    64
        
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    65
        @param ref: The feature reference to check.
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    66
        @param line: The line number to set to the created problem.
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    67
        @param line: The problem type to set to the created problem.
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    68
        """
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    69
        dview = self.context.configuration.get_default_view()
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    70
        try:
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    71
            dview.get_feature(ref)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    72
        except exceptions.NotFound:
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    73
            prob = api.Problem(
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    74
                msg = u"Setting '%s' not found in configuration" % ref,
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    75
                type = problem_type,
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    76
                line = line,
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    77
                file = self.impl.ref)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    78
            self.context.problems.append(prob)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    79
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    80
class GlobalValidatorBase(ValidatorBase):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    81
    """
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    82
    Base class for validators that validate the entire implementation set at once.
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    83
    """
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    84
    def validate(self):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    85
        pass
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    86
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    87
def get_validator_classes(problem_type_filter=None):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    88
    """
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    89
    Return a list of all ImplML validator classes that match the given
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    90
    problem type filter (i.e. all validator classes that yield problems
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    91
    that will not be filtered out).
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    92
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    93
    @param problem_type_filter: The filter, if None, all validator
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    94
        classes will be returned.
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    95
    """
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    96
    classes = []
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    97
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    98
    # Validators from plug-in entry points 
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
    99
    classes.extend(cone.validation.common.load_plugin_classes(
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   100
        'cone.plugins.implvalidators',
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   101
        ValidatorBase))
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   102
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   103
    # Built-in validators
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   104
    from cone.validation.builtinvalidators.implml import VALIDATOR_CLASSES
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   105
    classes.extend(VALIDATOR_CLASSES)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   106
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   107
    return cone.validation.common.filter_classes(classes, problem_type_filter)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   108
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   109
def validate_impl_set(impl_set, configuration, validator_classes=None):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   110
    """
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   111
    Validate the given implementation set.
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   112
    @param impl_set: The implementations to validate.
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   113
    @param configuration: The configuration used in the validation.
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   114
    @param validator_classes: The validator classes to use for the validation.
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   115
        If None, all validator classes will be used.
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   116
    @return: A list of Problem objects.
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   117
    """
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   118
    context = ValidationContext(configuration)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   119
    context.all_impls = _get_flat_impl_list(impl_set)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   120
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   121
    if validator_classes is None:
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   122
        validator_classes = get_validator_classes()
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   123
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   124
    # Run global validation first
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   125
    for vc in validator_classes:
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   126
        if issubclass(vc, GlobalValidatorBase):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   127
            try:
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   128
                validator = vc(context)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   129
                validator.validate()
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   130
            except Exception, e:
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   131
                utils.log_exception(logging.getLogger('cone'),
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   132
                                    "Error while validating: %s: %s" \
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   133
                                    % (e.__class__.__name__, e))
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   134
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   135
    # Then run validation for individual implementations
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   136
    for impl in context.all_impls:
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   137
        for vc in validator_classes:
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   138
            if issubclass(vc, ImplValidatorBase) and isinstance(impl, vc.SUPPORTED_IMPL_CLASSES):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   139
                try:
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   140
                    validator = vc(context, impl)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   141
                    validator.validate()
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   142
                except Exception, e:
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   143
                    utils.log_exception(logging.getLogger('cone'),
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   144
                                        "Error validating '%s': %s: %s" \
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   145
                                        % (impl, e.__class__.__name__, e))
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   146
    return context.problems
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   147
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   148
def _get_flat_impl_list(impl_set):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   149
    """
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   150
    Return a flat list of all implementations in the given set.
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   151
    """
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   152
    result = []
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   153
    def add_to_result(impl):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   154
        result.append(impl)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   155
        if isinstance(impl, plugin.ImplContainer):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   156
            for sub_impl in impl.impls:
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   157
                add_to_result(sub_impl)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   158
    for impl in impl_set:
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   159
        add_to_result(impl)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   160
    return result
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   161
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   162
def validate_impls(configuration, filter='.*', validator_classes=None):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   163
    """
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   164
    Validate all implementations in the given configuration.
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   165
    @param filter: Regex for filtering the implementations to validate.
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   166
    @param validator_classes: The validator classes to use for the validation.
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   167
        If None, all validator classes will be used.
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   168
    """
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   169
    # Set up the parse context to collect problems from the parsing phase
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   170
    context = ValidationParseContext()
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   171
    parsecontext.set_implml_context(context)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   172
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   173
    impl_set = plugin.get_impl_set(configuration, filter=filter)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   174
    problems = validate_impl_set(impl_set, configuration, validator_classes)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   175
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents:
diff changeset
   176
    return context.problems + problems