From fac5984419a51995974dd87c847f889d43a3d2ea Mon Sep 17 00:00:00 2001 From: Thomas Weller Date: Tue, 19 Dec 2023 10:44:55 +0100 Subject: [PATCH] Attempt to fix #15: Fix AASX files of old version --- src/Program.cs | 5 ++ src/RelationshipDefinitionFixer.cs | 1 + src/VersionFixer.cs | 109 +++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+) create mode 100644 src/VersionFixer.cs diff --git a/src/Program.cs b/src/Program.cs index 418a6ea..591402e 100644 --- a/src/Program.cs +++ b/src/Program.cs @@ -84,6 +84,8 @@ private void Run(string inputFileName, string outputFileName, bool unfix) new RelationshipFixer().Fix(package, _fixes); new RelationshipDefinitionFixer().Fix(package, _fixes); new ExternalReferenceFixer(package).Fix(); + new VersionFixer(package).Fix(); + // DisplayContentsForDebuggingPurposes(package); package.Flush(); @@ -118,6 +120,9 @@ private static void PrintUsage() Console.WriteLine("Fixes the external reference issue (bug #681) in an AASX file."); Console.WriteLine("This will only be done one-way, since Package Explorer can open fixed files."); Console.WriteLine(); + Console.WriteLine("Brings files from AASX version 1 to AASX version 3 by converting XML documents to the new namespace."); + Console.WriteLine("This will only be done one-way, since Package Explorer can open fixed files."); + Console.WriteLine(); Console.WriteLine("Usage: AASFix [--fix|--unfix]"); Console.WriteLine(" : source file for reading"); Console.WriteLine(" : destination file for writing"); diff --git a/src/RelationshipDefinitionFixer.cs b/src/RelationshipDefinitionFixer.cs index ece4047..2702942 100644 --- a/src/RelationshipDefinitionFixer.cs +++ b/src/RelationshipDefinitionFixer.cs @@ -61,6 +61,7 @@ private void FixDefinitionInXml(XDocument xml, List fixes) private void SaveXml(PackagePart part, XDocument xml) { using var stream = part.GetStream(FileMode.Open, FileAccess.Write); + stream.SetLength(0); xml.Save(stream); } } diff --git a/src/VersionFixer.cs b/src/VersionFixer.cs new file mode 100644 index 0000000..63ab380 --- /dev/null +++ b/src/VersionFixer.cs @@ -0,0 +1,109 @@ +// Copyright 2023 Lukas Benner, Thomas Weller +// +// 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. + +using System.IO.Packaging; +using System.Xml; +using System.Xml.Linq; +using System.Xml.XPath; + +namespace AASFix +{ + internal class VersionFixer + { + private readonly PackagePartCollection _parts; + private readonly XmlNamespaceManager _nsMgr = new(new NameTable()); + private readonly XNamespace _version3 = "https://admin-shell.io/aas/3/0"; + private readonly string _oldVersionNodesQuery; + private readonly List _oldVersions = new() + { + "https://admin-shell.io/aas/1/0", + "http://www.admin-shell.io/aas/1/0", + "https://www.admin-shell.io/aas/1/0", + "https://admin-shell.io/aas/2/0", + "http://www.admin-shell.io/aas/2/0", + "https://www.admin-shell.io/aas/2/0" + }; + + internal VersionFixer(Package package) + { + _parts = package.GetParts(); + _nsMgr.AddNamespace("aas3", "https://admin-shell.io/aas/3/0"); + _oldVersionNodesQuery = BuildQueryForOldVersions(_nsMgr, _oldVersions); + } + + internal void Fix() + { + var xmlFiles = FindXmlFiles(); + foreach (var xmlFile in xmlFiles) + { + var xml = LoadXml(xmlFile); + var incorrectNodes = FindIncorrectNodes(xml); + FixNamespace(incorrectNodes); + SaveXml(xmlFile, xml); + } + } + + private IEnumerable FindXmlFiles() + { + return _parts.Where(p => p.ContentType == "text/xml"); + } + + private IEnumerable FindIncorrectNodes(XDocument xml) + { + return xml.XPathSelectElements(_oldVersionNodesQuery, _nsMgr); + } + + private void FixNamespace(IEnumerable incorrectNodes) + { + if (incorrectNodes.Any()) + { + Console.WriteLine("Converting XML to version 3."); + } + + foreach (var node in incorrectNodes) + { + node.Name = _version3 + node.Name.LocalName; + } + } + + private string BuildQueryForOldVersions(XmlNamespaceManager nsMgr, List oldVersions) + { + var queries = new List(); + var i= 0; + foreach (var version in oldVersions) + { + i++; + var prefix = $"old{i}"; + queries.Add($"//{prefix}:*"); + nsMgr.AddNamespace(prefix, version); + } + return string.Join(" | ", queries); + } + + private void SaveXml(PackagePart part, XDocument xml) + { + using var stream = part.GetStream(FileMode.Open, FileAccess.ReadWrite); + stream.Seek(0, SeekOrigin.Begin); + stream.SetLength(0); + xml.Save(stream); + } + + private XDocument LoadXml(PackagePart part) + { + using var stream = part.GetStream(FileMode.Open, FileAccess.ReadWrite); + var xml = XDocument.Load(stream); + return xml; + } + } +}