Added RedirectUsingNamedRoute
[castle.git] / InversionOfControl / Castle.Windsor / Configuration / Interpreters / XmlInterpreter.cs
blob6ccd29f1bdd6aa07c4afa0d14af23ab47e6413a6
1 // Copyright 2004-2008 Castle Project - http://www.castleproject.org/
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle.Windsor.Configuration.Interpreters
17 using System;
18 using System.Xml;
19 using System.Configuration;
20 using Castle.Core.Configuration.Xml;
21 using Castle.Core.Resource;
22 using Castle.Core.Configuration;
24 using Castle.MicroKernel;
25 using Castle.MicroKernel.SubSystems.Resource;
27 using Castle.Windsor.Configuration.Interpreters.XmlProcessor;
29 /// <summary>
30 /// Reads the configuration from a XmlFile. Sample structure:
31 /// <code>
32 /// &lt;configuration&gt;
33 /// &lt;facilities&gt;
34 /// &lt;facility id="myfacility"&gt;
35 ///
36 /// &lt;/facility&gt;
37 /// &lt;/facilities&gt;
38 ///
39 /// &lt;components&gt;
40 /// &lt;component id="component1"&gt;
41 ///
42 /// &lt;/component&gt;
43 /// &lt;/components&gt;
44 /// &lt;/configuration&gt;
45 /// </code>
46 /// </summary>
47 public class XmlInterpreter : AbstractInterpreter
49 private IKernel kernel;
51 #region Constructors
53 /// <summary>
54 /// Initializes a new instance of the <see cref="XmlInterpreter"/> class.
55 /// </summary>
56 public XmlInterpreter()
60 /// <summary>
61 /// Initializes a new instance of the <see cref="XmlInterpreter"/> class.
62 /// </summary>
63 /// <param name="filename">The filename.</param>
64 public XmlInterpreter(String filename) : base(filename)
68 /// <summary>
69 /// Initializes a new instance of the <see cref="XmlInterpreter"/> class.
70 /// </summary>
71 /// <param name="source">The source.</param>
72 public XmlInterpreter(Castle.Core.Resource.IResource source) : base(source)
76 #endregion
78 /// <summary>
79 /// Gets or sets the kernel.
80 /// </summary>
81 /// <value>The kernel.</value>
82 public IKernel Kernel
84 get { return kernel ; }
85 set { kernel = value; }
88 public override void ProcessResource(IResource source, IConfigurationStore store)
90 XmlProcessor.XmlProcessor processor = (kernel == null) ?
91 new XmlProcessor.XmlProcessor(EnvironmentName) :
92 new XmlProcessor.XmlProcessor(EnvironmentName,
93 kernel.GetSubSystem(SubSystemConstants.ResourceKey) as IResourceSubSystem);
95 try
97 XmlNode element = processor.Process(source);
99 Deserialize(element, store);
101 catch(XmlProcessorException)
103 string message = "Unable to process xml resource ";
105 throw new ConfigurationErrorsException(message);
109 protected void Deserialize(XmlNode section, IConfigurationStore store)
111 foreach(XmlNode node in section)
113 if (XmlConfigurationDeserializer.IsTextNode(node))
115 string message = String.Format("{0} cannot contain text nodes", node.Name);
117 throw new ConfigurationErrorsException(message);
119 else if (node.NodeType == XmlNodeType.Element)
121 DeserializeElement(node, store);
126 private void DeserializeElement(XmlNode node, IConfigurationStore store)
128 if (ContainersNodeName.Equals(node.Name))
130 DeserializeContainers(node.ChildNodes, store);
132 else if (FacilitiesNodeName.Equals(node.Name))
134 DeserializeFacilities(node.ChildNodes, store);
136 else if (ComponentsNodeName.Equals(node.Name))
138 DeserializeComponents(node.ChildNodes, store);
140 else if (BootstrapNodeName.Equals(node.Name))
142 DeserializeBootstrapComponents(node.ChildNodes, store);
144 else
146 string message = string.Format(
147 "Configuration parser encountered <{0}>, but it was expecting to find " +
148 "<{1}>, <{2}>, <{3}> or <{4}>. There might be either a typo on <{0}> or " +
149 "you might have forgotten to nest it properly.",
150 node.Name, ContainersNodeName, FacilitiesNodeName, ComponentsNodeName, BootstrapNodeName);
151 throw new ConfigurationErrorsException(message);
155 private void DeserializeContainers(XmlNodeList nodes, IConfigurationStore store)
157 foreach(XmlNode node in nodes)
159 if (node.NodeType == XmlNodeType.Element)
161 AssertNodeName(node, ContainerNodeName);
163 DeserializeContainer(node, store);
168 private void DeserializeContainer(XmlNode node, IConfigurationStore store)
170 String name = GetRequiredAttributeValue(node, "name");
172 IConfiguration config = XmlConfigurationDeserializer.GetDeserializedNode(node);
173 IConfiguration newConfig = new MutableConfiguration(config.Name, node.InnerXml);
175 // Copy all attributes
176 string[] allKeys = config.Attributes.AllKeys;
178 foreach(string key in allKeys)
180 newConfig.Attributes.Add(key, config.Attributes[key]);
183 // Copy all children
184 newConfig.Children.AddRange(config.Children);
186 AddChildContainerConfig(name, newConfig, store);
189 private void DeserializeFacilities(XmlNodeList nodes, IConfigurationStore store)
191 foreach(XmlNode node in nodes)
193 if (node.NodeType == XmlNodeType.Element)
195 AssertNodeName(node, FacilityNodeName);
197 DeserializeFacility(node, store);
202 private void DeserializeFacility(XmlNode node, IConfigurationStore store)
204 String id = GetRequiredAttributeValue(node, "id");
206 IConfiguration config = XmlConfigurationDeserializer.GetDeserializedNode(node);
208 AddFacilityConfig(id, config, store);
211 private void DeserializeComponents(XmlNodeList nodes, IConfigurationStore store)
213 foreach(XmlNode node in nodes)
215 if (node.NodeType == XmlNodeType.Element)
217 AssertNodeName(node, ComponentNodeName);
219 DeserializeComponent(node, store);
224 private void DeserializeBootstrapComponents(XmlNodeList nodes, IConfigurationStore store)
226 foreach(XmlNode node in nodes)
228 if (node.NodeType == XmlNodeType.Element)
230 AssertNodeName(node, ComponentNodeName);
232 DeserializeBootstrapComponent(node, store);
237 private void DeserializeComponent(XmlNode node, IConfigurationStore store)
239 String id = GetRequiredAttributeValue(node, "id");
241 IConfiguration config = XmlConfigurationDeserializer.GetDeserializedNode(node);
243 AddComponentConfig(id, config, store);
246 private void DeserializeBootstrapComponent(XmlNode node, IConfigurationStore store)
248 String id = GetRequiredAttributeValue(node, "id");
250 IConfiguration config = XmlConfigurationDeserializer.GetDeserializedNode(node);
252 AddBootstrapComponentConfig(id, config, store);
255 private String GetRequiredAttributeValue(XmlNode node, String attName)
257 String value = GetAttributeValue(node, attName);
259 if (value.Length == 0)
261 String message = String.Format("{0} elements expects required non blank attribute {1}",
262 node.Name, attName);
264 throw new ConfigurationErrorsException(message);
267 return value;
270 private String GetAttributeValue(XmlNode node, String attName)
272 XmlAttribute att = node.Attributes[attName];
274 return (att == null) ? String.Empty : att.Value.Trim();
277 private void AssertNodeName(XmlNode node, string expectedName)
279 if (!expectedName.Equals(node.Name))
281 String message = String.Format("Unexpected node under '{0}': Expected '{1}' but found '{2}'",
282 expectedName, expectedName, node.Name);
284 throw new ConfigurationErrorsException(message);