| 1 | // 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. |
| 2 | |
| 3 | namespace WixToolset.Core.WindowsInstaller.Bind |
| 4 | { |
| 5 | using System.Collections.Generic; |
| 6 | using System.Linq; |
| 7 | using WixToolset.Data; |
| 8 | using WixToolset.Data.Symbols; |
| 9 | using WixToolset.Extensibility.Data; |
| 10 | using WixToolset.Extensibility.Services; |
| 11 | |
| 12 | internal class GetFileFacadesCommand |
| 13 | { |
| 14 | public GetFileFacadesCommand(IntermediateSection section, IWindowsInstallerBackendHelper backendHelper) |
| 15 | { |
| 16 | this.Section = section; |
| 17 | this.BackendHelper = backendHelper; |
| 18 | } |
| 19 | |
| 20 | private IntermediateSection Section { get; } |
| 21 | |
| 22 | private IWindowsInstallerBackendHelper BackendHelper { get; } |
| 23 | |
| 24 | public List<IFileFacade> FileFacades { get; private set; } |
| 25 | |
| 26 | public void Execute() |
| 27 | { |
| 28 | var facades = new List<IFileFacade>(); |
| 29 | |
| 30 | #if TODO_PATCHING_DELTA |
| 31 | //var deltaPatchFiles = this.Section.Symbols.OfType<WixDeltaPatchFileSymbol>().ToDictionary(t => t.Id.Id); |
| 32 | #endif |
| 33 | |
| 34 | foreach (var file in this.Section.Symbols.OfType<FileSymbol>()) |
| 35 | { |
| 36 | #if TODO_PATCHING_DELTA |
| 37 | //deltaPatchFiles.TryGetValue(file.Id.Id, out var deltaPatchFile); |
| 38 | // TODO: should we be passing along delta information to the file facade? Probably, right? |
| 39 | #endif |
| 40 | var fileFacade = this.BackendHelper.CreateFileFacade(file); |
| 41 | |
| 42 | facades.Add(fileFacade); |
| 43 | } |
| 44 | |
| 45 | #if TODO_PATCHING_DELTA |
| 46 | this.ResolveDeltaPatchSymbolPaths(deltaPatchFiles, facades); |
| 47 | #endif |
| 48 | |
| 49 | this.FileFacades = facades; |
| 50 | } |
| 51 | |
| 52 | #if TODO_PATCHING_DELTA |
| 53 | /// <summary> |
| 54 | /// Merge data from the WixPatchSymbolPaths rows into the WixDeltaPatchFile rows. |
| 55 | /// </summary> |
| 56 | public void ResolveDeltaPatchSymbolPaths(Dictionary<string, WixDeltaPatchFileSymbol> deltaPatchFiles, IEnumerable<FileFacade> facades) |
| 57 | { |
| 58 | ILookup<string, FileFacade> filesByComponent = null; |
| 59 | ILookup<string, FileFacade> filesByDirectory = null; |
| 60 | ILookup<string, FileFacade> filesByDiskId = null; |
| 61 | |
| 62 | foreach (var row in this.Section.Symbols.OfType<WixDeltaPatchSymbolPathsSymbol>().OrderBy(r => r.SymbolType)) |
| 63 | { |
| 64 | switch (row.SymbolType) |
| 65 | { |
| 66 | case SymbolPathType.File: |
| 67 | this.MergeSymbolPaths(row, deltaPatchFiles[row.SymbolId]); |
| 68 | break; |
| 69 | |
| 70 | case SymbolPathType.Component: |
| 71 | if (null == filesByComponent) |
| 72 | { |
| 73 | filesByComponent = facades.ToLookup(f => f.File.ComponentRef); |
| 74 | } |
| 75 | |
| 76 | foreach (var facade in filesByComponent[row.SymbolId]) |
| 77 | { |
| 78 | this.MergeSymbolPaths(row, deltaPatchFiles[facade.File.Id.Id]); |
| 79 | } |
| 80 | break; |
| 81 | |
| 82 | case SymbolPathType.Directory: |
| 83 | if (null == filesByDirectory) |
| 84 | { |
| 85 | filesByDirectory = facades.ToLookup(f => f.File.DirectoryRef); |
| 86 | } |
| 87 | |
| 88 | foreach (var facade in filesByDirectory[row.SymbolId]) |
| 89 | { |
| 90 | this.MergeSymbolPaths(row, deltaPatchFiles[facade.File.Id.Id]); |
| 91 | } |
| 92 | break; |
| 93 | |
| 94 | case SymbolPathType.Media: |
| 95 | if (null == filesByDiskId) |
| 96 | { |
| 97 | filesByDiskId = facades.ToLookup(f => f.File.DiskId.ToString(CultureInfo.InvariantCulture)); |
| 98 | } |
| 99 | |
| 100 | foreach (var facade in filesByDiskId[row.SymbolId]) |
| 101 | { |
| 102 | this.MergeSymbolPaths(row, deltaPatchFiles[facade.File.Id.Id]); |
| 103 | } |
| 104 | break; |
| 105 | |
| 106 | case SymbolPathType.Product: |
| 107 | foreach (var fileRow in deltaPatchFiles.Values) |
| 108 | { |
| 109 | this.MergeSymbolPaths(row, fileRow); |
| 110 | } |
| 111 | break; |
| 112 | |
| 113 | default: |
| 114 | // error |
| 115 | break; |
| 116 | } |
| 117 | } |
| 118 | } |
| 119 | |
| 120 | /// <summary> |
| 121 | /// Merge data from a row in the WixPatchSymbolsPaths table into an associated WixDeltaPatchFile row. |
| 122 | /// </summary> |
| 123 | /// <param name="row">Row from the WixPatchSymbolsPaths table.</param> |
| 124 | /// <param name="file">FileRow into which to set symbol information.</param> |
| 125 | /// <comment>This includes PreviousData as well.</comment> |
| 126 | private void MergeSymbolPaths(WixDeltaPatchSymbolPathsSymbol row, WixDeltaPatchFileSymbol file) |
| 127 | { |
| 128 | if (file.SymbolPaths is null) |
| 129 | { |
| 130 | file.SymbolPaths = row.SymbolPaths; |
| 131 | } |
| 132 | else |
| 133 | { |
| 134 | file.SymbolPaths = String.Concat(file.SymbolPaths, ";", row.SymbolPaths); |
| 135 | } |
| 136 | |
| 137 | Field field = row.Fields[2]; |
| 138 | if (null != field.PreviousData) |
| 139 | { |
| 140 | if (null == file.PreviousSymbols) |
| 141 | { |
| 142 | file.PreviousSymbols = field.PreviousData; |
| 143 | } |
| 144 | else |
| 145 | { |
| 146 | file.PreviousSymbols = String.Concat(file.PreviousSymbols, ";", field.PreviousData); |
| 147 | } |
| 148 | } |
| 149 | } |
| 150 | #endif |
| 151 | } |
| 152 | } |