From d98126dc766b9b063d2d26ced62553d4a5a218b5 Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Thu, 18 Oct 2018 11:21:03 -0700 Subject: Minor project cleanup --- src/WixToolset.Core/Converter.cs | 619 --------------------------------------- 1 file changed, 619 deletions(-) delete mode 100644 src/WixToolset.Core/Converter.cs (limited to 'src/WixToolset.Core') diff --git a/src/WixToolset.Core/Converter.cs b/src/WixToolset.Core/Converter.cs deleted file mode 100644 index 1f83c88f..00000000 --- a/src/WixToolset.Core/Converter.cs +++ /dev/null @@ -1,619 +0,0 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. - -namespace WixToolset.Core -{ - using System; - using System.Collections.Generic; - using System.Globalization; - using System.IO; - using System.Linq; - using System.Xml; - using System.Xml.Linq; - using WixToolset.Data; - using WixToolset.Extensibility.Services; - - /// - /// WiX source code converter. - /// - internal class Converter - { - private const string XDocumentNewLine = "\n"; // XDocument normlizes "\r\n" to just "\n". - private static readonly XNamespace WixNamespace = "http://wixtoolset.org/schemas/v4/wxs"; - - private static readonly XName FileElementName = WixNamespace + "File"; - private static readonly XName ExePackageElementName = WixNamespace + "ExePackage"; - private static readonly XName MsiPackageElementName = WixNamespace + "MsiPackage"; - private static readonly XName MspPackageElementName = WixNamespace + "MspPackage"; - private static readonly XName MsuPackageElementName = WixNamespace + "MsuPackage"; - private static readonly XName PayloadElementName = WixNamespace + "Payload"; - private static readonly XName WixElementWithoutNamespaceName = XNamespace.None + "Wix"; - - private static readonly Dictionary OldToNewNamespaceMapping = new Dictionary() - { - { "http://schemas.microsoft.com/wix/BalExtension", "http://wixtoolset.org/schemas/v4/wxs/bal" }, - { "http://schemas.microsoft.com/wix/ComPlusExtension", "http://wixtoolset.org/schemas/v4/wxs/complus" }, - { "http://schemas.microsoft.com/wix/DependencyExtension", "http://wixtoolset.org/schemas/v4/wxs/dependency" }, - { "http://schemas.microsoft.com/wix/DifxAppExtension", "http://wixtoolset.org/schemas/v4/wxs/difxapp" }, - { "http://schemas.microsoft.com/wix/FirewallExtension", "http://wixtoolset.org/schemas/v4/wxs/firewall" }, - { "http://schemas.microsoft.com/wix/GamingExtension", "http://wixtoolset.org/schemas/v4/wxs/gaming" }, - { "http://schemas.microsoft.com/wix/IIsExtension", "http://wixtoolset.org/schemas/v4/wxs/iis" }, - { "http://schemas.microsoft.com/wix/MsmqExtension", "http://wixtoolset.org/schemas/v4/wxs/msmq" }, - { "http://schemas.microsoft.com/wix/NetFxExtension", "http://wixtoolset.org/schemas/v4/wxs/netfx" }, - { "http://schemas.microsoft.com/wix/PSExtension", "http://wixtoolset.org/schemas/v4/wxs/powershell" }, - { "http://schemas.microsoft.com/wix/SqlExtension", "http://wixtoolset.org/schemas/v4/wxs/sql" }, - { "http://schemas.microsoft.com/wix/TagExtension", "http://wixtoolset.org/schemas/v4/wxs/tag" }, - { "http://schemas.microsoft.com/wix/UtilExtension", "http://wixtoolset.org/schemas/v4/wxs/util" }, - { "http://schemas.microsoft.com/wix/VSExtension", "http://wixtoolset.org/schemas/v4/wxs/vs" }, - { "http://wixtoolset.org/schemas/thmutil/2010", "http://wixtoolset.org/schemas/v4/thmutil" }, - { "http://schemas.microsoft.com/wix/2009/Lux", "http://wixtoolset.org/schemas/v4/lux" }, - { "http://schemas.microsoft.com/wix/2006/wi", "http://wixtoolset.org/schemas/v4/wxs" }, - { "http://schemas.microsoft.com/wix/2006/localization", "http://wixtoolset.org/schemas/v4/wxl" }, - { "http://schemas.microsoft.com/wix/2006/libraries", "http://wixtoolset.org/schemas/v4/wixlib" }, - { "http://schemas.microsoft.com/wix/2006/objects", "http://wixtoolset.org/schemas/v4/wixobj" }, - { "http://schemas.microsoft.com/wix/2006/outputs", "http://wixtoolset.org/schemas/v4/wixout" }, - { "http://schemas.microsoft.com/wix/2007/pdbs", "http://wixtoolset.org/schemas/v4/wixpdb" }, - { "http://schemas.microsoft.com/wix/2003/04/actions", "http://wixtoolset.org/schemas/v4/wi/actions" }, - { "http://schemas.microsoft.com/wix/2006/tables", "http://wixtoolset.org/schemas/v4/wi/tables" }, - { "http://schemas.microsoft.com/wix/2006/WixUnit", "http://wixtoolset.org/schemas/v4/wixunit" }, - }; - - private Dictionary> ConvertElementMapping; - - /// - /// Instantiate a new Converter class. - /// - /// Indentation value to use when validating leading whitespace. - /// Test errors to display as warnings. - /// Test errors to ignore. - internal Converter(IMessaging messaging, int indentationAmount, IEnumerable errorsAsWarnings = null, IEnumerable ignoreErrors = null) - { - this.ConvertElementMapping = new Dictionary>() - { - { FileElementName, this.ConvertFileElement }, - { ExePackageElementName, this.ConvertSuppressSignatureValidation }, - { MsiPackageElementName, this.ConvertSuppressSignatureValidation }, - { MspPackageElementName, this.ConvertSuppressSignatureValidation }, - { MsuPackageElementName, this.ConvertSuppressSignatureValidation }, - { PayloadElementName, this.ConvertSuppressSignatureValidation }, - { WixElementWithoutNamespaceName, this.ConvertWixElementWithoutNamespace }, - }; - - this.Messaging = messaging; - - this.IndentationAmount = indentationAmount; - - this.ErrorsAsWarnings = new HashSet(this.YieldConverterTypes(errorsAsWarnings)); - - this.IgnoreErrors = new HashSet(this.YieldConverterTypes(ignoreErrors)); - } - - private int Errors { get; set; } - - private HashSet ErrorsAsWarnings { get; set; } - - private HashSet IgnoreErrors { get; set; } - - private IMessaging Messaging { get; } - - private int IndentationAmount { get; set; } - - private string SourceFile { get; set; } - - /// - /// Convert a file. - /// - /// The file to convert. - /// Option to save the converted errors that are found. - /// The number of errors found. - public int ConvertFile(string sourceFile, bool saveConvertedFile) - { - XDocument document; - - // Set the instance info. - this.Errors = 0; - this.SourceFile = sourceFile; - - try - { - document = XDocument.Load(this.SourceFile, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo); - } - catch (XmlException e) - { - this.OnError(ConverterTestType.XmlException, (XObject)null, "The xml is invalid. Detail: '{0}'", e.Message); - - return this.Errors; - } - - this.ConvertDocument(document); - - // Fix errors if requested and necessary. - if (saveConvertedFile && 0 < this.Errors) - { - try - { - using (StreamWriter writer = File.CreateText(this.SourceFile)) - { - document.Save(writer, SaveOptions.DisableFormatting | SaveOptions.OmitDuplicateNamespaces); - } - } - catch (UnauthorizedAccessException) - { - this.OnError(ConverterTestType.UnauthorizedAccessException, (XObject)null, "Could not write to file."); - } - } - - return this.Errors; - } - - /// - /// Convert a document. - /// - /// The document to convert. - /// The number of errors found. - public int ConvertDocument(XDocument document) - { - XDeclaration declaration = document.Declaration; - - // Convert the declaration. - if (null != declaration) - { - if (!String.Equals("utf-8", declaration.Encoding, StringComparison.OrdinalIgnoreCase)) - { - if (this.OnError(ConverterTestType.DeclarationEncodingWrong, document.Root, "The XML declaration encoding is not properly set to 'utf-8'.")) - { - declaration.Encoding = "utf-8"; - } - } - } - else // missing declaration - { - if (this.OnError(ConverterTestType.DeclarationMissing, (XNode)null, "This file is missing an XML declaration on the first line.")) - { - document.Declaration = new XDeclaration("1.0", "utf-8", null); - document.Root.AddBeforeSelf(new XText(XDocumentNewLine)); - } - } - - // Start converting the nodes at the top. - this.ConvertNode(document.Root, 0); - - return this.Errors; - } - - /// - /// Convert a single xml node. - /// - /// The node to convert. - /// The depth level of the node. - /// The converted node. - private void ConvertNode(XNode node, int level) - { - // Convert this node's whitespace. - if ((XmlNodeType.Comment == node.NodeType && 0 > ((XComment)node).Value.IndexOf(XDocumentNewLine, StringComparison.Ordinal)) || - XmlNodeType.CDATA == node.NodeType || XmlNodeType.Element == node.NodeType || XmlNodeType.ProcessingInstruction == node.NodeType) - { - this.ConvertWhitespace(node, level); - } - - // Convert this node if it is an element. - XElement element = node as XElement; - - if (null != element) - { - this.ConvertElement(element); - - // Convert all children of this element. - IEnumerable children = element.Nodes().ToList(); - - foreach (XNode child in children) - { - this.ConvertNode(child, level + 1); - } - } - } - - private void ConvertElement(XElement element) - { - // Gather any deprecated namespaces, then update this element tree based on those deprecations. - Dictionary deprecatedToUpdatedNamespaces = new Dictionary(); - - foreach (XAttribute declaration in element.Attributes().Where(a => a.IsNamespaceDeclaration)) - { - XNamespace ns; - - if (Converter.OldToNewNamespaceMapping.TryGetValue(declaration.Value, out ns)) - { - if (this.OnError(ConverterTestType.XmlnsValueWrong, declaration, "The namespace '{0}' is out of date. It must be '{1}'.", declaration.Value, ns.NamespaceName)) - { - deprecatedToUpdatedNamespaces.Add(declaration.Value, ns); - } - } - } - - if (deprecatedToUpdatedNamespaces.Any()) - { - Converter.UpdateElementsWithDeprecatedNamespaces(element.DescendantsAndSelf(), deprecatedToUpdatedNamespaces); - } - - // Convert the node in much greater detail. - Action convert; - - if (this.ConvertElementMapping.TryGetValue(element.Name, out convert)) - { - convert(element); - } - } - - private void ConvertFileElement(XElement element) - { - if (null == element.Attribute("Id")) - { - XAttribute attribute = element.Attribute("Name"); - - if (null == attribute) - { - attribute = element.Attribute("Source"); - } - - if (null != attribute) - { - string name = Path.GetFileName(attribute.Value); - - if (this.OnError(ConverterTestType.AssignAnonymousFileId, element, "The file id is being updated to '{0}' to ensure it remains the same as the default", name)) - { - IEnumerable attributes = element.Attributes().ToList(); - element.RemoveAttributes(); - element.Add(new XAttribute("Id", Common.GetIdentifierFromName(name))); - element.Add(attributes); - } - } - } - } - - private void ConvertSuppressSignatureValidation(XElement element) - { - XAttribute suppressSignatureValidation = element.Attribute("SuppressSignatureValidation"); - - if (null != suppressSignatureValidation) - { - if (this.OnError(ConverterTestType.SuppressSignatureValidationDeprecated, element, "The chain package element contains deprecated '{0}' attribute. Use the 'EnableSignatureValidation' instead.", suppressSignatureValidation)) - { - if ("no" == suppressSignatureValidation.Value) - { - element.Add(new XAttribute("EnableSignatureValidation", "yes")); - } - } - - suppressSignatureValidation.Remove(); - } - } - - /// - /// Converts a Wix element. - /// - /// The Wix element to convert. - /// The converted element. - private void ConvertWixElementWithoutNamespace(XElement element) - { - if (this.OnError(ConverterTestType.XmlnsMissing, element, "The xmlns attribute is missing. It must be present with a value of '{0}'.", WixNamespace.NamespaceName)) - { - element.Name = WixNamespace.GetName(element.Name.LocalName); - - element.Add(new XAttribute("xmlns", WixNamespace.NamespaceName)); // set the default namespace. - - foreach (XElement elementWithoutNamespace in element.Elements().Where(e => XNamespace.None == e.Name.Namespace)) - { - elementWithoutNamespace.Name = WixNamespace.GetName(elementWithoutNamespace.Name.LocalName); - } - } - } - - /// - /// Convert the whitespace adjacent to a node. - /// - /// The node to convert. - /// The depth level of the node. - private void ConvertWhitespace(XNode node, int level) - { - // Fix the whitespace before this node. - XText whitespace = node.PreviousNode as XText; - - if (null != whitespace) - { - if (XmlNodeType.CDATA == node.NodeType) - { - if (this.OnError(ConverterTestType.WhitespacePrecedingCDATAWrong, node, "There should be no whitespace preceding a CDATA node.")) - { - whitespace.Remove(); - } - } - else - { - if (!Converter.IsLegalWhitespace(this.IndentationAmount, level, whitespace.Value)) - { - if (this.OnError(ConverterTestType.WhitespacePrecedingNodeWrong, node, "The whitespace preceding this node is incorrect.")) - { - Converter.FixWhitespace(this.IndentationAmount, level, whitespace); - } - } - } - } - - // Fix the whitespace after CDATA nodes. - XCData cdata = node as XCData; - - if (null != cdata) - { - whitespace = cdata.NextNode as XText; - - if (null != whitespace) - { - if (this.OnError(ConverterTestType.WhitespaceFollowingCDATAWrong, node, "There should be no whitespace following a CDATA node.")) - { - whitespace.Remove(); - } - } - } - else - { - // Fix the whitespace inside and after this node (except for Error which may contain just whitespace). - XElement element = node as XElement; - - if (null != element && "Error" != element.Name.LocalName) - { - if (!element.HasElements && !element.IsEmpty && String.IsNullOrEmpty(element.Value.Trim())) - { - if (this.OnError(ConverterTestType.NotEmptyElement, element, "This should be an empty element since it contains nothing but whitespace.")) - { - element.RemoveNodes(); - } - } - - whitespace = node.NextNode as XText; - - if (null != whitespace) - { - if (!Converter.IsLegalWhitespace(this.IndentationAmount, level - 1, whitespace.Value)) - { - if (this.OnError(ConverterTestType.WhitespacePrecedingEndElementWrong, whitespace, "The whitespace preceding this end element is incorrect.")) - { - Converter.FixWhitespace(this.IndentationAmount, level - 1, whitespace); - } - } - } - } - } - } - - private IEnumerable YieldConverterTypes(IEnumerable types) - { - if (null != types) - { - foreach (string type in types) - { - ConverterTestType itt; - - if (Enum.TryParse(type, true, out itt)) - { - yield return itt; - } - else // not a known ConverterTestType - { - this.OnError(ConverterTestType.ConverterTestTypeUnknown, (XObject)null, "Unknown error type: '{0}'.", type); - } - } - } - } - - private static void UpdateElementsWithDeprecatedNamespaces(IEnumerable elements, Dictionary deprecatedToUpdatedNamespaces) - { - foreach (XElement element in elements) - { - XNamespace ns; - - if (deprecatedToUpdatedNamespaces.TryGetValue(element.Name.Namespace, out ns)) - { - element.Name = ns.GetName(element.Name.LocalName); - } - - // Remove all the attributes and add them back to with their namespace updated (as necessary). - IEnumerable attributes = element.Attributes().ToList(); - element.RemoveAttributes(); - - foreach (XAttribute attribute in attributes) - { - XAttribute convertedAttribute = attribute; - - if (attribute.IsNamespaceDeclaration) - { - if (deprecatedToUpdatedNamespaces.TryGetValue(attribute.Value, out ns)) - { - convertedAttribute = ("xmlns" == attribute.Name.LocalName) ? new XAttribute(attribute.Name.LocalName, ns.NamespaceName) : new XAttribute(XNamespace.Xmlns + attribute.Name.LocalName, ns.NamespaceName); - } - } - else if (deprecatedToUpdatedNamespaces.TryGetValue(attribute.Name.Namespace, out ns)) - { - convertedAttribute = new XAttribute(ns.GetName(attribute.Name.LocalName), attribute.Value); - } - - element.Add(convertedAttribute); - } - } - } - - /// - /// Determine if the whitespace preceding a node is appropriate for its depth level. - /// - /// Indentation value to use when validating leading whitespace. - /// The depth level that should match this whitespace. - /// The whitespace to validate. - /// true if the whitespace is legal; false otherwise. - private static bool IsLegalWhitespace(int indentationAmount, int level, string whitespace) - { - // strip off leading newlines; there can be an arbitrary number of these - while (whitespace.StartsWith(XDocumentNewLine, StringComparison.Ordinal)) - { - whitespace = whitespace.Substring(XDocumentNewLine.Length); - } - - // check the length - if (whitespace.Length != level * indentationAmount) - { - return false; - } - - // check the spaces - foreach (char character in whitespace) - { - if (' ' != character) - { - return false; - } - } - - return true; - } - - /// - /// Fix the whitespace in a Whitespace node. - /// - /// Indentation value to use when validating leading whitespace. - /// The depth level of the desired whitespace. - /// The whitespace node to fix. - private static void FixWhitespace(int indentationAmount, int level, XText whitespace) - { - int newLineCount = 0; - - for (int i = 0; i + 1 < whitespace.Value.Length; ++i) - { - if (XDocumentNewLine == whitespace.Value.Substring(i, 2)) - { - ++i; // skip an extra character - ++newLineCount; - } - } - - if (0 == newLineCount) - { - newLineCount = 1; - } - - // reset the whitespace value - whitespace.Value = String.Empty; - - // add the correct number of newlines - for (int i = 0; i < newLineCount; ++i) - { - whitespace.Value = String.Concat(whitespace.Value, XDocumentNewLine); - } - - // add the correct number of spaces based on configured indentation amount - whitespace.Value = String.Concat(whitespace.Value, new string(' ', level * indentationAmount)); - } - - /// - /// Output an error message to the console. - /// - /// The type of converter test. - /// The node that caused the error. - /// Detailed error message. - /// Additional formatted string arguments. - /// Returns true indicating that action should be taken on this error, and false if it should be ignored. - private bool OnError(ConverterTestType converterTestType, XObject node, string message, params object[] args) - { - if (this.IgnoreErrors.Contains(converterTestType)) // ignore the error - { - return false; - } - - // Increase the error count. - this.Errors++; - - SourceLineNumber sourceLine = (null == node) ? new SourceLineNumber(this.SourceFile ?? "wixcop.exe") : new SourceLineNumber(this.SourceFile, ((IXmlLineInfo)node).LineNumber); - bool warning = this.ErrorsAsWarnings.Contains(converterTestType); - string display = String.Format(CultureInfo.CurrentCulture, message, args); - - var msg = new Message(sourceLine, warning ? MessageLevel.Warning : MessageLevel.Error, (int)converterTestType, "{0} ({1})", display, converterTestType.ToString()); - - this.Messaging.Write(msg); - - return true; - } - - /// - /// Converter test types. These are used to condition error messages down to warnings. - /// - private enum ConverterTestType - { - /// - /// Internal-only: displayed when a string cannot be converted to an ConverterTestType. - /// - ConverterTestTypeUnknown, - - /// - /// Displayed when an XML loading exception has occurred. - /// - XmlException, - - /// - /// Displayed when a file cannot be accessed; typically when trying to save back a fixed file. - /// - UnauthorizedAccessException, - - /// - /// Displayed when the encoding attribute in the XML declaration is not 'UTF-8'. - /// - DeclarationEncodingWrong, - - /// - /// Displayed when the XML declaration is missing from the source file. - /// - DeclarationMissing, - - /// - /// Displayed when the whitespace preceding a CDATA node is wrong. - /// - WhitespacePrecedingCDATAWrong, - - /// - /// Displayed when the whitespace preceding a node is wrong. - /// - WhitespacePrecedingNodeWrong, - - /// - /// Displayed when an element is not empty as it should be. - /// - NotEmptyElement, - - /// - /// Displayed when the whitespace following a CDATA node is wrong. - /// - WhitespaceFollowingCDATAWrong, - - /// - /// Displayed when the whitespace preceding an end element is wrong. - /// - WhitespacePrecedingEndElementWrong, - - /// - /// Displayed when the xmlns attribute is missing from the document element. - /// - XmlnsMissing, - - /// - /// Displayed when the xmlns attribute on the document element is wrong. - /// - XmlnsValueWrong, - - /// - /// Assign an identifier to a File element when on Id attribute is specified. - /// - AssignAnonymousFileId, - - /// - /// SuppressSignatureValidation attribute is deprecated and replaced with EnableSignatureValidation. - /// - SuppressSignatureValidationDeprecated, - } - } -} -- cgit v1.2.3-55-g6feb