summaryrefslogtreecommitdiff
path: root/src/tools/heat/Serialize/CodeDomReader.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/heat/Serialize/CodeDomReader.cs')
-rw-r--r--src/tools/heat/Serialize/CodeDomReader.cs162
1 files changed, 162 insertions, 0 deletions
diff --git a/src/tools/heat/Serialize/CodeDomReader.cs b/src/tools/heat/Serialize/CodeDomReader.cs
new file mode 100644
index 00000000..0741bf68
--- /dev/null
+++ b/src/tools/heat/Serialize/CodeDomReader.cs
@@ -0,0 +1,162 @@
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.Harvesters.Serialize
4{
5 using System;
6 using System.Diagnostics.CodeAnalysis;
7 using System.Globalization;
8 using System.Reflection;
9 using System.Xml;
10 using WixToolset.Harvesters.Extensibility.Serialize;
11
12 /// <summary>
13 /// Class used for reading XML files in to the CodeDom.
14 /// </summary>
15 public class CodeDomReader
16 {
17 private Assembly[] assemblies;
18
19 /// <summary>
20 /// Creates a new CodeDomReader, using the current assembly.
21 /// </summary>
22 public CodeDomReader()
23 {
24 this.assemblies = new Assembly[] { Assembly.GetExecutingAssembly() };
25 }
26
27 /// <summary>
28 /// Creates a new CodeDomReader, and takes in a list of assemblies in which to
29 /// look for elements.
30 /// </summary>
31 /// <param name="assemblies">Assemblies in which to look for types that correspond
32 /// to elements.</param>
33 public CodeDomReader(Assembly[] assemblies)
34 {
35 this.assemblies = assemblies;
36 }
37
38 /// <summary>
39 /// Loads an XML file into a strongly-typed code dom.
40 /// </summary>
41 /// <param name="filePath">File to load into the code dom.</param>
42 /// <returns>The strongly-typed object at the root of the tree.</returns>
43 [SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters", MessageId = "System.InvalidOperationException.#ctor(System.String)")]
44 public ISchemaElement Load(string filePath)
45 {
46 XmlDocument document = new XmlDocument();
47 document.Load(filePath);
48 ISchemaElement schemaElement = null;
49
50 foreach (XmlNode node in document.ChildNodes)
51 {
52 XmlElement element = node as XmlElement;
53 if (element != null)
54 {
55 if (schemaElement != null)
56 {
57 throw new InvalidOperationException(WixHarvesterStrings.EXP_MultipleRootElementsFoundInFile);
58 }
59
60 schemaElement = this.CreateObjectFromElement(element);
61 this.ParseObjectFromElement(schemaElement, element);
62 }
63 }
64 return schemaElement;
65 }
66
67 /// <summary>
68 /// Sets an attribute on an ISchemaElement.
69 /// </summary>
70 /// <param name="schemaElement">Schema element to set attribute on.</param>
71 /// <param name="name">Name of the attribute to set.</param>
72 /// <param name="value">Value to set on the attribute.</param>
73 [SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters", MessageId = "System.InvalidOperationException.#ctor(System.String)")]
74 private static void SetAttributeOnObject(ISchemaElement schemaElement, string name, string value)
75 {
76 ISetAttributes setAttributes = schemaElement as ISetAttributes;
77 if (setAttributes == null)
78 {
79 throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixHarvesterStrings.EXP_ISchemaElementDoesnotImplementISetAttribute, schemaElement.GetType().FullName));
80 }
81 else
82 {
83 setAttributes.SetAttribute(name, value);
84 }
85 }
86
87 /// <summary>
88 /// Parses an ISchemaElement from the XmlElement.
89 /// </summary>
90 /// <param name="schemaElement">ISchemaElement to fill in.</param>
91 /// <param name="element">XmlElement to parse from.</param>
92 [SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters", MessageId = "System.InvalidOperationException.#ctor(System.String)")]
93 private void ParseObjectFromElement(ISchemaElement schemaElement, XmlElement element)
94 {
95 foreach (XmlAttribute attribute in element.Attributes)
96 {
97 SetAttributeOnObject(schemaElement, attribute.LocalName, attribute.Value);
98 }
99
100 foreach (XmlNode node in element.ChildNodes)
101 {
102 XmlElement childElement = node as XmlElement;
103 if (childElement != null)
104 {
105 ISchemaElement childSchemaElement = null;
106 ICreateChildren createChildren = schemaElement as ICreateChildren;
107 if (createChildren == null)
108 {
109 throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixHarvesterStrings.EXP_ISchemaElementDoesnotImplementICreateChildren, element.LocalName));
110 }
111 else
112 {
113 childSchemaElement = createChildren.CreateChild(childElement.LocalName);
114 }
115
116 if (childSchemaElement == null)
117 {
118 childSchemaElement = this.CreateObjectFromElement(childElement);
119 if (childSchemaElement == null)
120 {
121 throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixHarvesterStrings.EXP_XmlElementDoesnotHaveISchemaElement, childElement.LocalName));
122 }
123 }
124
125 this.ParseObjectFromElement(childSchemaElement, childElement);
126 IParentElement parentElement = (IParentElement)schemaElement;
127 parentElement.AddChild(childSchemaElement);
128 }
129 else
130 {
131 XmlText childText = node as XmlText;
132 if (childText != null)
133 {
134 SetAttributeOnObject(schemaElement, "Content", childText.Value);
135 }
136 }
137 }
138 }
139
140 /// <summary>
141 /// Creates an object from an XML element by digging through the assembly list.
142 /// </summary>
143 /// <param name="element">XML Element to create an ISchemaElement from.</param>
144 /// <returns>A constructed ISchemaElement.</returns>
145 private ISchemaElement CreateObjectFromElement(XmlElement element)
146 {
147 ISchemaElement schemaElement = null;
148 foreach (Assembly assembly in this.assemblies)
149 {
150 foreach (Type type in assembly.GetTypes())
151 {
152 if (type.FullName.EndsWith(element.LocalName, StringComparison.Ordinal)
153 && typeof(ISchemaElement).IsAssignableFrom(type))
154 {
155 schemaElement = (ISchemaElement)Activator.CreateInstance(type);
156 }
157 }
158 }
159 return schemaElement;
160 }
161 }
162}