Visual studio upgrade did not work well.
[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 #if MONOWEB_DEP
38 using Mono.Web.Util;
39 #endif
40 using System.Xml;
41 using System.Configuration;
42 using System.Configuration.Internal;
43 using _Configuration = System.Configuration.Configuration;
44
45 namespace System.Web.Configuration {
46
47         public static class WebConfigurationManager
48         {
49 #if !TARGET_J2EE
50                 static IInternalConfigConfigurationFactory configFactory;
51                 static Hashtable configurations = Hashtable.Synchronized (new Hashtable ());
52                 static Hashtable sectionCache = new Hashtable (StringComparer.OrdinalIgnoreCase);
53 #else
54                 const string AppSettingsKey = "WebConfigurationManager.AppSettings";
55                 static internal IInternalConfigConfigurationFactory configFactory
56                 {
57                         get{
58                                 IInternalConfigConfigurationFactory factory = (IInternalConfigConfigurationFactory)AppDomain.CurrentDomain.GetData("WebConfigurationManager.configFactory");
59                                 if (factory == null){
60                                         lock (AppDomain.CurrentDomain){
61                                                 object initialized = AppDomain.CurrentDomain.GetData("WebConfigurationManager.configFactory.initialized");
62                                                 if (initialized == null){
63                                                         PropertyInfo prop = typeof(ConfigurationManager).GetProperty("ConfigurationFactory", BindingFlags.Static | BindingFlags.NonPublic);
64                                                         if (prop != null){
65                                                                 factory = prop.GetValue(null, null) as IInternalConfigConfigurationFactory;
66                                                                 configFactory = factory;
67                                                         }
68                                                 }
69                                         }
70                                 }
71                                 return factory != null ? factory : configFactory;
72                         }
73                         set{
74                                 AppDomain.CurrentDomain.SetData("WebConfigurationManager.configFactory", value);
75                                 AppDomain.CurrentDomain.SetData("WebConfigurationManager.configFactory.initialized", true);
76                         }
77                 }
78
79                 static internal Hashtable configurations
80                 {
81                         get{
82                                 Hashtable table = (Hashtable)AppDomain.CurrentDomain.GetData("WebConfigurationManager.configurations");
83                                 if (table == null){
84                                         lock (AppDomain.CurrentDomain){
85                                                 object initialized = AppDomain.CurrentDomain.GetData("WebConfigurationManager.configurations.initialized");
86                                                 if (initialized == null){
87                                                         table = Hashtable.Synchronized (new Hashtable (StringComparer.OrdinalIgnoreCase));
88                                                         configurations = table;
89                                                 }
90                                         }
91                                 }
92                                 return table != null ? table : configurations;
93
94                         }
95                         set{
96                                 AppDomain.CurrentDomain.SetData("WebConfigurationManager.configurations", value);
97                                 AppDomain.CurrentDomain.SetData("WebConfigurationManager.configurations.initialized", true);
98                         }
99                 }
100
101                 static Hashtable sectionCache
102                 {
103                         get
104                         {
105                                 Hashtable sectionCache = (Hashtable) AppDomain.CurrentDomain.GetData ("sectionCache");
106                                 if (sectionCache == null) {
107                                         sectionCache = new Hashtable (StringComparer.OrdinalIgnoreCase);
108                                         AppDomain.CurrentDomain.SetData ("sectionCache", sectionCache);
109                                 }
110                                 return sectionCache;
111                         }
112                         set
113                         {
114                                 AppDomain.CurrentDomain.SetData ("sectionCache", value);
115                         }
116                 }
117 #endif
118
119                 static ArrayList extra_assemblies = null;
120                 static internal ArrayList ExtraAssemblies {
121                         get {
122                                 if (extra_assemblies == null)
123                                         extra_assemblies = new ArrayList();
124                                 return extra_assemblies;
125                         }
126                 }
127
128                 static bool hasConfigErrors = false;
129                 static object hasConfigErrorsLock = new object ();
130                 static internal bool HasConfigErrors {
131                         get {
132                                 lock (hasConfigErrorsLock) {
133                                         return hasConfigErrors;
134                                 }
135                         }
136                 }
137                 
138                 static WebConfigurationManager ()
139                 {
140                         PropertyInfo prop = typeof(ConfigurationManager).GetProperty ("ConfigurationFactory", BindingFlags.Static | BindingFlags.NonPublic);
141                         if (prop != null)
142                                 configFactory = prop.GetValue (null, null) as IInternalConfigConfigurationFactory;
143                 }
144
145                 public static _Configuration OpenMachineConfiguration ()
146                 {
147                         return ConfigurationManager.OpenMachineConfiguration ();
148                 }
149                 
150                 [MonoLimitation ("locationSubPath is not handled")]
151                 public static _Configuration OpenMachineConfiguration (string locationSubPath)
152                 {
153                         return OpenMachineConfiguration ();
154                 }
155
156                 [MonoLimitation("Mono does not support remote configuration")]
157                 public static _Configuration OpenMachineConfiguration (string locationSubPath,
158                                                                        string server)
159                 {
160                         if (server == null)
161                                 return OpenMachineConfiguration (locationSubPath);
162
163                         throw new NotSupportedException ("Mono doesn't support remote configuration");
164                 }
165
166                 [MonoLimitation("Mono does not support remote configuration")]
167                 public static _Configuration OpenMachineConfiguration (string locationSubPath,
168                                                                        string server,
169                                                                        IntPtr userToken)
170                 {
171                         if (server == null)
172                                 return OpenMachineConfiguration (locationSubPath);
173                         throw new NotSupportedException ("Mono doesn't support remote configuration");
174                 }
175
176                 [MonoLimitation("Mono does not support remote configuration")]
177                 public static _Configuration OpenMachineConfiguration (string locationSubPath,
178                                                                        string server,
179                                                                        string userName,
180                                                                        string password)
181                 {
182                         if (server == null)
183                                 return OpenMachineConfiguration (locationSubPath);
184                         throw new NotSupportedException ("Mono doesn't support remote configuration");
185                 }
186
187                 public static _Configuration OpenWebConfiguration (string path)
188                 {
189                         return OpenWebConfiguration (path, null, null, null, null, null);
190                 }
191                 
192                 public static _Configuration OpenWebConfiguration (string path, string site)
193                 {
194                         return OpenWebConfiguration (path, site, null, null, null, null);
195                 }
196                 
197                 public static _Configuration OpenWebConfiguration (string path, string site, string locationSubPath)
198                 {
199                         return OpenWebConfiguration (path, site, locationSubPath, null, null, null);
200                 }
201
202                 public static _Configuration OpenWebConfiguration (string path, string site, string locationSubPath, string server)
203                 {
204                         return OpenWebConfiguration (path, site, locationSubPath, server, null, null);
205                 }
206
207                 public static _Configuration OpenWebConfiguration (string path, string site, string locationSubPath, string server, IntPtr userToken)
208                 {
209                         return OpenWebConfiguration (path, site, locationSubPath, server, null, null);
210                 }
211                 
212                 public static _Configuration OpenWebConfiguration (string path, string site, string locationSubPath, string server, string userName, string password)
213                 {
214                         if (path == null || path.Length == 0)
215                                 path = "/";
216
217                         _Configuration conf;
218
219                         conf = (_Configuration) configurations [path];
220                         if (conf == null) {
221                                 try {
222                                         conf = ConfigurationFactory.Create (typeof (WebConfigurationHost), null, path, site, locationSubPath, server, userName, password);
223                                         configurations [path] = conf;
224                                 } catch (Exception ex) {
225                                         lock (hasConfigErrorsLock) {
226                                                 hasConfigErrors = true;
227                                         }
228                                         throw ex;
229                                 }
230                         }
231                         return conf;
232                 }
233
234                 public static _Configuration OpenMappedWebConfiguration (WebConfigurationFileMap fileMap, string path)
235                 {
236                         return ConfigurationFactory.Create (typeof(WebConfigurationHost), fileMap, path);
237                 }
238                 
239                 public static _Configuration OpenMappedWebConfiguration (WebConfigurationFileMap fileMap, string path, string site)
240                 {
241                         return ConfigurationFactory.Create (typeof(WebConfigurationHost), fileMap, path, site);
242                 }
243                 
244                 public static _Configuration OpenMappedWebConfiguration (WebConfigurationFileMap fileMap, string path, string site, string locationSubPath)
245                 {
246                         return ConfigurationFactory.Create (typeof(WebConfigurationHost), fileMap, path, site, locationSubPath);
247                 }
248                 
249                 public static _Configuration OpenMappedMachineConfiguration (ConfigurationFileMap fileMap)
250                 {
251                         return ConfigurationFactory.Create (typeof(WebConfigurationHost), fileMap);
252                 }
253
254                 public static _Configuration OpenMappedMachineConfiguration (ConfigurationFileMap fileMap,
255                                                                              string locationSubPath)
256                 {
257                         return OpenMappedMachineConfiguration (fileMap);
258                 }
259
260                 internal static object SafeGetSection (string sectionName, Type configSectionType)
261                 {
262                         try {
263                                 return GetSection (sectionName);
264                         } catch (Exception) {
265                                 if (configSectionType != null)
266                                         return Activator.CreateInstance (configSectionType);
267                                 return null;
268                         }
269                 }
270                 
271                 internal static object SafeGetSection (string sectionName, string path, Type configSectionType)
272                 {
273                         try {
274                                 return GetSection (sectionName, path);
275                         } catch (Exception) {
276                                 if (configSectionType != null)
277                                         return Activator.CreateInstance (configSectionType);
278                                 return null;
279                         }
280                 }
281                 
282                 public static object GetSection (string sectionName)
283                 {
284                         return GetSection (sectionName, GetCurrentPath (HttpContext.Current));
285                 }
286
287                 public static object GetSection (string sectionName, string path)
288                 {
289                         object cachedSection = sectionCache [GetSectionCacheKey (sectionName, path)];
290                         if (cachedSection != null)
291                                 return cachedSection;
292
293                         _Configuration c = OpenWebConfiguration (path);
294                         ConfigurationSection section = c.GetSection (sectionName);
295
296                         if (section == null)
297                                 return null;
298
299 #if TARGET_J2EE
300                         object value = get_runtime_object.Invoke (section, new object [0]);
301                         if (String.CompareOrdinal ("appSettings", sectionName) == 0) {
302                                 NameValueCollection collection;
303                                 collection = new KeyValueMergedCollection (HttpContext.Current, (NameValueCollection) value);
304                                 value = collection;
305                         }
306
307                         AddSectionToCache (GetSectionCacheKey (sectionName, path), value);
308                         return value;
309 #else
310 #if MONOWEB_DEP
311                         object value = SettingsMappingManager.MapSection (get_runtime_object.Invoke (section, new object [0]));
312 #else
313                         object value = null;
314 #endif
315                         AddSectionToCache (GetSectionCacheKey (sectionName, path), value);
316                         return value;
317 #endif
318                 }
319
320                 static string GetCurrentPath (HttpContext ctx)
321                 {
322                         return (ctx != null && ctx.Request != null) ? ctx.Request.Path : HttpRuntime.AppDomainAppVirtualPath;
323                 }
324
325                 internal static void RemoveConfigurationFromCache (HttpContext ctx)
326                 {
327                         configurations.Remove (GetCurrentPath (ctx));
328                 }
329
330                 readonly static MethodInfo get_runtime_object = typeof (ConfigurationSection).GetMethod ("GetRuntimeObject", BindingFlags.NonPublic | BindingFlags.Instance);
331
332                 public static object GetWebApplicationSection (string sectionName)
333                 {
334                         string path = (HttpContext.Current == null
335                                 || HttpContext.Current.Request == null
336                                 || HttpContext.Current.Request.ApplicationPath == null
337                                 || HttpContext.Current.Request.ApplicationPath == "") ?
338                                 String.Empty : HttpContext.Current.Request.ApplicationPath;
339
340                         return GetSection (sectionName, path);
341                 }
342
343                 public static NameValueCollection AppSettings {
344                         get { return ConfigurationManager.AppSettings; }
345                 }
346
347                 public static ConnectionStringSettingsCollection ConnectionStrings {
348                         get { return ConfigurationManager.ConnectionStrings; }
349                 }
350
351                 internal static IInternalConfigConfigurationFactory ConfigurationFactory {
352                         get { return configFactory; }
353                 }
354
355                 static void AddSectionToCache (string key, object section)
356                 {
357                         if (sectionCache [key] != null)
358                                 return;
359
360                         Hashtable tmpTable = (Hashtable) sectionCache.Clone ();
361                         if (tmpTable.Contains (key))
362                                 return;
363
364                         tmpTable.Add (key, section);
365                         sectionCache = tmpTable;
366                 }
367
368                 static string GetSectionCacheKey (string sectionName, string path)
369                 {
370                         return string.Concat (path, "/", sectionName);
371                 }
372
373                 
374 #region stuff copied from WebConfigurationSettings
375 #if TARGET_J2EE
376                 static internal IConfigurationSystem oldConfig {
377                         get {
378                                 return (IConfigurationSystem)AppDomain.CurrentDomain.GetData("WebConfigurationManager.oldConfig");
379                         }
380                         set {
381                                 AppDomain.CurrentDomain.SetData("WebConfigurationManager.oldConfig", value);
382                         }
383                 }
384
385                 static private Web20DefaultConfig config {
386                         get {
387                                 return (Web20DefaultConfig) AppDomain.CurrentDomain.GetData ("Web20DefaultConfig.config");
388                         }
389                         set {
390                                 AppDomain.CurrentDomain.SetData ("Web20DefaultConfig.config", value);
391                         }
392                 }
393
394                 static private IInternalConfigSystem configSystem {
395                         get {
396                                 return (IInternalConfigSystem) AppDomain.CurrentDomain.GetData ("IInternalConfigSystem.configSystem");
397                         }
398                         set {
399                                 AppDomain.CurrentDomain.SetData ("IInternalConfigSystem.configSystem", value);
400                         }
401                 }
402 #else
403                 static internal IConfigurationSystem oldConfig;
404                 static Web20DefaultConfig config;
405                 //static IInternalConfigSystem configSystem;
406 #endif
407                 const BindingFlags privStatic = BindingFlags.NonPublic | BindingFlags.Static;
408                 static readonly object lockobj = new object ();
409
410                 internal static void Init ()
411                 {
412                         lock (lockobj) {
413                                 if (config != null)
414                                         return;
415
416                                 /* deal with the ConfigurationSettings stuff */
417                                 {
418                                         Web20DefaultConfig settings = Web20DefaultConfig.GetInstance ();
419                                         Type t = typeof (ConfigurationSettings);
420                                         MethodInfo changeConfig = t.GetMethod ("ChangeConfigurationSystem",
421                                                                                privStatic);
422
423                                         if (changeConfig == null)
424                                                 throw new ConfigurationException ("Cannot find method CCS");
425
426                                         object [] args = new object [] {settings};
427                                         oldConfig = (IConfigurationSystem)changeConfig.Invoke (null, args);
428                                         config = settings;
429
430                                         config.Init ();
431                                 }
432
433                                 /* deal with the ConfigurationManager stuff */
434                                 {
435                                         HttpConfigurationSystem system = new HttpConfigurationSystem ();
436                                         Type t = typeof (ConfigurationManager);
437                                         MethodInfo changeConfig = t.GetMethod ("ChangeConfigurationSystem",
438                                                                                privStatic);
439
440                                         if (changeConfig == null)
441                                                 throw new ConfigurationException ("Cannot find method CCS");
442
443                                         object [] args = new object [] {system};
444                                         changeConfig.Invoke (null, args);
445                                         //configSystem = system;
446                                 }
447                         }
448                 }
449         }
450
451         class Web20DefaultConfig : IConfigurationSystem
452         {
453 #if TARGET_J2EE
454                 static private Web20DefaultConfig instance {
455                         get {
456                                 Web20DefaultConfig val = (Web20DefaultConfig)AppDomain.CurrentDomain.GetData("Web20DefaultConfig.instance");
457                                 if (val == null) {
458                                         val = new Web20DefaultConfig();
459                                         AppDomain.CurrentDomain.SetData("Web20DefaultConfig.instance", val);
460                                 }
461                                 return val;
462                         }
463                         set {
464                                 AppDomain.CurrentDomain.SetData("Web20DefaultConfig.instance", value);
465                         }
466                 }
467 #else
468                 static Web20DefaultConfig instance;
469 #endif
470
471                 static Web20DefaultConfig ()
472                 {
473                         instance = new Web20DefaultConfig ();
474                 }
475
476                 public static Web20DefaultConfig GetInstance ()
477                 {
478                         return instance;
479                 }
480
481                 public object GetConfig (string sectionName)
482                 {
483                         object o = WebConfigurationManager.GetWebApplicationSection (sectionName);
484
485                         if (o == null || o is IgnoreSection) {
486                                 /* this can happen when the section
487                                  * handler doesn't subclass from
488                                  * ConfigurationSection.  let's be
489                                  * nice and try to load it using the
490                                  * 1.x style routines in case there's
491                                  * a 1.x section handler registered
492                                  * for it.
493                                  */
494                                 object o1 = WebConfigurationManager.oldConfig.GetConfig (sectionName);
495                                 if (o1 != null)
496                                         return o1;
497                         }
498
499                         return o;
500                 }
501
502                 public void Init ()
503                 {
504                         // nothing. We need a context.
505                 }
506         }
507
508 #endregion
509 }
510
511 #endif