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