// // System.Web.Compilation.ClientBuildManager // // Authors: // Chris Toshok (toshok@ximian.com) // Gonzalo Paniagua Javier (gonzalo@ximian.com) // // (C) 2006 Novell, Inc (http://www.novell.com) // // // 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; using System.CodeDom; using System.CodeDom.Compiler; using System.Collections; using System.Globalization; using System.IO; using System.Web; using System.Web.Hosting; namespace System.Web.Compilation { public sealed class ClientBuildManager : MarshalByRefObject, IDisposable { string virt_dir; string phys_src_dir; //string phys_target_dir; //ClientBuildManagerParameter build_params; BareApplicationHost host; ApplicationManager manager; string app_id; string cache_path; public ClientBuildManager (string appVirtualDir, string appPhysicalSourceDir) { if (appVirtualDir == null || appVirtualDir == "") throw new ArgumentNullException ("appVirtualDir"); if (appPhysicalSourceDir == null || appPhysicalSourceDir == "") throw new ArgumentNullException ("appPhysicalSourceDir"); virt_dir = appVirtualDir; // TODO: adjust vpath (it allows 'blah' that turns into '/blah', '////blah', '\\blah'... phys_src_dir = appPhysicalSourceDir; manager = ApplicationManager.GetApplicationManager (); } public ClientBuildManager (string appVirtualDir, string appPhysicalSourceDir, string appPhysicalTargetDir) : this (appVirtualDir, appPhysicalSourceDir) { if (appPhysicalTargetDir == null || appPhysicalTargetDir == "") throw new ArgumentNullException ("appPhysicalTargetDir"); //phys_target_dir = appPhysicalTargetDir; } public ClientBuildManager (string appVirtualDir, string appPhysicalSourceDir, string appPhysicalTargetDir, ClientBuildManagerParameter parameter) : this (appVirtualDir, appPhysicalSourceDir, appPhysicalTargetDir) { //build_params = parameter; } public event BuildManagerHostUnloadEventHandler AppDomainShutdown; public event EventHandler AppDomainStarted; public event BuildManagerHostUnloadEventHandler AppDomainUnloaded; BareApplicationHost Host { get { if (host != null) return host; int hashcode = virt_dir.GetHashCode (); if (app_id != null) hashcode ^= Int32.Parse (app_id); app_id = hashcode.ToString (CultureInfo.InvariantCulture); host = manager.CreateHostWithCheck (app_id, virt_dir, phys_src_dir); cache_path = ""; //cache_path = Path.Combine (Path.GetTempPath (), //String.Format ("{0}-temp-aspnet-{1:x}", Environment.UserName, i)); int hash = virt_dir.GetHashCode () << 5 + phys_src_dir.GetHashCode (); cache_path = Path.Combine (cache_path, hash.ToString (CultureInfo.InvariantCulture)); Directory.CreateDirectory (cache_path); OnAppDomainStarted (); return host; } } void OnAppDomainStarted () { if (AppDomainStarted != null) AppDomainStarted (this, EventArgs.Empty); } void OnAppDomainShutdown (ApplicationShutdownReason reason) { if (AppDomainShutdown != null) { BuildManagerHostUnloadEventArgs args = new BuildManagerHostUnloadEventArgs (reason); AppDomainShutdown (this, args); } } // void OnDomainUnload (object sender, EventArgs args) // { // OnAppDomainUnloaded (0); // FIXME: set a reason? // } // // void OnAppDomainUnloaded (ApplicationShutdownReason reason) // { // if (AppDomainUnloaded != null) { // BuildManagerHostUnloadEventArgs args = new BuildManagerHostUnloadEventArgs (reason); // AppDomainUnloaded (this, args); // } // } [MonoTODO ("Not implemented")] public void CompileApplicationDependencies () { throw new NotImplementedException (); } public void CompileFile (string virtualPath) { CompileFile (virtualPath, null); } [MonoTODO ("Not implemented")] public void CompileFile (string virtualPath, ClientBuildManagerCallback callback) { // 1. Creates the Host // This creates a .compiled file + an assembly // App_Code reported to be built *before* anything else (with progress callback) throw new NotImplementedException (); } public IRegisteredObject CreateObject (Type type, bool failIfExists) { return manager.CreateObject (app_id, type, virt_dir, phys_src_dir, failIfExists); } [MonoTODO("Currently does not return the GeneratedCode")] public string GenerateCode (string virtualPath, string virtualFileString, out IDictionary linePragmasTable) { // This thing generates a .ccu (CodeCompileUnit?) file (reported as TrueType font data by 'file'!) // resultType=7 vs. resultType=3 for assemblies reported in the .compiled file // The virtual path is just added to the dependencies list, but is checked to be an absolute path. // IsHostCreated returns true after calling this method. // // A null file string causes virtualPath to be mapped and read to generate the code // if (virtualPath == null || virtualPath == "") throw new ArgumentNullException ("virtualPath"); CodeCompileUnit unit = null; Type cprovider_type; CompilerParameters parameters; unit = GenerateCodeCompileUnit (virtualPath, virtualFileString, out cprovider_type, out parameters, out linePragmasTable); return null; } [MonoTODO ("Not implemented")] public CodeCompileUnit GenerateCodeCompileUnit (string virtualPath, string virtualFileString, out Type codeDomProviderType, out CompilerParameters compilerParameters, out IDictionary linePragmasTable) { throw new NotImplementedException (); } public CodeCompileUnit GenerateCodeCompileUnit (string virtualPath, out Type codeDomProviderType, out CompilerParameters compilerParameters, out IDictionary linePragmasTable) { return GenerateCodeCompileUnit (virtualPath, out codeDomProviderType, out compilerParameters, out linePragmasTable); } static string [] shutdown_directories = new string [] { "bin", "App_GlobalResources", "App_Code", "App_WebReferences", "App_Browsers" }; public string [] GetAppDomainShutdownDirectories () { return shutdown_directories; } [MonoTODO ("Not implemented")] public IDictionary GetBrowserDefinitions () { throw new NotImplementedException (); } [MonoTODO ("Not implemented")] public void GetCodeDirectoryInformation (string virtualCodeDir, out Type codeDomProviderType, out CompilerParameters compilerParameters, out string generatedFilesDir) { throw new NotImplementedException (); } [MonoTODO ("Not implemented")] public Type GetCompiledType (string virtualPath) { // CompileFile + get the type based on .compiled file information // Throws if virtualPath is a special virtual directory (App_Code et al) throw new NotImplementedException (); } [MonoTODO ("Not implemented")] public void GetCompilerParameters (string virtualPath, out Type codeDomProviderType, out CompilerParameters compilerParameters) { throw new NotImplementedException (); } [MonoTODO ("Not implemented")] public string GetGeneratedFileVirtualPath (string filePath) { // returns empty string for any vpath. Test with real paths. throw new NotImplementedException (); } [MonoTODO ("Not implemented")] public string GetGeneratedSourceFile (string virtualPath) { // This one takes a directory name /xxx and /xxx/App_Code throw either // a KeyNotFoundException or an InvalidOperationException throw new NotImplementedException (); } [MonoTODO ("Not implemented")] public string [] GetTopLevelAssemblyReferences (string virtualPath) { throw new NotImplementedException (); } public string [] GetVirtualCodeDirectories () { // Host is created here when needed. (Unload()+GetVirtualCodeDirectories()+IsHostCreated -> true) //return Host. throw new NotImplementedException (); } public override object InitializeLifetimeService () { return null; } [MonoTODO ("Not implemented")] public bool IsCodeAssembly (string assemblyName) { // Trying all the assemblies loaded by FullName and GetName().Name yield false here :-? throw new NotImplementedException (); } [MonoTODO ("Not implemented")] public void PrecompileApplication () { throw new NotImplementedException (); } [MonoTODO ("Not implemented")] public void PrecompileApplication (ClientBuildManagerCallback callback) { throw new NotImplementedException (); } [MonoTODO ("Not implemented")] public void PrecompileApplication (ClientBuildManagerCallback callback, bool forceCleanBuild) { throw new NotImplementedException (); } public bool Unload () { if (host != null) { host.Shutdown (); OnAppDomainShutdown (0); host = null; } return true; // FIXME: may be we should do this synch. + timeout? Test! } public string CodeGenDir { get { return Host.GetCodeGenDir (); } } public bool IsHostCreated { get { return host != null; } } void IDisposable.Dispose () { Unload (); } } } #endif