2 // System.Web.Configuration.WebConfigurationManager.cs
5 // Lluis Sanchez Gual (lluis@novell.com)
6 // Chris Toshok (toshok@ximian.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) 2005 Novell, Inc (http://www.novell.com)
34 using System.Collections;
35 using System.Collections.Specialized;
36 using System.Reflection;
38 using System.Configuration;
39 using System.Configuration.Internal;
40 using _Configuration = System.Configuration.Configuration;
42 namespace System.Web.Configuration {
44 public static class WebConfigurationManager
47 static IInternalConfigConfigurationFactory configFactory;
48 static Hashtable configurations = new Hashtable ();
50 static internal IInternalConfigConfigurationFactory configFactory
53 IInternalConfigConfigurationFactory factory = (IInternalConfigConfigurationFactory)AppDomain.CurrentDomain.GetData("WebConfigurationManager.configFactory");
55 lock (AppDomain.CurrentDomain){
56 object initialized = AppDomain.CurrentDomain.GetData("WebConfigurationManager.configFactory.initialized");
57 if (initialized == null){
58 PropertyInfo prop = typeof(ConfigurationManager).GetProperty("ConfigurationFactory", BindingFlags.Static | BindingFlags.NonPublic);
60 factory = prop.GetValue(null, null) as IInternalConfigConfigurationFactory;
61 configFactory = factory;
66 return factory != null ? factory : configFactory;
69 AppDomain.CurrentDomain.SetData("WebConfigurationManager.configFactory", value);
70 AppDomain.CurrentDomain.SetData("WebConfigurationManager.configFactory.initialized", true);
74 static internal Hashtable configurations
77 Hashtable table = (Hashtable)AppDomain.CurrentDomain.GetData("WebConfigurationManager.configurations");
79 lock (AppDomain.CurrentDomain){
80 object initialized = AppDomain.CurrentDomain.GetData("WebConfigurationManager.configurations.initialized");
81 if (initialized == null){
82 table = new Hashtable();
83 configurations = table;
87 return table != null ? table : configurations;
91 AppDomain.CurrentDomain.SetData("WebConfigurationManager.configurations", value);
92 AppDomain.CurrentDomain.SetData("WebConfigurationManager.configurations.initialized", true);
97 static WebConfigurationManager ()
99 PropertyInfo prop = typeof(ConfigurationManager).GetProperty ("ConfigurationFactory", BindingFlags.Static | BindingFlags.NonPublic);
101 configFactory = prop.GetValue (null, null) as IInternalConfigConfigurationFactory;
104 public static _Configuration OpenMachineConfiguration ()
106 return ConfigurationManager.OpenMachineConfiguration ();
109 [MonoTODO ("need to handle locationSubPath")]
110 public static _Configuration OpenMachineConfiguration (string locationSubPath)
112 return OpenMachineConfiguration ();
116 public static _Configuration OpenMachineConfiguration (string locationSubPath,
120 return OpenMachineConfiguration (locationSubPath);
122 throw new NotSupportedException ("Mono doesn't support remote configuration");
126 public static _Configuration OpenMachineConfiguration (string locationSubPath,
131 return OpenMachineConfiguration (locationSubPath);
132 throw new NotSupportedException ("Mono doesn't support remote configuration");
136 public static _Configuration OpenMachineConfiguration (string locationSubPath,
142 return OpenMachineConfiguration (locationSubPath);
143 throw new NotSupportedException ("Mono doesn't support remote configuration");
146 public static _Configuration OpenWebConfiguration (string path)
148 return OpenWebConfiguration (path, null, null, null, null, null);
151 public static _Configuration OpenWebConfiguration (string path, string site)
153 return OpenWebConfiguration (path, site, null, null, null, null);
156 public static _Configuration OpenWebConfiguration (string path, string site, string locationSubPath)
158 return OpenWebConfiguration (path, site, locationSubPath, null, null, null);
162 public static _Configuration OpenWebConfiguration (string path, string site, string locationSubPath, string server)
164 throw new NotImplementedException ();
167 public static _Configuration OpenWebConfiguration (string path, string site, string locationSubPath, string server, IntPtr userToken)
169 return OpenWebConfiguration (path, site, locationSubPath, server, null, null);
173 public static _Configuration OpenWebConfiguration (string path, string site, string locationSubPath, string server, string userName, string password)
178 string basePath = GetBasePath (path);
182 lock (configurations) {
183 conf = (_Configuration) configurations [basePath];
185 conf = ConfigurationFactory.Create (typeof(WebConfigurationHost), null, basePath, site, locationSubPath, server, userName, password);
186 configurations [basePath] = conf;
189 if (basePath.Length < path.Length) {
191 // If the path has a file name, look for a location specific configuration
193 int dif = path.Length - basePath.Length;
194 string file = path.Substring (path.Length - dif);
196 while (i < file.Length && file [i] == '/')
199 file = file.Substring (i);
201 if (file.Length != 0) {
202 foreach (ConfigurationLocation loc in conf.Locations) {
203 if (loc.Path == file)
204 return loc.OpenConfiguration ();
211 public static _Configuration OpenMappedWebConfiguration (WebConfigurationFileMap fileMap, string path)
213 return ConfigurationFactory.Create (typeof(WebConfigurationHost), fileMap, path);
216 [MonoTODO ("Do something with the extra parameters")]
217 public static _Configuration OpenMappedWebConfiguration (WebConfigurationFileMap fileMap, string path, string site)
219 return ConfigurationFactory.Create (typeof(WebConfigurationHost), fileMap, path, site);
222 [MonoTODO ("Do something with the extra parameters")]
223 public static _Configuration OpenMappedWebConfiguration (WebConfigurationFileMap fileMap, string path, string site, string locationSubPath)
225 return ConfigurationFactory.Create (typeof(WebConfigurationHost), fileMap, path, site, locationSubPath);
228 public static _Configuration OpenMappedMachineConfiguration (ConfigurationFileMap fileMap)
230 return ConfigurationFactory.Create (typeof(WebConfigurationHost), fileMap);
233 [MonoTODO ("need to handle locationSubPath")]
234 public static _Configuration OpenMappedMachineConfiguration (ConfigurationFileMap fileMap,
235 string locationSubPath)
237 return OpenMappedMachineConfiguration (fileMap);
240 public static object GetSection (string sectionName)
243 if (HttpContext.Current != null
244 && HttpContext.Current.Request != null)
245 c = OpenWebConfiguration (HttpContext.Current.Request.Path);
247 c = OpenWebConfiguration (HttpRuntime.AppDomainAppVirtualPath);
252 return c.GetSection (sectionName);
256 public static object GetSection (string sectionName, string path)
259 _Configuration c = OpenWebConfiguration (path);
260 return c.GetSection (sectionName);
267 static _Configuration GetWebApplicationConfiguration ()
269 _Configuration config;
271 if (HttpContext.Current == null
272 || HttpContext.Current.Request == null
273 || HttpContext.Current.Request.ApplicationPath == null
274 || HttpContext.Current.Request.ApplicationPath == "") {
275 config = OpenWebConfiguration ("");
278 config = OpenWebConfiguration (HttpContext.Current.Request.ApplicationPath);
284 static MethodInfo get_runtime_object = typeof (ConfigurationSection).GetMethod ("GetRuntimeObject", BindingFlags.NonPublic | BindingFlags.Instance);
287 public static object GetWebApplicationSection (string sectionName)
289 _Configuration config = GetWebApplicationConfiguration ();
291 ConfigurationSection section = config.GetSection (sectionName);
293 return get_runtime_object.Invoke (section, new object [0]);
296 public static NameValueCollection AppSettings {
297 get { return ConfigurationManager.AppSettings; }
300 public static ConnectionStringSettingsCollection ConnectionStrings {
301 get { return ConfigurationManager.ConnectionStrings; }
304 internal static IInternalConfigConfigurationFactory ConfigurationFactory {
305 get { return configFactory; }
308 static string GetBasePath (string path)
310 if (path == "/" || path == "")
313 /* first if we can, map it to a physical path
314 * to see if it corresponds to a file */
315 if (HttpContext.Current != null
316 && HttpContext.Current.Request != null) {
317 string pd = HttpContext.Current.Request.MapPath (path);
319 if (!Directory.Exists (pd)) {
320 /* if it does, remove the file from the url */
321 int i = path.LastIndexOf ('/');
322 path = path.Substring (0, i);
326 if (path.Length == 0)
329 /* remove excess /'s from the end of the virtual path */
330 while (path [path.Length - 1] == '/')
331 path = path.Substring (0, path.Length - 1);
337 #region stuff copied from WebConfigurationSettings
339 static internal IConfigurationSystem oldConfig {
341 return (IConfigurationSystem)AppDomain.CurrentDomain.GetData("WebConfigurationManager.oldConfig");
344 AppDomain.CurrentDomain.SetData("WebConfigurationManager.oldConfig", value);
348 static private Web20DefaultConfig config {
350 return (Web20DefaultConfig) AppDomain.CurrentDomain.GetData ("Web20DefaultConfig.config");
353 AppDomain.CurrentDomain.SetData ("Web20DefaultConfig.config", value);
357 static private IInternalConfigSystem configSystem {
359 return (IInternalConfigSystem) AppDomain.CurrentDomain.GetData ("IInternalConfigSystem.configSystem");
362 AppDomain.CurrentDomain.SetData ("IInternalConfigSystem.configSystem", value);
366 static internal IConfigurationSystem oldConfig;
367 static Web20DefaultConfig config;
368 static IInternalConfigSystem configSystem;
370 const BindingFlags privStatic = BindingFlags.NonPublic | BindingFlags.Static;
371 static readonly object lockobj = new object ();
373 internal static void Init ()
379 /* deal with the ConfigurationSettings stuff */
381 Web20DefaultConfig settings = Web20DefaultConfig.GetInstance ();
382 Type t = typeof (ConfigurationSettings);
383 MethodInfo changeConfig = t.GetMethod ("ChangeConfigurationSystem",
386 if (changeConfig == null)
387 throw new ConfigurationException ("Cannot find method CCS");
389 object [] args = new object [] {settings};
390 oldConfig = (IConfigurationSystem)changeConfig.Invoke (null, args);
396 /* deal with the ConfigurationManager stuff */
398 HttpConfigurationSystem system = new HttpConfigurationSystem ();
399 Type t = typeof (ConfigurationManager);
400 MethodInfo changeConfig = t.GetMethod ("ChangeConfigurationSystem",
403 if (changeConfig == null)
404 throw new ConfigurationException ("Cannot find method CCS");
406 object [] args = new object [] {system};
407 changeConfig.Invoke (null, args);
408 configSystem = system;
414 class Web20DefaultConfig : IConfigurationSystem
417 static private Web20DefaultConfig instance {
419 Web20DefaultConfig val = (Web20DefaultConfig)AppDomain.CurrentDomain.GetData("Web20DefaultConfig.instance");
421 val = new Web20DefaultConfig();
422 AppDomain.CurrentDomain.SetData("Web20DefaultConfig.instance", val);
427 AppDomain.CurrentDomain.SetData("Web20DefaultConfig.instance", value);
431 static Web20DefaultConfig instance;
434 static Web20DefaultConfig ()
436 instance = new Web20DefaultConfig ();
439 public static Web20DefaultConfig GetInstance ()
444 public object GetConfig (string sectionName)
446 object o = WebConfigurationManager.GetWebApplicationSection (sectionName);
448 if (o == null || o is IgnoreSection) {
449 /* this can happen when the section
450 * handler doesn't subclass from
451 * ConfigurationSection. let's be
452 * nice and try to load it using the
453 * 1.x style routines in case there's
454 * a 1.x section handler registered
457 object o1 = WebConfigurationManager.oldConfig.GetConfig (sectionName);
467 // nothing. We need a context.