Source code for pyEDAA.IPXACT.Catalog

# ==================================================================================================================== #
#              _____ ____    _        _      ___ ______  __    _    ____ _____                                         #
#  _ __  _   _| ____|  _ \  / \      / \    |_ _|  _ \ \/ /   / \  / ___|_   _|                                        #
# | '_ \| | | |  _| | | | |/ _ \    / _ \    | || |_) \  /   / _ \| |     | |                                          #
# | |_) | |_| | |___| |_| / ___ \  / ___ \ _ | ||  __//  \  / ___ \ |___  | |                                          #
# | .__/ \__, |_____|____/_/   \_\/_/   \_(_)___|_|  /_/\_\/_/   \_\____| |_|                                          #
# |_|    |___/                                                                                                         #
# ==================================================================================================================== #
# Authors:                                                                                                             #
#   Patrick Lehmann                                                                                                    #
#                                                                                                                      #
# License:                                                                                                             #
# ==================================================================================================================== #
# Copyright 2017-2024 Patrick Lehmann - Bötzingen, Germany                                                             #
# Copyright 2016-2016 Patrick Lehmann - Dresden, Germany                                                               #
#                                                                                                                      #
# Licensed under the Apache License, Version 2.0 (the "License");                                                      #
# you may not use this file except in compliance with the License.                                                     #
# You may obtain a copy of the License at                                                                              #
#                                                                                                                      #
#   http://www.apache.org/licenses/LICENSE-2.0                                                                         #
#                                                                                                                      #
# Unless required by applicable law or agreed to in writing, software                                                  #
# distributed under the License is distributed on an "AS IS" BASIS,                                                    #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                             #
# See the License for the specific language governing permissions and                                                  #
# limitations under the License.                                                                                       #
#                                                                                                                      #
# SPDX-License-Identifier: Apache-2.0                                                                                  #
# ==================================================================================================================== #
#
from sys import version_info
from typing import List

from lxml               import etree
from os                 import chdir as os_chdir
from textwrap           import dedent

from pathlib            import Path

from pyTooling.Common import getFullyQualifiedName
from pyTooling.Decorators    import export

from pyEDAA.IPXACT           import RootElement, Vlnv, PyIpxactException, __URI_MAP__, __DEFAULT_SCHEMA__
from pyEDAA.IPXACT.Component import Component


