main
cs 228 lines 8.07 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.Data.WindowsInstaller
4 {
5 using System.Collections;
6 using System.Collections.Generic;
7 using System.Linq;
8 using System.Xml;
9
10 /// <summary>
11 /// Collection for table definitions indexed by table name.
12 /// </summary>
13 public sealed class TableDefinitionCollection : ICollection<TableDefinition>
14 {
15 public const string XmlNamespaceUri = "http://wixtoolset.org/schemas/v4/wi/tables";
16
17 private readonly Dictionary<string, TableDefinition> collection;
18
19 /// <summary>
20 /// Instantiate a new TableDefinitionCollection class.
21 /// </summary>
22 public TableDefinitionCollection()
23 {
24 this.collection = new Dictionary<string, TableDefinition>();
25 }
26
27 /// <summary>
28 /// Creates a shallow copy of the provided table definition collection.
29 /// </summary>
30 public TableDefinitionCollection(TableDefinitionCollection tableDefinitions)
31 {
32 this.collection = new Dictionary<string, TableDefinition>(tableDefinitions.collection);
33 }
34
35 /// <summary>
36 /// Creates a table definition collection with the given table definitions.
37 /// </summary>
38 public TableDefinitionCollection(IEnumerable<TableDefinition> tableDefinitions)
39 {
40 this.collection = tableDefinitions.ToDictionary(t => t.Name);
41 }
42
43 /// <summary>
44 /// Gets the number of items in the collection.
45 /// </summary>
46 /// <value>Number of items in collection.</value>
47 public int Count => this.collection.Count;
48
49 /// <summary>
50 /// Table definition collections are never read-only.
51 /// </summary>
52 public bool IsReadOnly => false;
53
54 /// <summary>
55 /// Gets a table definition by name.
56 /// </summary>
57 /// <param name="tableName">Name of table to locate.</param>
58 public TableDefinition this[string tableName]
59 {
60 get
61 {
62 if (!this.collection.TryGetValue(tableName, out var table))
63 {
64 throw new WixMissingTableDefinitionException(ErrorMessages.MissingTableDefinition(tableName));
65 }
66
67 return table;
68 }
69 }
70
71 /// <summary>
72 /// Tries to get a table definition by name.
73 /// </summary>
74 /// <param name="tableName">Name of table to locate.</param>
75 /// <param name="table">Table definition if found.</param>
76 /// <returns>True if table definition was found otherwise false.</returns>
77 public bool TryGet(string tableName, out TableDefinition table)
78 {
79 return this.collection.TryGetValue(tableName, out table);
80 }
81
82 /// <summary>
83 /// Adds a table definition to the collection.
84 /// </summary>
85 /// <param name="tableDefinition">Table definition to add to the collection.</param>
86 /// <value>Indexes by table definition name.</value>
87 public void Add(TableDefinition tableDefinition)
88 {
89 this.collection.Add(tableDefinition.Name, tableDefinition);
90 }
91
92 /// <summary>
93 /// Removes all table definitions from the collection.
94 /// </summary>
95 public void Clear()
96 {
97 this.collection.Clear();
98 }
99
100 /// <summary>
101 /// Checks if the collection contains a table name.
102 /// </summary>
103 /// <param name="tableName">The table to check in the collection.</param>
104 /// <returns>True if collection contains the table.</returns>
105 public bool Contains(string tableName)
106 {
107 return this.collection.ContainsKey(tableName);
108 }
109
110 /// <summary>
111 /// Checks if the collection contains a table.
112 /// </summary>
113 /// <param name="table">The table to check in the collection.</param>
114 /// <returns>True if collection contains the table.</returns>
115 public bool Contains(TableDefinition table)
116 {
117 return this.collection.ContainsKey(table.Name);
118 }
119
120 /// <summary>
121 /// Copies table definitions to an arry.
122 /// </summary>
123 /// <param name="array">Array to copy the table definitions to.</param>
124 /// <param name="index">Index in the array to start copying at.</param>
125 public void CopyTo(TableDefinition[] array, int index)
126 {
127 this.collection.Values.CopyTo(array, index);
128 }
129
130 /// <summary>
131 /// Removes a table definition from the collection.
132 /// </summary>
133 /// <param name="table">Table to remove from the collection.</param>
134 /// <returns>True if the table definition existed in the collection and was removed.</returns>
135 public bool Remove(TableDefinition table)
136 {
137 return this.collection.Remove(table.Name);
138 }
139
140 /// <summary>
141 /// Gets enumerator for the collection.
142 /// </summary>
143 /// <returns>Enumerator for the collection.</returns>
144 public IEnumerator<TableDefinition> GetEnumerator()
145 {
146 return this.collection.Values.GetEnumerator();
147 }
148
149 /// <summary>
150 /// Gets the untyped enumerator for the collection.
151 /// </summary>
152 /// <returns>Untyped enumerator for the collection.</returns>
153 IEnumerator IEnumerable.GetEnumerator()
154 {
155 return this.collection.Values.GetEnumerator();
156 }
157
158 /// <summary>
159 /// Loads a collection of table definitions from a XmlReader in memory.
160 /// </summary>
161 /// <param name="reader">Reader to get data from.</param>
162 /// <param name="tableDefinitions">Table definitions to use for strongly-typed rows.</param>
163 /// <returns>The TableDefinitionCollection represented by the xml.</returns>
164 internal static TableDefinitionCollection Read(XmlReader reader, TableDefinitionCollection tableDefinitions)
165 {
166 if ("tableDefinitions" != reader.LocalName)
167 {
168 throw new XmlException();
169 }
170
171 var empty = reader.IsEmptyElement;
172 var tableDefinitionCollection = new TableDefinitionCollection();
173
174 while (reader.MoveToNextAttribute())
175 {
176 }
177
178 // parse the child elements
179 if (!empty)
180 {
181 var done = false;
182
183 while (!done && reader.Read())
184 {
185 switch (reader.NodeType)
186 {
187 case XmlNodeType.Element:
188 switch (reader.LocalName)
189 {
190 case "tableDefinition":
191 tableDefinitionCollection.Add(TableDefinition.Read(reader, tableDefinitions));
192 break;
193 default:
194 throw new XmlException();
195 }
196 break;
197 case XmlNodeType.EndElement:
198 done = true;
199 break;
200 }
201 }
202
203 if (!done)
204 {
205 throw new XmlException();
206 }
207 }
208
209 return tableDefinitionCollection;
210 }
211
212 /// <summary>
213 /// Persists a TableDefinitionCollection in an XML format.
214 /// </summary>
215 /// <param name="writer">XmlWriter where the TableDefinitionCollection should persist itself as XML.</param>
216 internal void Write(XmlWriter writer)
217 {
218 writer.WriteStartElement("tableDefinitions", XmlNamespaceUri);
219
220 foreach (var tableDefinition in this.collection.Values.OrderBy(t => t.Name))
221 {
222 tableDefinition.Write(writer);
223 }
224
225 writer.WriteEndElement();
226 }
227 }
228 }