Refactor payload compiling and harvesting.
Sean Hall committed
Feb 28, 2021 at 21:04 UTC
a6013a643208a8d1fc2d1136ef8d3a6c3e909522
8 files changed
+546
-343
src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs
+6
-2
@@ -11,6 +11,7 @@ namespace WixToolset.Core.Burn
11
using WixToolset.Core.Bind;
12
using WixToolset.Core.Burn.Bind;
13
using WixToolset.Core.Burn.Bundles;
14
+ using WixToolset.Core.Burn.Interfaces;
15
using WixToolset.Data;
16
using WixToolset.Data.Burn;
17
using WixToolset.Data.Symbols;
@@ -31,6 +32,7 @@ namespace WixToolset.Core.Burn
32
33
this.BackendHelper = context.ServiceProvider.GetService<IBackendHelper>();
34
this.InternalBurnBackendHelper = context.ServiceProvider.GetService<IInternalBurnBackendHelper>();
35
+ this.PayloadHarvester = context.ServiceProvider.GetService<IPayloadHarvester>();
36
37
this.DefaultCompressionLevel = context.DefaultCompressionLevel;
38
this.DelayedFields = context.DelayedFields;
@@ -52,6 +54,8 @@ namespace WixToolset.Core.Burn
54
55
private IInternalBurnBackendHelper InternalBurnBackendHelper { get; }
56
57
+ private IPayloadHarvester PayloadHarvester { get; }
58
+
59
private CompressionLevel? DefaultCompressionLevel { get; }
60
61
public IEnumerable<IDelayedField> DelayedFields { get; }
@@ -165,7 +169,7 @@ namespace WixToolset.Core.Burn
169
// Process the explicitly authored payloads.
170
ISet<string> processedPayloads;
171
{
168
- var command = new ProcessPayloadsCommand(this.ServiceProvider, this.BackendHelper, payloadSymbols.Values, bundleSymbol.DefaultPackagingType, layoutDirectory);
172
+ var command = new ProcessPayloadsCommand(this.ServiceProvider, this.BackendHelper, this.PayloadHarvester, payloadSymbols.Values, bundleSymbol.DefaultPackagingType, layoutDirectory);
173
command.Execute();
174
175
fileTransfers.AddRange(command.FileTransfers);
@@ -247,7 +251,7 @@ namespace WixToolset.Core.Burn
251
{
252
var toProcess = payloadSymbols.Values.Where(r => !processedPayloads.Contains(r.Id.Id)).ToList();
253
250
- var command = new ProcessPayloadsCommand(this.ServiceProvider, this.BackendHelper, toProcess, bundleSymbol.DefaultPackagingType, layoutDirectory);
254
+ var command = new ProcessPayloadsCommand(this.ServiceProvider, this.BackendHelper, this.PayloadHarvester, toProcess, bundleSymbol.DefaultPackagingType, layoutDirectory);
255
command.Execute();
256
257
fileTransfers.AddRange(command.FileTransfers);
src/WixToolset.Core.Burn/Bundles/ProcessPayloadsCommand.cs
+6
-43
@@ -6,6 +6,7 @@ namespace WixToolset.Core.Burn.Bundles
6
using System.Collections.Generic;
7
using System.Diagnostics;
8
using System.IO;
9
+ using WixToolset.Core.Burn.Interfaces;
10
using WixToolset.Data;
11
using WixToolset.Data.Burn;
12
using WixToolset.Data.Symbols;
@@ -14,13 +15,12 @@ namespace WixToolset.Core.Burn.Bundles
15
16
internal class ProcessPayloadsCommand
17
{
17
- private static readonly Version EmptyVersion = new Version(0, 0, 0, 0);
18
-
19
- public ProcessPayloadsCommand(IWixToolsetServiceProvider serviceProvider, IBackendHelper backendHelper, IEnumerable<WixBundlePayloadSymbol> payloads, PackagingType defaultPackaging, string layoutDirectory)
18
+ public ProcessPayloadsCommand(IWixToolsetServiceProvider serviceProvider, IBackendHelper backendHelper, IPayloadHarvester payloadHarvester, IEnumerable<WixBundlePayloadSymbol> payloads, PackagingType defaultPackaging, string layoutDirectory)
19
{
20
this.Messaging = serviceProvider.GetService<IMessaging>();
21
22
this.BackendHelper = backendHelper;
23
+ this.PayloadHarvester = payloadHarvester;
24
this.Payloads = payloads;
25
this.DefaultPackaging = defaultPackaging;
26
this.LayoutDirectory = layoutDirectory;
@@ -34,6 +34,8 @@ namespace WixToolset.Core.Burn.Bundles
34
35
private IBackendHelper BackendHelper { get; }
36
37
+ private IPayloadHarvester PayloadHarvester { get; }
38
+
39
private IEnumerable<WixBundlePayloadSymbol> Payloads { get; }
40
41
private PackagingType DefaultPackaging { get; }
@@ -56,17 +58,13 @@ namespace WixToolset.Core.Burn.Bundles
58
59
this.UpdatePayloadPackagingType(payload);
60
59
- if (String.IsNullOrEmpty(sourceFile?.Path))
61
+ if (!this.PayloadHarvester.HarvestStandardInformation(payload))
62
{
63
// Remote payloads obviously cannot be embedded.
64
Debug.Assert(PackagingType.Embedded != payload.Packaging);
65
}
66
else // not a remote payload so we have a lot more to update.
67
{
66
- this.UpdatePayloadFileInformation(payload, sourceFile);
67
-
68
- this.UpdatePayloadVersionInformation(payload, sourceFile);
69
-
68
// External payloads need to be transfered.
69
if (PackagingType.External == payload.Packaging)
70
{
@@ -110,40 +108,5 @@ namespace WixToolset.Core.Burn.Bundles
108
payload.ContainerRef = BurnConstants.BurnDefaultAttachedContainerName;
109
}
110
}
113
-
114
- private void UpdatePayloadFileInformation(WixBundlePayloadSymbol payload, IntermediateFieldPathValue sourceFile)
115
- {
116
- var fileInfo = new FileInfo(sourceFile.Path);
117
-
118
- if (null != fileInfo)
119
- {
120
- payload.FileSize = fileInfo.Length;
121
-
122
- payload.Hash = BundleHashAlgorithm.Hash(fileInfo);
123
- }
124
- else
125
- {
126
- payload.FileSize = 0;
127
- }
128
- }
129
-
130
- private void UpdatePayloadVersionInformation(WixBundlePayloadSymbol payload, IntermediateFieldPathValue sourceFile)
131
- {
132
- var versionInfo = FileVersionInfo.GetVersionInfo(sourceFile.Path);
133
-
134
- if (null != versionInfo)
135
- {
136
- // Use the fixed version info block for the file since the resource text may not be a dotted quad.
137
- var version = new Version(versionInfo.ProductMajorPart, versionInfo.ProductMinorPart, versionInfo.ProductBuildPart, versionInfo.ProductPrivatePart);
138
-
139
- if (ProcessPayloadsCommand.EmptyVersion != version)
140
- {
141
- payload.Version = version.ToString();
142
- }
143
-
144
- payload.Description = versionInfo.FileDescription;
145
- payload.DisplayName = versionInfo.ProductName;
146
- }
147
- }
111
}
112
}
src/WixToolset.Core.Burn/ExtensibilityServices/PayloadHarvester.cs
new
+68
@@ -0,0 +1,68 @@
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.Burn.ExtensibilityServices
4
+{
5
+ using System;
6
+ using System.Diagnostics;
7
+ using System.IO;
8
+ using WixToolset.Core.Burn.Bundles;
9
+ using WixToolset.Core.Burn.Interfaces;
10
+ using WixToolset.Data.Symbols;
11
+
12
+ internal class PayloadHarvester : IPayloadHarvester
13
+ {
14
+ private static readonly Version EmptyVersion = new Version(0, 0, 0, 0);
15
+
16
+ /// <inheritdoc />
17
+ public bool HarvestStandardInformation(WixBundlePayloadSymbol payload)
18
+ {
19
+ var filePath = payload.SourceFile?.Path;
20
+
21
+ if (String.IsNullOrEmpty(filePath))
22
+ {
23
+ return false;
24
+ }
25
+
26
+ this.UpdatePayloadFileInformation(payload, filePath);
27
+
28
+ this.UpdatePayloadVersionInformation(payload, filePath);
29
+
30
+ return true;
31
+ }
32
+
33
+ private void UpdatePayloadFileInformation(WixBundlePayloadSymbol payload, string filePath)
34
+ {
35
+ var fileInfo = new FileInfo(filePath);
36
+
37
+ if (null != fileInfo)
38
+ {
39
+ payload.FileSize = fileInfo.Length;
40
+
41
+ payload.Hash = BundleHashAlgorithm.Hash(fileInfo);
42
+ }
43
+ else
44
+ {
45
+ payload.FileSize = 0;
46
+ }
47
+ }
48
+
49
+ private void UpdatePayloadVersionInformation(WixBundlePayloadSymbol payload, string filePath)
50
+ {
51
+ var versionInfo = FileVersionInfo.GetVersionInfo(filePath);
52
+
53
+ if (null != versionInfo)
54
+ {
55
+ // Use the fixed version info block for the file since the resource text may not be a dotted quad.
56
+ var version = new Version(versionInfo.ProductMajorPart, versionInfo.ProductMinorPart, versionInfo.ProductBuildPart, versionInfo.ProductPrivatePart);
57
+
58
+ if (PayloadHarvester.EmptyVersion != version)
59
+ {
60
+ payload.Version = version.ToString();
61
+ }
62
+
63
+ payload.Description = versionInfo.FileDescription;
64
+ payload.DisplayName = versionInfo.ProductName;
65
+ }
66
+ }
67
+ }
68
+}
src/WixToolset.Core.Burn/Interfaces/IPayloadHarvester.cs
new
+23
@@ -0,0 +1,23 @@
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.Burn.Interfaces
4
+{
5
+ using System.Diagnostics;
6
+ using WixToolset.Data.Symbols;
7
+
8
+ /// <summary>
9
+ /// Service for harvesting payload information.
10
+ /// </summary>
11
+ public interface IPayloadHarvester
12
+ {
13
+ /// <summary>
14
+ /// Uses <see cref="WixBundlePayloadSymbol.SourceFile"/> to:
15
+ /// update <see cref="WixBundlePayloadSymbol.Hash"/> from file contents,
16
+ /// update <see cref="WixBundlePayloadSymbol.FileSize"/> from file size, and
17
+ /// update <see cref="WixBundlePayloadSymbol.Description"/>, <see cref="WixBundlePayloadSymbol.DisplayName"/>, and <see cref="WixBundlePayloadSymbol.Version"/> from <see cref="FileVersionInfo"/>.
18
+ /// </summary>
19
+ /// <param name="payload">The symbol to update.</param>
20
+ /// <returns>Whether the symbol had a source file specified.</returns>
21
+ bool HarvestStandardInformation(WixBundlePayloadSymbol payload);
22
+ }
23
+}
src/WixToolset.Core.Burn/WixToolsetCoreServiceProviderExtensions.cs
+2
@@ -5,6 +5,7 @@ namespace WixToolset.Core.Burn
5
using System;
6
using System.Collections.Generic;
7
using WixToolset.Core.Burn.ExtensibilityServices;
8
+ using WixToolset.Core.Burn.Interfaces;
9
using WixToolset.Extensibility.Services;
10
11
/// <summary>
@@ -31,6 +32,7 @@ namespace WixToolset.Core.Burn
32
{
33
// Singletons.
34
coreProvider.AddService((provider, singletons) => AddSingleton<IInternalBurnBackendHelper>(singletons, new BurnBackendHelper(provider)));
35
+ coreProvider.AddService((provider, singletons) => AddSingleton<IPayloadHarvester>(singletons, new PayloadHarvester()));
36
coreProvider.AddService((provider, singletons) => AddSingleton<IBurnBackendHelper>(singletons, provider.GetService<IInternalBurnBackendHelper>()));
37
}
38
src/WixToolset.Core/Compile/CompilerPayload.cs
new
+247
@@ -0,0 +1,247 @@
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
4
+{
5
+ using System;
6
+ using System.IO;
7
+ using System.Xml.Linq;
8
+ using WixToolset.Data;
9
+ using WixToolset.Data.Burn;
10
+ using WixToolset.Data.Symbols;
11
+
12
+ internal class CompilerPayload
13
+ {
14
+ public YesNoDefaultType Compressed { get; set; } = YesNoDefaultType.Default;
15
+
16
+ public string Description { get; set; }
17
+
18
+ public string DisplayName { get; set; }
19
+
20
+ public string DownloadUrl { get; set; }
21
+
22
+ public string Hash { get; set; }
23
+
24
+ public Identifier Id { get; set; }
25
+
26
+ public bool IsRequired { get; set; } = true;
27
+
28
+ public string Name { get; set; }
29
+
30
+ public string ProductName { get; set; }
31
+
32
+ public long? Size { get; set; }
33
+
34
+ public string SourceFile { get; set; }
35
+
36
+ public string Version { get; set; }
37
+
38
+ public CompilerPayload(CompilerCore core, SourceLineNumber sourceLineNumbers, XElement element)
39
+ {
40
+ this.Core = core;
41
+ this.Element = element;
42
+ this.SourceLineNumbers = sourceLineNumbers;
43
+ }
44
+
45
+ private CompilerCore Core { get; }
46
+
47
+ private XElement Element { get; }
48
+
49
+ private SourceLineNumber SourceLineNumbers { get; }
50
+
51
+ private void CalculateAndVerifyFields(CompilerPayload remotePayload = null)
52
+ {
53
+ if (String.IsNullOrEmpty(this.SourceFile))
54
+ {
55
+ if (String.IsNullOrEmpty(this.Name))
56
+ {
57
+ if (this.IsRequired)
58
+ {
59
+ this.Core.Write(ErrorMessages.ExpectedAttributesWithOtherAttribute(this.SourceLineNumbers, this.Element.Name.LocalName, "Name", "SourceFile"));
60
+ }
61
+ }
62
+ else if (remotePayload == null)
63
+ {
64
+ this.SourceFile = Path.Combine("SourceDir", this.Name);
65
+ }
66
+ }
67
+ else if (remotePayload != null)
68
+ {
69
+ this.Core.Write(ErrorMessages.UnexpectedElementWithAttribute(this.SourceLineNumbers, this.Element.Name.LocalName, "RemotePayload", "SourceFile"));
70
+ }
71
+ else if (this.SourceFile.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal))
72
+ {
73
+ if (String.IsNullOrEmpty(this.Name))
74
+ {
75
+ this.Core.Write(ErrorMessages.ExpectedAttribute(this.SourceLineNumbers, this.Element.Name.LocalName, "Name", "SourceFile", this.SourceFile));
76
+ }
77
+ else
78
+ {
79
+ this.SourceFile = Path.Combine(this.SourceFile, Path.GetFileName(this.Name));
80
+ }
81
+ }
82
+
83
+ if (remotePayload != null)
84
+ {
85
+ if (this.DownloadUrl == null)
86
+ {
87
+ this.Core.Write(ErrorMessages.ExpectedAttributeWithElement(this.SourceLineNumbers, this.Element.Name.LocalName, "DownloadUrl", "RemotePayload"));
88
+ }
89
+
90
+ if (YesNoDefaultType.No != this.Compressed)
91
+ {
92
+ this.Compressed = YesNoDefaultType.No;
93
+ this.Core.Write(WarningMessages.RemotePayloadsMustNotAlsoBeCompressed(this.SourceLineNumbers, this.Element.Name.LocalName));
94
+ }
95
+
96
+ this.Description = remotePayload.Description;
97
+ this.DisplayName = remotePayload.DisplayName;
98
+ this.Hash = remotePayload.Hash;
99
+ this.Size = remotePayload.Size;
100
+ this.Version = remotePayload.Version;
101
+ }
102
+ }
103
+
104
+ public WixBundlePayloadSymbol CreatePayloadSymbol(ComplexReferenceParentType parentType, string parentId, ComplexReferenceChildType previousType = ComplexReferenceChildType.Unknown, string previousId = null)
105
+ {
106
+ WixBundlePayloadSymbol symbol = null;
107
+
108
+ if (parentType == ComplexReferenceParentType.Container && parentId == BurnConstants.BurnUXContainerName)
109
+ {
110
+ if (this.Compressed == YesNoDefaultType.No)
111
+ {
112
+ this.Core.Write(WarningMessages.UxPayloadsOnlySupportEmbedding(this.SourceLineNumbers, this.SourceFile));
113
+ }
114
+
115
+ if (!String.IsNullOrEmpty(this.DownloadUrl))
116
+ {
117
+ this.Core.Write(WarningMessages.DownloadUrlNotSupportedForEmbeddedPayloads(this.SourceLineNumbers, this.Id.Id));
118
+ }
119
+
120
+ this.Compressed = YesNoDefaultType.Yes;
121
+ this.DownloadUrl = null;
122
+ }
123
+
124
+ if (!this.Core.EncounteredError)
125
+ {
126
+ symbol = this.Core.AddSymbol(new WixBundlePayloadSymbol(this.SourceLineNumbers, this.Id)
127
+ {
128
+ Name = String.IsNullOrEmpty(this.Name) ? Path.GetFileName(this.SourceFile) : this.Name,
129
+ SourceFile = new IntermediateFieldPathValue { Path = this.SourceFile },
130
+ DownloadUrl = this.DownloadUrl,
131
+ Compressed = (this.Compressed == YesNoDefaultType.Yes) ? true : (this.Compressed == YesNoDefaultType.No) ? (bool?)false : null,
132
+ UnresolvedSourceFile = this.SourceFile, // duplicate of sourceFile but in a string column so it won't get resolved to a full path during binding.
133
+ DisplayName = this.DisplayName ?? this.ProductName,
134
+ Description = this.Description,
135
+ Hash = this.Hash,
136
+ FileSize = this.Size,
137
+ Version = this.Version,
138
+ });
139
+
140
+ this.Core.CreateGroupAndOrderingRows(this.SourceLineNumbers, parentType, parentId, ComplexReferenceChildType.Payload, symbol.Id.Id, previousType, previousId);
141
+ }
142
+
143
+ return symbol;
144
+ }
145
+
146
+ public void FinishCompilingPackage(CompilerPayload remotePayload)
147
+ {
148
+ this.CalculateAndVerifyFields(remotePayload);
149
+ this.GenerateIdFromFilename();
150
+
151
+ if (this.Id == null)
152
+ {
153
+ this.Core.Write(ErrorMessages.ExpectedAttribute(this.SourceLineNumbers, this.Element.Name.LocalName, "Id"));
154
+ this.Id = Identifier.Invalid;
155
+ }
156
+ }
157
+
158
+ public void FinishCompilingPayload()
159
+ {
160
+ this.CalculateAndVerifyFields();
161
+ this.GenerateIdFromPrefix("pay");
162
+ }
163
+
164
+ private void GenerateIdFromFilename()
165
+ {
166
+ if (this.Id == null)
167
+ {
168
+ if (!String.IsNullOrEmpty(this.Name))
169
+ {
170
+ this.Id = this.Core.CreateIdentifierFromFilename(Path.GetFileName(this.Name));
171
+ }
172
+ else if (!String.IsNullOrEmpty(this.SourceFile))
173
+ {
174
+ this.Id = this.Core.CreateIdentifierFromFilename(Path.GetFileName(this.SourceFile));
175
+ }
176
+ }
177
+ }
178
+
179
+ private void GenerateIdFromPrefix(string prefix)
180
+ {
181
+ if (this.Id == null)
182
+ {
183
+ this.Id = this.Core.CreateIdentifier(prefix, this.SourceFile?.ToUpperInvariant() ?? String.Empty);
184
+ }
185
+ }
186
+
187
+ public void ParseCompressed(XAttribute attrib)
188
+ {
189
+ this.Compressed = this.Core.GetAttributeYesNoDefaultValue(this.SourceLineNumbers, attrib);
190
+ }
191
+
192
+ public void ParseDescription(XAttribute attrib)
193
+ {
194
+ this.Description = this.Core.GetAttributeValue(this.SourceLineNumbers, attrib);
195
+ }
196
+
197
+ public void ParseDisplayName(XAttribute attrib)
198
+ {
199
+ this.DisplayName = this.Core.GetAttributeValue(this.SourceLineNumbers, attrib);
200
+ }
201
+
202
+ public void ParseDownloadUrl(XAttribute attrib)
203
+ {
204
+ this.DownloadUrl = this.Core.GetAttributeValue(this.SourceLineNumbers, attrib);
205
+ }
206
+
207
+ public void ParseHash(XAttribute attrib)
208
+ {
209
+ this.Hash = this.Core.GetAttributeValue(this.SourceLineNumbers, attrib);
210
+ }
211
+
212
+ public void ParseId(XAttribute attrib)
213
+ {
214
+ this.Id = this.Core.GetAttributeIdentifier(this.SourceLineNumbers, attrib);
215
+ }
216
+
217
+ public void ParseName(XAttribute attrib)
218
+ {
219
+ this.Name = this.Core.GetAttributeLongFilename(this.SourceLineNumbers, attrib, false, true);
220
+ if (!this.Core.IsValidLongFilename(this.Name, false, true))
221
+ {
222
+ this.Core.Write(ErrorMessages.IllegalLongFilename(this.SourceLineNumbers, this.Element.Name.LocalName, "Name", this.Name));
223
+ }
224
+ }
225
+
226
+ public void ParseProductName(XAttribute attrib)
227
+ {
228
+ this.ProductName = this.Core.GetAttributeValue(this.SourceLineNumbers, attrib);
229
+ }
230
+
231
+ public void ParseSize(XAttribute attrib)
232
+ {
233
+ this.Size = this.Core.GetAttributeLongValue(this.SourceLineNumbers, attrib, 1, Int64.MaxValue);
234
+ }
235
+
236
+ public void ParseSourceFile(XAttribute attrib)
237
+ {
238
+ this.SourceFile = this.Core.GetAttributeValue(this.SourceLineNumbers, attrib);
239
+ }
240
+
241
+ public void ParseVersion(XAttribute attrib)
242
+ {
243
+ this.Version = this.Core.GetAttributeValue(this.SourceLineNumbers, attrib);
244
+ }
245
+
246
+ }
247
+}
src/WixToolset.Core/CompilerCore.cs
+40
@@ -340,6 +340,46 @@ namespace WixToolset.Core
340
return Common.IsValidModuleOrBundleVersion(version);
341
}
342
343
+ /// <summary>
344
+ /// Creates group and ordering information.
345
+ /// </summary>
346
+ /// <param name="sourceLineNumbers">Source line numbers.</param>
347
+ /// <param name="parentType">Type of parent group, if known.</param>
348
+ /// <param name="parentId">Identifier of parent group, if known.</param>
349
+ /// <param name="type">Type of this item.</param>
350
+ /// <param name="id">Identifier for this item.</param>
351
+ /// <param name="previousType">Type of previous item, if known.</param>
352
+ /// <param name="previousId">Identifier of previous item, if known</param>
353
+ public void CreateGroupAndOrderingRows(SourceLineNumber sourceLineNumbers,
354
+ ComplexReferenceParentType parentType, string parentId,
355
+ ComplexReferenceChildType type, string id,
356
+ ComplexReferenceChildType previousType, string previousId)
357
+ {
358
+ if (this.EncounteredError)
359
+ {
360
+ return;
361
+ }
362
+
363
+ if (parentType != ComplexReferenceParentType.Unknown && parentId != null)
364
+ {
365
+ this.CreateWixGroupRow(sourceLineNumbers, parentType, parentId, type, id);
366
+ }
367
+
368
+ if (previousType != ComplexReferenceChildType.Unknown && previousId != null)
369
+ {
370
+ // TODO: Should we define our own enum for this, just to ensure there's no "cross-contamination"?
371
+ // TODO: Also, we could potentially include an 'Attributes' field to track things like
372
+ // 'before' vs. 'after', and explicit vs. inferred dependencies.
373
+ this.AddSymbol(new WixOrderingSymbol(sourceLineNumbers)
374
+ {
375
+ ItemType = type,
376
+ ItemIdRef = id,
377
+ DependsOnType = previousType,
378
+ DependsOnIdRef = previousId,
379
+ });
380
+ }
381
+ }
382
+
383
/// <summary>
384
/// Creates a version 3 name-based UUID.
385
/// </summary>
src/WixToolset.Core/Compiler_Bundle.cs
+154
-298
@@ -651,7 +651,7 @@ namespace WixToolset.Core
651
switch (child.Name.LocalName)
652
{
653
case "BootstrapperApplicationDll":
654
- previousId = this.ParseBootstrapperApplicationDllElement(child, previousType, previousId);
654
+ previousId = this.ParseBootstrapperApplicationDllElement(child, id, previousType, previousId);
655
previousType = ComplexReferenceChildType.Payload;
656
break;
657
case "Payload":
@@ -683,15 +683,21 @@ namespace WixToolset.Core
683
/// Parse the BoostrapperApplication element.
684
/// </summary>
685
/// <param name="node">Element to parse</param>
686
+ /// <param name="defaultId"></param>
687
/// <param name="previousType"></param>
688
/// <param name="previousId"></param>
688
- private Identifier ParseBootstrapperApplicationDllElement(XElement node, ComplexReferenceChildType previousType, Identifier previousId)
689
+ private Identifier ParseBootstrapperApplicationDllElement(XElement node, Identifier defaultId, ComplexReferenceChildType previousType, Identifier previousId)
690
{
691
var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
692
+ var compilerPayload = new CompilerPayload(this.Core, sourceLineNumbers, node)
693
+ {
694
+ Id = defaultId,
695
+ };
696
var dpiAwareness = WixBootstrapperApplicationDpiAwarenessType.PerMonitorV2;
697
693
- // The BootstrapperApplicationDll element acts like a Payload element so delegate to the "Payload" attribute parsing code to parse and create a Payload entry.
694
- this.ParsePayloadElementContent(node, ComplexReferenceParentType.Container, Compiler.BurnUXContainerId, previousType, previousId, true, out var id);
698
+ // This list lets us evaluate extension attributes *after* all core attributes
699
+ // have been parsed and dealt with, regardless of authoring order.
700
+ var extensionAttributes = new List<XAttribute>();
701
702
foreach (var attrib in node.Attributes())
703
{
@@ -699,6 +705,15 @@ namespace WixToolset.Core
705
{
706
switch (attrib.Name.LocalName)
707
{
708
+ case "Id":
709
+ compilerPayload.ParseId(attrib);
710
+ break;
711
+ case "Name":
712
+ compilerPayload.ParseName(attrib);
713
+ break;
714
+ case "SourceFile":
715
+ compilerPayload.ParseSourceFile(attrib);
716
+ break;
717
case "DpiAwareness":
718
var dpiAwarenessValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
719
switch (dpiAwarenessValue)
@@ -723,8 +738,28 @@ namespace WixToolset.Core
738
break;
739
}
740
break;
741
+ default:
742
+ this.Core.UnexpectedAttribute(node, attrib);
743
+ break;
744
}
745
}
746
+ else
747
+ {
748
+ extensionAttributes.Add(attrib);
749
+ }
750
+ }
751
+
752
+ compilerPayload.FinishCompilingPayload();
753
+
754
+ // Now that the Id is known, we can parse the extension attributes.
755
+ var context = new Dictionary<string, string>
756
+ {
757
+ ["Id"] = compilerPayload.Id.Id,
758
+ };
759
+
760
+ foreach (var extensionAttribute in extensionAttributes)
761
+ {
762
+ this.Core.ParseExtensionAttribute(node, extensionAttribute, context);
763
}
764
765
foreach (var child in node.Elements())
@@ -746,19 +781,20 @@ namespace WixToolset.Core
781
782
if (!this.Core.EncounteredError)
783
{
784
+ compilerPayload.CreatePayloadSymbol(ComplexReferenceParentType.Container, Compiler.BurnUXContainerId.Id, previousType, previousId?.Id);
785
this.Core.AddSymbol(new WixBundleContainerSymbol(sourceLineNumbers, Compiler.BurnUXContainerId)
786
{
787
Name = "bundle-ux.cab",
788
Type = ContainerType.Attached
789
});
790
755
- this.Core.AddSymbol(new WixBootstrapperApplicationDllSymbol(sourceLineNumbers, id)
791
+ this.Core.AddSymbol(new WixBootstrapperApplicationDllSymbol(sourceLineNumbers, compilerPayload.Id)
792
{
793
DpiAwareness = dpiAwareness,
794
});
795
}
796
761
- return id;
797
+ return compilerPayload.Id;
798
}
799
800
/// <summary>
@@ -1134,16 +1170,57 @@ namespace WixToolset.Core
1170
private void ParseBundleExtensionElement(XElement node)
1171
{
1172
var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
1173
+ var compilerPayload = new CompilerPayload(this.Core, sourceLineNumbers, node);
1174
Identifier previousId = null;
1175
var previousType = ComplexReferenceChildType.Unknown;
1176
1140
- // The BundleExtension element acts like a Payload element so delegate to the "Payload" attribute parsing code to parse and create a Payload entry.
1141
- if (this.ParsePayloadElementContent(node, ComplexReferenceParentType.Container, Compiler.BurnUXContainerId, previousType, previousId, true, out var id))
1177
+ // This list lets us evaluate extension attributes *after* all core attributes
1178
+ // have been parsed and dealt with, regardless of authoring order.
1179
+ var extensionAttributes = new List<XAttribute>();
1180
+
1181
+ foreach (var attrib in node.Attributes())
1182
{
1143
- previousId = id;
1144
- previousType = ComplexReferenceChildType.Payload;
1183
+ if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
1184
+ {
1185
+ switch (attrib.Name.LocalName)
1186
+ {
1187
+ case "Id":
1188
+ compilerPayload.ParseId(attrib);
1189
+ break;
1190
+ case "Name":
1191
+ compilerPayload.ParseName(attrib);
1192
+ break;
1193
+ case "SourceFile":
1194
+ compilerPayload.ParseSourceFile(attrib);
1195
+ break;
1196
+ default:
1197
+ this.Core.UnexpectedAttribute(node, attrib);
1198
+ break;
1199
+ }
1200
+ }
1201
+ else
1202
+ {
1203
+ extensionAttributes.Add(attrib);
1204
+ }
1205
}
1206
1207
+ compilerPayload.FinishCompilingPayload();
1208
+
1209
+ // Now that the Id is known, we can parse the extension attributes.
1210
+ var context = new Dictionary<string, string>
1211
+ {
1212
+ ["Id"] = compilerPayload.Id.Id,
1213
+ };
1214
+
1215
+ foreach (var extensionAttribute in extensionAttributes)
1216
+ {
1217
+ this.Core.ParseExtensionAttribute(node, extensionAttribute, context);
1218
+ }
1219
+
1220
+ compilerPayload.CreatePayloadSymbol(ComplexReferenceParentType.Container, Compiler.BurnUXContainerId.Id, previousType, previousId?.Id);
1221
+ previousId = compilerPayload.Id;
1222
+ previousType = ComplexReferenceChildType.Payload;
1223
+
1224
foreach (var child in node.Elements())
1225
{
1226
if (CompilerCore.WixNamespace == child.Name.Namespace)
@@ -1172,9 +1249,9 @@ namespace WixToolset.Core
1249
// Add the BundleExtension.
1250
if (!this.Core.EncounteredError)
1251
{
1175
- this.Core.AddSymbol(new WixBundleExtensionSymbol(sourceLineNumbers, id)
1252
+ this.Core.AddSymbol(new WixBundleExtensionSymbol(sourceLineNumbers, compilerPayload.Id)
1253
{
1177
- PayloadRef = id.Id,
1254
+ PayloadRef = compilerPayload.Id.Id,
1255
});
1256
}
1257
}
@@ -1294,53 +1371,8 @@ namespace WixToolset.Core
1371
Debug.Assert(ComplexReferenceParentType.PayloadGroup == parentType || ComplexReferenceParentType.Package == parentType || ComplexReferenceParentType.Container == parentType);
1372
Debug.Assert(ComplexReferenceChildType.Unknown == previousType || ComplexReferenceChildType.PayloadGroup == previousType || ComplexReferenceChildType.Payload == previousType);
1373
1297
- this.ParsePayloadElementContent(node, parentType, parentId, previousType, previousId, true, out var id);
1298
- var context = new Dictionary<string, string>
1299
- {
1300
- ["Id"] = id?.Id
1301
- };
1302
-
1303
- foreach (var child in node.Elements())
1304
- {
1305
- if (CompilerCore.WixNamespace == child.Name.Namespace)
1306
- {
1307
- switch (child.Name.LocalName)
1308
- {
1309
- default:
1310
- this.Core.UnexpectedElement(node, child);
1311
- break;
1312
- }
1313
- }
1314
- else
1315
- {
1316
- this.Core.ParseExtensionElement(node, child, context);
1317
- }
1318
- }
1319
-
1320
- return id;
1321
- }
1322
-
1323
- /// <summary>
1324
- /// Parse the attributes of the Payload element.
1325
- /// </summary>
1326
- /// <param name="node">Element to parse</param>
1327
- /// <param name="parentType">ComplexReferenceParentType of parent element.</param>
1328
- /// <param name="parentId">Identifier of parent element.</param>
1329
- /// <param name="previousType"></param>
1330
- /// <param name="previousId"></param>
1331
- /// <param name="required"></param>
1332
- /// <param name="id"></param>
1333
- /// <returns>Whether SourceFile was specified.</returns>
1334
- private bool ParsePayloadElementContent(XElement node, ComplexReferenceParentType parentType, Identifier parentId, ComplexReferenceChildType previousType, Identifier previousId, bool required, out Identifier id)
1335
- {
1336
- Debug.Assert(ComplexReferenceParentType.PayloadGroup == parentType || ComplexReferenceParentType.Package == parentType || ComplexReferenceParentType.Container == parentType);
1337
-
1374
var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
1339
- var compressed = YesNoDefaultType.Default;
1340
- id = null;
1341
- string name = null;
1342
- string sourceFile = null;
1343
- string downloadUrl = null;
1375
+ var compilerPayload = new CompilerPayload(this.Core, sourceLineNumbers, node);
1376
1377
// This list lets us evaluate extension attributes *after* all core attributes
1378
// have been parsed and dealt with, regardless of authoring order.
@@ -1350,32 +1382,32 @@ namespace WixToolset.Core
1382
{
1383
if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
1384
{
1385
+ var allowed = true;
1386
switch (attrib.Name.LocalName)
1387
{
1355
- case "Id":
1356
- id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
1357
- break;
1358
- case "Compressed":
1359
- compressed = this.Core.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib);
1360
- break;
1361
- case "Name":
1362
- name = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, false, true);
1363
- break;
1364
- case "SourceFile":
1365
- sourceFile = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1366
- break;
1367
- case "DownloadUrl":
1368
- downloadUrl = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1369
- break;
1370
- case "DpiAwareness":
1371
- if (node.Name.LocalName != "BootstrapperApplicationDll")
1372
- {
1373
- this.Core.UnexpectedAttribute(node, attrib);
1374
- }
1375
- break;
1376
- default:
1388
+ case "Id":
1389
+ compilerPayload.ParseId(attrib);
1390
+ break;
1391
+ case "Compressed":
1392
+ compilerPayload.ParseCompressed(attrib);
1393
+ break;
1394
+ case "Name":
1395
+ compilerPayload.ParseName(attrib);
1396
+ break;
1397
+ case "SourceFile":
1398
+ compilerPayload.ParseSourceFile(attrib);
1399
+ break;
1400
+ case "DownloadUrl":
1401
+ compilerPayload.ParseDownloadUrl(attrib);
1402
+ break;
1403
+ default:
1404
+ allowed = false;
1405
+ break;
1406
+ }
1407
+
1408
+ if (!allowed)
1409
+ {
1410
this.Core.UnexpectedAttribute(node, attrib);
1378
- break;
1411
}
1412
}
1413
else
@@ -1384,15 +1416,12 @@ namespace WixToolset.Core
1416
}
1417
}
1418
1387
- if (null == id)
1388
- {
1389
- id = this.Core.CreateIdentifier("pay", sourceFile?.ToUpperInvariant() ?? String.Empty);
1390
- }
1419
+ compilerPayload.FinishCompilingPayload();
1420
1421
// Now that the PayloadId is known, we can parse the extension attributes.
1422
var context = new Dictionary<string, string>
1423
{
1395
- ["Id"] = id.Id
1424
+ ["Id"] = compilerPayload.Id.Id,
1425
};
1426
1427
foreach (var extensionAttribute in extensionAttributes)
@@ -1400,36 +1429,32 @@ namespace WixToolset.Core
1429
this.Core.ParseExtensionAttribute(node, extensionAttribute, context);
1430
}
1431
1403
- // Let caller handle the children.
1404
-
1405
- if (Compiler.BurnUXContainerId == parentId)
1432
+ foreach (var child in node.Elements())
1433
{
1407
- if (compressed == YesNoDefaultType.No)
1434
+ if (CompilerCore.WixNamespace == child.Name.Namespace)
1435
{
1409
- this.Core.Write(WarningMessages.UxPayloadsOnlySupportEmbedding(sourceLineNumbers, sourceFile));
1436
+ switch (child.Name.LocalName)
1437
+ {
1438
+ default:
1439
+ this.Core.UnexpectedElement(node, child);
1440
+ break;
1441
+ }
1442
}
1411
-
1412
- compressed = YesNoDefaultType.Yes;
1413
- }
1414
-
1415
- if (sourceFile == null)
1416
- {
1417
- if (required)
1443
+ else
1444
{
1419
- this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "SourceFile"));
1445
+ this.Core.ParseExtensionElement(node, child, context);
1446
}
1421
- return false;
1447
}
1448
1424
- this.CreatePayloadRow(sourceLineNumbers, id, name, sourceFile, downloadUrl, parentType, parentId, previousType, previousId, compressed, null, null, null);
1449
+ compilerPayload.CreatePayloadSymbol(parentType, parentId?.Id, previousType, previousId?.Id);
1450
1426
- return true;
1451
+ return compilerPayload.Id;
1452
}
1453
1429
- private RemotePayload ParseRemotePayloadElement(XElement node)
1454
+ private CompilerPayload ParseRemotePayloadElement(XElement node)
1455
{
1456
var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
1432
- var remotePayload = new RemotePayload();
1457
+ var remotePayload = new CompilerPayload(this.Core, sourceLineNumbers, node);
1458
1459
foreach (var attrib in node.Attributes())
1460
{
@@ -1438,19 +1463,19 @@ namespace WixToolset.Core
1463
switch (attrib.Name.LocalName)
1464
{
1465
case "Description":
1441
- remotePayload.Description = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1466
+ remotePayload.ParseDescription(attrib);
1467
break;
1468
case "Hash":
1444
- remotePayload.Hash = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1469
+ remotePayload.ParseHash(attrib);
1470
break;
1471
case "ProductName":
1447
- remotePayload.ProductName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1472
+ remotePayload.ParseProductName(attrib);
1473
break;
1474
case "Size":
1450
- remotePayload.Size = this.Core.GetAttributeLongValue(sourceLineNumbers, attrib, 0, Int64.MaxValue);
1475
+ remotePayload.ParseSize(attrib);
1476
break;
1477
case "Version":
1453
- remotePayload.Version = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1478
+ remotePayload.ParseVersion(attrib);
1479
break;
1480
default:
1481
this.Core.UnexpectedAttribute(node, attrib);
@@ -1491,57 +1516,6 @@ namespace WixToolset.Core
1516
return remotePayload;
1517
}
1518
1494
- /// <summary>
1495
- /// Creates the row for a Payload.
1496
- /// </summary>
1497
- /// <param name="sourceLineNumbers"></param>
1498
- /// <param name="id"></param>
1499
- /// <param name="name"></param>
1500
- /// <param name="sourceFile"></param>
1501
- /// <param name="downloadUrl"></param>
1502
- /// <param name="parentType">ComplexReferenceParentType of parent element</param>
1503
- /// <param name="parentId">Identifier of parent element.</param>
1504
- /// <param name="previousType"></param>
1505
- /// <param name="previousId"></param>
1506
- /// <param name="compressed"></param>
1507
- /// <param name="displayName"></param>
1508
- /// <param name="description"></param>
1509
- /// <param name="remotePayload"></param>
1510
- /// <returns></returns>
1511
- private WixBundlePayloadSymbol CreatePayloadRow(SourceLineNumber sourceLineNumbers, Identifier id, string name, string sourceFile, string downloadUrl, ComplexReferenceParentType parentType,
1512
- Identifier parentId, ComplexReferenceChildType previousType, Identifier previousId, YesNoDefaultType compressed, string displayName, string description,
1513
- RemotePayload remotePayload)
1514
- {
1515
- WixBundlePayloadSymbol symbol = null;
1516
-
1517
- if (!this.Core.EncounteredError)
1518
- {
1519
- symbol = this.Core.AddSymbol(new WixBundlePayloadSymbol(sourceLineNumbers, id)
1520
- {
1521
- Name = String.IsNullOrEmpty(name) ? Path.GetFileName(sourceFile) : name,
1522
- SourceFile = new IntermediateFieldPathValue { Path = sourceFile },
1523
- DownloadUrl = downloadUrl,
1524
- Compressed = (compressed == YesNoDefaultType.Yes) ? true : (compressed == YesNoDefaultType.No) ? (bool?)false : null,
1525
- UnresolvedSourceFile = sourceFile, // duplicate of sourceFile but in a string column so it won't get resolved to a full path during binding.
1526
- DisplayName = displayName,
1527
- Description = description,
1528
- });
1529
-
1530
- if (null != remotePayload)
1531
- {
1532
- symbol.Description = remotePayload.Description;
1533
- symbol.DisplayName = remotePayload.ProductName;
1534
- symbol.Hash = remotePayload.Hash;
1535
- symbol.FileSize = remotePayload.Size;
1536
- symbol.Version = remotePayload.Version;
1537
- }
1538
-
1539
- this.CreateGroupAndOrderingRows(sourceLineNumbers, parentType, parentId.Id, ComplexReferenceChildType.Payload, id.Id, previousType, previousId?.Id);
1540
- }
1541
-
1542
- return symbol;
1543
- }
1544
-
1519
/// <summary>
1520
/// Parse PayloadGroup element.
1521
/// </summary>
@@ -1613,7 +1587,7 @@ namespace WixToolset.Core
1587
{
1588
this.Core.AddSymbol(new WixBundlePayloadGroupSymbol(sourceLineNumbers, id));
1589
1616
- this.CreateGroupAndOrderingRows(sourceLineNumbers, parentType, parentId?.Id, ComplexReferenceChildType.PayloadGroup, id.Id, ComplexReferenceChildType.Unknown, null);
1590
+ this.Core.CreateGroupAndOrderingRows(sourceLineNumbers, parentType, parentId?.Id, ComplexReferenceChildType.PayloadGroup, id.Id, ComplexReferenceChildType.Unknown, null);
1591
}
1592
}
1593
@@ -1661,51 +1635,11 @@ namespace WixToolset.Core
1635
1636
this.Core.ParseForExtensionElements(node);
1637
1664
- this.CreateGroupAndOrderingRows(sourceLineNumbers, parentType, parentId?.Id, ComplexReferenceChildType.PayloadGroup, id?.Id, previousType, previousId?.Id);
1638
+ this.Core.CreateGroupAndOrderingRows(sourceLineNumbers, parentType, parentId?.Id, ComplexReferenceChildType.PayloadGroup, id?.Id, previousType, previousId?.Id);
1639
1640
return id;
1641
}
1642
1669
- /// <summary>
1670
- /// Creates group and ordering information.
1671
- /// </summary>
1672
- /// <param name="sourceLineNumbers">Source line numbers.</param>
1673
- /// <param name="parentType">Type of parent group, if known.</param>
1674
- /// <param name="parentId">Identifier of parent group, if known.</param>
1675
- /// <param name="type">Type of this item.</param>
1676
- /// <param name="id">Identifier for this item.</param>
1677
- /// <param name="previousType">Type of previous item, if known.</param>
1678
- /// <param name="previousId">Identifier of previous item, if known</param>
1679
- private void CreateGroupAndOrderingRows(SourceLineNumber sourceLineNumbers,
1680
- ComplexReferenceParentType parentType, string parentId,
1681
- ComplexReferenceChildType type, string id,
1682
- ComplexReferenceChildType previousType, string previousId)
1683
- {
1684
- if (this.Core.EncounteredError)
1685
- {
1686
- return;
1687
- }
1688
-
1689
- if (ComplexReferenceParentType.Unknown != parentType && null != parentId)
1690
- {
1691
- this.Core.CreateWixGroupRow(sourceLineNumbers, parentType, parentId, type, id);
1692
- }
1693
-
1694
- if (ComplexReferenceChildType.Unknown != previousType && null != previousId)
1695
- {
1696
- // TODO: Should we define our own enum for this, just to ensure there's no "cross-contamination"?
1697
- // TODO: Also, we could potentially include an 'Attributes' field to track things like
1698
- // 'before' vs. 'after', and explicit vs. inferred dependencies.
1699
- this.Core.AddSymbol(new WixOrderingSymbol(sourceLineNumbers)
1700
- {
1701
- ItemType = type,
1702
- ItemIdRef = id,
1703
- DependsOnType = previousType,
1704
- DependsOnIdRef = previousId
1705
- });
1706
- }
1707
- }
1708
-
1643
/// <summary>
1644
/// Parse ExitCode element.
1645
/// </summary>
@@ -2050,17 +1984,15 @@ namespace WixToolset.Core
1984
Debug.Assert(ComplexReferenceParentType.PackageGroup == parentType);
1985
Debug.Assert(ComplexReferenceChildType.Unknown == previousType || ComplexReferenceChildType.PackageGroup == previousType || ComplexReferenceChildType.Package == previousType);
1986
2053
- var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
2054
- Identifier id = null;
2055
- string name = null;
2056
- string sourceFile = null;
2057
- string downloadUrl = null;
1987
+ var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);;
1988
+ var compilerPayload = new CompilerPayload(this.Core, sourceLineNumbers, node)
1989
+ {
1990
+ IsRequired = false,
1991
+ };
1992
string after = null;
1993
string installCondition = null;
1994
var cache = YesNoAlwaysType.Yes; // the default is to cache everything in tradeoff for stability over disk space.
1995
string cacheId = null;
2062
- string description = null;
2063
- string displayName = null;
1996
var logPathVariable = (packageType == WixBundlePackageType.Msu) ? String.Empty : null;
1997
var rollbackPathVariable = (packageType == WixBundlePackageType.Msu) ? String.Empty : null;
1998
var permanent = YesNoType.NotSet;
@@ -2074,10 +2006,9 @@ namespace WixToolset.Core
2006
string protocol = null;
2007
var installSize = CompilerConstants.IntegerNotSet;
2008
string msuKB = null;
2077
- var compressed = YesNoDefaultType.Default;
2009
var enableFeatureSelection = YesNoType.NotSet;
2010
var forcePerMachine = YesNoType.NotSet;
2080
- RemotePayload remotePayload = null;
2011
+ CompilerPayload remotePayload = null;
2012
var slipstream = YesNoType.NotSet;
2013
2014
var expectedNetFx4Args = new string[] { "/q", "/norestart", "/chainingpackage" };
@@ -2094,20 +2025,16 @@ namespace WixToolset.Core
2025
switch (attrib.Name.LocalName)
2026
{
2027
case "Id":
2097
- id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
2028
+ compilerPayload.ParseId(attrib);
2029
break;
2030
case "Name":
2100
- name = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, false, true);
2101
- if (!this.Core.IsValidLongFilename(name, false, true))
2102
- {
2103
- this.Core.Write(ErrorMessages.IllegalLongFilename(sourceLineNumbers, node.Name.LocalName, "Name", name));
2104
- }
2031
+ compilerPayload.ParseName(attrib);
2032
break;
2033
case "SourceFile":
2107
- sourceFile = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2034
+ compilerPayload.ParseSourceFile(attrib);
2035
break;
2036
case "DownloadUrl":
2110
- downloadUrl = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2037
+ compilerPayload.ParseDownloadUrl(attrib);
2038
break;
2039
case "After":
2040
after = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
@@ -2139,10 +2066,10 @@ namespace WixToolset.Core
2066
cacheId = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2067
break;
2068
case "Description":
2142
- description = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2069
+ compilerPayload.ParseDescription(attrib);
2070
break;
2071
case "DisplayName":
2145
- displayName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2072
+ compilerPayload.ParseDisplayName(attrib);
2073
break;
2074
case "EnableFeatureSelection":
2075
enableFeatureSelection = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
@@ -2200,7 +2127,7 @@ namespace WixToolset.Core
2127
allowed = (packageType == WixBundlePackageType.Msu);
2128
break;
2129
case "Compressed":
2203
- compressed = this.Core.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib);
2130
+ compilerPayload.ParseCompressed(attrib);
2131
break;
2132
case "Slipstream":
2133
slipstream = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
@@ -2242,65 +2169,8 @@ namespace WixToolset.Core
2169
remotePayload = this.ParseRemotePayloadElement(child);
2170
}
2171
2245
- if (String.IsNullOrEmpty(sourceFile))
2246
- {
2247
- if (String.IsNullOrEmpty(name))
2248
- {
2249
- this.Core.Write(ErrorMessages.ExpectedAttributesWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Name", "SourceFile"));
2250
- }
2251
- else if (null == remotePayload)
2252
- {
2253
- sourceFile = Path.Combine("SourceDir", name);
2254
- }
2255
- }
2256
- else if (null != remotePayload)
2257
- {
2258
- this.Core.Write(ErrorMessages.UnexpectedElementWithAttribute(sourceLineNumbers, node.Name.LocalName, "RemotePayload", "SourceFile"));
2259
- }
2260
- else if (sourceFile.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal))
2261
- {
2262
- if (String.IsNullOrEmpty(name))
2263
- {
2264
- this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name", "SourceFile", sourceFile));
2265
- }
2266
- else
2267
- {
2268
- sourceFile = Path.Combine(sourceFile, Path.GetFileName(name));
2269
- }
2270
- }
2271
-
2272
- if (null == downloadUrl && null != remotePayload)
2273
- {
2274
- this.Core.Write(ErrorMessages.ExpectedAttributeWithElement(sourceLineNumbers, node.Name.LocalName, "DownloadUrl", "RemotePayload"));
2275
- }
2276
-
2277
- if (YesNoDefaultType.No != compressed && null != remotePayload)
2278
- {
2279
- compressed = YesNoDefaultType.No;
2280
- this.Core.Write(WarningMessages.RemotePayloadsMustNotAlsoBeCompressed(sourceLineNumbers, node.Name.LocalName));
2281
- }
2282
-
2283
- if (null == id)
2284
- {
2285
- if (!String.IsNullOrEmpty(name))
2286
- {
2287
- id = this.Core.CreateIdentifierFromFilename(Path.GetFileName(name));
2288
- }
2289
- else if (!String.IsNullOrEmpty(sourceFile))
2290
- {
2291
- id = this.Core.CreateIdentifierFromFilename(Path.GetFileName(sourceFile));
2292
- }
2293
-
2294
- if (null == id)
2295
- {
2296
- this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
2297
- id = Identifier.Invalid;
2298
- }
2299
- else if (!Common.IsIdentifier(id.Id))
2300
- {
2301
- this.Core.Write(ErrorMessages.IllegalIdentifier(sourceLineNumbers, node.Name.LocalName, "Id", id.Id));
2302
- }
2303
- }
2172
+ compilerPayload.FinishCompilingPackage(remotePayload);
2173
+ var id = compilerPayload.Id;
2174
2175
if (null == logPathVariable)
2176
{
@@ -2424,7 +2294,7 @@ namespace WixToolset.Core
2294
}
2295
else
2296
{
2427
- var context = new Dictionary<string, string>() { { "Id", id?.Id } };
2297
+ var context = new Dictionary<string, string>() { { "Id", id.Id } };
2298
this.Core.ParseExtensionElement(node, child, context);
2299
}
2300
}
@@ -2432,8 +2302,7 @@ namespace WixToolset.Core
2302
if (!this.Core.EncounteredError)
2303
{
2304
// We create the package contents as a payload with this package as the parent
2435
- this.CreatePayloadRow(sourceLineNumbers, id, name, sourceFile, downloadUrl, ComplexReferenceParentType.Package, id,
2436
- ComplexReferenceChildType.Unknown, null, compressed, displayName, description, remotePayload);
2305
+ compilerPayload.CreatePayloadSymbol(ComplexReferenceParentType.Package, id.Id);
2306
2307
this.Core.AddSymbol(new WixChainItemSymbol(sourceLineNumbers, id));
2308
@@ -2801,7 +2670,7 @@ namespace WixToolset.Core
2670
previousId = afterId;
2671
}
2672
2804
- this.CreateGroupAndOrderingRows(sourceLineNumbers, parentType, parentId, type, id, previousType, previousId);
2673
+ this.Core.CreateGroupAndOrderingRows(sourceLineNumbers, parentType, parentId, type, id, previousType, previousId);
2674
}
2675
2676
/// <summary>
@@ -3251,18 +3120,5 @@ namespace WixToolset.Core
3120
3121
return WixBundleVariableType.String;
3122
}
3254
-
3255
- private class RemotePayload
3256
- {
3257
- public string Description { get; set; }
3258
-
3259
- public string Hash { get; set; }
3260
-
3261
- public string ProductName { get; set; }
3262
-
3263
- public long Size { get; set; }
3264
-
3265
- public string Version { get; set; }
3266
- }
3123
}
3124
}