Moved TestConfiguration.cs to Npgsql.
[mono.git] / mcs / class / System.Web / System.Web.Configuration_2.0 / WebConfigurationManager.cs
1 //
2 // System.Web.Configuration.WebConfigurationManager.cs
3 //
4 // Authors:
5 //      Lluis Sanchez Gual (lluis@novell.com)
6 //      Chris Toshok (toshok@ximian.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.
26 //
27 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
28 //
29
30 #if NET_2_0
31
32 using System;
33 using System.IO;
34 using System.Collections;
35 using System.Collections.Specialized;
36 using System.Reflection;
37 using System.Xml;
38 using System.Configuration;
39 using System.Configuration.Internal;
40 using _Configuration = System.Configuration.Configuration;
41
42 namespace System.Web.Configuration {
43
44         public static class WebConfigurationManager
45         {
46 #if !TARGET_J2EE
47                 static IInternalConfigConfigurationFactory configFactory;
48                 static Hashtable configurations = new Hashtable ();
49 #else
50         static internal IInternalConfigConfigurationFactory configFactory
51         {
52             get{
53                 IInternalConfigConfigurationFactory factory = (IInternalConfigConfigurationFactory)AppDomain.CurrentDomain.GetData("WebConfigurationManager.configFactory");
54                 if (factory == null){
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);
59                             if (prop != null){
60                                 factory = prop.GetValue(null, null) as IInternalConfigConfigurationFactory;
61                                 configFactory = factory;
62                             }
63                         }
64                     }
65                 }
66                 return factory != null ? factory : configFactory;
67             }
68             set{
69                 AppDomain.CurrentDomain.SetData("WebConfigurationManager.configFactory", value);
70                 AppDomain.CurrentDomain.SetData("WebConfigurationManager.configFactory.initialized", true);
71             }
72         }
73
74         static internal Hashtable configurations
75         {
76             get{
77                 Hashtable table = (Hashtable)AppDomain.CurrentDomain.GetData("WebConfigurationManager.configurations");
78                 if (table == null){
79                     lock (AppDomain.CurrentDomain){
80                         object initialized = AppDomain.CurrentDomain.GetData("WebConfigurationManager.configurations.initialized");
81                         if (initialized == null){
82                             table = new Hashtable();
83                             configurations = table;
84                         }
85                     }
86                 }
87                 return table != null ? table : configurations;
88
89             }
90             set{
91                 AppDomain.CurrentDomain.SetData("WebConfigurationManager.configurations", value);
92                 AppDomain.CurrentDomain.SetData("WebConfigurationManager.configurations.initialized", true);
93             }
94         }
95 #endif
96                 
97                 static WebConfigurationManager ()
98                 {
99                         PropertyInfo prop = typeof(ConfigurationManager).GetProperty ("ConfigurationFactory", BindingFlags.Static | BindingFlags.NonPublic);
100                         if (prop != null)
101                                 configFactory = prop.GetValue (null, null) as IInternalConfigConfigurationFactory;
102                 }
103
104                 public static _Configuration OpenMachineConfiguration ()
105                 {
106                         return ConfigurationManager.OpenMachineConfiguration ();
107                 }
108                 
109                 [MonoTODO ("need to handle locationSubPath")]
110                 public static _Configuration OpenMachineConfiguration (string locationSubPath)
111                 {
112                         return OpenMachineConfiguration ();
113                 }
114
115                 [MonoTODO]
116                 public static _Configuration OpenMachineConfiguration (string locationSubPath,
117                                                                        string server)
118                 {
119                         if (server == null)
120                                 return OpenMachineConfiguration (locationSubPath);
121
122                         throw new NotSupportedException ("Mono doesn't support remote configuration");
123                 }
124
125                 [MonoTODO]
126                 public static _Configuration OpenMachineConfiguration (string locationSubPath,
127                                                                        string server,
128                                                                        IntPtr userToken)
129                 {
130                         if (server == null)
131                                 return OpenMachineConfiguration (locationSubPath);
132                         throw new NotSupportedException ("Mono doesn't support remote configuration");
133                 }
134
135                 [MonoTODO]
136                 public static _Configuration OpenMachineConfiguration (string locationSubPath,
137                                                                        string server,
138                                                                        string userName,
139                                                                        string password)
140                 {
141                         if (server == null)
142                                 return OpenMachineConfiguration (locationSubPath);
143                         throw new NotSupportedException ("Mono doesn't support remote configuration");
144                 }
145
146                 public static _Configuration OpenWebConfiguration (string path)
147                 {
148                         return OpenWebConfiguration (path, null, null, null, null, null);
149                 }
150                 
151                 public static _Configuration OpenWebConfiguration (string path, string site)
152                 {
153                         return OpenWebConfiguration (path, site, null, null, null, null);
154                 }
155                 
156                 public static _Configuration OpenWebConfiguration (string path, string site, string locationSubPath)
157                 {
158                         return OpenWebConfiguration (path, site, locationSubPath, null, null, null);
159                 }
160
161                 [MonoTODO]
162                 public static _Configuration OpenWebConfiguration (string path, string site, string locationSubPath, string server)
163                 {
164                         throw new NotImplementedException ();
165                 }
166
167                 public static _Configuration OpenWebConfiguration (string path, string site, string locationSubPath, string server, IntPtr userToken)
168                 {
169                         return OpenWebConfiguration (path, site, locationSubPath, server, null, null);
170                 }
171                 
172                 [MonoTODO]
173                 public static _Configuration OpenWebConfiguration (string path, string site, string locationSubPath, string server, string userName, string password)
174                 {
175                         if (path == null)
176                                 path = "";
177
178                         string basePath = GetBasePath (path);
179                         _Configuration conf;
180
181                         
182                         lock (configurations) {
183                                 conf = (_Configuration) configurations [basePath];
184                                 if (conf == null) {
185                                         conf = ConfigurationFactory.Create (typeof(WebConfigurationHost), null, basePath, site, locationSubPath, server, userName, password);
186                                         configurations [basePath] = conf;
187                                 }
188                         }
189                         if (basePath.Length < path.Length) {
190                         
191                                 // If the path has a file name, look for a location specific configuration
192                                 
193                                 int dif = path.Length - basePath.Length;
194                                 string file = path.Substring (path.Length - dif);
195                                 int i=0;
196                                 while (i < file.Length && file [i] == '/')
197                                         i++;
198                                 if (i != 0)
199                                         file = file.Substring (i);
200
201                                 if (file.Length != 0) {
202                                         foreach (ConfigurationLocation loc in conf.Locations) {
203                                                 if (loc.Path == file)
204                                                         return loc.OpenConfiguration ();
205                                         }
206                                 }
207                         }
208                         return conf;
209                 }
210
211                 public static _Configuration OpenMappedWebConfiguration (WebConfigurationFileMap fileMap, string path)
212                 {
213                         return ConfigurationFactory.Create (typeof(WebConfigurationHost), fileMap, path);
214                 }
215                 
216                 [MonoTODO ("Do something with the extra parameters")]
217                 public static _Configuration OpenMappedWebConfiguration (WebConfigurationFileMap fileMap, string path, string site)
218                 {
219                         return ConfigurationFactory.Create (typeof(WebConfigurationHost), fileMap, path, site);
220                 }
221                 
222                 [MonoTODO ("Do something with the extra parameters")]
223                 public static _Configuration OpenMappedWebConfiguration (WebConfigurationFileMap fileMap, string path, string site, string locationSubPath)
224                 {
225                         return ConfigurationFactory.Create (typeof(WebConfigurationHost), fileMap, path, site, locationSubPath);
226                 }
227                 
228                 public static _Configuration OpenMappedMachineConfiguration (ConfigurationFileMap fileMap)
229                 {
230                         return ConfigurationFactory.Create (typeof(WebConfigurationHost), fileMap);
231                 }
232
233                 [MonoTODO ("need to handle locationSubPath")]
234                 public static _Configuration OpenMappedMachineConfiguration (ConfigurationFileMap fileMap,
235                                                                              string locationSubPath)
236                 {
237                         return OpenMappedMachineConfiguration (fileMap);
238                 }
239
240                 public static object GetSection (string sectionName)
241                 {
242                         _Configuration c;
243                         if (HttpContext.Current != null
244                             && HttpContext.Current.Request != null)
245                                 c = OpenWebConfiguration (HttpContext.Current.Request.Path);
246                         else
247                                 c = OpenWebConfiguration (HttpRuntime.AppDomainAppVirtualPath);
248
249                         if (c == null)
250                                 return null;
251                         else
252                                 return c.GetSection (sectionName);
253                 }
254
255                 [MonoTODO]
256                 public static object GetSection (string sectionName, string path)
257                 {
258                         try {
259                                 _Configuration c = OpenWebConfiguration (path);
260                                 return c.GetSection (sectionName);
261                         }
262                         catch {
263                                 return null;
264                         }
265                 }
266
267                 static _Configuration GetWebApplicationConfiguration ()
268                 {
269                         _Configuration config;
270
271                         if (HttpContext.Current == null
272                             || HttpContext.Current.Request == null
273                             || HttpContext.Current.Request.ApplicationPath == null
274                             || HttpContext.Current.Request.ApplicationPath == "") {
275                                 config = OpenWebConfiguration ("");
276                         }
277                         else {
278                                 config = OpenWebConfiguration (HttpContext.Current.Request.ApplicationPath);
279                         }
280
281                         return config;
282                 }
283
284                 static MethodInfo get_runtime_object = typeof (ConfigurationSection).GetMethod ("GetRuntimeObject", BindingFlags.NonPublic | BindingFlags.Instance);
285
286                 [MonoTODO]
287                 public static object GetWebApplicationSection (string sectionName)
288                 {
289                         _Configuration config = GetWebApplicationConfiguration ();
290
291                         ConfigurationSection section = config.GetSection (sectionName);
292
293                         return get_runtime_object.Invoke (section, new object [0]);
294                 }
295
296                 public static NameValueCollection AppSettings {
297                         get { return ConfigurationManager.AppSettings; }
298                 }
299
300                 public static ConnectionStringSettingsCollection ConnectionStrings {
301                         get { return ConfigurationManager.ConnectionStrings; }
302                 }
303
304                 internal static IInternalConfigConfigurationFactory ConfigurationFactory {
305                         get { return configFactory; }
306                 }
307                 
308                 static string GetBasePath (string path)
309                 {
310                         if (path == "/" || path == "")
311                                 return path;
312
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);
318
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);
323                                 } 
324                         }
325                         
326                         if (path.Length == 0)
327                                 return path;
328
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);
332
333                         return path;
334                 }
335
336
337 #region stuff copied from WebConfigurationSettings
338 #if TARGET_J2EE
339                 static internal IConfigurationSystem oldConfig {
340                         get {
341                                 return (IConfigurationSystem)AppDomain.CurrentDomain.GetData("WebConfigurationManager.oldConfig");
342                         }
343                         set {
344                                 AppDomain.CurrentDomain.SetData("WebConfigurationManager.oldConfig", value);
345                         }
346                 }
347
348                 static private Web20DefaultConfig config {
349                         get {
350                                 return (Web20DefaultConfig) AppDomain.CurrentDomain.GetData ("Web20DefaultConfig.config");
351                         }
352                         set {
353                                 AppDomain.CurrentDomain.SetData ("Web20DefaultConfig.config", value);
354                         }
355                 }
356
357                 static private IInternalConfigSystem configSystem {
358                         get {
359                                 return (IInternalConfigSystem) AppDomain.CurrentDomain.GetData ("IInternalConfigSystem.configSystem");
360                         }
361                         set {
362                                 AppDomain.CurrentDomain.SetData ("IInternalConfigSystem.configSystem", value);
363                         }
364                 }
365 #else
366                 static internal IConfigurationSystem oldConfig;
367                 static Web20DefaultConfig config;
368                 static IInternalConfigSystem configSystem;
369 #endif
370                 const BindingFlags privStatic = BindingFlags.NonPublic | BindingFlags.Static;
371                 static readonly object lockobj = new object ();
372
373                 internal static void Init ()
374                 {
375                         lock (lockobj) {
376                                 if (config != null)
377                                         return;
378
379                                 /* deal with the ConfigurationSettings stuff */
380                                 {
381                                         Web20DefaultConfig settings = Web20DefaultConfig.GetInstance ();
382                                         Type t = typeof (ConfigurationSettings);
383                                         MethodInfo changeConfig = t.GetMethod ("ChangeConfigurationSystem",
384                                                                                privStatic);
385
386                                         if (changeConfig == null)
387                                                 throw new ConfigurationException ("Cannot find method CCS");
388
389                                         object [] args = new object [] {settings};
390                                         oldConfig = (IConfigurationSystem)changeConfig.Invoke (null, args);
391                                         config = settings;
392
393                                         config.Init ();
394                                 }
395
396                                 /* deal with the ConfigurationManager stuff */
397                                 {
398                                         HttpConfigurationSystem system = new HttpConfigurationSystem ();
399                                         Type t = typeof (ConfigurationManager);
400                                         MethodInfo changeConfig = t.GetMethod ("ChangeConfigurationSystem",
401                                                                                privStatic);
402
403                                         if (changeConfig == null)
404                                                 throw new ConfigurationException ("Cannot find method CCS");
405
406                                         object [] args = new object [] {system};
407                                         changeConfig.Invoke (null, args);
408                                         configSystem = system;
409                                 }
410                         }
411                 }
412         }
413
414         class Web20DefaultConfig : IConfigurationSystem
415         {
416 #if TARGET_J2EE
417                 static private Web20DefaultConfig instance {
418                         get {
419                                 Web20DefaultConfig val = (Web20DefaultConfig)AppDomain.CurrentDomain.GetData("Web20DefaultConfig.instance");
420                                 if (val == null) {
421                                         val = new Web20DefaultConfig();
422                                         AppDomain.CurrentDomain.SetData("Web20DefaultConfig.instance", val);
423                                 }
424                                 return val;
425                         }
426                         set {
427                                 AppDomain.CurrentDomain.SetData("Web20DefaultConfig.instance", value);
428                         }
429                 }
430 #else
431                 static Web20DefaultConfig instance;
432 #endif
433
434                 static Web20DefaultConfig ()
435                 {
436                         instance = new Web20DefaultConfig ();
437                 }
438
439                 public static Web20DefaultConfig GetInstance ()
440                 {
441                         return instance;
442                 }
443
444                 public object GetConfig (string sectionName)
445                 {
446                         object o = WebConfigurationManager.GetWebApplicationSection (sectionName);
447
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
455                                  * for it.
456                                  */
457                                 object o1 = WebConfigurationManager.oldConfig.GetConfig (sectionName);
458                                 if (o1 != null)
459                                         return o1;
460                         }
461
462                         return o;
463                 }
464
465                 public void Init ()
466                 {
467                         // nothing. We need a context.
468                 }
469         }
470
471 #endregion
472 }
473
474 #endif