Forráskód Böngészése

2008-04-07 Marek Habersack <[email protected]>

	* VirtualPath.cs: added

2008-04-08  Marek Habersack  <[email protected]>

	* System.Web.dll.sources: added System.Web/VirtualPath.cs

2008-04-08  Marek Habersack  <[email protected]>

	* DefaultVirtualDirectory.cs: fixed the constructor - derive
	virtual directory from the original path.
	AddDirectories and AddFiles combine the virtual paths properly
	now.

2008-04-08  Marek Habersack  <[email protected]>

	* TemplateParser.cs: CodeFile/Src handling uses
	HostingEnvironment.VirtualPathProvider to check for file
	existence.

2008-04-08  Marek Habersack  <[email protected]>

	* TemplateParser.cs: CodeFile/Src handling uses
	HostingEnvironment.VirtualPathProvider to check for file
	existence.

2008-04-08  Marek Habersack  <[email protected]>

	* AppCodeCompiler.cs: VirtualPath used in PhysicalToVirtual.

	* BuildManager.cs: switched to VirtualPath instead of a string
	path in several methods.
	Batch compilation is turned off if we have a custom
	VirtualPathProvider which implements only the VirtualFile and
	falls back to DefaultVirtualDirectory implementation for directory
	access.

	* GenericBuildProvider.cs: AddCodeFile accepts a virtual path.

	* BuildProvider.cs: SetVirtualPath accepts a VirtualPath now.

	* AssemblyBuilder.cs: constructors use the new VirtualPath class
	now.
	AddCodeFile can use the VirtualPathProvider if necessary now.
	BuildAssembly overloads accept VirtualPath parameter instead of a
	string path now.

	* TemplateBuildProvider.cs: GetCodeBehindSource returns the
	virtual path now.

svn path=/trunk/mcs/; revision=100063
Marek Habersack 17 éve
szülő
commit
1e9e697cc9

+ 4 - 0
mcs/class/System.Web/ChangeLog

@@ -1,3 +1,7 @@
+2008-04-08  Marek Habersack  <[email protected]>
+
+	* System.Web.dll.sources: added System.Web/VirtualPath.cs
+
 2008-03-09  Dean Brettle <[email protected]> 
 
 	* System.Web_test.dll.sources: added

+ 2 - 2
mcs/class/System.Web/System.Web.Compilation/AppCodeCompiler.cs

@@ -271,9 +271,9 @@ namespace System.Web.Compilation
 			}
 		}
 		
-		private string PhysicalToVirtual (string file)
+		private VirtualPath PhysicalToVirtual (string file)
 		{
-			return file.Replace (HttpRuntime.AppDomainAppPath, "/").Replace (Path.DirectorySeparatorChar, '/');
+			return new VirtualPath (file.Replace (HttpRuntime.AppDomainAppPath, "/").Replace (Path.DirectorySeparatorChar, '/'));
 		}
 		
 		private BuildProvider GetBuildProviderFor (string file, BuildProviderCollection buildProviders)

+ 41 - 11
mcs/class/System.Web/System.Web.Compilation/AssemblyBuilder.cs

@@ -41,6 +41,7 @@ using System.IO;
 using System.Reflection;
 using System.Web.Configuration;
 using System.Web.Util;
