New test.
[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                         if (config == null)
291                                 return null;
292
293                         ConfigurationSection section = config.GetSection (sectionName);
294                         if (section == null)
295                                 return null;
296                         
297                         return get_runtime_object.Invoke (section, new object [0]);
298                 }
299
300                 public static NameValueCollection AppSettings {
301                         get { return ConfigurationManager.AppSettings; }
302                 }
303
304                 public static ConnectionStringSettingsCollection ConnectionStrings {
305                         get { return ConfigurationManager.ConnectionStrings; }
306                 }
307
308                 internal static IInternalConfigConfigurationFactory ConfigurationFactory {
309                         get { return configFactory; }
310                 }
311                 
312                 static string GetBasePath (string path)
313                 {
314                         if (path == "/" || path == "")
315                                 return path;
316
317                         /* first if we can, map it to a physical path
318                          * to see if it corresponds to a file */
319                         if (HttpContext.Current != null
320                             && HttpContext.Current.Request != null) {
321                                 string pd = HttpContext.Current.Request.MapPath (path);
322
323                                 if (!Directory.Exists (pd)) {
324                                         /* if it does, remove the file from the url */
325                                         int i = path.LastIndexOf ('/');
326                                         path = path.Substring (0, i);
327                                 } 
328                         }
329                         
330                         if (path.Length == 0)
331                                 return path;
332
333                         /* remove excess /'s from the end of the virtual path */
334                         while (path [path.Length - 1] == '/')
335                                 path = path.Substring (0, path.Length - 1);
336
337                         return path;
338                 }
339
340
341 #region stuff copied from WebConfigurationSettings
342 #if TARGET_J2EE
343                 static internal IConfigurationSystem oldConfig {
344                         get {
345                                 return (IConfigurationSystem)AppDomain.CurrentDomain.GetData("WebConfigurationManager.oldConfig");
346                         }
347                         set {
348                                 AppDomain.CurrentDomain.SetData("WebConfigurationManager.oldConfig", value);
349                         }
350                 }
351
352                 static private Web20DefaultConfig config {
353                         get {
354                                 return (Web20DefaultConfig) AppDomain.CurrentDomain.GetData ("Web20DefaultConfig.config");
355                         }
356                         set {
357                                 AppDomain.CurrentDomain.SetData ("Web20DefaultConfig.config", value);
358                         }
359                 }
360
361                 static private IInternalConfigSystem configSystem {
362                         get {
363                                 return (IInternalConfigSystem) AppDomain.CurrentDomain.GetData ("IInternalConfigSystem.configSystem");
364                         }
365                         set {
366                                 AppDomain.CurrentDomain.SetData ("IInternalConfigSystem.configSystem", value);
367                         }
368                 }
369 #else
370                 static internal IConfigurationSystem oldConfig;
371                 static Web20DefaultConfig config;
372                 static IInternalConfigSystem configSystem;
373 #endif
374                 const BindingFlags privStatic = BindingFlags.NonPublic | BindingFlags.Static;
375                 static readonly object lockobj = new object ();
376
377                 internal static void Init ()
378                 {
379                         lock (lockobj) {
380                                 if (config != null)
381                                         return;
382
383                                 /* deal with the ConfigurationSettings stuff */
384                                 {
385                                         Web20DefaultConfig settings = Web20DefaultConfig.GetInstance ();
386                                         Type t = typeof (ConfigurationSettings);
387                                         MethodInfo changeConfig = t.GetMethod ("ChangeConfigurationSystem",
388                                                                                privStatic);
389
390                                         if (changeConfig == null)
391                                                 throw new ConfigurationException ("Cannot find method CCS");
392
393                                         object [] args = new object [] {settings};
394                                         oldConfig = (IConfigurationSystem)changeConfig.Invoke (null, args);
395                                         config = settings;
396
397                                         config.Init ();
398                                 }
399
400                                 /* deal with the ConfigurationManager stuff */
401                                 {
402                                         HttpConfigurationSystem system = new HttpConfigurationSystem ();
403                                         Type t = typeof (ConfigurationManager);
404                                         MethodInfo changeConfig = t.GetMethod ("ChangeConfigurationSystem",
405                                                                                privStatic);
406
407                                         if (changeConfig == null)
408                                                 throw new ConfigurationException ("Cannot find method CCS");
409
410                                         object [] args = new object [] {system};
411                                         changeConfig.Invoke (null, args);
412                                         configSystem = system;
413                                 }
414                         }
415                 }
416         }
417
418         class Web20DefaultConfig : IConfigurationSystem
419         {
420 #if TARGET_J2EE
421                 static private Web20DefaultConfig instance {
422                         get {
423                                 Web20DefaultConfig val = (Web20DefaultConfig)AppDomain.CurrentDomain.GetData("Web20DefaultConfig.instance");
424                                 if (val == null) {
425                                         val = new Web20DefaultConfig();
426                                         AppDomain.CurrentDomain.SetData("Web20DefaultConfig.instance", val);
427                                 }
428                                 return val;
429                         }
430                         set {
431                                 AppDomain.CurrentDomain.SetData("Web20DefaultConfig.instance", value);
432                         }
433                 }
434 #else
435                 static Web20DefaultConfig instance;
436 #endif
437
438                 static Web20DefaultConfig ()
439                 {
440                         instance = new Web20DefaultConfig ();
441                 }
442
443                 public static Web20DefaultConfig GetInstance ()
444                 {
445                         return instance;
446                 }
447
448                 public object GetConfig (string sectionName)
449                 {
450                         object o = WebConfigurationManager.GetWebApplicationSection (sectionName);
451
452                         if (o == null || o is IgnoreSection) {
453                                 /* this can happen when the section
454                                  * handler doesn't subclass from
455                                  * ConfigurationSection.  let's be
456                                  * nice and try to load it using the
457                                  * 1.x style routines in case there's
458                                  * a 1.x section handler registered
459                                  * for it.
460                                  */
461                                 object o1 = WebConfigurationManager.oldConfig.GetConfig (sectionName);
462                                 if (o1 != null)
463                                         return o1;
464                         }
465
466                         return o;
467                 }
468
469                 public void Init ()
470                 {
471                         // nothing. We need a context.
472                 }
473         }
474
475 #endregion
476 }
477
478 #endif