diff options
Diffstat (limited to 'src/api/burn/WixToolset.Mba.Core/PackageInfo.cs')
-rw-r--r-- | src/api/burn/WixToolset.Mba.Core/PackageInfo.cs | 317 |
1 files changed, 317 insertions, 0 deletions
diff --git a/src/api/burn/WixToolset.Mba.Core/PackageInfo.cs b/src/api/burn/WixToolset.Mba.Core/PackageInfo.cs new file mode 100644 index 00000000..567a7cdd --- /dev/null +++ b/src/api/burn/WixToolset.Mba.Core/PackageInfo.cs | |||
@@ -0,0 +1,317 @@ | |||
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.Mba.Core | ||
4 | { | ||
5 | using System; | ||
6 | using System.Collections.Generic; | ||
7 | using System.Xml; | ||
8 | using System.Xml.XPath; | ||
9 | |||
10 | /// <summary> | ||
11 | /// | ||
12 | /// </summary> | ||
13 | public enum PackageType | ||
14 | { | ||
15 | /// <summary> | ||
16 | /// | ||
17 | /// </summary> | ||
18 | Unknown, | ||
19 | |||
20 | /// <summary> | ||
21 | /// | ||
22 | /// </summary> | ||
23 | Exe, | ||
24 | |||
25 | /// <summary> | ||
26 | /// | ||
27 | /// </summary> | ||
28 | Msi, | ||
29 | |||
30 | /// <summary> | ||
31 | /// | ||
32 | /// </summary> | ||
33 | Msp, | ||
34 | |||
35 | /// <summary> | ||
36 | /// | ||
37 | /// </summary> | ||
38 | Msu, | ||
39 | |||
40 | /// <summary> | ||
41 | /// | ||
42 | /// </summary> | ||
43 | UpgradeBundle, | ||
44 | |||
45 | /// <summary> | ||
46 | /// | ||
47 | /// </summary> | ||
48 | AddonBundle, | ||
49 | |||
50 | /// <summary> | ||
51 | /// | ||
52 | /// </summary> | ||
53 | PatchBundle, | ||
54 | } | ||
55 | |||
56 | /// <summary> | ||
57 | /// Default implementation of <see cref="IPackageInfo"/>. | ||
58 | /// </summary> | ||
59 | public class PackageInfo : IPackageInfo | ||
60 | { | ||
61 | /// <inheritdoc/> | ||
62 | public string Id { get; internal set; } | ||
63 | |||
64 | /// <inheritdoc/> | ||
65 | public string DisplayName { get; internal set; } | ||
66 | |||
67 | /// <inheritdoc/> | ||
68 | public string Description { get; internal set; } | ||
69 | |||
70 | /// <inheritdoc/> | ||
71 | public PackageType Type { get; internal set; } | ||
72 | |||
73 | /// <inheritdoc/> | ||
74 | public bool Permanent { get; internal set; } | ||
75 | |||
76 | /// <inheritdoc/> | ||
77 | public bool Vital { get; internal set; } | ||
78 | |||
79 | /// <inheritdoc/> | ||
80 | public string DisplayInternalUICondition { get; internal set; } | ||
81 | |||
82 | /// <inheritdoc/> | ||
83 | public string ProductCode { get; internal set; } | ||
84 | |||
85 | /// <inheritdoc/> | ||
86 | public string UpgradeCode { get; internal set; } | ||
87 | |||
88 | /// <inheritdoc/> | ||
89 | public string Version { get; internal set; } | ||
90 | |||
91 | /// <inheritdoc/> | ||
92 | public string InstallCondition { get; internal set; } | ||
93 | |||
94 | /// <inheritdoc/> | ||
95 | public BOOTSTRAPPER_CACHE_TYPE CacheType { get; internal set; } | ||
96 | |||
97 | /// <inheritdoc/> | ||
98 | public bool PrereqPackage { get; internal set; } | ||
99 | |||
100 | /// <inheritdoc/> | ||
101 | public string PrereqLicenseFile { get; internal set; } | ||
102 | |||
103 | /// <inheritdoc/> | ||
104 | public string PrereqLicenseUrl { get; internal set; } | ||
105 | |||
106 | /// <inheritdoc/> | ||
107 | public object CustomData { get; set; } | ||
108 | |||
109 | internal PackageInfo() { } | ||
110 | |||
111 | /// <summary> | ||
112 | /// | ||
113 | /// </summary> | ||
114 | /// <param name="root"></param> | ||
115 | /// <returns></returns> | ||
116 | public static IDictionary<string, IPackageInfo> ParsePackagesFromXml(XPathNavigator root) | ||
117 | { | ||
118 | var packagesById = new Dictionary<string, IPackageInfo>(); | ||
119 | XmlNamespaceManager namespaceManager = new XmlNamespaceManager(root.NameTable); | ||
120 | namespaceManager.AddNamespace("p", BootstrapperApplicationData.XMLNamespace); | ||
121 | XPathNodeIterator nodes = root.Select("/p:BootstrapperApplicationData/p:WixPackageProperties", namespaceManager); | ||
122 | |||
123 | foreach (XPathNavigator node in nodes) | ||
124 | { | ||
125 | var package = new PackageInfo(); | ||
126 | |||
127 | string id = BootstrapperApplicationData.GetAttribute(node, "Package"); | ||
128 | if (id == null) | ||
129 | { | ||
130 | throw new Exception("Failed to get package identifier for package."); | ||
131 | } | ||
132 | package.Id = id; | ||
133 | |||
134 | package.DisplayName = BootstrapperApplicationData.GetAttribute(node, "DisplayName"); | ||
135 | |||
136 | package.Description = BootstrapperApplicationData.GetAttribute(node, "Description"); | ||
137 | |||
138 | PackageType? packageType = GetPackageTypeAttribute(node, "PackageType"); | ||
139 | if (!packageType.HasValue) | ||
140 | { | ||
141 | throw new Exception("Failed to get package type for package."); | ||
142 | } | ||
143 | package.Type = packageType.Value; | ||
144 | |||
145 | bool? permanent = BootstrapperApplicationData.GetYesNoAttribute(node, "Permanent"); | ||
146 | if (!permanent.HasValue) | ||
147 | { | ||
148 | throw new Exception("Failed to get permanent settings for package."); | ||
149 | } | ||
150 | package.Permanent = permanent.Value; | ||
151 | |||
152 | bool? vital = BootstrapperApplicationData.GetYesNoAttribute(node, "Vital"); | ||
153 | if (!vital.HasValue) | ||
154 | { | ||
155 | throw new Exception("Failed to get vital setting for package."); | ||
156 | } | ||
157 | package.Vital = vital.Value; | ||
158 | |||
159 | package.ProductCode = BootstrapperApplicationData.GetAttribute(node, "ProductCode"); | ||
160 | |||
161 | package.UpgradeCode = BootstrapperApplicationData.GetAttribute(node, "UpgradeCode"); | ||
162 | |||
163 | package.Version = BootstrapperApplicationData.GetAttribute(node, "Version"); | ||
164 | |||
165 | package.InstallCondition = BootstrapperApplicationData.GetAttribute(node, "InstallCondition"); | ||
166 | |||
167 | packagesById.Add(package.Id, package); | ||
168 | } | ||
169 | |||
170 | ParseBalPackageInfoFromXml(root, namespaceManager, packagesById); | ||
171 | return packagesById; | ||
172 | } | ||
173 | |||
174 | /// <summary> | ||
175 | /// | ||
176 | /// </summary> | ||
177 | /// <param name="node"></param> | ||
178 | /// <param name="attributeName"></param> | ||
179 | /// <returns></returns> | ||
180 | public static BOOTSTRAPPER_CACHE_TYPE? GetCacheTypeAttribute(XPathNavigator node, string attributeName) | ||
181 | { | ||
182 | string attributeValue = BootstrapperApplicationData.GetAttribute(node, attributeName); | ||
183 | |||
184 | if (attributeValue == null) | ||
185 | { | ||
186 | return null; | ||
187 | } | ||
188 | |||
189 | if (attributeValue.Equals("keep", StringComparison.InvariantCulture)) | ||
190 | { | ||
191 | return BOOTSTRAPPER_CACHE_TYPE.Keep; | ||
192 | } | ||
193 | else if (attributeValue.Equals("force", StringComparison.InvariantCulture)) | ||
194 | { | ||
195 | return BOOTSTRAPPER_CACHE_TYPE.Force; | ||
196 | } | ||
197 | else | ||
198 | { | ||
199 | return BOOTSTRAPPER_CACHE_TYPE.Remove; | ||
200 | } | ||
201 | } | ||
202 | |||
203 | /// <summary> | ||
204 | /// | ||
205 | /// </summary> | ||
206 | /// <param name="node"></param> | ||
207 | /// <param name="attributeName"></param> | ||
208 | /// <returns></returns> | ||
209 | public static PackageType? GetPackageTypeAttribute(XPathNavigator node, string attributeName) | ||
210 | { | ||
211 | string attributeValue = BootstrapperApplicationData.GetAttribute(node, attributeName); | ||
212 | |||
213 | if (attributeValue == null) | ||
214 | { | ||
215 | return null; | ||
216 | } | ||
217 | |||
218 | if (attributeValue.Equals("Exe", StringComparison.InvariantCulture)) | ||
219 | { | ||
220 | return PackageType.Exe; | ||
221 | } | ||
222 | else if (attributeValue.Equals("Msi", StringComparison.InvariantCulture)) | ||
223 | { | ||
224 | return PackageType.Msi; | ||
225 | } | ||
226 | else if (attributeValue.Equals("Msp", StringComparison.InvariantCulture)) | ||
227 | { | ||
228 | return PackageType.Msp; | ||
229 | } | ||
230 | else if (attributeValue.Equals("Msu", StringComparison.InvariantCulture)) | ||
231 | { | ||
232 | return PackageType.Msu; | ||
233 | } | ||
234 | else | ||
235 | { | ||
236 | return PackageType.Unknown; | ||
237 | } | ||
238 | } | ||
239 | |||
240 | /// <summary> | ||
241 | /// | ||
242 | /// </summary> | ||
243 | /// <param name="id"></param> | ||
244 | /// <param name="relationType"></param> | ||
245 | /// <param name="perMachine"></param> | ||
246 | /// <param name="version"></param> | ||
247 | /// <returns></returns> | ||
248 | public static IPackageInfo GetRelatedBundleAsPackage(string id, RelationType relationType, bool perMachine, string version) | ||
249 | { | ||
250 | PackageInfo package = new PackageInfo(); | ||
251 | package.Id = id; | ||
252 | package.Version = version; | ||
253 | |||
254 | switch (relationType) | ||
255 | { | ||
256 | case RelationType.Addon: | ||
257 | package.Type = PackageType.AddonBundle; | ||
258 | break; | ||
259 | case RelationType.Patch: | ||
260 | package.Type = PackageType.PatchBundle; | ||
261 | break; | ||
262 | case RelationType.Upgrade: | ||
263 | package.Type = PackageType.UpgradeBundle; | ||
264 | break; | ||
265 | default: | ||
266 | throw new Exception(string.Format("Unknown related bundle type: {0}", relationType)); | ||
267 | } | ||
268 | |||
269 | return package; | ||
270 | } | ||
271 | |||
272 | internal static void ParseBalPackageInfoFromXml(XPathNavigator root, XmlNamespaceManager namespaceManager, Dictionary<string, IPackageInfo> packagesById) | ||
273 | { | ||
274 | XPathNodeIterator nodes = root.Select("/p:BootstrapperApplicationData/p:WixBalPackageInfo", namespaceManager); | ||
275 | |||
276 | foreach (XPathNavigator node in nodes) | ||
277 | { | ||
278 | string id = BootstrapperApplicationData.GetAttribute(node, "PackageId"); | ||
279 | if (id == null) | ||
280 | { | ||
281 | throw new Exception("Failed to get package identifier for WixBalPackageInfo."); | ||
282 | } | ||
283 | |||
284 | if (!packagesById.TryGetValue(id, out var ipackage)) | ||
285 | { | ||
286 | throw new Exception(string.Format("Failed to find package specified in WixBalPackageInfo: {0}", id)); | ||
287 | } | ||
288 | |||
289 | var package = (PackageInfo)ipackage; | ||
290 | |||
291 | package.DisplayInternalUICondition = BootstrapperApplicationData.GetAttribute(node, "DisplayInternalUICondition"); | ||
292 | } | ||
293 | |||
294 | nodes = root.Select("/p:BootstrapperApplicationData/p:WixMbaPrereqInformation", namespaceManager); | ||
295 | |||
296 | foreach (XPathNavigator node in nodes) | ||
297 | { | ||
298 | string id = BootstrapperApplicationData.GetAttribute(node, "PackageId"); | ||
299 | if (id == null) | ||
300 | { | ||
301 | throw new Exception("Failed to get package identifier for WixMbaPrereqInformation."); | ||
302 | } | ||
303 | |||
304 | if (!packagesById.TryGetValue(id, out var ipackage)) | ||
305 | { | ||
306 | throw new Exception(string.Format("Failed to find package specified in WixMbaPrereqInformation: {0}", id)); | ||
307 | } | ||
308 | |||
309 | var package = (PackageInfo)ipackage; | ||
310 | |||
311 | package.PrereqPackage = true; | ||
312 | package.PrereqLicenseFile = BootstrapperApplicationData.GetAttribute(node, "LicenseFile"); | ||
313 | package.PrereqLicenseUrl = BootstrapperApplicationData.GetAttribute(node, "LicenseUrl"); | ||
314 | } | ||
315 | } | ||
316 | } | ||
317 | } | ||