2007-05-06 Igor Zelmanovich <igorz@mainsoft.com>
[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 internal ArrayList extra_assemblies = null;
98                 static internal ArrayList ExtraAssemblies {
99                         get {
100                                 if (extra_assemblies == null)
101                                         extra_assemblies = new ArrayList();
102                                 return extra_assemblies;
103                         }
104                 }
105                 
106                 static WebConfigurationManager ()
107                 {
108                         PropertyInfo prop = typeof(ConfigurationManager).GetProperty ("ConfigurationFactory", BindingFlags.Static | BindingFlags.NonPublic);
109                         if (prop != null)
110                                 configFactory = prop.GetValue (null, null) as IInternalConfigConfigurationFactory;
111                 }
112
113                 public static _Configuration OpenMachineConfiguration ()
114                 {
115                         return ConfigurationManager.OpenMachineConfiguration ();
116                 }
117                 
118                 [MonoTODO ("need to handle locationSubPath")]
119                 public static _Configuration OpenMachineConfiguration (string locationSubPath)
120                 {
121                         return OpenMachineConfiguration ();
122                 }
123
124                 [MonoTODO("Mono does not support remote configuration")]
125                 public static _Configuration OpenMachineConfiguration (string locationSubPath,
126                                                                        string server)
127                 {
128                         if (server == null)
129                                 return OpenMachineConfiguration (locationSubPath);
130
131                         throw new NotSupportedException ("Mono doesn't support remote configuration");
132                 }
133
134                 [MonoTODO("Mono does not support remote configuration")]
135                 public static _Configuration OpenMachineConfiguration (string locationSubPath,
136                                                                        string server,
137                                                                        IntPtr userToken)
138                 {
139                         if (server == null)
140                                 return OpenMachineConfiguration (locationSubPath);
141                         throw new NotSupportedException ("Mono doesn't support remote configuration");
142                 }
143
144                 [MonoTODO("Mono does not support remote configuration")]
145                 public static _Configuration OpenMachineConfiguration (string locationSubPath,
146                                                                        string server,
147                                                                        string userName,
148                                                                        string password)
149                 {
150                         if (server == null)
151                                 return OpenMachineConfiguration (locationSubPath);
152                         throw new NotSupportedException ("Mono doesn't support remote configuration");
153                 }
154
155                 public static _Configuration OpenWebConfiguration (string path)
156                 {
157                         return OpenWebConfiguration (path, null, null, null, null, null);
158                 }
159                 
160                 public static _Configuration OpenWebConfiguration (string path, string site)
161                 {
162                         return OpenWebConfiguration (path, site, null, null, null, null);
163                 }
164                 
165                 public static _Configuration OpenWebConfiguration (string path, string site, string locationSubPath)
166                 {
167                         return OpenWebConfiguration (path, site, locationSubPath, null, null, null);
168                 }
169
170                 public static _Configuration OpenWebConfiguration (string path, string site, string locationSubPath, string server)
171                 {
172                         return OpenWebConfiguration (path, site, locationSubPath, server, null, null);
173                 }
174
175                 public static _Configuration OpenWebConfiguration (string path, string site, string locationSubPath, string server, IntPtr userToken)
176                 {
177                         return OpenWebConfiguration (path, site, locationSubPath, server, null, null);
178                 }
179                 
180                 public static _Configuration OpenWebConfiguration (string path, string site, string locationSubPath, string server, string userName, string password)
181                 {
182                         if (path == null || path.Length == 0)
183                                 path = "/";
184
185                         _Configuration conf;
186
187                         conf = (_Configuration) configurations [path];
188                         if (conf == null) {
189                                 lock (configurations) {
190                                         conf = (_Configuration) configurations [path];
191                                         if (conf == null) {
192                                                 conf = ConfigurationFactory.Create (typeof (WebConfigurationHost), null, path, site, locationSubPath, server, userName, password);
193                                                 configurations [path] = conf;
194                                         }
195                                 }
196                         }
197                         return conf;
198                 }
199
200                 public static _Configuration OpenMappedWebConfiguration (WebConfigurationFileMap fileMap, string path)
201                 {
202                         return ConfigurationFactory.Create (typeof(WebConfigurationHost), fileMap, path);
203                 }
204                 
205                 public static _Configuration OpenMappedWebConfiguration (WebConfigurationFileMap fileMap, string path, string site)
206                 {
207                         return ConfigurationFactory.Create (typeof(WebConfigurationHost), fileMap, path, site);
208                 }
209                 
210                 public static _Configuration OpenMappedWebConfiguration (WebConfigurationFileMap fileMap, string path, string site, string locationSubPath)
211                 {
212                         return ConfigurationFactory.Create (typeof(WebConfigurationHost), fileMap, path, site, locationSubPath);
213                 }
214                 
215                 public static _Configuration OpenMappedMachineConfiguration (ConfigurationFileMap fileMap)
216                 {
217                         return ConfigurationFactory.Create (typeof(WebConfigurationHost), fileMap);
218                 }
219
220                 public static _Configuration OpenMappedMachineConfiguration (ConfigurationFileMap fileMap,
221                                                                              string locationSubPath)
222                 {
223                         return OpenMappedMachineConfiguration (fileMap);
224                 }
225
226                 internal static object SafeGetSection (string sectionName, Type configSectionType)
227                 {
228                         try {
229                                 return GetSection (sectionName);
230                         } catch (Exception) {
231                                 if (configSectionType != null)
232                                         return Activator.CreateInstance (configSectionType);
233                                 return null;
234                         }
235                 }
236                 
237                 internal static object SafeGetSection (string sectionName, string path, Type configSectionType)
238                 {
239                         try {
240                                 return GetSection (sectionName, path);
241                         } catch (Exception) {
242                                 if (configSectionType != null)
243                                         return Activator.CreateInstance (configSectionType);
244                                 return null;
245                         }
246                 }
247                 
248                 public static object GetSection (string sectionName)
249                 {
250                         string path = (HttpContext.Current != null
251                             && HttpContext.Current.Request != null) ?
252                                 HttpContext.Current.Request.Path : HttpRuntime.AppDomainAppVirtualPath;
253
254                         return GetSection (sectionName, path);
255                 }
256
257                 public static object GetSection (string sectionName, string path)
258                 {
259                         _Configuration c = OpenWebConfiguration (path);
260                         ConfigurationSection section = c.GetSection (sectionName);
261
262                         if (section == null)
263                                 return null;
264
265                         return get_runtime_object.Invoke (section, new object [0]);
266                 }
267
268                 readonly static MethodInfo get_runtime_object = typeof (ConfigurationSection).GetMethod ("GetRuntimeObject", BindingFlags.NonPublic | BindingFlags.Instance);
269
270                 public static object GetWebApplicationSection (string sectionName)
271                 {
272                         string path = (HttpContext.Current == null
273                                 || HttpContext.Current.Request == null
274                                 || HttpContext.Current.Request.ApplicationPath == null
275                                 || HttpContext.Current.Request.ApplicationPath == "") ?
276                                 String.Empty : HttpContext.Current.Request.ApplicationPath;
277
278                         return GetSection (sectionName, path);
279                 }
280
281                 public static NameValueCollection AppSettings {
282                         get { return ConfigurationManager.AppSettings; }
283                 }
284
285                 public static ConnectionStringSettingsCollection ConnectionStrings {
286                         get { return ConfigurationManager.ConnectionStrings; }
287                 }
288
289                 internal static IInternalConfigConfigurationFactory ConfigurationFactory {
290                         get { return configFactory; }
291                 }
292                 
293 #region stuff copied from WebConfigurationSettings
294 #if TARGET_J2EE
295                 static internal IConfigurationSystem oldConfig {
296                         get {
297                                 return (IConfigurationSystem)AppDomain.CurrentDomain.GetData("WebConfigurationManager.oldConfig");
298                         }
299                         set {
300                                 AppDomain.CurrentDomain.SetData("WebConfigurationManager.oldConfig", value);
301                         }
302                 }
303
304                 static private Web20DefaultConfig config {
305                         get {
306                                 return (Web20DefaultConfig) AppDomain.CurrentDomain.GetData ("Web20DefaultConfig.config");
307                         }
308                         set {
309                                 AppDomain.CurrentDomain.SetData ("Web20DefaultConfig.config", value);
310                         }
311                 }
312
313                 static private IInternalConfigSystem configSystem {
314                         get {
315                                 return (IInternalConfigSystem) AppDomain.CurrentDomain.GetData ("IInternalConfigSystem.configSystem");
316                         }
317                         set {
318                                 AppDomain.CurrentDomain.SetData ("IInternalConfigSystem.configSystem", value);
319                         }
320                 }
321 #else
322                 static internal IConfigurationSystem oldConfig;
323                 static Web20DefaultConfig config;
324                 //static IInternalConfigSystem configSystem;
325 #endif
326                 const BindingFlags privStatic = BindingFlags.NonPublic | BindingFlags.Static;
327                 static readonly object lockobj = new object ();
328
329                 internal static void Init ()
330                 {
331                         lock (lockobj) {
332                                 if (config != null)
333                                         return;
334
335                                 /* deal with the ConfigurationSettings stuff */
336                                 {
337                                         Web20DefaultConfig settings = Web20DefaultConfig.GetInstance ();
338                                         Type t = typeof (ConfigurationSettings);
339                                         MethodInfo changeConfig = t.GetMethod ("ChangeConfigurationSystem",
340                                                                                privStatic);
341
342                                         if (changeConfig == null)
343                                                 throw new ConfigurationException ("Cannot find method CCS");
344
345                                         object [] args = new object [] {settings};
346                                         oldConfig = (IConfigurationSystem)changeConfig.Invoke (null, args);
347                                         config = settings;
348
349                                         config.Init ();
350                                 }
351
352                                 /* deal with the ConfigurationManager stuff */
353                                 {
354                                         HttpConfigurationSystem system = new HttpConfigurationSystem ();
355                                         Type t = typeof (ConfigurationManager);
356                                         MethodInfo changeConfig = t.GetMethod ("ChangeConfigurationSystem",
357                                                                                privStatic);
358
359                                         if (changeConfig == null)
360                                                 throw new ConfigurationException ("Cannot find method CCS");
361
362                                         object [] args = new object [] {system};
363                                         changeConfig.Invoke (null, args);
364                                         //configSystem = system;
365                                 }
366                         }
367                 }
368         }
369
370         class Web20DefaultConfig : IConfigurationSystem
371         {
372 #if TARGET_J2EE
373                 static private Web20DefaultConfig instance {
374                         get {
375                                 Web20DefaultConfig val = (Web20DefaultConfig)AppDomain.CurrentDomain.GetData("Web20DefaultConfig.instance");
376                                 if (val == null) {
377                                         val = new Web20DefaultConfig();
378                                         AppDomain.CurrentDomain.SetData("Web20DefaultConfig.instance", val);
379                                 }
380                                 return val;
381                         }
382                         set {
383                                 AppDomain.CurrentDomain.SetData("Web20DefaultConfig.instance", value);
384                         }
385                 }
386 #else
387                 static Web20DefaultConfig instance;
388 #endif
389
390                 static Web20DefaultConfig ()
391                 {
392                         instance = new Web20DefaultConfig ();
393                 }
394
395                 public static Web20DefaultConfig GetInstance ()
396                 {
397                         return instance;
398                 }
399
400                 public object GetConfig (string sectionName)
401                 {
402                         object o = WebConfigurationManager.GetWebApplicationSection (sectionName);
403
404                         if (o == null || o is IgnoreSection) {
405                                 /* this can happen when the section
406                                  * handler doesn't subclass from
407                                  * ConfigurationSection.  let's be
408                                  * nice and try to load it using the
409                                  * 1.x style routines in case there's
410                                  * a 1.x section handler registered
411                                  * for it.
412                                  */
413                                 object o1 = WebConfigurationManager.oldConfig.GetConfig (sectionName);
414                                 if (o1 != null)
415                                         return o1;
416                         }
417
418                         return o;
419                 }
420
421                 public void Init ()
422                 {
423                         // nothing. We need a context.
424                 }
425         }
426
427 #endregion
428 }
429
430 #endif