return false;
}
- public override void ReadConfig (Configuration cfg, string streamName, XmlTextReader reader)
+ public override void ReadConfig (Configuration cfg, string streamName, XmlReader reader)
{
StreamName = streamName;
ConfigHost = cfg.ConfigHost;
if (name == "section")
cinfo = new SectionInfo ();
- else if (name == "sectionGroup")
+ else if (name == "sectionGroup") {
cinfo = new SectionGroupInfo ();
- else
+ } else
ThrowException ("Unrecognized element: " + reader.Name, reader);
cinfo.ReadConfig (cfg, streamName, reader);
if (actInfo != null) {
if (actInfo.GetType () != cinfo.GetType ())
ThrowException ("A section or section group named '" + cinfo.Name + "' already exists", reader);
+ // Merge all the new data
+ actInfo.Merge (cinfo);
+
// Make sure that this section is saved in this configuration file:
actInfo.StreamName = streamName;
}
writer.WriteEndElement ();
}
- private void ReadRemoveSection (XmlTextReader reader)
+ private void ReadRemoveSection (XmlReader reader)
{
if (!reader.MoveToNextAttribute () || reader.Name != "name")
ThrowException ("Unrecognized attribute.", reader);
string removeValue = reader.Value;
- if (removeValue == null || removeValue.Length == 0)
+ if (String.IsNullOrEmpty (removeValue))
ThrowException ("Empty name to remove", reader);
reader.MoveToElement ();
reader.Skip ();
}
- public void ReadRootData (XmlTextReader reader, Configuration config, bool overrideAllowed)
+ public void ReadRootData (XmlReader reader, Configuration config, bool overrideAllowed)
{
reader.MoveToContent ();
- ReadContent (reader, config, overrideAllowed);
+ ReadContent (reader, config, overrideAllowed, true);
}
- public override void ReadData (Configuration config, XmlTextReader reader, bool overrideAllowed)
+ public override void ReadData (Configuration config, XmlReader reader, bool overrideAllowed)
{
reader.MoveToContent ();
- reader.ReadStartElement ();
- ReadContent (reader, config, overrideAllowed);
- reader.MoveToContent ();
- reader.ReadEndElement ();
+ if (!reader.IsEmptyElement) {
+ reader.ReadStartElement ();
+ ReadContent (reader, config, overrideAllowed, false);
+ reader.MoveToContent ();
+ reader.ReadEndElement ();
+ } else
+ reader.Read ();
}
- void ReadContent (XmlTextReader reader, Configuration config, bool overrideAllowed)
+ void ReadContent (XmlReader reader, Configuration config, bool overrideAllowed, bool root)
{
- StringBuilder spacing = new StringBuilder ();
- while (reader.NodeType != XmlNodeType.EndElement) {
+ while (reader.NodeType != XmlNodeType.EndElement && reader.NodeType != XmlNodeType.None) {
if (reader.NodeType != XmlNodeType.Element) {
- if (reader.NodeType == XmlNodeType.Whitespace)
- spacing.Append (reader.Value);
reader.Skip ();
continue;
}
-
- if (reader.LocalName == "location")
- ThrowException ("<location> elements are only allowed in <configuration> elements.", reader);
-
- ConfigInfo data = (sections != null) ? (ConfigInfo) sections [reader.LocalName] : (ConfigInfo) null;
- if (data == null) data = (groups != null) ? (ConfigInfo) groups [reader.LocalName] : (ConfigInfo) null;
-
+
+ if (reader.LocalName == "dllmap") {
+ reader.Skip ();
+ continue;
+ }
+
+ if (reader.LocalName == "location") {
+ if (!root)
+ ThrowException ("<location> elements are only allowed in <configuration> elements.", reader);
+
+ string allowOverrideAttr = reader.GetAttribute ("allowOverride");
+ bool allowOverride = allowOverrideAttr == null || allowOverrideAttr.Length == 0 || bool.Parse (allowOverrideAttr);
+ string path = reader.GetAttribute ("path");
+ if (path != null && path.Length > 0) {
+ string xml = reader.ReadOuterXml ();
+ string[] pathList = path.Split (',');
+ string tpath;
+ foreach (string p in pathList) {
+ tpath = p.Trim ();
+ if (config.Locations.Find (tpath) != null)
+ ThrowException ("Sections must only appear once per config file.", reader);
+
+ ConfigurationLocation loc = new ConfigurationLocation (tpath, xml, config, allowOverride);
+ config.Locations.Add (loc);
+ }
+ } else {
+ ReadData (config, reader, allowOverride);
+ }
+ continue;
+ }
+
+ ConfigInfo data = GetConfigInfo (reader, this);
if (data != null)
data.ReadData (config, reader, overrideAllowed);
else
ThrowException ("Unrecognized configuration section <" + reader.LocalName + ">", reader);
}
}
+
+ ConfigInfo GetConfigInfo (XmlReader reader, SectionGroupInfo current)
+ {
+ ConfigInfo data = null;
+ if (current.sections != null)
+ data = current.sections [reader.LocalName];
+ if (data != null)
+ return data;
+ if (current.groups != null)
+ data = current.groups [reader.LocalName];
+ if (data != null)
+ return data;
+ if (current.groups == null)
+ return null;
+ // It might be a section in descendant sectionGroups
+ foreach (string key in current.groups.AllKeys) {
+ data = GetConfigInfo (reader, (SectionGroupInfo) current.groups [key]);
+ if (data != null)
+ return data;
+ }
+
+ // It might be in the root section group
+ return null;
+ }
+
+ internal override void Merge (ConfigInfo newData)
+ {
+ SectionGroupInfo data = newData as SectionGroupInfo;
+ if (data == null)
+ return;
+ ConfigInfo actInfo;
+ if (data.sections != null && data.sections.Count > 0)
+ foreach (string key in data.sections.AllKeys) {
+ actInfo = sections[key];
+ if (actInfo != null)
+ continue;
+ sections.Add (key, data.sections[key]);
+ }
+
+ if (data.groups != null && data.sections != null && data.sections.Count > 0)
+ foreach (string key in data.groups.AllKeys) {
+ actInfo = groups[key];
+ if (actInfo != null)
+ continue;
+ groups.Add (key, data.groups[key]);
+ }
+ }
public void WriteRootData (XmlWriter writer, Configuration config, ConfigurationSaveMode mode)
{
internal class ConfigInfoCollection : NameObjectCollectionBase
{
+ public ConfigInfoCollection ()
+ : base (StringComparer.Ordinal)
+ {
+ }
+
public ICollection AllKeys
{
get { return Keys; }