[docs] @export class IpxactFile: """Represents a IP-XACT file.""" _vlnv: Vlnv #: VLNV unique identifier _name: str #: Name _description: str #: Description
[docs] def __init__(self, vlnv: Vlnv, name: str, description: str): """Constructor""" self._vlnv = vlnv self._name = name self._description = description
[docs] @classmethod def FromXml(cls, element): """Constructs an instance of ``IpxactFile`` from an lxml element.""" elementTag = etree.QName(element.tag) if elementTag.localname != "ipxactFile": raise PyIpxactException("Expected tag 'ipxactFile'.") for element2 in element: element3 = etree.QName(element2) if element3.localname == "vlnv": vendor = element2.get("vendor") library = element2.get("library") name2 = element2.get("name") version = element2.get("version") vlnv = Vlnv(vendor, library, name2, version) elif element3.localname == "name": name = element2.text elif element3.localname == "description": description = element2.text else: raise PyIpxactException(f"Unsupported tag '{element.localname}' in node 'ipxactFile'.") ipxactFile = cls(vlnv, name, description) return ipxactFile
[docs] def ToXml(self, indent): """Converts the object's data into XML format.""" _indent = "\t" * indent prefix = __DEFAULT_SCHEMA__.NamespacePrefix buffer = dedent(f"""\ {_indent}<{prefix}:ipxactFile> {_indent} {self._vlnv.ToXml(0)} {_indent} <{prefix}:name>{self._name}</{prefix}:name> {_indent} <{prefix}:description>{self._description}</{prefix}:description> {_indent}</{prefix}:ipxactFile> """) return buffer
[docs] @export class Catalog(RootElement): """Represents an IP-XACT catalog.""" _description: str _abstractionDefinitions: List _abstractors: List _busInterfaces: List _catalogs: List _components: List _designConfigurations: List _designs: List _generatorChains: List
[docs] def __init__(self, vlnv: Vlnv, description: str): super().__init__(vlnv) self._description = description self._abstractionDefinitions = [] self._abstractors = [] self._busInterfaces = [] self._catalogs = [] self._components = [] self._designConfigurations = [] self._designs = [] self._generatorChains = []
[docs] @classmethod def FromFile(cls, filePath : Path): """Constructs an instance of ``Catalog`` from a file.""" if not filePath.exists(): raise PyIpxactException(f"File '{filePath}' not found.") from FileNotFoundError(str(filePath)) try: with filePath.open("r", encoding="utf-8") as fileHandle: # TODO: why not open in binary? content = fileHandle.read() content = bytes(bytearray(content, encoding='utf-8')) except OSError as ex: raise PyIpxactException("Couldn't open '{0!s}'.".format(filePath)) from ex schemaPath = Path("../lib/schema/ieee-1685-2014/index.xsd") try: with schemaPath.open("r", encoding="utf-8") as fileHandle: # TODO: why not opening as binary? schema = fileHandle.read() schema = bytes(bytearray(schema, encoding='utf-8')) except OSError as ex: raise PyIpxactException(f"Couldn't open '{schemaPath}'.") from ex xmlParser = etree.XMLParser(remove_blank_text=True, encoding="utf-8") schemaRoot = etree.XML(schema, xmlParser) schemaTree = etree.ElementTree(schemaRoot) xmlschema = etree.XMLSchema(schemaTree) root = etree.XML(content, xmlParser) rootTag = etree.QName(root.tag) if not xmlschema.validate(root): raise PyIpxactException("The input IP-XACT file is not valid.") elif rootTag.namespace not in __URI_MAP__: raise PyIpxactException(f"The input IP-XACT file uses an unsupported namespace: '{rootTag.namespace}'.") elif rootTag.localname != "catalog": raise PyIpxactException("The input IP-XACT file is not a catalog file.") print("==" * 20) items = [] for rootElements in root: element = etree.QName(rootElements) if element.localname == "vendor": vendor = rootElements.text elif element.localname == "library": library = rootElements.text elif element.localname == "name": name = rootElements.text elif element.localname == "version": version = rootElements.text elif element.localname == "description": description = rootElements.text elif element.localname == "catalogs": for ipxactFileElement in rootElements: items.append(IpxactFile.FromXml(ipxactFileElement)) else: raise PyIpxactException(f"Unsupported tag '{element.localname}' at root-level.") print("==" * 20) vlnv = Vlnv(vendor=vendor, library=library, name=name, version=version) catalog = cls(vlnv, description=description) for item in items: catalog.AddItem(item) return catalog
def AddItem(self, item) -> None: if isinstance(item, IpxactFile): self._catalogs.append(item) elif isinstance(item, Component): self._components.append(item) else: ex = TypeError(f"Parameter 'item' is neither a 'IpxactFile' nor a 'Component'.") if version_info >= (3, 11): # pragma: no cover ex.add_note(f"Got type '{getFullyQualifiedName(item)}'.") raise ex
[docs] def ToXml(self) -> str: """Converts the object's data into XML format.""" buffer = dedent("""\ <?xml version="1.0" encoding="UTF-8"?> <{xmlns}:catalog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:{xmlns}="{schemaUri}" xsi:schemaLocation="{schemaUri} {schemaUrl}"> {versionedIdentifier} <{xmlns}:description>{description}</{xmlns}:description> """).format( xmlns=__DEFAULT_SCHEMA__.NamespacePrefix, schemaUri=__DEFAULT_SCHEMA__.SchemaUri, schemaUrl=__DEFAULT_SCHEMA__.SchemaUrl, versionedIdentifier=self._vlnv.ToXml(isVersionedIdentifier=True), description=self._description ) if self._catalogs: buffer += "\t<{xmlns}:catalogs>\n" for ipxactFile in self._catalogs: buffer += ipxactFile.ToXml(2) buffer += "\t</{xmlns}:catalogs>\n" if self._components: buffer += "\t<{xmlns}:components>\n" for ipxactFile in self._components: buffer += ipxactFile.ToXml(2) buffer += "\t</{xmlns}:components>\n" buffer += dedent("""\ </{xmlns}:catalog> """) return buffer.format(xmlns=__DEFAULT_SCHEMA__.NamespacePrefix)