2 // System.Configuration.ConfigurationLocation.cs
5 // Duncan Mak (duncan@ximian.com)
6 // Lluis Sanchez Gual (lluis@novell.com)
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:
16 // The above copyright notice and this permission notice shall be
17 // included in all copies or substantial portions of the Software.
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
31 using System
.Collections
;
32 using System
.Collections
.Specialized
;
36 namespace System
.Configuration
{
38 public sealed class Configuration
41 Hashtable elementData
= new Hashtable ();
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
)
64 rootGroup
= parent
.rootGroup
;
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; }
86 public PathLevel ConfigurationPathLevel
{
87 get { throw new NotImplementedException (); }
91 public ConnectionStringsSection ConnectionStrings
{
92 get { throw new NotImplementedException (); }
96 public string FilePath
{
97 get { throw new NotImplementedException (); }
101 public bool HasFile
{
102 get { throw new NotImplementedException (); }
105 public ConfigurationLocationCollection Locations
{
107 if (locations
== null) locations
= new ConfigurationLocationCollection ();
114 get { throw new NotImplementedException (); }
117 public ConfigurationSectionGroup RootSectionGroup
{
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
);
151 public static Configuration
GetMachineConfiguration (string path
, string server
)
153 throw new NotImplementedException ();
157 public static Configuration
GetMachineConfiguration (
158 string path
, string server
, IntPtr user_token
)
160 throw new NotImplementedException ();
164 public static Configuration
GetMachineConfiguration (
165 string path
, string server
, string username
, string password
)
167 throw new NotImplementedException ();
171 public static Configuration
GetWebConfiguration ()
173 throw new NotImplementedException ();
177 public static Configuration
GetWebConfiguration (string path
)
179 return new Configuration (path
, GetMachineConfiguration ());
183 public static Configuration
GetWebConfiguration (string path
, string site
)
185 throw new NotImplementedException ();
189 public static Configuration
GetWebConfiguration (string path
, string site
, string subpath
)
191 throw new NotImplementedException ();
195 public static Configuration
GetWebConfiguration (
196 string path
, string site
, string subpath
, string server
)
198 throw new NotImplementedException ();
202 public static Configuration
GetWebConfiguration (
203 string path
, string site
, string subpath
, string server
, IntPtr user_token
)
205 throw new NotImplementedException ();
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 ();
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);
234 XmlTextReader r
= new XmlTextReader (new StringReader (data
as string));
235 sec
.ReadXml (r
, this);
239 elementData
[config
] = sec
;
243 internal ConfigurationSectionGroup
GetSectionGroupInstance (SectionGroupInfo
group)
245 ConfigurationSectionGroup gr
= group.CreateInstance () as ConfigurationSectionGroup
;
246 if (gr
!= null) gr
.Initialize (this, group);
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
;
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
;
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
;
311 tw
.WriteStartElement ("configuration");
312 if (rootGroup
.HasConfigContent (this)) {
313 rootGroup
.WriteConfig (this, tw
, mode
);
315 rootGroup
.WriteRootData (tw
, this, mode
);
316 tw
.WriteEndElement ();
323 internal bool Load (string fileName
)
325 this.fileName
= fileName
;
326 if (!File
.Exists (fileName
))
327 throw new ConfigurationException ("File '" + fileName
+ "' not found");
329 XmlTextReader reader
= null;
332 FileStream fs
= new FileStream (fileName
, FileMode
.Open
, FileAccess
.Read
);
333 reader
= new XmlTextReader (fs
);
334 ReadConfigFile (reader
, fileName
);
335 /* } catch (ConfigurationException) {
337 } catch (Exception e) {
338 throw new ConfigurationException ("Error reading " + fileName, e);
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
) {
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);
378 private void ThrowException (string text
, XmlTextReader reader
)
380 throw new ConfigurationException (text
, fileName
, reader
.LineNumber
);