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