// 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.WindowsInstaller.Bind { using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using WixToolset.Data; using WixToolset.Data.Tuples; using WixToolset.Data.WindowsInstaller; using WixToolset.Extensibility; using WixToolset.Extensibility.Services; internal class LoadTableDefinitionsCommand { public LoadTableDefinitionsCommand(IMessaging messaging, IntermediateSection section, IEnumerable backendExtensions) { this.Messaging = messaging; this.Section = section; this.BackendExtensions = backendExtensions; } public IMessaging Messaging { get; } private IntermediateSection Section { get; } private IEnumerable BackendExtensions { get; } public TableDefinitionCollection TableDefinitions { get; private set; } public TableDefinitionCollection Execute() { var tableDefinitions = new TableDefinitionCollection(WindowsInstallerTableDefinitions.All); var customColumnsById = this.Section.Tuples.OfType().ToDictionary(t => t.Id.Id); if (customColumnsById.Any()) { foreach (var tuple in this.Section.Tuples.OfType()) { var customTableDefinition = this.CreateCustomTable(tuple, customColumnsById); tableDefinitions.Add(customTableDefinition); } } foreach (var backendExtension in this.BackendExtensions) { foreach (var tableDefinition in backendExtension.TableDefinitions) { if (tableDefinitions.Contains(tableDefinition.Name)) { this.Messaging.Write(ErrorMessages.DuplicateExtensionTable(backendExtension.GetType().Assembly.Location, tableDefinition.Name)); } tableDefinitions.Add(tableDefinition); } } this.TableDefinitions = tableDefinitions; return this.TableDefinitions; } private TableDefinition CreateCustomTable(WixCustomTableTuple tuple, Dictionary customColumnsById) { var columnNames = tuple.ColumnNamesSeparated; var columns = new List(columnNames.Length); foreach (var name in columnNames) { var column = customColumnsById[tuple.Id.Id + "/" + name]; var type = ColumnType.Unknown; if (column.Type == IntermediateFieldType.String) { type = column.Localizable ? ColumnType.Localized : ColumnType.String; } else if (column.Type == IntermediateFieldType.Number) { type = ColumnType.Number; } else if (column.Type == IntermediateFieldType.Path) { type = ColumnType.Object; } var category = ColumnCategory.Unknown; switch (column.Category) { case "Text": category = ColumnCategory.Text; break; case "UpperCase": category = ColumnCategory.UpperCase; break; case "LowerCase": category = ColumnCategory.LowerCase; break; case "Integer": category = ColumnCategory.Integer; break; case "DoubleInteger": category = ColumnCategory.DoubleInteger; break; case "TimeDate": category = ColumnCategory.TimeDate; break; case "Identifier": category = ColumnCategory.Identifier; break; case "Property": category = ColumnCategory.Property; break; case "Filename": category = ColumnCategory.Filename; break; case "WildCardFilename": category = ColumnCategory.WildCardFilename; break; case "Path": category = ColumnCategory.Path; break; case "Paths": category = ColumnCategory.Paths; break; case "AnyPath": category = ColumnCategory.AnyPath; break; case "DefaultDir": category = ColumnCategory.DefaultDir; break; case "RegPath": category = ColumnCategory.RegPath; break; case "Formatted": category = ColumnCategory.Formatted; break; case "FormattedSddl": category = ColumnCategory.FormattedSDDLText; break; case "Template": category = ColumnCategory.Template; break; case "Condition": category = ColumnCategory.Condition; break; case "Guid": category = ColumnCategory.Guid; break; case "Version": category = ColumnCategory.Version; break; case "Language": category = ColumnCategory.Language; break; case "Binary": category = ColumnCategory.Binary; break; case "CustomSource": category = ColumnCategory.CustomSource; break; case "Cabinet": category = ColumnCategory.Cabinet; break; case "Shortcut": category = ColumnCategory.Shortcut; break; default: break; } var modularization = ColumnModularizeType.None; switch (column.Modularize) { case null: case WixCustomTableColumnModularizeType.None: modularization = ColumnModularizeType.None; break; case WixCustomTableColumnModularizeType.Column: modularization = ColumnModularizeType.Column; break; case WixCustomTableColumnModularizeType.CompanionFile: modularization = ColumnModularizeType.CompanionFile; break; case WixCustomTableColumnModularizeType.Condition: modularization = ColumnModularizeType.Condition; break; case WixCustomTableColumnModularizeType.ControlEventArgument: modularization = ColumnModularizeType.ControlEventArgument; break; case WixCustomTableColumnModularizeType.ControlText: modularization = ColumnModularizeType.ControlText; break; case WixCustomTableColumnModularizeType.Icon: modularization = ColumnModularizeType.Icon; break; case WixCustomTableColumnModularizeType.Property: modularization = ColumnModularizeType.Property; break; case WixCustomTableColumnModularizeType.SemicolonDelimited: modularization = ColumnModularizeType.SemicolonDelimited; break; } var columnDefinition = new ColumnDefinition(name, type, column.Width, column.PrimaryKey, column.Nullable, category, column.MinValue, column.MaxValue, column.KeyTable, column.KeyColumn, column.Set, column.Description, modularization, ColumnType.Localized == type, useCData: true, column.Unreal); columns.Add(columnDefinition); } var customTable = new TableDefinition(tuple.Id.Id, null, columns, tuple.Unreal); return customTable; } } }