+using System.Web.Hosting;
 
 namespace System.Web.Compilation {
 	internal class CompileUnitPartialType
@@ -78,6 +79,7 @@ namespace System.Web.Compilation {
 	
 	public class AssemblyBuilder {
 		const string DEFAULT_ASSEMBLY_BASE_NAME = "App_Web_";
+		const int COPY_BUFFER_SIZE = 8192;
 		
 		static bool KeepFiles = (Environment.GetEnvironmentVariable ("MONO_ASPNET_NODELETE") != null);
 		
@@ -103,11 +105,11 @@ namespace System.Web.Compilation {
 		: this (null, provider, assemblyBaseName)
 		{}
 
-		internal AssemblyBuilder (string virtualPath, CodeDomProvider provider)
+		internal AssemblyBuilder (VirtualPath virtualPath, CodeDomProvider provider)
 		: this (virtualPath, provider, DEFAULT_ASSEMBLY_BASE_NAME)
 		{}
 		
-		internal AssemblyBuilder (string virtualPath, CodeDomProvider provider, string assemblyBaseName)
+		internal AssemblyBuilder (VirtualPath virtualPath, CodeDomProvider provider, string assemblyBaseName)
 		{
 			this.provider = provider;
 			this.outputFilesPrefix = assemblyBaseName ?? DEFAULT_ASSEMBLY_BASE_NAME;
@@ -116,7 +118,7 @@ namespace System.Web.Compilation {
 
 			CompilationSection section;
 			if (virtualPath != null)
-				section = (CompilationSection) WebConfigurationManager.GetSection ("system.web/compilation", virtualPath);
+				section = (CompilationSection) WebConfigurationManager.GetSection ("system.web/compilation", virtualPath.Absolute);
 			else
 				section = (CompilationSection) WebConfigurationManager.GetSection ("system.web/compilation");
 			string tempdir = section.TempDirectory;
@@ -296,10 +298,15 @@ namespace System.Web.Compilation {
 
 		internal void AddCodeFile (string path)
 		{
-			AddCodeFile (path, null);
+			AddCodeFile (path, null, false);
 		}
-		
+
 		internal void AddCodeFile (string path, BuildProvider bp)
+		{
+			AddCodeFile (path, bp, false);
+		}
+		
+		internal void AddCodeFile (string path, BuildProvider bp, bool isVirtual)
 		{
 			if (String.IsNullOrEmpty (path))
 				return;
@@ -315,7 +322,24 @@ namespace System.Web.Compilation {
 				return; // maybe better to throw an exception here?
 			extension = extension.Substring (1);
 			string filename = GetTempFilePhysicalPath (extension);
-			File.Copy (path, filename, true);
+
+			if (isVirtual) {
+				VirtualFile vf = HostingEnvironment.VirtualPathProvider.GetFile (path);
+				if (vf == null)
+					throw new HttpException (404, "Virtual file '" + path + "' does not exist.");
+				
+				using (FileStream f = new FileStream (filename, FileMode.Create, FileAccess.Write)) {
+					using (Stream s = vf.Open ()) {
+						byte[] input = new byte [COPY_BUFFER_SIZE];
+						int retval;
+
+						while ((retval = s.Read (input, 0, COPY_BUFFER_SIZE)) > 0)
+							f.Write (input, 0, retval);
+					}
+				}
+			} else
+				File.Copy (path, filename);
+			
 			SourceFiles.Add (filename);
 		}
 		
@@ -478,7 +502,7 @@ namespace System.Web.Compilation {
 			return null;
 		}
 		
-		internal CompilerResults BuildAssembly (string virtualPath)
+		internal CompilerResults BuildAssembly (VirtualPath virtualPath)
 		{
 			return BuildAssembly (virtualPath, CompilerOptions);
 		}
@@ -488,7 +512,7 @@ namespace System.Web.Compilation {
 			return BuildAssembly (null, options);
 		}
 		
-		internal CompilerResults BuildAssembly (string virtualPath, CompilerParameters options)
+		internal CompilerResults BuildAssembly (VirtualPath virtualPath, CompilerParameters options)
 		{
 			if (options == null)
 				throw new ArgumentNullException ("options");
@@ -546,15 +570,21 @@ namespace System.Web.Compilation {
 						fileText = sr.ReadToEnd ();
 					}
 				} catch (Exception) {}
-
-				throw new CompilationException (virtualPath, results, fileText);
+				
+#if DEBUG
+				Console.WriteLine ("Compilation failed. Errors:");
+				foreach (CompilerError err in results.Errors)
+					Console.WriteLine (err);
+#endif
+				
+				throw new CompilationException (virtualPath.Original, results, fileText);
 			}
 			
 			Assembly assembly = results.CompiledAssembly;
 			if (assembly == null) {
 				if (!File.Exists (options.OutputAssembly)) {
 					results.TempFiles.Delete ();
-					throw new CompilationException (virtualPath, results.Errors,
+					throw new CompilationException (virtualPath.Original, results.Errors,
 						"No assembly returned after compilation!?");
 				}
 

+ 78 - 94
mcs/class/System.Web/System.Web.Compilation/BuildManager.cs

@@ -353,18 +353,18 @@ namespace System.Web.Compilation {
 			return null; // null is ok here until we store the dependency set in the Cache.
 		}
 
-		internal static BuildProvider GetBuildProviderForPath (string virtualPath, bool throwOnMissing)
+		internal static BuildProvider GetBuildProviderForPath (VirtualPath virtualPath, bool throwOnMissing)
 		{
 			return GetBuildProviderForPath (virtualPath, null, throwOnMissing);
 		}
 		
-		internal static BuildProvider GetBuildProviderForPath (string virtualPath, CompilationSection section, bool throwOnMissing)
+		internal static BuildProvider GetBuildProviderForPath (VirtualPath virtualPath, CompilationSection section, bool throwOnMissing)
 		{
-			string extension = VirtualPathUtility.GetExtension (virtualPath);
+			string extension = virtualPath.Extension;
 			CompilationSection c = section;
 
 			if (c == null)
-				c = WebConfigurationManager.GetSection ("system.web/compilation", virtualPath) as CompilationSection;
+				c = WebConfigurationManager.GetSection ("system.web/compilation", virtualPath.Original) as CompilationSection;
 			
 			if (c == null)
 				if (throwOnMissing)
@@ -387,7 +387,7 @@ namespace System.Web.Compilation {
 			return provider;
 		}
 
-		static string GetAbsoluteVirtualPath (string virtualPath)
+		static VirtualPath GetAbsoluteVirtualPath (string virtualPath)
 		{
 			string vp;
 
@@ -401,19 +401,16 @@ namespace System.Web.Compilation {
 					throw new HttpException ("No context, cannot map paths.");
 			} else
 				vp = virtualPath;
-			
-			if (VirtualPathUtility.IsAppRelative (vp))
-				return VirtualPathUtility.ToAbsolute (vp);
-			else
-				return vp;
+
+			return new VirtualPath (vp);
 		}
 		
-		static BuildCacheItem GetCachedItem (string virtualPath)
+		static BuildCacheItem GetCachedItem (VirtualPath virtualPath)
 		{
 			BuildCacheItem ret;
 			
 			lock (buildCacheLock) {
-				if (buildCache.TryGetValue (virtualPath, out ret))
+				if (buildCache.TryGetValue (virtualPath.Absolute, out ret))
 					return ret;
 			}
 
@@ -422,7 +419,7 @@ namespace System.Web.Compilation {
 		
 		public static Assembly GetCompiledAssembly (string virtualPath)
 		{
-			string vp = GetAbsoluteVirtualPath (virtualPath);
+			VirtualPath vp = GetAbsoluteVirtualPath (virtualPath);
 			BuildCacheItem ret = GetCachedItem (vp);
 			if (ret != null)
 				return ret.assembly;
@@ -437,7 +434,7 @@ namespace System.Web.Compilation {
 
 		public static Type GetCompiledType (string virtualPath)
 		{
-			string vp = GetAbsoluteVirtualPath (virtualPath);
+			VirtualPath vp = GetAbsoluteVirtualPath (virtualPath);
 			BuildCacheItem ret = GetCachedItem (vp);
 
 			if (ret != null)
@@ -454,7 +451,7 @@ namespace System.Web.Compilation {
 		
 		public static string GetCompiledCustomString (string virtualPath)
 		{
-			string vp = GetAbsoluteVirtualPath (virtualPath);
+			VirtualPath vp = GetAbsoluteVirtualPath (virtualPath);
 			BuildCacheItem ret = GetCachedItem (vp);
 			if (ret != null)
 				return ret.compiledCustomString;
@@ -466,25 +463,19 @@ namespace System.Web.Compilation {
 
 			return null;
 		}
-		
-		static List <string> GetFilesForBuild (string virtualPath, string physicalDir, out BuildKind kind)
+
+		static List <VirtualFile> GetFilesForBuild (VirtualPath virtualPath, out BuildKind kind)
 		{
-			string extension = VirtualPathUtility.GetExtension (virtualPath);
-			List <string> ret = new List <string> ();
+			string extension = virtualPath.Extension;
+			var ret = new List <VirtualFile> ();
 			
-			if (StrUtils.StartsWith (virtualPath, FAKE_VIRTUAL_PATH_PREFIX)) {
+			if (virtualPath.StartsWith (FAKE_VIRTUAL_PATH_PREFIX)) {
 				kind = BuildKind.Fake;
 				return ret;
 			}
 			
 			if (!knownFileTypes.TryGetValue (extension, out kind)) {
-				string tmp;
-				if (VirtualPathUtility.IsAbsolute (virtualPath))
-					tmp = VirtualPathUtility.ToAppRelative (virtualPath);
-				else
-					tmp = virtualPath;
-					
-				if (StrUtils.StartsWith (tmp, "~/App_Themes/"))
+				if (StrUtils.StartsWith (virtualPath.AppRelative, "~/App_Themes/"))
 					kind = BuildKind.Theme;
 				else
 					kind = BuildKind.Unknown;
@@ -500,20 +491,32 @@ namespace System.Web.Compilation {
 					doBatch = false;
 				recursiveBuilds.Push (kind);
 			}
+
+			string vpAbsolute = virtualPath.Absolute;
+			VirtualPathProvider vpp = HostingEnvironment.VirtualPathProvider;
+			VirtualDirectory dir = vpp.GetDirectory (vpAbsolute);
+			
+			if (doBatch && HostingEnvironment.HaveCustomVPP && dir != null && dir is DefaultVirtualDirectory)
+				doBatch = false;
 			
 			if (doBatch) {
-				string[] files = Directory.GetFiles (physicalDir, "*.*");
+				if (dir == null)
+					throw new HttpException (404, "Virtual directory '" + virtualPath.Directory + "' does not exist.");
+				
 				BuildKind fileKind;
-			
-				foreach (string file in files) {
-					if (!knownFileTypes.TryGetValue (Path.GetExtension (file), out fileKind))
+				foreach (VirtualFile file in dir.Files) {
+					if (!knownFileTypes.TryGetValue (VirtualPathUtility.GetExtension (file.Name), out fileKind))
 						continue;
-					
+
 					if (kind == fileKind)
 						ret.Add (file);
 				}
-			} else
-				ret.Add (Path.Combine (physicalDir, VirtualPathUtility.GetFileName (virtualPath)));
+			} else {
+				VirtualFile vf = vpp.GetFile (vpAbsolute);
+				if (vf == null)
+					throw new HttpException (404, "Virtual file '" + virtualPath + "' does not exist.");
+				ret.Add (vf);
+			}
 			
 			return ret;
 		}
@@ -531,24 +534,9 @@ namespace System.Web.Compilation {
 				throw new HttpException (String.Concat ("Provider '", provider, " 'fails to specify the compiler type."));
 
 			return codeDomProviderType;
-		}
-		
-		static string GetVirtualPathDirectory (string virtualPath)
-		{
-			string vp;
-			if (!VirtualPathUtility.IsRooted (virtualPath))
-				vp = VirtualPathUtility.ToAbsolute ("~/" + virtualPath);
-			else {
-				if (VirtualPathUtility.IsAppRelative (virtualPath))
-					vp = VirtualPathUtility.ToAbsolute (virtualPath);
-				else
-					vp = virtualPath;
-			}
-
-			return VirtualPathUtility.GetDirectory (vp);
-		}
+		}		
 
-		static List <BuildItem> LoadBuildProviders (string virtualPath, string virtualDir, Dictionary <string, bool> vpCache,
+		static List <BuildItem> LoadBuildProviders (VirtualPath virtualPath, string virtualDir, Dictionary <string, bool> vpCache,
 							    out BuildKind kind, out string assemblyBaseName)
 		{
 			HttpContext ctx = HttpContext.Current;
@@ -557,13 +545,12 @@ namespace System.Web.Compilation {
 			if (req == null)
 				throw new HttpException ("No context available, cannot build.");
 
-			CompilationSection section = WebConfigurationManager.GetSection ("system.web/compilation", virtualPath) as CompilationSection;
-			string physicalDir = req.MapPath (virtualDir);
-			
-			List <string> files;
+			string vpAbsolute = virtualPath.Absolute;
+			CompilationSection section = WebConfigurationManager.GetSection ("system.web/compilation", vpAbsolute) as CompilationSection;
+			List <VirtualFile> files;
 			
 			try {
-				files = GetFilesForBuild (virtualPath, physicalDir, out kind);
+				files = GetFilesForBuild (virtualPath, out kind);
 			} catch (Exception ex) {
 				throw new HttpException ("Error loading build providers for path '" + virtualDir + "'.", ex);
 			}
@@ -603,10 +590,8 @@ namespace System.Web.Compilation {
 			string fileName;
 			
 			lock (buildCacheLock) {
-				foreach (string f in files) {
-					fileName = Path.GetFileName (f);
-					fileVirtualPath = VirtualPathUtility.Combine (virtualDir, fileName);
-
+				foreach (VirtualFile f in files) {
+					fileVirtualPath = f.VirtualPath;
 					if (IgnoreVirtualPath (fileVirtualPath))
 						continue;
 					
@@ -614,7 +599,7 @@ namespace System.Web.Compilation {
 						continue;
 					
 					vpCache.Add (fileVirtualPath, true);
-					provider = GetBuildProviderForPath (fileVirtualPath, section, false);
+					provider = GetBuildProviderForPath (new VirtualPath (fileVirtualPath), section, false);
 					if (provider == null)
 						continue;
 
@@ -641,11 +626,12 @@ namespace System.Web.Compilation {
 			if (virtualPathsToIgnore == null)
 				virtualPathsToIgnore = new Dictionary <string, bool> ();
 			
-			string path = GetAbsoluteVirtualPath (vp);
-			if (virtualPathsToIgnore.ContainsKey (path))
+			VirtualPath path = GetAbsoluteVirtualPath (vp);
+			string vpAbsolute = path.Absolute;
+			if (virtualPathsToIgnore.ContainsKey (vpAbsolute))
 				return;
 
-			virtualPathsToIgnore.Add (path, true);
+			virtualPathsToIgnore.Add (vpAbsolute, true);
 			haveVirtualPathsToIgnore = true;
 		}
 
@@ -702,7 +688,7 @@ namespace System.Web.Compilation {
 			}
 		}
 		
-		static AssemblyBuilder CreateAssemblyBuilder (string assemblyBaseName, string virtualPath, BuildItem buildItem)
+		static AssemblyBuilder CreateAssemblyBuilder (string assemblyBaseName, VirtualPath virtualPath, BuildItem buildItem)
 		{
 			buildItem.assemblyBuilder = new AssemblyBuilder (virtualPath, buildItem.CreateCodeDomProvider (), assemblyBaseName);
 			buildItem.assemblyBuilder.CompilerOptions = buildItem.CompilerOptions;
@@ -843,7 +829,7 @@ namespace System.Web.Compilation {
 			return true;
 		}
 		
-		static void AssignToAssemblyBuilder (string assemblyBaseName, string virtualPath, BuildItem buildItem,
+		static void AssignToAssemblyBuilder (string assemblyBaseName, VirtualPath virtualPath, BuildItem buildItem,
 						     Dictionary <Type, List <AssemblyBuilder>> assemblyBuilders)
 		{
 			if (!buildItem.codeGenerated)
@@ -871,47 +857,44 @@ namespace System.Web.Compilation {
 			buildItem.StoreCodeUnit ();
 		}
 
-		static void AssertVirtualPathExists (string virtualPath)
+		static void AssertVirtualPathExists (VirtualPath virtualPath)
 		{
 			string realpath;
-			bool fakePath;
+			bool dothrow = false;
 			
-			if (StrUtils.StartsWith (virtualPath, FAKE_VIRTUAL_PATH_PREFIX)) {
-				realpath = virtualPath.Substring (FAKE_VIRTUAL_PATH_PREFIX.Length);
-				fakePath = true;
+			if (virtualPath.StartsWith (FAKE_VIRTUAL_PATH_PREFIX)) {
+				realpath = virtualPath.Original.Substring (FAKE_VIRTUAL_PATH_PREFIX.Length);
+				if (!File.Exists (realpath) && !Directory.Exists (realpath))
+					dothrow = true;
 			} else {
-				HttpContext ctx = HttpContext.Current;
-				HttpRequest req = ctx != null ? ctx.Request : null;
-
-				if (req == null)
-					throw new HttpException ("Missing context, cannot continue.");
-
-				realpath = req.MapPath (virtualPath);
+				VirtualPathProvider vpp = HostingEnvironment.VirtualPathProvider;
+				string vpPath = virtualPath.Original;
+				
+				if (!vpp.FileExists (vpPath) && !vpp.DirectoryExists (vpPath))
+					dothrow = true;
 			}
 
-			if (!File.Exists (realpath) && !Directory.Exists (realpath))
-				if (!HostingEnvironment.VirtualPathProvider.FileExists (virtualPath))
-					throw new HttpException (404,
-								 "The file '" + virtualPath + "' does not exist.",
-								 fakePath ? Path.GetFileName (realpath) : virtualPath);
+			if (dothrow)
+				throw new HttpException (404, "The file '" + virtualPath + "' does not exist.");
 		}
 		
-		static void BuildAssembly (string virtualPath)
+		static void BuildAssembly (VirtualPath virtualPath)
 		{
 			AssertVirtualPathExists (virtualPath);
 			LoadVirtualPathsToIgnore ();
 			
 			object ticket;
 			bool acquired;
-			string virtualDir = GetVirtualPathDirectory (virtualPath);
+			string virtualDir = virtualPath.Directory;
 			BuildKind buildKind = BuildKind.Unknown;
 			bool kindPushed = false;
+			string vpAbsolute = virtualPath.Absolute;
 			
 			acquired = AcquireCompilationTicket (virtualDir, out ticket);
 			try {
 				Monitor.Enter (ticket);
 				lock (buildCacheLock) {
-					if (buildCache.ContainsKey (virtualPath))
+					if (buildCache.ContainsKey (vpAbsolute))
 						return;
 				}
 				
@@ -951,7 +934,7 @@ namespace System.Web.Compilation {
 						try {
 							results = abuilder.BuildAssembly (virtualPath);
 						} catch (CompilationException ex) {
-							throw new HttpException ("Compilation failed for virtual path '" + virtualPath + "'.", ex);
+							throw new HttpException ("Compilation failed for virtual path '" + virtualPath.Original + "'.", ex);
 						}
 						
 						// No results is not an error - it is possible that the assembly builder contained only .asmx and
@@ -1052,7 +1035,7 @@ namespace System.Web.Compilation {
 						       
 		}
 
-		static int RemoveVirtualPathFromCaches (string virtualPath)
+		static int RemoveVirtualPathFromCaches (VirtualPath virtualPath)
 		{
 			lock (buildCacheLock) {
 				// This is expensive, but we must do it - we must not leave
@@ -1063,13 +1046,14 @@ namespace System.Web.Compilation {
 				if (item == null)
 					return 0;
 
-				if (buildCache.ContainsKey (virtualPath))
-					buildCache.Remove (virtualPath);
+				string vpAbsolute = virtualPath.Absolute;
+				if (buildCache.ContainsKey (vpAbsolute))
+					buildCache.Remove (vpAbsolute);
 
 				Assembly asm;
 				
-				if (nonPagesCache.TryGetValue (virtualPath, out asm)) {
-					nonPagesCache.Remove (virtualPath);
+				if (nonPagesCache.TryGetValue (vpAbsolute, out asm)) {
+					nonPagesCache.Remove (vpAbsolute);
 					if (referencedAssemblies.Contains (asm))
 						referencedAssemblies.Remove (asm);
 
@@ -1099,7 +1083,7 @@ namespace System.Web.Compilation {
 			else
 				return;
 
-			RemoveVirtualPathFromCaches (virtualPath);
+			RemoveVirtualPathFromCaches (new VirtualPath (virtualPath));
 		}
 		
 		static bool AcquireCompilationTicket (string key, out object ticket)
@@ -1148,7 +1132,7 @@ namespace System.Web.Compilation {
 		{
 			BuildProvider provider = bprovider;
 			if (provider == null)
-				provider = GetBuildProviderForPath (virtualPath, false);
+				provider = GetBuildProviderForPath (new VirtualPath (virtualPath), false);
 			if (provider == null)
 				return null;
 			return provider.VirtualPathDependencies;

+ 3 - 10
mcs/class/System.Web/System.Web.Compilation/BuildProvider.cs

@@ -55,16 +55,9 @@ namespace System.Web.Compilation {
 			ref_assemblies = new ArrayList ();
 		}
 
-		internal void SetVirtualPath (string virtualPath)
-		{
-			if (!VirtualPathUtility.IsRooted (virtualPath))
-				virtual_path = "/" + virtualPath;
-			else {
-				if (VirtualPathUtility.IsAppRelative (virtualPath))
-					virtual_path = VirtualPathUtility.ToAbsolute (virtualPath);
-				else
-					virtual_path = virtualPath;
-			}
+		internal void SetVirtualPath (VirtualPath virtualPath)
+		{
+			virtual_path = virtualPath.Absolute;
 		}
 
 		internal virtual void GenerateCode ()

+ 24 - 0
mcs/class/System.Web/System.Web.Compilation/ChangeLog

@@ -1,3 +1,27 @@
+2008-04-08  Marek Habersack  <[email protected]>
+
+	* AppCodeCompiler.cs: VirtualPath used in PhysicalToVirtual.
+
+	* BuildManager.cs: switched to VirtualPath instead of a string
+	path in several methods.
+	Batch compilation is turned off if we have a custom
+	VirtualPathProvider which implements only the VirtualFile and
+	falls back to DefaultVirtualDirectory implementation for directory
+	access.
+
+	* GenericBuildProvider.cs: AddCodeFile accepts a virtual path.
+
+	* BuildProvider.cs: SetVirtualPath accepts a VirtualPath now.
+
+	* AssemblyBuilder.cs: constructors use the new VirtualPath class
+	now.
+	AddCodeFile can use the VirtualPathProvider if necessary now.
+	BuildAssembly overloads accept VirtualPath parameter instead of a
+	string path now.
+
+	* TemplateBuildProvider.cs: GetCodeBehindSource returns the
+	virtual path now.
+
 2008-03-31  Marek Habersack  <[email protected]>
 
 	* AppCodeCompiler.cs: implemented support for AppInitialize (a

+ 1 - 1
mcs/class/System.Web/System.Web.Compilation/GenericBuildProvider.cs

@@ -106,7 +106,7 @@ namespace System.Web.Compilation
 			
 			string codeBehindSource = GetCodeBehindSource (parser);
 			if (codeBehindSource != null)
-				assemblyBuilder.AddCodeFile (codeBehindSource, this);
+				assemblyBuilder.AddCodeFile (codeBehindSource, this, true);
 
 			List <string> refasms = GetReferencedAssemblies (parser);
 			if (refasms != null && refasms.Count > 0) {

+ 2 - 8
mcs/class/System.Web/System.Web.Compilation/TemplateBuildProvider.cs

@@ -71,15 +71,9 @@ namespace System.Web.Compilation
 			if (parser != null) {
 				string codeBehind = parser.CodeBehindSource;
 				if (String.IsNullOrEmpty (codeBehind))
-					return null;
-				
-				HttpContext ctx = HttpContext.Current;
-				HttpRequest req = ctx != null ? ctx.Request : null;
+					return null;				
 
-				if (req == null)
-					throw new HttpException ("Missing current context.");
-
-				return req.MapPath (parser.CodeBehindSource);
+				return parser.CodeBehindSource;
 			}
 			
 			return null;

+ 7 - 0
mcs/class/System.Web/System.Web.Hosting/ChangeLog

@@ -1,3 +1,10 @@
+2008-04-08  Marek Habersack  <[email protected]>
+
+	* DefaultVirtualDirectory.cs: fixed the constructor - derive
+	virtual directory from the original path.
+	AddDirectories and AddFiles combine the virtual paths properly
+	now.
+
 2008-04-01  Marek Habersack  <[email protected]>
 
 	* HostingEnvironment.cs: initialize custom VPP on

+ 3 - 3
mcs/class/System.Web/System.Web.Hosting/DefaultVirtualDirectory.cs

@@ -50,15 +50,15 @@ namespace System.Web.Hosting {
 		{
 			if (phys_dir == null) {
 				string vpath = VirtualPath;
-				phys_dir = HostingEnvironment.MapPath (vpath);
 				virtual_dir = VirtualPathUtility.GetDirectory (vpath);
+				phys_dir = HostingEnvironment.MapPath (virtual_dir);
 			}
 		}
 
 		ArrayList AddDirectories (ArrayList list, string dir)
 		{
 			foreach (string name in Directory.GetDirectories (phys_dir)) {
-				string vdir = VirtualPathUtility.Combine (virtual_dir, name);
+				string vdir = VirtualPathUtility.Combine (virtual_dir, Path.GetFileName (name));
 				list.Add (new DefaultVirtualDirectory (vdir));
 			}
 			return list;
@@ -67,7 +67,7 @@ namespace System.Web.Hosting {
 		ArrayList AddFiles (ArrayList list, string dir)
 		{
 			foreach (string name in Directory.GetFiles (phys_dir)) {
-				string vdir = VirtualPathUtility.Combine (virtual_dir, name);
+				string vdir = VirtualPathUtility.Combine (virtual_dir, Path.GetFileName (name));
 				list.Add (new DefaultVirtualFile (vdir));
 			}
 			return list;

+ 6 - 0
mcs/class/System.Web/System.Web.UI/ChangeLog

@@ -1,3 +1,9 @@
+2008-04-08  Marek Habersack  <[email protected]>
+
+	* TemplateParser.cs: CodeFile/Src handling uses
+	HostingEnvironment.VirtualPathProvider to check for file
+	existence.
+
 2008-04-02  Marek Habersack  <[email protected]>
 
 	* Page.cs: make SetContext internal (used from tests).

+ 3 - 3
mcs/class/System.Web/System.Web.UI/TemplateParser.cs

@@ -629,8 +629,8 @@ namespace System.Web.UI {
 				// Make sure the source exists
 				src = UrlUtils.Combine (BaseVirtualDir, src);
 				srcRealPath = MapPath (src, false);
-				
-				if (!File.Exists (srcRealPath))
+
+				if (!HostingEnvironment.VirtualPathProvider.FileExists (src))
 					ThrowParseException ("File " + src + " not found");
 
 				// We are going to create a partial class that shares
@@ -839,7 +839,7 @@ namespace System.Web.UI {
 			abuilder.CompilerOptions = parameters;
 			abuilder.AddAssemblyReference (BuildManager.GetReferencedAssemblies () as List <Assembly>);
 			abuilder.AddCodeFile (realPath);
-			result = abuilder.BuildAssembly (vpath);
+			result = abuilder.BuildAssembly (new VirtualPath (vpath));
 #else
 			result = CachingCompiler.Compile (language, realPath, realPath, assemblies, Debug);
 #endif

+ 1 - 0
mcs/class/System.Web/System.Web.dll.sources

@@ -1159,6 +1159,7 @@ System.Web.Util/WebEncoding.cs
 System.Web.Util/WebTrace.cs
 System.Web.Util/WorkItemCallback.cs
 System.Web.Util/WorkItem.cs
+System.Web/VirtualPath.cs
 System.Web/VirtualPathUtility.cs
 System.Web/WebCategoryAttribute.cs
 System.Web/WebPageTraceListener.cs

+ 4 - 0
mcs/class/System.Web/System.Web/ChangeLog

@@ -1,3 +1,7 @@
+2008-04-07  Marek Habersack  <[email protected]>
+
+	* VirtualPath.cs: added
+
 2008-04-02  Marek Habersack  <[email protected]>
 
 	* HttpRequest.cs: make sure QueryStringRaw is always returned with

+ 166 - 0
mcs/class/System.Web/System.Web/VirtualPath.cs

@@ -0,0 +1,166 @@
+//
+// System.Web.VirtualPath.cs
+//
+// Authors:
+//   Marek Habersack ([email protected])
+//
+// (C) 2008 Novell, Inc
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+#if NET_2_0
+using System.Web.Util;
+
+namespace System.Web
+{
+	internal class VirtualPath : IDisposable
+	{
+		string _absolute;
+		string _appRelative;
+		string _appRelativeNotRooted;
+		string _extension;
+		string _directory;
+		
+		public bool IsAbsolute {
+			get;
+			private set;
+		}
+
+		public bool IsRooted {
+			get;
+			private set;
+		}
+
+		public bool IsAppRelative {
+			get;
+			private set;
+		}
+		
+		public string Original {
+			get;
+			private set;
+		}
+
+		public string Absolute {
+			get {
+				if (IsAbsolute)
+					return Original;
+
+				if (_absolute == null) {
+					string original = Original;
+					
+					if (!VirtualPathUtility.IsRooted (original))
+						_absolute = MakeRooted (original);
+					else
+						_absolute = original;
+
+					if (VirtualPathUtility.IsAppRelative (_absolute))
+						_absolute = VirtualPathUtility.ToAbsolute (_absolute);
+				}
+
+				return _absolute;
+			}
+		}
+
+		public string AppRelative {
+			get {
+				if (IsAppRelative)
+					return Original;
+
+				if (_appRelative == null) {
+					string original = Original;
+					
+					if (!VirtualPathUtility.IsRooted (original))
+						_appRelative = MakeRooted (original);
+					else
+						_appRelative = original;
+					
+					if (VirtualPathUtility.IsAbsolute (_appRelative))
+						_appRelative = VirtualPathUtility.ToAppRelative (_appRelative);
+				}
+
+				return _appRelative;
+			}
+		}
+		
+		public string AppRelativeNotRooted {
+			get {
+				if (_appRelativeNotRooted == null)
+					_appRelativeNotRooted = AppRelative.Substring (2);
+
+				return _appRelativeNotRooted;
+			}
+		}
+
+		public string Extension {
+			get {
+				if (_extension == null)
+					_extension = VirtualPathUtility.GetExtension (Original);
+
+				return _extension;
+			}
+		}
+
+		public string Directory {
+			get {
+				if (_directory == null)
+					_directory = VirtualPathUtility.GetDirectory (Absolute);
+
+				return _directory;
+			}
+		}
+		
+		public VirtualPath (string vpath)
+		{
+			Original = vpath;
+
+			IsRooted = VirtualPathUtility.IsRooted (vpath);
+			IsAbsolute = VirtualPathUtility.IsAbsolute (vpath);
+			IsAppRelative = VirtualPathUtility.IsAppRelative (vpath);
+		}
+
+		public bool StartsWith (string s)
+		{
+			return StrUtils.StartsWith (Original, s);
+		}
+		
+		string MakeRooted (string original)
+		{
+			return VirtualPathUtility.Combine (HttpRuntime.AppDomainAppVirtualPath, original);
+		}
+
+		public void Dispose ()
+		{
+			_absolute = null;
+			_appRelative = null;
+			_appRelativeNotRooted = null;
+			_extension = null;
+			_directory = null;
+		}
+		
+		public override string ToString ()
+		{
+			return Original;
+		}
+	}
+}
+#endif