**** Merged from MCS ****
[mono-project.git] / mcs / class / System / System.Configuration / Configuration.cs
blobf2e0a326536d70b4228e4b4bb18691ca3c22f728
1 //
2 // System.Configuration.ConfigurationLocation.cs
3 //
4 // Authors:
5 // Duncan Mak (duncan@ximian.com)
6 // Lluis Sanchez Gual (lluis@novell.com)
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining
9 // a copy of this software and associated documentation files (the
10 // "Software"), to deal in the Software without restriction, including
11 // without limitation the rights to use, copy, modify, merge, publish,
12 // distribute, sublicense, and/or sell copies of the Software, and to
13 // permit persons to whom the Software is furnished to do so, subject to
14 // the following conditions:
15 //
16 // The above copyright notice and this permission notice shall be
17 // included in all copies or substantial portions of the Software.
18 //
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
29 #if NET_2_0 && XML_DEP
30 using System;
31 using System.Collections;
32 using System.Collections.Specialized;
33 using System.Xml;
34 using System.IO;
36 namespace System.Configuration {
38 public sealed class Configuration
40 Configuration parent;
41 Hashtable elementData = new Hashtable ();
42 string fileName;
43 ConfigurationSectionGroup rootSectionGroup;
44 ConfigurationLocationCollection locations;
45 SectionGroupInfo rootGroup;
47 internal Configuration (): this (null, null)
51 internal Configuration (string file): this (file, null)
55 internal Configuration (Configuration parent): this (null, parent)
59 internal Configuration (string file, Configuration parent)
61 fileName = file;
62 this.parent = parent;
63 if (parent != null)
64 rootGroup = parent.rootGroup;
65 else {
66 rootGroup = new SectionGroupInfo ();
67 rootGroup.FileName = file;
70 if (file != null) Load (file);
73 internal Configuration Parent {
74 get { return parent; }
77 internal string FileName {
78 get { return fileName; }
81 public AppSettingsSection AppSettings {
82 get { return Sections ["appSettings"] as AppSettingsSection; }
85 [MonoTODO]
86 public PathLevel ConfigurationPathLevel {
87 get { throw new NotImplementedException (); }
90 [MonoTODO]
91 public ConnectionStringsSection ConnectionStrings {
92 get { throw new NotImplementedException (); }
95 [MonoTODO]
96 public string FilePath {
97 get { throw new NotImplementedException (); }
100 [MonoTODO]
101 public bool HasFile {
102 get { throw new NotImplementedException (); }
105 public ConfigurationLocationCollection Locations {
106 get {
107 if (locations == null) locations = new ConfigurationLocationCollection ();
108 return locations;
112 [MonoTODO]
113 public string Path {
114 get { throw new NotImplementedException (); }
117 public ConfigurationSectionGroup RootSectionGroup {
118 get {
119 if (rootSectionGroup == null) {
120 rootSectionGroup = new ConfigurationSectionGroup ();
121 rootSectionGroup.Initialize (this, rootGroup);
123 return rootSectionGroup;
127 public ConfigurationSectionGroupCollection SectionGroups {
128 get { return RootSectionGroup.SectionGroups; }
131 public ConfigurationSectionCollection Sections {
132 get { return RootSectionGroup.Sections; }
135 public static Configuration GetExeConfiguration (string path, ConfigurationUserLevel level)
137 return new Configuration (path + ".config", GetMachineConfiguration ());
140 public static Configuration GetMachineConfiguration ()
142 return GetMachineConfiguration (System.Runtime.InteropServices.RuntimeEnvironment.SystemConfigurationFile);
145 public static Configuration GetMachineConfiguration (string path)
147 return new Configuration (path);
150 [MonoTODO]
151 public static Configuration GetMachineConfiguration (string path, string server)
153 throw new NotImplementedException ();
156 [MonoTODO]
157 public static Configuration GetMachineConfiguration (
158 string path, string server, IntPtr user_token)
160 throw new NotImplementedException ();
163 [MonoTODO]
164 public static Configuration GetMachineConfiguration (
165 string path, string server, string username, string password)
167 throw new NotImplementedException ();
170 [MonoTODO]
171 public static Configuration GetWebConfiguration ()
173 throw new NotImplementedException ();
176 [MonoTODO]
177 public static Configuration GetWebConfiguration (string path)
179 return new Configuration (path, GetMachineConfiguration ());
182 [MonoTODO]
183 public static Configuration GetWebConfiguration (string path, string site)
185 throw new NotImplementedException ();
188 [MonoTODO]
189 public static Configuration GetWebConfiguration (string path, string site, string subpath)
191 throw new NotImplementedException ();
194 [MonoTODO]
195 public static Configuration GetWebConfiguration (
196 string path, string site, string subpath, string server)
198 throw new NotImplementedException ();
201 [MonoTODO]
202 public static Configuration GetWebConfiguration (
203 string path, string site, string subpath, string server, IntPtr user_token)
205 throw new NotImplementedException ();
208 [MonoTODO]
209 public static Configuration GetWebConfiguration (
210 string path, string site, string subpath, string server, string username, string password)
212 throw new NotImplementedException ();
215 internal ConfigurationSection GetSectionInstance (SectionInfo config, bool createDefaultInstance)
217 object data = elementData [config];
218 ConfigurationSection sec = data as ConfigurationSection;
219 if (sec != null || !createDefaultInstance) return sec;
221 object secObj = config.CreateInstance () as ConfigurationSection;
222 if (!(secObj is ConfigurationSection))
223 sec = new RuntimeOnlySection ();
224 else {
225 sec = (ConfigurationSection) secObj;
228 ConfigurationSection parentSection = parent != null ? parent.GetSectionInstance (config, true) : null;
229 sec.RawXml = data as string;
230 sec.SetPath (config.XPath);
231 sec.Reset (parentSection, this);
233 if (data != null) {
234 XmlTextReader r = new XmlTextReader (new StringReader (data as string));
235 sec.ReadXml (r, this);
236 r.Close ();
239 elementData [config] = sec;
240 return sec;
243 internal ConfigurationSectionGroup GetSectionGroupInstance (SectionGroupInfo group)
245 ConfigurationSectionGroup gr = group.CreateInstance () as ConfigurationSectionGroup;
246 if (gr != null) gr.Initialize (this, group);
247 return gr;
250 internal void SetConfigurationSection (SectionInfo config, ConfigurationSection sec)
252 elementData [config] = sec;
255 internal void SetSectionXml (SectionInfo config, string data)
257 elementData [config] = data;
260 internal string GetSectionXml (SectionInfo config)
262 return elementData [config] as string;
265 internal void CreateSection (SectionGroupInfo group, string name, ConfigurationSection sec)
267 if (group.HasChild (name)) throw new ConfigurationException ("Cannot add a ConfigurationSection. A section or section group already exists with the name '" + name + "'");
268 if (sec.TypeName == null) sec.TypeName = sec.GetType ().AssemblyQualifiedName;
269 sec.SetName (name);
271 SectionInfo section = new SectionInfo (name, sec.TypeName, sec.AllowLocation, sec.AllowDefinition);
272 section.FileName = FileName;
273 group.AddChild (section);
274 elementData [section] = sec;
275 sec.SetPath (section.XPath);
278 internal void CreateSectionGroup (SectionGroupInfo parentGroup, string name, ConfigurationSectionGroup sec)
280 if (parentGroup.HasChild (name)) throw new ConfigurationException ("Cannot add a ConfigurationSectionGroup. A section or section group already exists with the name '" + name + "'");
281 if (sec.TypeName == null) sec.TypeName = sec.GetType ().AssemblyQualifiedName;
282 sec.SetName (name);
284 SectionGroupInfo section = new SectionGroupInfo (name, sec.TypeName);
285 section.FileName = FileName;
286 parentGroup.AddChild (section);
287 elementData [section] = sec;
290 internal void RemoveConfigInfo (ConfigInfo config)
292 elementData.Remove (config);
295 public void Update ()
297 Update (ConfigurationUpdateMode.Modified, false);
300 public void Update (ConfigurationUpdateMode mode)
302 Update (mode, false);
305 [MonoTODO ("Detect if file has changed")]
306 public void Update (ConfigurationUpdateMode mode, bool forceUpdateAll)
308 XmlTextWriter tw = new XmlTextWriter (new StreamWriter (fileName));
309 tw.Formatting = Formatting.Indented;
310 try {
311 tw.WriteStartElement ("configuration");
312 if (rootGroup.HasConfigContent (this)) {
313 rootGroup.WriteConfig (this, tw, mode);
315 rootGroup.WriteRootData (tw, this, mode);
316 tw.WriteEndElement ();
318 finally {
319 tw.Close ();
323 internal bool Load (string fileName)
325 this.fileName = fileName;
326 if (!File.Exists (fileName))
327 throw new ConfigurationException ("File '" + fileName + "' not found");
328 #if (XML_DEP)
329 XmlTextReader reader = null;
331 try {
332 FileStream fs = new FileStream (fileName, FileMode.Open, FileAccess.Read);
333 reader = new XmlTextReader (fs);
334 ReadConfigFile (reader, fileName);
335 /* } catch (ConfigurationException) {
336 throw;
337 } catch (Exception e) {
338 throw new ConfigurationException ("Error reading " + fileName, e);
339 */ } finally {
340 if (reader != null)
341 reader.Close();
343 #endif
344 return true;
347 #if (XML_DEP)
349 internal void ReadConfigFile (XmlTextReader reader, string fileName)
351 reader.MoveToContent ();
352 if (reader.NodeType != XmlNodeType.Element || reader.Name != "configuration")
353 ThrowException ("Configuration file does not have a valid root element", reader);
355 if (reader.HasAttributes)
356 ThrowException ("Unrecognized attribute in root element", reader);
358 if (reader.IsEmptyElement) {
359 reader.Skip ();
360 return;
363 reader.ReadStartElement ();
364 reader.MoveToContent ();
366 if (reader.LocalName == "configSections") {
367 if (reader.HasAttributes)
368 ThrowException ("Unrecognized attribute in <configSections>.", reader);
370 rootGroup.ReadConfig (this, reader);
373 rootGroup.ReadRootData (reader, this);
376 #endif
378 private void ThrowException (string text, XmlTextReader reader)
380 throw new ConfigurationException (text, fileName, reader.LineNumber);
385 #endif