2 // System.Configuration.SectionGroupInfo.cs
5 // Lluis Sanchez (lluis@novell.com)
7 // Permission is hereby granted, free of charge, to any person obtaining
8 // a copy of this software and associated documentation files (the
9 // "Software"), to deal in the Software without restriction, including
10 // without limitation the rights to use, copy, modify, merge, publish,
11 // distribute, sublicense, and/or sell copies of the Software, and to
12 // permit persons to whom the Software is furnished to do so, subject to
13 // the following conditions:
15 // The above copyright notice and this permission notice shall be
16 // included in all copies or substantial portions of the Software.
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
28 #if NET_2_0 && XML_DEP
30 using System.Collections;
31 using System.Collections.Specialized;
35 namespace System.Configuration
37 internal class SectionGroupInfo: ConfigInfo
39 ConfigInfoCollection sections;
40 ConfigInfoCollection groups;
41 static ConfigInfoCollection emptyList = new ConfigInfoCollection ();
43 public SectionGroupInfo ()
45 TypeName = "System.Configuration.ConfigurationSectionGroup";
48 public SectionGroupInfo (string groupName, string typeName)
54 public void AddChild (ConfigInfo data)
57 if (data is SectionInfo) {
58 if (sections == null) sections = new ConfigInfoCollection ();
59 sections [data.Name] = data;
62 if (groups == null) groups = new ConfigInfoCollection ();
63 groups [data.Name] = data;
69 if (sections != null) sections.Clear ();
70 if (groups != null) groups.Clear ();
73 public bool HasChild (string name)
75 if (sections != null && sections [name] != null) return true;
76 return (groups != null && groups [name] != null);
79 public void RemoveChild (string name)
82 sections.Remove (name);
87 public SectionInfo GetChildSection (string name)
90 return sections [name] as SectionInfo;
95 public SectionGroupInfo GetChildGroup (string name)
98 return groups [name] as SectionGroupInfo;
103 public ConfigInfoCollection Sections
105 get { if (sections == null) return emptyList; else return sections; }
108 public ConfigInfoCollection Groups
110 get { if (groups == null) return emptyList; else return groups; }
113 public override bool HasDataContent (Configuration config)
115 foreach (ConfigInfoCollection col in new object[] {Sections, Groups}) {
116 foreach (string key in col) {
117 ConfigInfo cinfo = col [key];
118 if (cinfo.HasDataContent (config))
125 public override bool HasConfigContent (Configuration cfg)
127 if (FileName == cfg.FileName) return true;
128 foreach (ConfigInfoCollection col in new object[] {Sections, Groups}) {
129 foreach (string key in col) {
130 ConfigInfo cinfo = col [key];
131 if (cinfo.HasConfigContent (cfg))
140 public override void ReadConfig (Configuration cfg, XmlTextReader reader)
142 FileName = cfg.FileName;
144 if (reader.LocalName != "configSections")
146 while (reader.MoveToNextAttribute ()) {
147 if (reader.Name == "name")
149 else if (reader.Name == "type")
150 TypeName = reader.Value;
152 ThrowException ("Unrecognized attribute", reader);
156 ThrowException ("sectionGroup must have a 'name' attribute", reader);
158 if (Name == "location")
159 ThrowException ("location is a reserved section name", reader);
162 if (TypeName == null)
163 TypeName = "System.Configuration.ConfigurationSectionGroup";
165 if (reader.IsEmptyElement) {
170 reader.ReadStartElement ();
171 reader.MoveToContent ();
173 while (reader.NodeType != XmlNodeType.EndElement)
175 if (reader.NodeType != XmlNodeType.Element) {
180 string name = reader.LocalName;
181 ConfigInfo cinfo = null;
183 if (name == "remove") {
184 ReadRemoveSection (reader);
188 if (name == "clear") {
189 if (reader.HasAttributes)
190 ThrowException ("Unrecognized attribute.", reader);
197 if (name == "section")
198 cinfo = new SectionInfo ();
199 else if (name == "sectionGroup")
200 cinfo = new SectionGroupInfo ();
202 ThrowException ("Unrecognized element: " + reader.Name, reader);
204 cinfo.ReadConfig (cfg, reader);
205 ConfigInfo actInfo = Groups [cinfo.Name];
206 if (actInfo == null) actInfo = Sections [cinfo.Name];
208 if (actInfo != null) {
209 if (actInfo.GetType () != cinfo.GetType ())
210 ThrowException ("A section or section group named '" + cinfo.Name + "' already exists", reader);
211 // Make sure that this section is saved in this configuration file:
212 actInfo.FileName = cfg.FileName;
218 reader.ReadEndElement ();
221 public override void WriteConfig (Configuration cfg, XmlWriter writer, ConfigurationUpdateMode mode)
224 writer.WriteStartElement ("sectionGroup");
225 writer.WriteAttributeString ("name", Name);
226 if (TypeName != null && TypeName != "" && TypeName != "System.Configuration.ConfigurationSectionGroup")
227 writer.WriteAttributeString ("type", TypeName);
230 writer.WriteStartElement ("configSections");
232 foreach (ConfigInfoCollection col in new object[] {Sections, Groups}) {
233 foreach (string key in col) {
234 ConfigInfo cinfo = col [key];
235 if (cinfo.HasConfigContent (cfg))
236 cinfo.WriteConfig (cfg, writer, mode);
240 writer.WriteEndElement ();
243 private void ReadRemoveSection (XmlTextReader reader)
245 if (!reader.MoveToNextAttribute () || reader.Name != "name")
246 ThrowException ("Unrecognized attribute.", reader);
248 string removeValue = reader.Value;
249 if (removeValue == null || removeValue.Length == 0)
250 ThrowException ("Empty name to remove", reader);
252 reader.MoveToElement ();
254 if (!HasChild (removeValue))
255 ThrowException ("No factory for " + removeValue, reader);
257 RemoveChild (removeValue);
261 public void ReadRootData (XmlTextReader reader, Configuration config)
263 reader.MoveToContent ();
264 ReadContent (reader, config);
267 public override void ReadData (Configuration config, XmlTextReader reader)
269 reader.MoveToContent ();
270 reader.ReadStartElement ();
271 ReadContent (reader, config);
272 reader.MoveToContent ();
273 reader.ReadEndElement ();
276 void ReadContent (XmlTextReader reader, Configuration config)
278 while (reader.NodeType != XmlNodeType.EndElement) {
279 if (reader.NodeType != XmlNodeType.Element) {
283 if (reader.LocalName == "location") {
284 Configuration locConfig = new Configuration (config);
285 string path = reader.GetAttribute ("path");
286 ConfigurationLocation loc = new ConfigurationLocation (path, locConfig);
287 config.Locations.Add (loc);
288 ReadData (locConfig, reader);
291 ConfigInfo data = (sections != null) ? (ConfigInfo) sections [reader.LocalName] : (ConfigInfo) null;
292 if (data == null) data = (groups != null) ? (ConfigInfo) groups [reader.LocalName] : (ConfigInfo) null;
295 data.ReadData (config, reader);
297 ThrowException ("Unrecognized configuration section <" + reader.LocalName + ">", reader);
301 public void WriteRootData (XmlWriter writer, Configuration config, ConfigurationUpdateMode mode)
303 WriteContent (writer, config, mode, false);
306 public override void WriteData (Configuration config, XmlWriter writer, ConfigurationUpdateMode mode)
308 writer.WriteStartElement (Name);
309 WriteContent (writer, config, mode, true);
310 writer.WriteEndElement ();
313 public void WriteContent (XmlWriter writer, Configuration config, ConfigurationUpdateMode mode, bool writeElem)
315 foreach (ConfigInfoCollection col in new object[] {Sections, Groups}) {
316 foreach (string key in col) {
317 ConfigInfo cinfo = col [key];
318 if (cinfo.HasDataContent (config))
319 cinfo.WriteData (config, writer, mode);
326 internal class ConfigInfoCollection : NameObjectCollectionBase
328 public ICollection AllKeys
333 public ConfigInfo this [string name]
335 get { return (ConfigInfo) BaseGet (name); }
336 set { BaseSet (name, value); }
339 public ConfigInfo this [int index]
341 get { return (ConfigInfo) BaseGet (index); }
342 set { BaseSet (index, value); }
345 public void Add (string name, ConfigInfo config)
347 BaseAdd (name, config);
355 public string GetKey (int index)
357 return BaseGetKey (index);
360 public void Remove (string name)
365 public void RemoveAt (int index)
367 BaseRemoveAt (index);