2009-06-05 Marek Habersack <mhabersack@novell.com>
[mono.git] / mcs / class / System.Web / System.Web.Configuration_2.0 / WebConfigurationHost.cs
index a9b92baefeb7b2fd425323ae318c7d177b6e4f6b..24cd3b01150530ebcc5bbb35763415652ceff83f 100644 (file)
 #if NET_2_0
 
 using System;
+using System.Collections;
 using System.IO;
 using System.Security;
 using System.Configuration;
 using System.Configuration.Internal;
+using System.Web.Hosting;
 using System.Web.Util;
+using System.Reflection;
 
+/*
+ * this class needs to be rewritten to support usage of the
+ * IRemoteWebConfigurationHostServer interface.  Once that's done, we
+ * need an implementation of that interface that talks (through a web
+ * service?) to a remote site..
+ *
+ * for now, though, just implement it as we do
+ * System.Configuration.InternalConfigurationHost, i.e. the local
+ * case.
+ */
 namespace System.Web.Configuration
 {
        class WebConfigurationHost: IInternalConfigHost
@@ -45,15 +58,20 @@ namespace System.Web.Configuration
                
                public virtual object CreateConfigurationContext (string configPath, string locationSubPath)
                {
-                       return null;
+                       return new WebContext (WebApplicationLevel.AtApplication /* XXX */,
+                                              "" /* site XXX */,
+                                              "" /* application path XXX */,
+                                              configPath,
+                                              locationSubPath);
                }
                
                public virtual object CreateDeprecatedConfigContext (string configPath)
                {
-                       throw new NotImplementedException ();
+                       return new HttpConfigurationContext(configPath);
                }
                
-               public virtual string DecryptSection (string encryptedXml, ProtectedConfigurationProvider protectionProvider, ProtectedConfigurationSection protectedSection)
+               public virtual string DecryptSection (string encryptedXml, ProtectedConfigurationProvider protectionProvider,
+                                                     ProtectedConfigurationSection protectedSection)
                {
                        throw new NotImplementedException ();
                }
@@ -63,7 +81,8 @@ namespace System.Web.Configuration
                        File.Delete (streamName);
                }
                
-               public virtual string EncryptSection (string encryptedXml, ProtectedConfigurationProvider protectionProvider, ProtectedConfigurationSection protectedSection)
+               public virtual string EncryptSection (string encryptedXml, ProtectedConfigurationProvider protectionProvider,
+                                                     ProtectedConfigurationSection protectedSection)
                {
                        throw new NotImplementedException ();
                }
@@ -75,7 +94,7 @@ namespace System.Web.Configuration
                
                public virtual Type GetConfigType (string typeName, bool throwOnError)
                {
-                       Type type = Type.GetType (typeName);
+                       Type type = HttpApplication.LoadType (typeName);
                        if (type == null && throwOnError)
                                throw new ConfigurationErrorsException ("Type not found: '" + typeName + "'");
                        return type;
@@ -86,7 +105,8 @@ namespace System.Web.Configuration
                        return t.AssemblyQualifiedName;
                }
                
-               public virtual void GetRestrictedPermissions (IInternalConfigRecord configRecord, out PermissionSet permissionSet, out bool isHostReady)
+               public virtual void GetRestrictedPermissions (IInternalConfigRecord configRecord, out PermissionSet permissionSet,
+                                                             out bool isHostReady)
                {
                        throw new NotImplementedException ();
                }
