2 // System.Web.Compilation.ClientBuildManager
5 // Chris Toshok (toshok@ximian.com)
6 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
8 // (C) 2006 Novell, Inc (http://www.novell.com)
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 using System.CodeDom.Compiler;
36 using System.ComponentModel;
37 using System.Collections;
38 using System.Globalization;
41 using System.Web.Hosting;
42 using System.Web.Util;
44 namespace System.Web.Compilation {
45 public sealed class ClientBuildManager : MarshalByRefObject, IDisposable {
46 static readonly object appDomainShutdownEvent = new object ();
47 static readonly object appDomainStartedEvent = new object ();
48 static readonly object appDomainUnloadedEvent = new object ();
52 //string phys_target_dir;
53 //ClientBuildManagerParameter build_params;
54 BareApplicationHost host;
55 ApplicationManager manager;
59 EventHandlerList events = new EventHandlerList ();
61 public event BuildManagerHostUnloadEventHandler AppDomainShutdown {
62 add { events.AddHandler (appDomainShutdownEvent, value); }
63 remove { events.RemoveHandler (appDomainShutdownEvent, value); }
66 public event EventHandler AppDomainStarted {
67 add { events.AddHandler (appDomainStartedEvent, value); }
68 remove { events.RemoveHandler (appDomainStartedEvent, value); }
71 public event BuildManagerHostUnloadEventHandler AppDomainUnloaded {
72 add { events.AddHandler (appDomainUnloadedEvent, value); }
73 remove { events.RemoveHandler (appDomainUnloadedEvent, value); }
76 public ClientBuildManager (string appVirtualDir, string appPhysicalSourceDir)
78 if (appVirtualDir == null || appVirtualDir == "")
79 throw new ArgumentNullException ("appVirtualDir");
80 if (appPhysicalSourceDir == null || appPhysicalSourceDir == "")
81 throw new ArgumentNullException ("appPhysicalSourceDir");
83 virt_dir = appVirtualDir; // TODO: adjust vpath (it allows 'blah' that turns into '/blah', '////blah', '\\blah'...
84 phys_src_dir = appPhysicalSourceDir;
85 manager = ApplicationManager.GetApplicationManager ();
88 public ClientBuildManager (string appVirtualDir, string appPhysicalSourceDir,
89 string appPhysicalTargetDir)
90 : this (appVirtualDir, appPhysicalSourceDir)
92 if (appPhysicalTargetDir == null || appPhysicalTargetDir == "")
93 throw new ArgumentNullException ("appPhysicalTargetDir");
95 //phys_target_dir = appPhysicalTargetDir;
98 public ClientBuildManager (string appVirtualDir, string appPhysicalSourceDir,
99 string appPhysicalTargetDir, ClientBuildManagerParameter parameter)
100 : this (appVirtualDir, appPhysicalSourceDir, appPhysicalTargetDir)
102 //build_params = parameter;
105 BareApplicationHost Host {
110 int hashcode = virt_dir.GetHashCode ();
112 hashcode ^= Int32.Parse (app_id);
114 app_id = hashcode.ToString (Helpers.InvariantCulture);
115 host = manager.CreateHostWithCheck (app_id, virt_dir, phys_src_dir);
117 //cache_path = Path.Combine (Path.GetTempPath (),
118 //String.Format ("{0}-temp-aspnet-{1:x}", Environment.UserName, i));
120 int hash = virt_dir.GetHashCode () << 5 + phys_src_dir.GetHashCode ();
121 cache_path = Path.Combine (cache_path, hash.ToString (Helpers.InvariantCulture));
122 Directory.CreateDirectory (cache_path);
123 OnAppDomainStarted ();
128 void OnAppDomainStarted ()
130 EventHandler eh = events [appDomainStartedEvent] as EventHandler;
132 eh (this, EventArgs.Empty);
135 void OnAppDomainShutdown (ApplicationShutdownReason reason)
137 BuildManagerHostUnloadEventHandler eh = events [appDomainShutdownEvent] as BuildManagerHostUnloadEventHandler;
139 BuildManagerHostUnloadEventArgs args = new BuildManagerHostUnloadEventArgs (reason);
144 // void OnDomainUnload (object sender, EventArgs args)
146 // OnAppDomainUnloaded (0); // FIXME: set a reason?
149 // void OnAppDomainUnloaded (ApplicationShutdownReason reason)
151 // if (AppDomainUnloaded != null) {
152 // BuildManagerHostUnloadEventArgs args = new BuildManagerHostUnloadEventArgs (reason);
153 // AppDomainUnloaded (this, args);
157 [MonoTODO ("Not implemented")]
158 public void CompileApplicationDependencies ()
160 throw new NotImplementedException ();
163 public void CompileFile (string virtualPath)
165 CompileFile (virtualPath, null);
168 [MonoTODO ("Not implemented")]
169 public void CompileFile (string virtualPath, ClientBuildManagerCallback callback)
171 // 1. Creates the Host
172 // This creates a .compiled file + an assembly
173 // App_Code reported to be built *before* anything else (with progress callback)
174 throw new NotImplementedException ();
177 public IRegisteredObject CreateObject (Type type, bool failIfExists)
179 return manager.CreateObject (app_id, type, virt_dir, phys_src_dir, failIfExists);
182 [MonoTODO("Currently does not return the GeneratedCode")]
183 public string GenerateCode (string virtualPath, string virtualFileString, out IDictionary linePragmasTable)
185 // This thing generates a .ccu (CodeCompileUnit?) file (reported as TrueType font data by 'file'!)
186 // resultType=7 vs. resultType=3 for assemblies reported in the .compiled file
187 // The virtual path is just added to the dependencies list, but is checked to be an absolute path.
188 // IsHostCreated returns true after calling this method.
190 // A null file string causes virtualPath to be mapped and read to generate the code
193 if (String.IsNullOrEmpty (virtualPath))
194 throw new ArgumentNullException ("virtualPath");
197 CompilerParameters parameters;
198 GenerateCodeCompileUnit (virtualPath, virtualFileString, out cprovider_type,
199 out parameters, out linePragmasTable);
203 [MonoTODO ("Not implemented")]
204 public CodeCompileUnit GenerateCodeCompileUnit (string virtualPath,
205 string virtualFileString,
206 out Type codeDomProviderType,
207 out CompilerParameters compilerParameters,
208 out IDictionary linePragmasTable)
210 throw new NotImplementedException ();
213 public CodeCompileUnit GenerateCodeCompileUnit (string virtualPath,
214 out Type codeDomProviderType,
215 out CompilerParameters compilerParameters,
216 out IDictionary linePragmasTable)
218 return GenerateCodeCompileUnit (virtualPath, out codeDomProviderType,
219 out compilerParameters, out linePragmasTable);
222 static string [] shutdown_directories = new string [] {
223 "bin", "App_GlobalResources", "App_Code",
224 "App_WebReferences", "App_Browsers" };
226 public string [] GetAppDomainShutdownDirectories ()
228 return shutdown_directories;
231 [MonoTODO ("Not implemented")]
232 public IDictionary GetBrowserDefinitions ()
234 throw new NotImplementedException ();
237 [MonoTODO ("Not implemented")]
238 public void GetCodeDirectoryInformation (string virtualCodeDir,
239 out Type codeDomProviderType,
240 out CompilerParameters compilerParameters,
241 out string generatedFilesDir)
243 throw new NotImplementedException ();
246 [MonoTODO ("Not implemented")]
247 public Type GetCompiledType (string virtualPath)
249 // CompileFile + get the type based on .compiled file information
250 // Throws if virtualPath is a special virtual directory (App_Code et al)
251 throw new NotImplementedException ();
254 [MonoTODO ("Not implemented")]
255 public void GetCompilerParameters (string virtualPath,
256 out Type codeDomProviderType,
257 out CompilerParameters compilerParameters)
259 throw new NotImplementedException ();
262 [MonoTODO ("Not implemented")]
263 public string GetGeneratedFileVirtualPath (string filePath)
265 // returns empty string for any vpath. Test with real paths.
266 throw new NotImplementedException ();
269 [MonoTODO ("Not implemented")]
270 public string GetGeneratedSourceFile (string virtualPath)
272 // This one takes a directory name /xxx and /xxx/App_Code throw either
273 // a KeyNotFoundException or an InvalidOperationException
274 throw new NotImplementedException ();
277 [MonoTODO ("Not implemented")]
278 public string [] GetTopLevelAssemblyReferences (string virtualPath)
280 throw new NotImplementedException ();
283 public string [] GetVirtualCodeDirectories ()
285 // Host is created here when needed. (Unload()+GetVirtualCodeDirectories()+IsHostCreated -> true)
287 throw new NotImplementedException ();
290 public override object InitializeLifetimeService ()
295 [MonoTODO ("Not implemented")]
296 public bool IsCodeAssembly (string assemblyName)
298 // Trying all the assemblies loaded by FullName and GetName().Name yield false here :-?
299 throw new NotImplementedException ();
302 [MonoTODO ("Not implemented")]
303 public void PrecompileApplication ()
305 throw new NotImplementedException ();
308 [MonoTODO ("Not implemented")]
309 public void PrecompileApplication (ClientBuildManagerCallback callback)
311 throw new NotImplementedException ();
314 [MonoTODO ("Not implemented")]
315 public void PrecompileApplication (ClientBuildManagerCallback callback, bool forceCleanBuild)
317 throw new NotImplementedException ();
320 public bool Unload ()
324 OnAppDomainShutdown (0);
328 return true; // FIXME: may be we should do this synch. + timeout? Test!
331 public string CodeGenDir {
332 get { return Host.GetCodeGenDir (); }
335 public bool IsHostCreated {
336 get { return host != null; }
339 void IDisposable.Dispose ()