--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/conesub_validate.py Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,298 @@
+#
+# 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 sys, os, shutil
+import logging
+from optparse import OptionParser, OptionGroup
+import cone_common
+from cone.report import report_util
+from cone.public import api, exceptions, utils, plugin, parsecontext
+import cone.validation.parsecontext
+import cone.validation.schemavalidation
+import cone.validation.implmlvalidation
+import cone.validation.confmlvalidation
+from cone.validation.problem_type_filter import ProblemTypeFilter
+
+ROOT_PATH = os.path.abspath(os.path.dirname(__file__))
+
+VERSION = '1.0'
+
+logger = logging.getLogger('cone')
+
+REPORT_SHORTCUTS = {
+ 'xml': report_util.ReportShortcut(
+ os.path.join(ROOT_PATH, 'validation_report_template.xml'),
+ 'validation_report.xml',
+ "Create a validation report of xml type."),
+
+ 'html': report_util.ReportShortcut(
+ os.path.join(ROOT_PATH, 'validation_report_template.html'),
+ 'validation_report.html',
+ "Create a validation report of html type."),
+}
+
+def main():
+ """ Validate a configuration, or individual confml/implml files. """
+ shortcut_container = report_util.ReportShortcutContainer(REPORT_SHORTCUTS,
+ 'html')
+
+ parser = OptionParser(version="ConE validate %s" % VERSION)
+
+ parser.add_options(cone_common.COMMON_OPTIONS)
+
+ parser.add_option("-c", "--configuration",
+ dest="configuration",
+ help="Defines the name of the configuration for the action",
+ metavar="CONFIG")
+
+ parser.add_option("-p", "--project",
+ dest="project",
+ default=".",
+ help="defines the location of current project. Default is the "\
+ "current working directory.",
+ metavar="STORAGE")
+
+ group = OptionGroup(parser, 'Validate options',
+ 'The validate action is intended for performing validation on a '\
+ 'configuration or individual files. ')
+
+ group.add_option('--confml-file',
+ action="append",
+ help='Validate only the given single ConfML file.',
+ metavar="FILE",
+ default=None)
+
+ group.add_option('--implml-file',
+ action="append",
+ help='Validate only the given single ImplML file.',
+ metavar="FILE",
+ default=None)
+
+ group.add_option("--template",
+ help="Template used in report generation. "\
+ "Example: --template=report_template.html.",
+ metavar="FILE",
+ default=None)
+
+ group.add_option("--report-type",
+ help="The type of the report to generate. This is a convenience "\
+ "switch for setting the used template. If --template is given, this option has no effect. "\
+ "Possible values: "\
+ + shortcut_container.get_shortcut_help_text(),
+ metavar="TYPE",\
+ default=None)
+
+ group.add_option("--report",
+ help="Specifies the location of the validation report. "\
+ "Example --report=report.html.",
+ metavar="FILE",
+ default=None)
+
+ group.add_option("--dump-schema-files",
+ help="Dump the XML schema files used for validation into the specified directory.",
+ metavar="DIR",
+ default=None)
+
+ group.add_option("--exclude-filter",
+ action="append",
+ help="Exclude validation problems by given filter. "\
+ "Examples: --exclude-filter=schema, --exclude-filter=schema.implml, --exclude-filter=schema.confml, --exclude-filter=schema.implml.ruleml",
+ default=None)
+
+ group.add_option("--include-filter",
+ action="append",
+ help="Include validation problems by given filter."\
+ "Examples: --include-filter=schema.implml, --include-filter=schema.implml.ruleml",
+ default=None)
+
+ parser.add_option_group(group)
+ (options, _) = parser.parse_args()
+
+ cone_common.handle_common_options(options)
+
+ if not shortcut_container.is_valid_shortcut(options.report_type):
+ parser.error("Invalid report type: %s" % options.report_type)
+
+ if options.dump_schema_files:
+ dump_dir = options.dump_schema_files
+ print "Dumping XML schema files to '%s'" % dump_dir
+
+ cone.validation.schemavalidation.dump_schema_files(dump_dir)
+ return
+
+ pt_filter = ProblemTypeFilter(includes = options.include_filter or [],
+ excludes = options.exclude_filter or [])
+
+ problems = []
+ if options.confml_file or options.implml_file:
+ if options.confml_file:
+
+ func = cone.validation.schemavalidation.validate_confml_data
+ for file in options.confml_file:
+ problems.extend(validate_file(file, func))
+ if options.implml_file:
+ func = cone.validation.schemavalidation.validate_implml_data
+ for file in options.implml_file:
+ problems.extend(validate_file(file, func))
+ else:
+ problems = validate_configuration(options.project, options.configuration, pt_filter)
+
+ if problems is not None:
+ filters = {'filter_by_severity':filter_by_severity}
+ problems = pt_filter.filter(problems)
+
+ print "Total %d problem(s) after filtering" % len(problems)
+
+ print "Generating report..."
+ problems.sort(key=lambda p: (p.severity, p.file, p.line))
+ template, report = shortcut_container.determine_template_and_report(
+ options.report_type,
+ options.template,
+ options.report,
+ 'validation_report')
+ report_util.generate_report(template, report, {'problems': problems},extra_filters=filters)
+
+def extend_without_duplicates(source, target):
+ for item in source:
+ if item not in target:
+ target.append(item)
+
+def validate_file(filename, validator_func):
+ if not os.path.isfile(filename):
+ print "'%s' does not exist or is not a file!" % filename
+ return
+ else:
+ print "Validating file '%s'" % filename
+
+ f = open(filename, 'rb')
+ try: data = f.read()
+ finally: f.close()
+
+ problems = []
+ try:
+ validator_func(data)
+ except exceptions.ParseError, e:
+ problems.append(api.Problem.from_exception(e))
+ print "Found %d problem(s)" % len(problems)
+
+ for p in problems:
+ p.file = filename
+ return problems
+
+def validate_configuration(project_path, config_path, problem_type_filter):
+ print "Project: %s" % project_path
+ try:
+ project = api.Project(api.Storage.open(project_path, 'r'))
+ except exceptions.StorageException:
+ print "No such project."
+ return
+
+ confml_parse_context = cone.validation.parsecontext.ValidationParseContext()
+ parsecontext.set_confml_context(confml_parse_context)
+
+ if config_path is None:
+ config_path = project.get_storage().get_active_configuration()
+ if config_path is None:
+ print "Project does not have an active configuration, please specify the configuration using --configuration."
+ return
+ print "Configuration: %s" % config_path
+
+ try:
+ config = project.get_configuration(config_path)
+ except exceptions.NotFound:
+ print "No such configuration in project."
+ return
+
+ result = []
+
+
+ print "Finding ConfML files in configuration..."
+ configs = config._traverse(type=api.Configuration)
+ print "%d ConfML file(s)" % len(configs)
+ print "%d problem(s) while parsing" % len(confml_parse_context.problems)
+ result.extend(confml_parse_context.problems)
+
+ # Schema-validate ConfML files if not filtered out
+ if problem_type_filter.match('schema.confml'):
+ print "Performing XML schema validation on ConfML files..."
+ schema_problems = cone.validation.schemavalidation.validate_confml_file(config, config_path)
+ for conf in configs:
+ path = conf.get_full_path()
+ problems = cone.validation.schemavalidation.validate_confml_file(config, path)
+ schema_problems.extend(problems)
+ print "%d problem(s)" % len(schema_problems)
+
+ # Add the schema problems with duplicates removed, since XML parse
+ # errors might have already been recorded in the ConfML parsing phase
+ extend_without_duplicates(source=schema_problems, target=result)
+
+
+ # Validate the ConfML model if not filtered out
+ validator_classes = cone.validation.confmlvalidation.get_validator_classes(problem_type_filter)
+ if validator_classes:
+ print "Validating ConfML model..."
+ model_problems = cone.validation.confmlvalidation.validate_configuration(config, validator_classes).problems
+ print "%d problem(s)" % len(model_problems)
+ result.extend(model_problems)
+
+
+ print "Finding ImplML files in configuration..."
+ impls = []
+ for file in config.get_layer().list_implml():
+ if plugin.ImplFactory.is_supported_impl_file(file):
+ impls.append(file)
+ print "Found %d supported files" % len(impls)
+
+ # Schema-validate ImplML files if not filtered out
+ if problem_type_filter.match('schema.implml'):
+ print "Performing XML schema validation on ImplML files..."
+ schema_problems = []
+ for impl in impls:
+ probs = cone.validation.schemavalidation.validate_implml_file(config, impl)
+ schema_problems.extend(probs)
+ print "%d problem(s)" % len(schema_problems)
+ result.extend(schema_problems)
+
+ # Validate the ImplML model if not filtered out
+ if problem_type_filter.match('model.implml'):
+ print "Parsing implementations..."
+ implml_parse_context = cone.validation.parsecontext.ValidationParseContext()
+ parsecontext.set_implml_context(implml_parse_context)
+ impl_set = plugin.create_impl_set(impls, config)
+
+ # Add the model-level problems with duplicates removed, since XML parse
+ # errors might have already been recorded in the schema validation phase
+ extend_without_duplicates(source=implml_parse_context.problems, target=result)
+
+
+ validator_classes = cone.validation.implmlvalidation.get_validator_classes(problem_type_filter)
+ if validator_classes:
+ print "Validating implementations..."
+ impl_problems = cone.validation.implmlvalidation.validate_impl_set(impl_set, config, validator_classes)
+ print "%d problem(s)" % len(impl_problems)
+ result.extend(impl_problems)
+
+ return result
+
+
+def filter_by_severity(problems, severity):
+ """
+ Filter problems by severity
+ """
+ return [p for p in problems if p.severity == severity]
+
+if __name__ == "__main__":
+ main()