@@ -99,12 +119,30 @@ namespace System.Web.Configuration
                                else
                                        return map.MachineConfigFilename;
                        } else if (configPath == MachineWebPath) {
-                               if (map == null) {
-                                       string mdir = Path.GetDirectoryName (System.Runtime.InteropServices.RuntimeEnvironment.SystemConfigurationFile);
-                                       return GetWebConfigFileName (mdir);
+                               string mdir;
+
+                               if (map == null)
+#if TARGET_J2EE
+                               {
+                                       // check META-INF/web.config exists
+                                       java.lang.ClassLoader cl = (java.lang.ClassLoader) AppDomain.CurrentDomain.GetData ("GH_ContextClassLoader");
+                                       if (cl == null)
+                                               return null;
+                                       java.io.InputStream wcs = cl.getResourceAsStream ("META-INF/web.config");
+                                       if (wcs == null)
+                                               return null;
+
+                                       wcs.close ();
+
+                                       return "/META-INF/web.config";
                                }
+#else
+                                       mdir = Path.GetDirectoryName (System.Runtime.InteropServices.RuntimeEnvironment.SystemConfigurationFile);
+#endif
                                else
-                                       return null;
+                                       mdir = Path.GetDirectoryName (map.MachineConfigFilename);
+
+                               return GetWebConfigFileName (mdir);
                        }
                        
                        string dir = MapPath (configPath);
@@ -130,36 +168,38 @@ namespace System.Web.Configuration
                {
                }
                
-               public virtual void InitForConfiguration (ref string locationSubPath, out string configPath, out string locationConfigPath, IInternalConfigRoot root, params object[] hostInitConfigurationParams)
+               public virtual void InitForConfiguration (ref string locationSubPath, out string configPath,
+                                                         out string locationConfigPath, IInternalConfigRoot root,
+                                                         params object[] hostInitConfigurationParams)
                {
                        string fullPath = (string) hostInitConfigurationParams [1];
-                       
                        map = (WebConfigurationFileMap) hostInitConfigurationParams [0];
-                       
+
                        if (locationSubPath == MachineWebPath) {
                                locationSubPath = MachinePath;
                                configPath = MachineWebPath;
                                locationConfigPath = null;
-                       }
-                       else if (locationSubPath == MachinePath) {
+                       } else if (locationSubPath == MachinePath) {
                                locationSubPath = null;
                                configPath = MachinePath;
                                locationConfigPath = null;
-                       }
-                       else {
-                               
+                       } else {
                                int i;
-                               if (locationSubPath == null) {
+                               if (locationSubPath == null)
+                               {
                                        configPath = fullPath;
-                                       i = fullPath.LastIndexOf ("/");
-                               } else {
-                                       configPath = locationSubPath;
-                                       if (locationSubPath != "/")
-                                               i = locationSubPath.LastIndexOf ('/');
-                                       else
-                                               i = -1;
+                                       if (configPath.Length > 1)
+                                               configPath = VirtualPathUtility.RemoveTrailingSlash (configPath);
                                }
-                               
+                               else
+                                       configPath = locationSubPath;
+
+                               if (configPath == HttpRuntime.AppDomainAppVirtualPath
+                                   || configPath == "/")
+                                       i = -1;
+                               else
+                                       i = configPath.LastIndexOf ("/");
+
                                if (i != -1) {
                                        locationConfigPath = configPath.Substring (i+1);
                                        
@@ -172,19 +212,28 @@ namespace System.Web.Configuration
                                        locationConfigPath = null;
                                }
                        }
-                       
-                       if (GetStreamName (configPath) == null) {
-                               // There is no config file for this path. Get the next one in the chain.
-                               InitForConfiguration (ref locationSubPath, out configPath, out locationConfigPath, root, hostInitConfigurationParams);
-                       }
                }
                
                public string MapPath (string virtualPath)
                {
+                       if (!String.IsNullOrEmpty (virtualPath)) {
+                               if (virtualPath.StartsWith (System.Web.Compilation.BuildManager.FAKE_VIRTUAL_PATH_PREFIX, StringComparison.Ordinal))
+                                       return HttpRuntime.AppDomainAppPath;
+                       }
+                       
                        if (map != null)
                                return MapPathFromMapper (virtualPath);
-                       else
+                       else if (HttpContext.Current != null && HttpContext.Current.Request != null)
                                return HttpContext.Current.Request.MapPath (virtualPath);
+                       else if (HttpRuntime.AppDomainAppVirtualPath != null &&
+                                virtualPath.StartsWith (HttpRuntime.AppDomainAppVirtualPath)) {
+                               if (virtualPath == HttpRuntime.AppDomainAppVirtualPath)
+                                       return HttpRuntime.AppDomainAppPath;
+                               return UrlUtils.Combine (HttpRuntime.AppDomainAppPath,
+                                                        virtualPath.Substring (HttpRuntime.AppDomainAppVirtualPath.Length));
+                       }
+                       
+                       return virtualPath;
                }
                
                public string NormalizeVirtualPath (string virtualPath)
@@ -231,17 +280,68 @@ namespace System.Web.Configuration
                        throw new HttpException ("Invalid virtual directory: " + virtualPath);
                }
 
-               string GetWebConfigFileName (string dir)
+               internal static string GetWebConfigFileName (string dir)
                {
-                       string file = Path.Combine (dir, "Web.config");
-                       if (File.Exists (file))
-                               return file;
-                       file = Path.Combine (dir, "web.config");
-                       if (File.Exists (file))
-                               return file;
+#if TARGET_J2EE
+                       DirectoryInfo d = GetCaseSensitiveExistingDirectory (new DirectoryInfo (dir));
+                       if (d == null)
+                               return null;
+
+                       FileInfo file = (FileInfo) FindByName ("web.config", d.GetFiles ("W*"));
+                       if (file == null)
+                               file = (FileInfo) FindByName ("web.config", d.GetFiles ("w*"));
+
+                       if (file != null)
+                               return file.FullName;
+#else
+                       AppDomain domain = AppDomain.CurrentDomain;
+                       bool hosted = (domain.GetData (ApplicationHost.MonoHostedDataKey) as string) == "yes";
+
+                       if (hosted) {
+                               foreach (string fn in ApplicationHost.WebConfigFileNames) {
+                                       string file = Path.Combine (dir, fn);
+                                       if (File.Exists (file))
+                                               return file;
+                               }
+                       } else {
+                               Assembly asm = Assembly.GetEntryAssembly () ?? Assembly.GetCallingAssembly ();
+                               string name = Path.GetFileName (asm.Location);
+                               string[] fileNames = new string[] {name + ".config", name + ".Config"};
+                               string appDir = domain.BaseDirectory;
+                               string file;
+
+                               foreach (string fn in fileNames) {
+                                       file = Path.Combine (appDir, fn);
+                                       if (File.Exists (file))
+                                               return file;
+                               }
+                       }
+#endif                 
                        return null;
                }
+#if TARGET_J2EE
+               static DirectoryInfo GetCaseSensitiveExistingDirectory (DirectoryInfo dir) {
+                       if (dir == null)
+                               return null;
+                       if (dir.Exists)
+                               return dir;
+
+                       DirectoryInfo parent = GetCaseSensitiveExistingDirectory (dir.Parent);
+                       if (parent == null)
+                               return null;
+
+                       return (DirectoryInfo) FindByName (dir.Name, parent.GetDirectories ());
+               }
                
+               static FileSystemInfo FindByName (string name, FileSystemInfo [] infos)
+               {
+                       for (int i = 0; i < infos.Length; i++) {
+                               if (String.Compare (name, infos [i].Name, StringComparison.OrdinalIgnoreCase) == 0)
+                                       return infos [i];
+                       }
+                       return null;
+               }
+#endif
                public virtual bool IsAboveApplication (string configPath)
                {
                        throw new NotImplementedException ();
@@ -252,14 +352,19 @@ namespace System.Web.Configuration
                        throw new NotImplementedException ();
                }
                
-               public virtual bool IsDefinitionAllowed (string configPath, ConfigurationAllowDefinition allowDefinition, ConfigurationAllowExeDefinition allowExeDefinition)
+               public virtual bool IsDefinitionAllowed (string configPath, ConfigurationAllowDefinition allowDefinition,
+                                                        ConfigurationAllowExeDefinition allowExeDefinition)
                {
                        switch (allowDefinition) {
                                case ConfigurationAllowDefinition.MachineOnly:
                                        return configPath == MachinePath || configPath == MachineWebPath;
                                case ConfigurationAllowDefinition.MachineToWebRoot:
                                case ConfigurationAllowDefinition.MachineToApplication:
-                                       return configPath == MachinePath || configPath == MachineWebPath || configPath == "/";
+                                       return (String.Compare (configPath, MachinePath, StringComparison.Ordinal) == 0) ||
+                                               (String.Compare (configPath, MachineWebPath, StringComparison.Ordinal) == 0) ||
+                                               (String.Compare (configPath, "/", StringComparison.Ordinal) == 0) ||
+                                               (String.Compare (configPath, "~", StringComparison.Ordinal) == 0) ||
+                                               (String.Compare (configPath, HttpRuntime.AppDomainAppVirtualPath) == 0);
                                default:
                                        return true;
                        }
@@ -277,13 +382,26 @@ namespace System.Web.Configuration
                
                public virtual Stream OpenStreamForRead (string streamName)
                {
-                       if (!File.Exists (streamName))
+                       if (!File.Exists (streamName)) {
+#if TARGET_J2EE
+                               if (streamName != null && (streamName.EndsWith ("machine.config") ||
+                                                          streamName.EndsWith ("web.config"))) {
+                                       if (streamName.StartsWith ("/"))
+                                               streamName = streamName.Substring (1);
+                                       java.lang.ClassLoader cl = (java.lang.ClassLoader) AppDomain.CurrentDomain.GetData ("GH_ContextClassLoader");
+                                       if (cl != null) {
+                                               java.io.InputStream inputStream = cl.getResourceAsStream (streamName);
+                                               return new System.Web.J2EE.J2EEUtils.InputStreamWrapper (inputStream);
+                                       }
+                               }
+#endif
                                throw new ConfigurationException ("File '" + streamName + "' not found");
+                       }
                                
                        return new FileStream (streamName, FileMode.Open, FileAccess.Read);
                }
 
-               [MonoTODO]
+               [MonoTODO ("Not implemented")]
                public virtual Stream OpenStreamForRead (string streamName, bool assertPermissions)
                {
                        throw new NotImplementedException ();
@@ -294,8 +412,9 @@ namespace System.Web.Configuration
                        return new FileStream (streamName, FileMode.Create, FileAccess.Write);
                }
 
-               [MonoTODO]
-               public virtual Stream OpenStreamForWrite (string streamName, string templateStreamName, ref object writeContext, bool assertPermissions)
+               [MonoTODO ("Not implemented")]
+               public virtual Stream OpenStreamForWrite (string streamName, string templateStreamName, ref object writeContext,
+                                                         bool assertPermissions)
                {
                        throw new NotImplementedException ();
                }
@@ -310,7 +429,7 @@ namespace System.Web.Configuration
                        throw new NotImplementedException ();
                }
 
-               [MonoTODO]
+               [MonoTODO ("Not implemented")]
                public virtual void RequireCompleteInit (IInternalConfigRecord configRecord)
                {
                        throw new NotImplementedException ();
@@ -326,17 +445,20 @@ namespace System.Web.Configuration
                        throw new NotImplementedException ();
                }
                
-               public virtual void VerifyDefinitionAllowed (string configPath, ConfigurationAllowDefinition allowDefinition, ConfigurationAllowExeDefinition allowExeDefinition, IConfigErrorInfo errorInfo)
+               public virtual void VerifyDefinitionAllowed (string configPath, ConfigurationAllowDefinition allowDefinition,
+                                                            ConfigurationAllowExeDefinition allowExeDefinition,
+                                                            IConfigErrorInfo errorInfo)
                {
                        if (!IsDefinitionAllowed (configPath, allowDefinition, allowExeDefinition))
                                throw new ConfigurationErrorsException ("The section can't be defined in this file (the allowed definition context is '" + allowDefinition + "').", errorInfo.Filename, errorInfo.LineNumber);
                }
                
+               [MonoTODO("Does nothing")]
                public virtual void WriteCompleted (string streamName, bool success, object writeContext)
                {
                }
                
-               [MonoTODO]
+               [MonoTODO("Does nothing")]
                public virtual void WriteCompleted (string streamName, bool success, object writeContext, bool assertPermissions)
                {
                }
@@ -357,30 +479,30 @@ namespace System.Web.Configuration
                        get { return false; }
                }
 
-               [MonoTODO]
+               [MonoTODO("Always returns false")]
                public virtual bool IsRemote {
                        get { return false; }
                }
 
-               [MonoTODO]
+               [MonoTODO ("Not implemented")]
                public virtual bool IsFullTrustSectionWithoutAptcaAllowed (IInternalConfigRecord configRecord)
                {
                        throw new NotImplementedException ();
                }
 
-               [MonoTODO]
+               [MonoTODO ("Not implemented")]
                public virtual bool IsInitDelayed (IInternalConfigRecord configRecord)
                {
                        throw new NotImplementedException ();
                }
 
-               [MonoTODO]
+               [MonoTODO ("Not implemented")]
                public virtual bool IsSecondaryRoot (string configPath)
                {
                        throw new NotImplementedException ();
                }
 
-               [MonoTODO]
+               [MonoTODO ("Not implemented")]
                public virtual bool IsTrustedConfigPath (string configPath)
                {
                        throw new NotImplementedException ();