diff -r d8fccb2cd802 -r 468f4c8d3d5b Orb/python/orb/sysdef.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Orb/python/orb/sysdef.py Wed Aug 11 14:49:30 2010 +0100 @@ -0,0 +1,1522 @@ +# Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# This component and the accompanying materials are made available +# under the terms of the License "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: +# +try: + from xml.etree import cElementTree as etree +except ImportError: + from xml.etree import ElementTree as etree +import os +import logging +import weakref +import re +import xml + + +logger = logging.getLogger('orb.sysdef') + + +""" +When time to test with 2.6 +try: + from collections import namedtuple + + Layer = namedtuple('Layer', 'id name packages') + Package = namedtuple('Package', 'id name collections') + Collection = namedtuple('Collection', 'id name components') + Component = namedtuple('Component', 'id name bldinfs') +except ImportError, e: +""" +class Layer(object): + def __init__(self, id, name, packages): + self.id = id + self.name = name + self.packages = packages + +class Package(object): + def __init__(self, id, name, collections): + self.id = id + self.name = name + self.collections = collections + + +class Collection(object): + def __init__(self, id, name, components): + self.id = id + self.name = name + self.components = components + + +class Component(object): + def __init__(self, id, name, bldinfs): + self.id = id + self.name = name + self.bldinfs = bldinfs + + +class SystemDefinitionParserException(Exception): + "Raised if a System defintion file is invalid" + + +class PackageDefinionNotFoundError(Exception): + "Raised if a package definition file could not be found" + + +class PackageDefinitionLoader(object): + def __init__(self, sysdefpath, path=os.path): + self.sysdefpath = "" + if not hasattr(sysdefpath, "read"): + self.sysdefpath = path.abspath(path.dirname(sysdefpath)) + self.path = path + + def _get_pkgdef_path(self, pkgpath): + return self.path.abspath(self.path.join(self.sysdefpath, pkgpath)) + + def load(self, pkgpath): + if hasattr(pkgpath, "read"): + return pkgpath + fullpkgpath = self._get_pkgdef_path(pkgpath) + if not self.path.exists(fullpkgpath): + raise PackageDefinionNotFoundError( + '''Package definition "%s" was not found. + System definition directory is: "%s". + Relative path in System definition was "%s"''' % (fullpkgpath, self.sysdefpath, pkgpath)) + return fullpkgpath + + +class SystemDefinitionParser(object): + """ + NOTE: Variable names and comments use System definition 3 terminology + + Creates an ElementTree from a System definition file and creates + a parser (depending on the schema version) and stores the packages + and components mentioned in the file. + """ + def __init__(self, sysdeffile, pkgloader=PackageDefinitionLoader): + self.parser = None + try: + tree = etree.parse(sysdeffile) + #except xml.parsers.expat.ExpatError, e: + except Exception, e: + raise SystemDefinitionParserException(str(e)) + root = tree.getroot() + if "schema" not in root.attrib: + raise SystemDefinitionParserException("Unknown XML file found, root node does not have a schema attribute") + schema = root.attrib["schema"] + if schema.startswith("2.0"): + logger.debug("Creating a version 2 system definition parser, schema was: " + schema) + self._parser = SystemDefinitionV2Parser(sysdeffile, pkgloader, tree) + elif schema.startswith("3.0"): + logger.debug("Creating a version 3 system definition parser, schema was: " + schema) + self._parser = SystemDefinitionV3Parser(sysdeffile, pkgloader, tree) + else: + raise SystemDefinitionParserException("Unsupported system definition scheme: '%s'" % schema) + self._parser.parse() + + def __getattr__(self, name): + return getattr(self._parser, name) + + +class SystemDefinitionParserBase(object): + "Base class inherited by System definition parsers" + # Default to version 3 values + _id = "id" + _name = "name" + _layer = "layer" + _pkgname = "package" + _collection = "collection" + _component = "component" + + def __init__(self, sysdefpath, pkgloader, tree): + self._pkgloader = pkgloader(sysdefpath) + self._tree = tree + self.__name = "" + self.layers = [] + # Dict of id -> weakrefs to cut down on searches + self._components = {} + self._packages = {} + + @property + def name(self): + if self.__name != "": + return self.__name + root = self._tree.getroot() + if "name" in root.attrib: + self.__name = root.attrib["name"] + else: + sysmodel = root.find("systemModel") + if "name" in sysmodel.attrib: + self.__name = sysmodel.attrib["name"] + return self.__name + + def _load_distributed_pkg(self, href): + try: + return etree.parse(self._pkgloader.load(href)).find("//" + self._pkgname) + except PackageDefinionNotFoundError, e: + logger.error("Package definition not found: %s" % str(e)) + return None + + def _get_bldfile_prefix(self, href): + bldFile_prefix = "" + for p in href.split(".."): + if p != "/": + bldFile_prefix = p.replace("package_definition.xml", "") + return bldFile_prefix + + def _get_name_and_id(self, item): + id = item.attrib[self._id] if self._id in item.attrib else "" + name = item.attrib[self._name] if self._name in item.attrib else id + return (id, name) + + def _get_bldinfs(self, component, bldFile_prefix): + bldinfs = [] + for unit in [unit for unit in component.findall("unit") if "bldFile" in unit.attrib]: + bldinfs.append(bldFile_prefix + unit.attrib["bldFile"]) + logger.debug("Found bldFile: %s" % unit.attrib["bldFile"]) + return bldinfs + + def _get_components(self, pkgel, bldFile_prefix): + components = [] + for component in pkgel.findall(self._component): + id, name = self._get_name_and_id(component) + logger.debug("Adding component to components list: %s" % id) + c = Component( + id = id, + name = name, + bldinfs = self._get_bldinfs(component, bldFile_prefix) + ) + components.append(c) + self._components[c.id] = weakref.ref(c) + return components + + def _get_collections(self, parent, bldFile_prefix): + collections = [] + for coll in parent.findall(self._collection): + id, name = self._get_name_and_id(coll) + logger.debug("Adding collection to collections list: %s" % id) + collections.append(Collection( + id = id, + name = name, + components = self._get_components(coll, bldFile_prefix) + )) + return collections + + def _get_packages(self, parent): + packages = [] + bldFile_prefix = "" + for pkg in parent.findall(self._pkgname): + if "href" in pkg.attrib: + href = pkg.attrib["href"] + pkg = self._load_distributed_pkg(href) + bldFile_prefix = self._get_bldfile_prefix(href) + if pkg is not None: + logger.debug("Adding package to packages list: %s" % pkg.attrib[self._id]) + id, name = self._get_name_and_id(pkg) + p = Package( + id = id, + name = name, + collections = self._get_collections(pkg, bldFile_prefix) + ) + packages.append(p) + self._packages[p.id] = weakref.ref(p) + return packages + + def parse(self): + """ + Parses a system definition file and builds a hierarchical list of objects. + Hierarchy is: + Layer + +- Package + +- Collection + +- Component + So a Layer contains information about itself and a list of Packages. A + Package contains infromation about itself and a list of collections, etc. + + Supports both distributed and non-distributed sysdef 3 files. (Also supports + distributed sysdef 2 files for coding simplicity, not sure if they ever existed). + """ + for layer in self._tree.findall("//" + self._layer): + id, name = self._get_name_and_id(layer) + self.layers.append(Layer( + id = id, + name = name, + packages = self._get_packages(layer) + )) + + +class SystemDefinitionV2Parser(SystemDefinitionParserBase): + "Changes required to get base class to support sysdef 2" + _id = "name" + _name = "long-name" + _pkgname = "block" + + +class SystemDefinitionV3Parser(SystemDefinitionParserBase): + "Base class covers sysdef 3 support by default" + + +class SystemDefinition(object): + """ + Used to represent a System Definition file. Presents a queryable + interface to clients. Uses a SystemDefinitionParser to query the + underlying system definition XML file. + """ + def __init__(self, sysdeffile, cwd="", sysdefparser=SystemDefinitionParser, pkgloader=PackageDefinitionLoader): + self._parser = sysdefparser(sysdeffile, pkgloader) + self.cwd = cwd.replace("\\", "/") + if self.cwd.endswith("/"): + self.cwd = self.cwd[:-1] + self._pkgs = None + + @property + def name(self): + return self._parser.name + + @property + def layers(self): + return self._parser.layers + + def get_packages(self): + """ + Returns the list of Package objects found in the System definition + file + """ + return [p() for p in self._parser._packages.values()] + + def get_components(self, package_id): + """ + Returns the list of Component objects found in the Package in + the System definition file + """ + comps = [] + try: + for collection in self._parser._packages[package_id]().collections: + comps.extend(collection.components) + except KeyError: + logger.error("Package with package_id: %s, was not found" % package_id) + return comps + + def _get_component(self, component_id): + try: + return self._parser._components[component_id]() + except KeyError: + return None + + def get_sbs_output_dir(self, component_id): + """ + Returns the list of "sbs output directories" found under the + Component in the System definition file. + + An "sbs output directory" is the directory name used by sbs + when creating its output directories. + If the bld.inf file is in a directory called "group", it is + the parent directory of the group directory. + If the bld.inf file is not in a directory called group, it is + the name of the directory that contains the bld.inf file. + """ + component = self._get_component(component_id) + if component is None: + logger.error("Component with an id of: %s, was not found" % component_id) + return None + if len(component.bldinfs) == 0: + logger.info('No bldFiles found for: %s' % component_id) + return None + # Otherwise take the first one? + bldinf = component.bldinfs[0] + search = re.search(r".*/(.*)/group", bldinf, re.IGNORECASE) + if not search: + search = re.search(r".*/(.*)", bldinf) + if not search: + logger.error('Could not determine bldFile dir name from unit bldFile attribute: "%s"' % bldinf) + return "" + return search.group(1) + + def get_bldinfs(self, component_id): + """ + Returns the list of "bld.inf" files found in the Component in + the System definition file + """ + bldfiles = [] + component = self._get_component(component_id) + if component is None: + logger.error("Component with id: '%s' not found" % component_id) + else: + for bf in component.bldinfs: + logger.debug("Found bldFile (or directory): %s" % bf) + bf = bf.replace("\\","/") + if bf.startswith(".."): + bf = bf.replace("..","") + if bf.startswith("/"): + bf = bf[1:] + if bf.startswith("sf"): + bf = "%s/%s" % (os.path.splitdrive(self.cwd)[0], bf) + else: + bf = "%s/sf/%s" % (os.path.splitdrive(self.cwd)[0], bf) + if not bf.endswith("bld.inf"): + bf = "%s/%s" % (bf, "bld.inf") + bf = os.path.normpath(bf) + bf = bf.replace("\\","/") + logger.debug("Saving bldFile as: %s" % bf) + bldfiles.append(bf) + return bldfiles + + +################################################################ +# Unit test code +################################################################ +import unittest +from cStringIO import StringIO + + +class PathMock(object): + "Mock os.path so I can change os.path.exists return values" + + @classmethod + def abspath(self, p): + return os.path.abspath(p) + + @classmethod + def dirname(self, p): + return os.path.dirname(p) + + @classmethod + def join(self, a, b): + return os.path.join(a, b) + + @classmethod + def exists(self, p): + if "data" in p: + return True + else: + return False + + +class MockPackageDefinitionLoader(object): + def __init__(self, sysdefpath): + pass + + def load(self, pkgpath): + if "kernelhwsrv" in pkgpath: + return StringIO(kernelhwsrv_pkg_def) + elif "classicui" in pkgpath: + return StringIO(classicui_pkg_def) + else: + raise PackageDefinionNotFoundError("File not found") + + +class TestSystemDefinitionParser(unittest.TestCase): + + def setUp(self): + self.sysdefs = { + "System definition V2": sysdefv2, + "System definition V3 distributed": sysdefv3_distributed, + "System definition V3 non-distributed": sysdefv3_nondistributed + } + self.unsupported_sysdefs = { + "System definition V1.4": sysdefv1_unsupported, + "System definition V2.1": sysdefv2_unsupported, + "System definition V3.1": sysdefv3_unsupported + } + + def test_i_raise_an_exception_if_the_sysdef_file_is_invalid(self): + try: + SystemDefinitionParser(StringIO("")) + self.fail("An exception should have been raised") + except SystemDefinitionParserException: + pass # Expected + + def test_i_raise_an_exception_if_given_an_unkown_xml_file(self): + try: + SystemDefinitionParser(StringIO("")) + self.fail("An exception should have been raised") + except SystemDefinitionParserException: + pass # Expected + + def test_i_raise_an_exception_if_given_an_unsupported_SystemDefinition_version(self): + for name, sysdef in self.unsupported_sysdefs.items(): + try: + SystemDefinitionParser(StringIO(sysdef)) + self.fail("Should have raised a SystemDefinitionParserException as I do not support %s" % name) + except SystemDefinitionParserException: + pass # Expected + + def test_i_can_parse_supported_sysdefs_files(self): + for name, sysdef in self.sysdefs.items(): + try: + SystemDefinitionParser(StringIO(sysdef), pkgloader=MockPackageDefinitionLoader) + except Exception, e: + self.fail("An exception should not have been raised. Using '%s': %s" % (name, str(e))) + + def test_i_store_all_the_layers_in_a_sysdef_file(self): + for name, sysdef in self.sysdefs.items(): + parser = SystemDefinitionParser(StringIO(sysdef), pkgloader=MockPackageDefinitionLoader) + items = len(parser.layers) + layer = parser.layers[0] + self.assertEquals(items, 2, msg="Expected number of layers '%s' not stored, using %s" % (items, name)) + self.assertEquals(layer.id, "os", msg="Expected layer id '%s' not stored, using %s" % (parser.layers[0].id, name)) + self.assertEquals(layer.name, "OS", msg="Expected layer name '%s' not stored, using %s" % (parser.layers[0].name, name)) + + def test_i_store_all_the_packages_in_a_layer(self): + for name, sysdef in self.sysdefs.items(): + parser = SystemDefinitionParser(StringIO(sysdef), pkgloader=MockPackageDefinitionLoader) + items = len(parser.layers[0].packages) + self.assertEquals(items, 1, msg="Expected number of packages '%s' not stored, using %s" % (items, name)) + item = parser.layers[0].packages[0] + self.assertEquals(item.id, "kernelhwsrv", msg="Expected package id '%s' not stored, using %s" % (item.id, name)) + self.assertEquals(item.name, "Kernel and Hardware Services", msg="Expected package name '%s' not stored, using %s" % (item.name, name)) + + def test_i_store_all_the_collections_in_a_package(self): + for name, sysdef in self.sysdefs.items(): + parser = SystemDefinitionParser(StringIO(sysdef), pkgloader=MockPackageDefinitionLoader) + items = len(parser.layers[0].packages[0].collections) + self.assertEquals(items, 12, msg="Expected number of collections '%s' not stored, using %s" % (items, name)) + item = parser.layers[0].packages[0].collections[0] + self.assertEquals(item.id, "brdbootldr", msg="Expected collection id '%s' not stored, using %s" % (item.id, name)) + self.assertEquals(item.name, "Board Boot Loader", msg="Expected collection name '%s' not stored, using %s" % (item.name, name)) + + def test_i_store_all_the_components_in_a_collection(self): + for name, sysdef in self.sysdefs.items(): + parser = SystemDefinitionParser(StringIO(sysdef), pkgloader=MockPackageDefinitionLoader) + items = len(parser.layers[0].packages[0].collections[0].components) + self.assertEquals(items, 1, msg="Expected number of components '%s' not stored, using %s" % (items, name)) + item = parser.layers[0].packages[0].collections[0].components[0] + self.assertEquals(item.id, "ubootldr", msg="Expected component id '%s' not stored, using %s" % (item.id, name)) + self.assertEquals(item.name, "Boot Loader", msg="Expected component name '%s' not stored, using %s" % (item.name, name)) + + def test_i_store_all_the_bldinfs_in_a_component(self): + for name, sysdef in self.sysdefs.items(): + parser = SystemDefinitionParser(StringIO(sysdef), pkgloader=MockPackageDefinitionLoader) + items = len(parser.layers[0].packages[0].collections[1].components[0].bldinfs) + self.assertEquals(items, 1, msg="Expected number of bldinfs '%s' not stored, using %s" % (items, name)) + + def test_i_store_a_sysdefs_name(self): + for name, sysdef in self.sysdefs.items(): + parser = SystemDefinitionParser(StringIO(sysdef), pkgloader=MockPackageDefinitionLoader) + self.assertEquals(parser.name, "Symbian^3", msg="Expected name not stored. Recieved: '%s', using %s" % (parser.name, name)) + + +class TestSystemDefinition(unittest.TestCase): + def setUp(self): + self.sysdefs = { + "sysdefv2": SystemDefinition(StringIO(sysdefv2), "y:\\"), + "sysdefv3_dist": SystemDefinition(StringIO(sysdefv3_distributed), "y:\\", pkgloader=MockPackageDefinitionLoader), + "sysdefv3_nondist": SystemDefinition(StringIO(sysdefv3_nondistributed), "y:\\") + } + + def test_i_return_the_list_of_packages(self): + for name, sysdef in self.sysdefs.items(): + packages = sysdef.get_packages() + self.assertEquals(len(packages), 2, msg="Correct number of packages were not found, using %s" % name) + self.assertEquals(packages[0].id, "kernelhwsrv", msg="Incorrect package id found, using %s" % name) + self.assertEquals(packages[1].id, "classicui", msg="Incorrect package id found, using %s" % name) + + def test_i_can_handle_invalid_href_urls(self): + sysdefv3 = SystemDefinition(StringIO(sysdefv3_distributed_invalid_href), "y:\\", pkgloader=MockPackageDefinitionLoader) + try: + packages = sysdefv3.get_packages() + except Exception, e: + self.fail("Should have carried on and not raised an exception. %s" % str(e)) + self.assertEquals(len(packages), 1) + + def test_i_can_handle_being_asked_for_components_given_an_nonexistent_packageid(self): + for name, sysdef in self.sysdefs.items(): + components = sysdef.get_components("classicgui") + self.assertEquals(len(components), 0, msg="Incorrect number of components returned, using %s" % name) + + def test_i_can_return_components_given_a_packageid(self): + for name, sysdef in self.sysdefs.items(): + components = sysdef.get_components("classicui") + self.assertEquals(len(components), 34, msg="Incorrect number of components returned, using %s" % name) + self.assertTrue("pslngsplugin" in [component.id for component in components], msg="Expected component not found, using %s" % name) + + def test_i_can_handle_being_asked_for_bldinfs_given_a_nonexistant_component_name(self): + for name, sysdef in self.sysdefs.items(): + bldfiles = sysdef.get_bldinfs("classicgui") + self.assertEquals(len(bldfiles), 0, msg="Incorrect number of bldfiles returned, using %s" % name) + + def test_i_can_return_bldinfs_given_a_component_name(self): + for name, sysdef in self.sysdefs.items(): + bldfiles = sysdef.get_bldinfs("pslngsplugin") + self.assertEquals(len(bldfiles), 1, msg="Incorrect number of bldfiles returned, using %s" % name) + self.assertTrue(bldfiles[0].endswith("bld.inf")) + bldinf_path = "y:/sf/mw/classicui/psln/pslngsplugin/Group/bld.inf" + self.assertEquals(bldfiles[0], bldinf_path, msg="%s != %s. using %s" % (bldfiles[0], bldinf_path, name)) + + def test_i_can_handle_additional_dots_in_the_bldfile_path(self): + for name, sysdef in self.sysdefs.items(): + bldfiles = sysdef.get_bldinfs("animation") # paths start with ../ + self.assertEquals(len(bldfiles), 1, msg="Incorrect number of bldfiles returned, using %s" % name) + self.assertTrue(bldfiles[0].endswith("bld.inf")) + bldinf_path = "y:/sf/mw/classicui/lafagnosticuifoundation/animation/group/bld.inf" + self.assertEquals(bldfiles[0], bldinf_path, msg="%s != %s. using %s" % (bldfiles[0], bldinf_path, name)) + + def test_i_can_handle_a_slash_at_the_start_in_the_bldfile_path(self): + for name, sysdef in self.sysdefs.items(): + bldfiles = sysdef.get_bldinfs("bmpanimation") # paths start with / + self.assertEquals(len(bldfiles), 1, msg="Incorrect number of bldfiles returned, using %s" % name) + self.assertTrue(bldfiles[0].endswith("bld.inf")) + bldinf_path = "y:/sf/mw/classicui/lafagnosticuifoundation/bmpanimation/group/bld.inf" + self.assertEquals(bldfiles[0], bldinf_path, msg="%s != %s. using %s" % (bldfiles[0], bldinf_path, name)) + + def test_i_handle_being_asked_for_sbsdir_when_a_given_component_is_not_found(self): + for name, sysdef in self.sysdefs.items(): + self.assertEquals(sysdef.get_sbs_output_dir("foobar"), None, msg="Did not handle an invalid component name correctly, using: %s" % name) + + def test_i_handle_being_asked_for_sbsdir_when_a_given_component_has_no_bldinfs(self): + for name, sysdef in self.sysdefs.items(): + self.assertEquals(sysdef.get_sbs_output_dir("pslnengine"), None, msg="Did not handle an invalid component name correctly, using: %s" % name) + + def test_i_can_return_sbs_output_dir_given_a_component(self): + for name, sysdef in self.sysdefs.items(): + self.assertEquals(sysdef.get_sbs_output_dir("pslngsplugin"), "pslngsplugin", msg="Expected directory value not returned, using %s" % name) + outdir = sysdef.get_sbs_output_dir("rofs") + self.assertEquals(outdir, "srofs", msg="Expected directory value not returned '%s', using %s" % (outdir, name)) + + def test_i_can_handle_invalid_bldfile_lines_when_asked_for_a_sbs_output_dir(self): + for name, sysdef in self.sysdefs.items(): + self.assertEquals(sysdef.get_sbs_output_dir("uiklaf"), "", msg="Expected directory value not returned, using %s" % name) + + def test_i_can_return_a_sysdef_name(self): + for name, sysdef in self.sysdefs.items(): + self.assertEquals(sysdef.name, "Symbian^3", msg="Expected title value not returned, using %s" % name) + +class TestPackageDefinitionLoader(unittest.TestCase): + def setUp(self): + self.sysdefpath = __file__ + + def test_i_can_raise_an_exception_if_i_cannot_load_a_pkg_definition(self): + pl = PackageDefinitionLoader(self.sysdefpath, path=PathMock) + try: + pl.load("package_definition.xml") + self.fail("Should have raised a PackageDefinionNotFoundError") + except PackageDefinionNotFoundError: + pass # Expected + + def test_i_can_load_a_pkg_definition(self): + pl = PackageDefinitionLoader(self.sysdefpath, path=PathMock) + try: + pl.load("data/package_definition.xml") + except Exception: + self.fail("PackageLoader.load did not find a file that exists (mocked)") + + def test_if_passed_a_file_like_object_i_just_return_it(self): + pl = PackageDefinitionLoader(self.sysdefpath, path=PathMock) + pkgdef = pl.load(StringIO(kernelhwsrv_pkg_def)) + try: + etree.parse(pkgdef) + except Exception: + self.fail("PackageLoader.load did not find a file that exists (mocked)") + + def test_if_passed_a_file_like_object_as_a_sysdef_i_use_it(self): + try: + PackageDefinitionLoader(StringIO(sysdefv3_nondistributed)) + except Exception: + self.fail("PackageLoader did not handle a file-like object as sysdef") + + +sysdefv1_unsupported = """ +""" + +sysdefv2_unsupported = """ +""" + +sysdefv3_unsupported = """ +""" + +sysdefv2 = """ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +""" + + +sysdefv3_nondistributed = """ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +""" + +sysdefv3_distributed = """ + + + + + + + + + +""" + +sysdefv3_distributed_invalid_href = """ + + + + + + + + + +""" + +kernelhwsrv_pkg_def = """ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +""" + +classicui_pkg_def = """ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +""" \ No newline at end of file