aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Data.WindowsInstaller/Rows/WixActionRow.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/WixToolset.Data.WindowsInstaller/Rows/WixActionRow.cs')
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Rows/WixActionRow.cs374
1 files changed, 374 insertions, 0 deletions
diff --git a/src/WixToolset.Data.WindowsInstaller/Rows/WixActionRow.cs b/src/WixToolset.Data.WindowsInstaller/Rows/WixActionRow.cs
new file mode 100644
index 00000000..3009e59d
--- /dev/null
+++ b/src/WixToolset.Data.WindowsInstaller/Rows/WixActionRow.cs
@@ -0,0 +1,374 @@
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
3namespace WixToolset.Data.Rows
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Diagnostics;
8 using System.Globalization;
9 using System.Xml;
10 using System.Xml.Schema;
11
12 /// <summary>
13 /// The Sequence tables that actions may belong to.
14 /// </summary>
15 public enum SequenceTable
16 {
17 /// <summary>AdminUISequence</summary>
18 AdminUISequence,
19
20 /// <summary>AdminExecuteSequence</summary>
21 AdminExecuteSequence,
22
23 /// <summary>AdvtExecuteSequence</summary>
24 AdvtExecuteSequence,
25
26 /// <summary>InstallUISequence</summary>
27 InstallUISequence,
28
29 /// <summary>InstallExecuteSequence</summary>
30 InstallExecuteSequence
31 }
32
33 /// <summary>
34 /// Specialization of a row for the sequence tables.
35 /// </summary>
36 public sealed class WixActionRow : Row, IComparable
37 {
38 private WixActionRowCollection previousActionRows;
39 private WixActionRowCollection nextActionRows;
40
41 /// <summary>
42 /// Instantiates an ActionRow that belongs to a table.
43 /// </summary>
44 /// <param name="sourceLineNumbers">Original source lines for this row.</param>
45 /// <param name="table">Table this Action row belongs to and should get its column definitions from.</param>
46 public WixActionRow(SourceLineNumber sourceLineNumbers, Table table) :
47 base(sourceLineNumbers, table)
48 {
49 }
50
51 /// <summary>
52 /// Instantiates a standard ActionRow.
53 /// </summary>
54 /// <param name="sequenceTable">The sequence table of the standard action.</param>
55 /// <param name="action">The name of the standard action.</param>
56 /// <param name="condition">The condition of the standard action.</param>
57 /// <param name="sequence">The suggested sequence number of the standard action.</param>
58 private WixActionRow(SequenceTable sequenceTable, string action, string condition, int sequence) :
59 base(null, WindowsInstallerStandard.GetTableDefinitions()["WixAction"])
60 {
61 this.SequenceTable = sequenceTable;
62 this.Action = action;
63 this.Condition = condition;
64 this.Sequence = sequence;
65 this.Overridable = true; // all standard actions are overridable by default
66 }
67
68 /// <summary>
69 /// Instantiates an ActionRow by copying data from another ActionRow.
70 /// </summary>
71 /// <param name="source">The row the data is copied from.</param>
72 /// <remarks>The previous and next action collections are not copied.</remarks>
73 private WixActionRow(WixActionRow source)
74 : base(source)
75 {
76 }
77
78 /// <summary>
79 /// Gets or sets the name of the action.
80 /// </summary>
81 /// <value>The name of the action.</value>
82 public string Action
83 {
84 get { return (string)this.Fields[1].Data; }
85 set { this.Fields[1].Data = value; }
86 }
87
88 /// <summary>
89 /// Gets the name of the action this action should be scheduled after.
90 /// </summary>
91 /// <value>The name of the action this action should be scheduled after.</value>
92 public string After
93 {
94 get { return (string)this.Fields[5].Data; }
95 set { this.Fields[5].Data = value; }
96 }
97
98 /// <summary>
99 /// Gets the name of the action this action should be scheduled before.
100 /// </summary>
101 /// <value>The name of the action this action should be scheduled before.</value>
102 public string Before
103 {
104 get { return (string)this.Fields[4].Data; }
105 set { this.Fields[4].Data = value; }
106 }
107
108 /// <summary>
109 /// Gets or sets the condition of the action.
110 /// </summary>
111 /// <value>The condition of the action.</value>
112 public string Condition
113 {
114 get { return (string)this.Fields[2].Data; }
115 set { this.Fields[2].Data = value; }
116 }
117
118 /// <summary>
119 /// Gets or sets whether this action is overridable.
120 /// </summary>
121 /// <value>Whether this action is overridable.</value>
122 public bool Overridable
123 {
124 get { return (1 == Convert.ToInt32(this.Fields[6].Data, CultureInfo.InvariantCulture)); }
125 set { this.Fields[6].Data = (value ? 1 : 0); }
126 }
127
128 /// <summary>
129 /// Gets or sets the sequence number of this action.
130 /// </summary>
131 /// <value>The sequence number of this action.</value>
132 public int Sequence
133 {
134 get { return Convert.ToInt32(this.Fields[3].Data, CultureInfo.InvariantCulture); }
135 set { this.Fields[3].Data = value; }
136 }
137
138 /// <summary>
139 /// Gets of sets the sequence table of this action.
140 /// </summary>
141 /// <value>The sequence table of this action.</value>
142 public SequenceTable SequenceTable
143 {
144 get { return (SequenceTable)Enum.Parse(typeof(SequenceTable), (string)this.Fields[0].Data); }
145 set { this.Fields[0].Data = value.ToString(); }
146 }
147
148 /// <summary>
149 /// Gets the actions that should be scheduled after this action.
150 /// </summary>
151 /// <value>The actions that should be scheduled after this action.</value>
152 public WixActionRowCollection NextActionRows
153 {
154 get
155 {
156 if (null == this.nextActionRows)
157 {
158 this.nextActionRows = new WixActionRowCollection();
159 }
160
161 return this.nextActionRows;
162 }
163 }
164
165 /// <summary>
166 /// Gets the actions that should be scheduled before this action.
167 /// </summary>
168 /// <value>The actions that should be scheduled before this action.</value>
169 public WixActionRowCollection PreviousActionRows
170 {
171 get
172 {
173 if (null == this.previousActionRows)
174 {
175 this.previousActionRows = new WixActionRowCollection();
176 }
177
178 return this.previousActionRows;
179 }
180 }
181
182 /// <summary>
183 /// Creates a clone of the action row.
184 /// </summary>
185 /// <returns>A shallow copy of the source object.</returns>
186 /// <remarks>The previous and next action collections are not copied.</remarks>
187 public WixActionRow Clone()
188 {
189 return new WixActionRow(this);
190 }
191
192 /// <summary>
193 /// Compares the current instance with another object of the same type.
194 /// </summary>
195 /// <param name="obj">Other reference to compare this one to.</param>
196 /// <returns>Returns less than 0 for less than, 0 for equals, and greater than 0 for greater.</returns>
197 public int CompareTo(object obj)
198 {
199 WixActionRow otherActionRow = (WixActionRow)obj;
200
201 return this.Sequence.CompareTo(otherActionRow.Sequence);
202 }
203
204 /// <summary>
205 /// Parses ActionRows from the Xml reader.
206 /// </summary>
207 /// <param name="reader">Xml reader that contains serialized ActionRows.</param>
208 /// <returns>The parsed ActionRows.</returns>
209 internal static WixActionRow[] Parse(XmlReader reader)
210 {
211 Debug.Assert("action" == reader.LocalName);
212
213 string id = null;
214 string condition = null;
215 bool empty = reader.IsEmptyElement;
216 int sequence = int.MinValue;
217 int sequenceCount = 0;
218 SequenceTable[] sequenceTables = new SequenceTable[Enum.GetValues(typeof(SequenceTable)).Length];
219
220 while (reader.MoveToNextAttribute())
221 {
222 switch (reader.Name)
223 {
224 case "name":
225 id = reader.Value;
226 break;
227 case "AdminExecuteSequence":
228 if (reader.Value.Equals("yes"))
229 {
230 sequenceTables[sequenceCount] = SequenceTable.AdminExecuteSequence;
231 ++sequenceCount;
232 }
233 break;
234 case "AdminUISequence":
235 if (reader.Value.Equals("yes"))
236 {
237 sequenceTables[sequenceCount] = SequenceTable.AdminUISequence;
238 ++sequenceCount;
239 }
240 break;
241 case "AdvtExecuteSequence":
242 if (reader.Value.Equals("yes"))
243 {
244 sequenceTables[sequenceCount] = SequenceTable.AdvtExecuteSequence;
245 ++sequenceCount;
246 }
247 break;
248 case "condition":
249 condition = reader.Value;
250 break;
251 case "InstallExecuteSequence":
252 if (reader.Value.Equals("yes"))
253 {
254 sequenceTables[sequenceCount] = SequenceTable.InstallExecuteSequence;
255 ++sequenceCount;
256 }
257 break;
258 case "InstallUISequence":
259 if (reader.Value.Equals("yes"))
260 {
261 sequenceTables[sequenceCount] = SequenceTable.InstallUISequence;
262 ++sequenceCount;
263 }
264 break;
265 case "sequence":
266 sequence = Convert.ToInt32(reader.Value, CultureInfo.InvariantCulture);
267 break;
268 }
269 }
270
271 if (null == id)
272 {
273 throw new XmlException();
274 }
275
276 if (int.MinValue == sequence)
277 {
278 throw new XmlException();
279 }
280 else if (1 > sequence)
281 {
282 throw new XmlException();
283 }
284
285 if (0 == sequenceCount)
286 {
287 throw new XmlException();
288 }
289
290 if (!empty && reader.Read() && XmlNodeType.EndElement != reader.MoveToContent())
291 {
292 throw new XmlException();
293 }
294
295 // create the actions
296 WixActionRow[] actionRows = new WixActionRow[sequenceCount];
297 for (int i = 0; i < sequenceCount; i++)
298 {
299 WixActionRow actionRow = new WixActionRow(sequenceTables[i], id, condition, sequence);
300 actionRows[i] = actionRow;
301 }
302
303 return actionRows;
304 }
305
306 /// <summary>
307 /// Determines whether this ActionRow contains the specified ActionRow as a child in its dependency tree.
308 /// </summary>
309 /// <param name="actionRow">The possible child ActionRow.</param>
310 /// <returns>true if the ActionRow is a child of this ActionRow; false otherwise.</returns>
311 public bool ContainsChildActionRow(WixActionRow actionRow)
312 {
313 if (null != this.previousActionRows)
314 {
315 if (this.previousActionRows.Contains(actionRow.SequenceTable, actionRow.Action))
316 {
317 return true;
318 }
319 }
320
321 if (null != this.nextActionRows)
322 {
323 if (this.nextActionRows.Contains(actionRow.SequenceTable, actionRow.Action))
324 {
325 return true;
326 }
327 }
328
329 return false;
330 }
331
332 /// <summary>
333 /// Get all the actions scheduled before this one in a particular sequence table.
334 /// </summary>
335 /// <param name="sequenceTable">The sequence table.</param>
336 /// <param name="allPreviousActionRows">A RowCollection which will contain all the previous actions.</param>
337 public void GetAllPreviousActionRows(SequenceTable sequenceTable, IList<WixActionRow> allPreviousActionRows)
338 {
339 if (null != this.previousActionRows)
340 {
341 foreach (WixActionRow actionRow in this.previousActionRows)
342 {
343 if (sequenceTable == actionRow.SequenceTable)
344 {
345 actionRow.GetAllPreviousActionRows(sequenceTable, allPreviousActionRows);
346 allPreviousActionRows.Add(actionRow);
347 actionRow.GetAllNextActionRows(sequenceTable, allPreviousActionRows);
348 }
349 }
350 }
351 }
352
353 /// <summary>
354 /// Get all the actions scheduled after this one in a particular sequence table.
355 /// </summary>
356 /// <param name="sequenceTable">The sequence table.</param>
357 /// <param name="allNextActionRows">A RowCollection which will contain all the next actions.</param>
358 public void GetAllNextActionRows(SequenceTable sequenceTable, IList<WixActionRow> allNextActionRows)
359 {
360 if (null != this.nextActionRows)
361 {
362 foreach (WixActionRow actionRow in this.nextActionRows)
363 {
364 if (sequenceTable == actionRow.SequenceTable)
365 {
366 actionRow.GetAllPreviousActionRows(sequenceTable, allNextActionRows);
367 allNextActionRows.Add(actionRow);
368 actionRow.GetAllNextActionRows(sequenceTable, allNextActionRows);
369 }
370 }
371 }
372 }
373 }
374}