main
cs 271 lines 11.1 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 Example.Extension
4 {
5 using System;
6 using System.Collections.Generic;
7 using System.Xml.Linq;
8 using WixToolset.Data;
9 using WixToolset.Extensibility;
10 using WixToolset.Extensibility.Data;
11
12 internal class ExampleCompilerExtension : BaseCompilerExtension
13 {
14 private const string BootstrapperExtensionId = "ExampleBootstrapperExtension";
15
16 public override XNamespace Namespace => ExampleConstants.Namespace;
17
18 public override void ParseElement(Intermediate intermediate, IntermediateSection section, XElement parentElement, XElement element, IDictionary<string, string> context)
19 {
20 var processed = false;
21
22 switch (parentElement.Name.LocalName)
23 {
24 case "Bundle":
25 case "Fragment":
26 switch (element.Name.LocalName)
27 {
28 case "ExampleEnsureTable":
29 this.ParseExampleEnsureTableElement(intermediate, section, element);
30 processed = true;
31 break;
32 case "ExampleSearch":
33 this.ParseExampleSearchElement(intermediate, section, element);
34 processed = true;
35 break;
36 case "ExampleSearchRef":
37 this.ParseExampleSearchRefElement(intermediate, section, element);
38 processed = true;
39 break;
40 }
41 break;
42 case "Component":
43 var componentId = context["ComponentId"];
44
45 switch (element.Name.LocalName)
46 {
47 case "Example":
48 this.ParseExampleElement(intermediate, section, element, componentId);
49 processed = true;
50 break;
51 }
52 break;
53 }
54
55 if (!processed)
56 {
57 base.ParseElement(intermediate, section, parentElement, element, context);
58 }
59 }
60
61 public override IComponentKeyPath ParsePossibleKeyPathElement(Intermediate intermediate, IntermediateSection section, XElement parentElement, XElement element, IDictionary<string, string> context)
62 {
63 switch (parentElement.Name.LocalName)
64 {
65 case "Component":
66 var componentId = context["ComponentId"];
67
68 switch (element.Name.LocalName)
69 {
70 case "ExampleSetKeyPath":
71 return this.ParseExampleSetKeyPathElement(intermediate, section, element, componentId);
72 }
73 break;
74 }
75
76 return base.ParsePossibleKeyPathElement(intermediate, section, parentElement, element, context);
77 }
78
79 private void ParseExampleElement(Intermediate intermediate, IntermediateSection section, XElement element, string componentId)
80 {
81 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
82 Identifier id = null;
83 string value = null;
84
85 foreach (var attrib in element.Attributes())
86 {
87 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
88 {
89 switch (attrib.Name.LocalName)
90 {
91 case "Id":
92 id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
93 break;
94
95 case "Value":
96 value = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
97 break;
98
99 default:
100 this.ParseHelper.UnexpectedAttribute(element, attrib);
101 break;
102 }
103 }
104 else
105 {
106 this.ParseAttribute(intermediate, section, element, attrib, null);
107 }
108 }
109
110 if (null == id)
111 {
112 //this.Messaging(WixErrors.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Id"));
113 }
114
115 if (!this.Messaging.EncounteredError)
116 {
117 var symbol = this.ParseHelper.CreateSymbol(section, sourceLineNumbers, "Example", id);
118 symbol.Set(0, componentId);
119 symbol.Set(1, value);
120 }
121 }
122
123 private IComponentKeyPath ParseExampleSetKeyPathElement(Intermediate intermediate, IntermediateSection section, XElement element, string componentId)
124 {
125 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
126 Identifier file = null;
127 Identifier reg = null;
128 var explicitly = false;
129
130 foreach (var attrib in element.Attributes())
131 {
132 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
133 {
134 switch (attrib.Name.LocalName)
135 {
136 case "File":
137 file = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
138 break;
139
140 case "Registry":
141 reg = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
142 break;
143
144 case "Explicitly":
145 explicitly = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) == YesNoType.Yes;
146 break;
147
148 default:
149 this.ParseHelper.UnexpectedAttribute(element, attrib);
150 break;
151 }
152 }
153 else
154 {
155 this.ParseAttribute(intermediate, section, element, attrib, null);
156 }
157 }
158
159 if (file == null && reg == null)
160 {
161 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "File", "Registry", true));
162 }
163
164 if (!this.Messaging.EncounteredError)
165 {
166 var componentKeyPath = this.CreateComponentKeyPath();
167 componentKeyPath.Id = file ?? reg;
168 componentKeyPath.Explicit = explicitly;
169 componentKeyPath.Type = file is null ? PossibleKeyPathType.Registry : PossibleKeyPathType.File;
170 return componentKeyPath;
171 }
172
173 return null;
174 }
175
176 private void ParseExampleEnsureTableElement(Intermediate intermediate, IntermediateSection section, XElement element)
177 {
178 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
179 this.ParseHelper.EnsureTable(section, sourceLineNumbers, ExampleTableDefinitions.NotInAll);
180 }
181
182 private void ParseExampleSearchElement(Intermediate intermediate, IntermediateSection section, XElement element)
183 {
184 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
185 Identifier id = null;
186 string searchFor = null;
187 string variable = null;
188 string condition = null;
189 string after = null;
190
191 foreach (var attrib in element.Attributes())
192 {
193 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
194 {
195 switch (attrib.Name.LocalName)
196 {
197 case "Id":
198 id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
199 break;
200 case "Variable":
201 variable = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
202 break;
203 case "Condition":
204 condition = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
205 break;
206 case "After":
207 after = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
208 break;
209 case "SearchFor":
210 searchFor = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
211 break;
212
213 default:
214 this.ParseHelper.UnexpectedAttribute(element, attrib);
215 break;
216 }
217 }
218 else
219 {
220 this.ParseAttribute(intermediate, section, element, attrib, null);
221 }
222 }
223
224 if (null == id)
225 {
226 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Id"));
227 }
228
229 if (!this.Messaging.EncounteredError)
230 {
231 this.ParseHelper.CreateWixSearchSymbol(section, sourceLineNumbers, element.Name.LocalName, id, variable, condition, after, BootstrapperExtensionId);
232 }
233
234 if (!this.Messaging.EncounteredError)
235 {
236 section.AddSymbol(new ExampleSearchSymbol(sourceLineNumbers, id)
237 {
238 SearchFor = searchFor,
239 });
240 }
241 }
242
243 private void ParseExampleSearchRefElement(Intermediate intermediate, IntermediateSection section, XElement element)
244 {
245 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
246
247 foreach (var attrib in element.Attributes())
248 {
249 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
250 {
251 switch (attrib.Name.LocalName)
252 {
253 case "Id":
254 var refId = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
255 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, ExampleSymbolDefinitions.ExampleSearch, refId);
256 break;
257 default:
258 this.ParseHelper.UnexpectedAttribute(element, attrib);
259 break;
260 }
261 }
262 else
263 {
264 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib);
265 }
266 }
267
268 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element);
269 }
270 }
271 }