XmlInterpreter
Reads the configuration from a XmlFile. Sample structure:
<configuration>
<facilities>
<facility>
</facility>
</facilities>
<components>
<component id="component1">
</component>
</components>
</configuration>
using Castle.Core;
using Castle.Core.Configuration;
using Castle.Core.Configuration.Xml;
using Castle.Core.Resource;
using Castle.MicroKernel;
using Castle.MicroKernel.SubSystems.Configuration;
using Castle.MicroKernel.SubSystems.Conversion;
using Castle.MicroKernel.SubSystems.Resource;
using Castle.Windsor.Configuration.Interpreters.XmlProcessor;
using System;
using System.Xml;
namespace Castle.Windsor.Configuration.Interpreters
{
public class XmlInterpreter : AbstractInterpreter
{
public XmlInterpreter(string filename)
: base(filename)
{
}
public XmlInterpreter(IResource source)
: base(source)
{
}
public override void ProcessResource(IResource source, IConfigurationStore store, IKernel kernel)
{
IResourceSubSystem resourceSubSystem = kernel.GetSubSystem(SubSystemConstants.ResourceKey) as IResourceSubSystem;
Castle.Windsor.Configuration.Interpreters.XmlProcessor.XmlProcessor xmlProcessor = new Castle.Windsor.Configuration.Interpreters.XmlProcessor.XmlProcessor(base.EnvironmentName, resourceSubSystem);
try {
XmlNode section = xmlProcessor.Process(source);
IConversionManager conversionManager = kernel.GetConversionManager();
Deserialize(section, store, conversionManager);
} catch (XmlProcessorException innerException) {
throw new ConfigurationProcessingException("Unable to process xml resource.", innerException);
}
}
protected static void Deserialize(XmlNode section, IConfigurationStore store, IConversionManager converter)
{
foreach (XmlNode item in section) {
if (XmlConfigurationDeserializer.IsTextNode(item))
throw new ConfigurationProcessingException($"{item.Name}""");
if (item.NodeType == XmlNodeType.Element)
DeserializeElement(item, store, converter);
}
}
private static void AssertNodeName(XmlNode node, IEquatable<string> expectedName)
{
if (expectedName.Equals(node.Name))
return;
throw new ConfigurationProcessingException($"""{expectedName}""{expectedName}""{node.Name}""");
}
private static void DeserializeComponent(XmlNode node, IConfigurationStore store, IConversionManager converter)
{
IConfiguration deserializedNode = XmlConfigurationDeserializer.GetDeserializedNode(node);
string text = deserializedNode.Attributes["id"];
if (string.IsNullOrEmpty(text)) {
text = ComponentName.DefaultNameFor(converter.PerformConversion<Type>(deserializedNode.Attributes["type"]));
deserializedNode.Attributes["id"] = text;
deserializedNode.Attributes.Add("id-automatic", bool.TrueString);
}
AbstractInterpreter.AddComponentConfig(text, deserializedNode, store);
}
private static void DeserializeComponents(XmlNodeList nodes, IConfigurationStore store, IConversionManager converter)
{
foreach (XmlNode node in nodes) {
if (node.NodeType == XmlNodeType.Element) {
AssertNodeName(node, AbstractInterpreter.ComponentNodeName);
DeserializeComponent(node, store, converter);
}
}
}
private static void DeserializeContainer(XmlNode node, IConfigurationStore store)
{
IConfiguration deserializedNode = XmlConfigurationDeserializer.GetDeserializedNode(node);
IConfiguration configuration = new MutableConfiguration(deserializedNode.Name, node.InnerXml);
string[] allKeys = deserializedNode.Attributes.AllKeys;
foreach (string name in allKeys) {
configuration.Attributes.Add(name, deserializedNode.Attributes[name]);
}
configuration.Children.AddRange(deserializedNode.Children);
AbstractInterpreter.AddChildContainerConfig(GetRequiredAttributeValue(deserializedNode, "name"), configuration, store);
}
private static void DeserializeContainers(XmlNodeList nodes, IConfigurationStore store)
{
foreach (XmlNode node in nodes) {
if (node.NodeType == XmlNodeType.Element) {
AssertNodeName(node, AbstractInterpreter.ContainerNodeName);
DeserializeContainer(node, store);
}
}
}
private static void DeserializeElement(XmlNode node, IConfigurationStore store, IConversionManager converter)
{
if (AbstractInterpreter.ContainersNodeName.Equals(node.Name))
DeserializeContainers(node.ChildNodes, store);
else if (AbstractInterpreter.FacilitiesNodeName.Equals(node.Name)) {
DeserializeFacilities(node.ChildNodes, store, converter);
} else if (AbstractInterpreter.InstallersNodeName.Equals(node.Name)) {
DeserializeInstallers(node.ChildNodes, store);
} else {
if (!AbstractInterpreter.ComponentsNodeName.Equals(node.Name))
throw new ConfigurationProcessingException(string.Format("Configuration parser encountered <{0}>, but it was expecting to find <{1}>, <{2}> or <{3}>. There might be either a typo on <{0}> or you might have forgotten to nest it properly.", node.Name, AbstractInterpreter.InstallersNodeName, AbstractInterpreter.FacilitiesNodeName, AbstractInterpreter.ComponentsNodeName));
DeserializeComponents(node.ChildNodes, store, converter);
}
}
private static void DeserializeFacilities(XmlNodeList nodes, IConfigurationStore store, IConversionManager converter)
{
foreach (XmlNode node in nodes) {
if (node.NodeType == XmlNodeType.Element) {
AssertNodeName(node, AbstractInterpreter.FacilityNodeName);
DeserializeFacility(node, store, converter);
}
}
}
private static void DeserializeFacility(XmlNode node, IConfigurationStore store, IConversionManager converter)
{
IConfiguration deserializedNode = XmlConfigurationDeserializer.GetDeserializedNode(node);
ThrowIfFacilityConfigurationHasIdAttribute(deserializedNode);
string requiredAttributeValue = GetRequiredAttributeValue(deserializedNode, "type");
AbstractInterpreter.AddFacilityConfig(converter.PerformConversion<Type>(requiredAttributeValue).FullName, deserializedNode, store);
}
private static void DeserializeInstaller(XmlNode node, IConfigurationStore store)
{
IConfiguration deserializedNode = XmlConfigurationDeserializer.GetDeserializedNode(node);
string value = deserializedNode.Attributes["type"];
string value2 = deserializedNode.Attributes["assembly"];
string value3 = deserializedNode.Attributes["directory"];
int num = 0;
if (!string.IsNullOrEmpty(value))
num++;
if (!string.IsNullOrEmpty(value2))
num++;
if (!string.IsNullOrEmpty(value3))
num++;
if (num != 1)
throw new ConfigurationProcessingException("install must have exactly one of the following attributes defined: 'type', 'assembly' or 'directory'.");
AbstractInterpreter.AddInstallerConfig(deserializedNode, store);
}
private static void DeserializeInstallers(XmlNodeList nodes, IConfigurationStore store)
{
foreach (XmlNode node in nodes) {
if (node.NodeType == XmlNodeType.Element) {
AssertNodeName(node, AbstractInterpreter.InstallNodeName);
DeserializeInstaller(node, store);
}
}
}
private static string GetRequiredAttributeValue(IConfiguration configuration, string attributeName)
{
string text = configuration.Attributes[attributeName];
if (string.IsNullOrEmpty(text))
throw new ConfigurationProcessingException($"{configuration.Name}""{attributeName}");
return text;
}
private static void ThrowIfFacilityConfigurationHasIdAttribute(IConfiguration config)
{
if (config.Attributes["id"] != null)
throw new ConfigurationProcessingException("The 'id' attribute has been removed from facility configurations, please remove it from your configuration.");
}
}
}