main
cs 137 lines 6.66 KB
Raw
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.Bundles
4 {
5 using System;
6 using System.Collections.Generic;
7 using System.Linq;
8 using WixToolset.Data;
9 using WixToolset.Data.Burn;
10 using WixToolset.Data.Symbols;
11 using WixToolset.Extensibility.Services;
12
13 internal class DetectPayloadCollisionsCommand
14 {
15 public DetectPayloadCollisionsCommand(IMessaging messaging, Dictionary<string, WixBundleContainerSymbol> containerSymbols, IEnumerable<PackageFacade> packages, Dictionary<string, WixBundlePayloadSymbol> payloadSymbols, Dictionary<string, Dictionary<string, WixBundlePayloadSymbol>> packagePayloads)
16 {
17 this.Messaging = messaging;
18 this.Containers = containerSymbols;
19 this.Packages = packages;
20 this.PayloadSymbols = payloadSymbols;
21 this.PackagePayloads = packagePayloads;
22 }
23
24 private IMessaging Messaging { get; }
25
26 private Dictionary<string, WixBundleContainerSymbol> Containers { get; }
27
28 private IEnumerable<PackageFacade> Packages { get; }
29
30 private Dictionary<string, WixBundlePayloadSymbol> PayloadSymbols { get; }
31
32 private Dictionary<string, Dictionary<string, WixBundlePayloadSymbol>> PackagePayloads { get; }
33
34 public void Execute()
35 {
36 this.DetectAttachedContainerCollisions();
37 this.DetectExternalCollisions();
38 this.DetectPackageCacheCollisions();
39 }
40
41 public void DetectAttachedContainerCollisions()
42 {
43 var attachedContainerPayloadsByNameByContainer = new Dictionary<string, Dictionary<string, WixBundlePayloadSymbol>>();
44
45 foreach (var payload in this.PayloadSymbols.Values.Where(p => p.Packaging == PackagingType.Embedded))
46 {
47 var containerId = payload.ContainerRef;
48 var container = this.Containers[containerId];
49 if (container.Type == ContainerType.Attached)
50 {
51 if (!attachedContainerPayloadsByNameByContainer.TryGetValue(containerId, out var attachedContainerPayloadsByName))
52 {
53 attachedContainerPayloadsByName = new Dictionary<string, WixBundlePayloadSymbol>(StringComparer.OrdinalIgnoreCase);
54 attachedContainerPayloadsByNameByContainer.Add(containerId, attachedContainerPayloadsByName);
55 }
56
57 if (!attachedContainerPayloadsByName.TryGetValue(payload.Name, out var collisionPayload))
58 {
59 attachedContainerPayloadsByName.Add(payload.Name, payload);
60 }
61 else
62 {
63 if (containerId == BurnConstants.BurnUXContainerName)
64 {
65 this.Messaging.Write(BurnBackendErrors.BAContainerPayloadCollision(payload.SourceLineNumbers, payload.Id.Id, payload.Name));
66 this.Messaging.Write(BurnBackendErrors.BAContainerPayloadCollision2(collisionPayload.SourceLineNumbers));
67 }
68 else
69 {
70 this.Messaging.Write(BurnBackendWarnings.AttachedContainerPayloadCollision(payload.SourceLineNumbers, payload.Id.Id, payload.Name));
71 this.Messaging.Write(BurnBackendWarnings.AttachedContainerPayloadCollision2(collisionPayload.SourceLineNumbers));
72 }
73 }
74 }
75 }
76 }
77
78 public void DetectExternalCollisions()
79 {
80 var externalPayloadsByName = new Dictionary<string, IntermediateSymbol>(StringComparer.OrdinalIgnoreCase);
81
82 foreach (var payload in this.PayloadSymbols.Values.Where(p => p.Packaging == PackagingType.External))
83 {
84 if (!externalPayloadsByName.TryGetValue(payload.Name, out var collisionSymbol))
85 {
86 externalPayloadsByName.Add(payload.Name, payload);
87 }
88 else
89 {
90 this.Messaging.Write(BurnBackendErrors.ExternalPayloadCollision(payload.SourceLineNumbers, "Payload", payload.Id.Id, payload.Name));
91 this.Messaging.Write(BurnBackendErrors.ExternalPayloadCollision2(collisionSymbol.SourceLineNumbers));
92 }
93 }
94
95 foreach (var container in this.Containers.Values.Where(c => c.Type == ContainerType.Detached))
96 {
97 if (!externalPayloadsByName.TryGetValue(container.Name, out var collisionSymbol))
98 {
99 externalPayloadsByName.Add(container.Name, container);
100 }
101 else
102 {
103 this.Messaging.Write(BurnBackendErrors.ExternalPayloadCollision(container.SourceLineNumbers, "Container", container.Id.Id, container.Name));
104 this.Messaging.Write(BurnBackendErrors.ExternalPayloadCollision2(collisionSymbol.SourceLineNumbers));
105 }
106 }
107 }
108
109 public void DetectPackageCacheCollisions()
110 {
111 var packageCachePayloadsByNameByCacheId = new Dictionary<string, Dictionary<string, WixBundlePayloadSymbol>>();
112
113 foreach (var packageFacade in this.Packages)
114 {
115 var packagePayloads = this.PackagePayloads[packageFacade.PackageId];
116 if (!packageCachePayloadsByNameByCacheId.TryGetValue(packageFacade.PackageSymbol.CacheId, out var packageCachePayloadsByName))
117 {
118 packageCachePayloadsByName = new Dictionary<string, WixBundlePayloadSymbol>(StringComparer.OrdinalIgnoreCase);
119 packageCachePayloadsByNameByCacheId.Add(packageFacade.PackageSymbol.CacheId, packageCachePayloadsByName);
120 }
121
122 foreach (var payload in packagePayloads.Values)
123 {
124 if (!packageCachePayloadsByName.TryGetValue(payload.Name, out var collisionPayload))
125 {
126 packageCachePayloadsByName.Add(payload.Name, payload);
127 }
128 else
129 {
130 this.Messaging.Write(BurnBackendErrors.PackageCachePayloadCollision(payload.SourceLineNumbers, payload.Id.Id, payload.Name, packageFacade.PackageId));
131 this.Messaging.Write(BurnBackendErrors.PackageCachePayloadCollision2(collisionPayload.SourceLineNumbers));
132 }
133 }
134 }
135 }
136 }
137 }