2 // System.Web.Compilation.ClientBuildManager
5 // Chris Toshok (toshok@ximian.com)
6 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
8 // (C) 2006-2009 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.
34 using System.CodeDom.Compiler;
35 using System.ComponentModel;
36 using System.Collections;
37 using System.Globalization;
40 using System.Web.Hosting;
41 using System.Web.Util;
43 namespace System.Web.Compilation
45 public sealed class ClientBuildManager : MarshalByRefObject, IDisposable
47 static readonly object appDomainShutdownEvent = new object ();
48 static readonly object appDomainStartedEvent = new object ();
49 static readonly object appDomainUnloadedEvent = new object ();
53 //string phys_target_dir;
54 //ClientBuildManagerParameter build_params;
55 BareApplicationHost host;
56 ApplicationManager manager;
60 EventHandlerList events = new EventHandlerList ();
62 public event BuildManagerHostUnloadEventHandler AppDomainShutdown {
63 add { events.AddHandler (appDomainShutdownEvent, value); }
64 remove { events.RemoveHandler (appDomainShutdownEvent, value); }
67 public event EventHandler AppDomainStarted {
68 add { events.AddHandler (appDomainStartedEvent, value); }
69 remove { events.RemoveHandler (appDomainStartedEvent, value); }
72 public event BuildManagerHostUnloadEventHandler AppDomainUnloaded {
73 add { events.AddHandler (appDomainUnloadedEvent, value); }
74 remove { events.RemoveHandler (appDomainUnloadedEvent, value); }
77 public ClientBuildManager (string appVirtualDir, string appPhysicalSourceDir)
79 if (appVirtualDir == null || appVirtualDir == "")
80 throw new ArgumentNullException ("appVirtualDir");
81 if (appPhysicalSourceDir == null || appPhysicalSourceDir == "")
82 throw new ArgumentNullException ("appPhysicalSourceDir");
84 virt_dir = appVirtualDir; // TODO: adjust vpath (it allows 'blah' that turns into '/blah', '////blah', '\\blah'...
85 phys_src_dir = appPhysicalSourceDir;
86 manager = ApplicationManager.GetApplicationManager ();
89 public ClientBuildManager (string appVirtualDir, string appPhysicalSourceDir,
90 string appPhysicalTargetDir)
91 : this (appVirtualDir, appPhysicalSourceDir)
93 if (appPhysicalTargetDir == null || appPhysicalTargetDir == "")
94 throw new ArgumentNullException ("appPhysicalTargetDir");
96 //phys_target_dir = appPhysicalTargetDir;
99 public ClientBuildManager (string appVirtualDir, string appPhysicalSourceDir,
100 string appPhysicalTargetDir, ClientBuildManagerParameter parameter)
101 : this (appVirtualDir, appPhysicalSourceDir, appPhysicalTargetDir)
103 //build_params = parameter;
106 BareApplicationHost Host {
111 int hashcode = virt_dir.GetHashCode ();
113 hashcode ^= Int32.Parse (app_id);
115 app_id = hashcode.ToString (Helpers.InvariantCulture);
116 host = manager.CreateHostWithCheck (app_id, virt_dir, phys_src_dir);
118 //cache_path = Path.Combine (Path.GetTempPath (),
119 //String.Format ("{0}-temp-aspnet-{1:x}", Environment.UserName, i));
121 int hash = virt_dir.GetHashCode () << 5 + phys_src_dir.GetHashCode ();
122 cache_path = Path.Combine (cache_path, hash.ToString (Helpers.InvariantCulture));
123 Directory.CreateDirectory (cache_path);
124 OnAppDomainStarted ();
129 void OnAppDomainStarted ()
131 EventHandler eh = events [appDomainStartedEvent] as EventHandler;
133 eh (this, EventArgs.Empty);
136 void OnAppDomainShutdown (ApplicationShutdownReason reason)
138 BuildManagerHostUnloadEventHandler eh = events [appDomainShutdownEvent] as BuildManagerHostUnloadEventHandler;
140 BuildManagerHostUnloadEventArgs args = new BuildManagerHostUnloadEventArgs (reason);
145 // void OnDomainUnload (object sender, EventArgs args)
147 // OnAppDomainUnloaded (0); // FIXME: set a reason?
150 // void OnAppDomainUnloaded (ApplicationShutdownReason reason)
152 // if (AppDomainUnloaded != null) {
153 // BuildManagerHostUnloadEventArgs args = new BuildManagerHostUnloadEventArgs (reason);
154 // AppDomainUnloaded (this, args);
158 [MonoTODO ("Not implemented")]
159 public void CompileApplicationDependencies ()
161 throw new NotImplementedException ();
164 public void CompileFile (string virtualPath)
166 CompileFile (virtualPath, null);
169 [MonoTODO ("Not implemented")]
170 public void CompileFile (string virtualPath, ClientBuildManagerCallback callback)
172 // 1. Creates the Host
173 // This creates a .compiled file + an assembly
174 // App_Code reported to be built *before* anything else (with progress callback)
175 throw new NotImplementedException ();
178 public IRegisteredObject CreateObject (Type type, bool failIfExists)
180 return manager.CreateObject (app_id, type, virt_dir, phys_src_dir, failIfExists);
183 [MonoTODO("Currently does not return the GeneratedCode")]
184 public string GenerateCode (string virtualPath, string virtualFileString, out IDictionary linePragmasTable)
186 // This thing generates a .ccu (CodeCompileUnit?) file (reported as TrueType font data by 'file'!)
187 // resultType=7 vs. resultType=3 for assemblies reported in the .compiled file
188 // The virtual path is just added to the dependencies list, but is checked to be an absolute path.
189 // IsHostCreated returns true after calling this method.
191 // A null file string causes virtualPath to be mapped and read to generate the code
194 if (String.IsNullOrEmpty (virtualPath))
195 throw new ArgumentNullException ("virtualPath");
198 CompilerParameters parameters;
199 GenerateCodeCompileUnit (virtualPath, virtualFileString, out cprovider_type,
200 out parameters, out linePragmasTable);
204 [MonoTODO ("Not implemented")]
205 public CodeCompileUnit GenerateCodeCompileUnit (string virtualPath,
206 string virtualFileString,
207 out Type codeDomProviderType,
208 out CompilerParameters compilerParameters,
209 out IDictionary linePragmasTable)
211 throw new NotImplementedException ();
214 public CodeCompileUnit GenerateCodeCompileUnit (string virtualPath,
215 out Type codeDomProviderType,
216 out CompilerParameters compilerParameters,
217 out IDictionary linePragmasTable)
219 return GenerateCodeCompileUnit (virtualPath, out codeDomProviderType,
220 out compilerParameters, out linePragmasTable);
223 static string [] shutdown_directories = new string [] {
224 "bin", "App_GlobalResources", "App_Code",
225 "App_WebReferences", "App_Browsers" };
227 public string [] GetAppDomainShutdownDirectories ()
229 return shutdown_directories;
232 [MonoTODO ("Not implemented")]
233 public IDictionary GetBrowserDefinitions ()
235 throw new NotImplementedException ();
238 [MonoTODO ("Not implemented")]
239 public void GetCodeDirectoryInformation (string virtualCodeDir,
240 out Type codeDomProviderType,
241 out CompilerParameters compilerParameters,
242 out string generatedFilesDir)
244 throw new NotImplementedException ();
247 [MonoTODO ("Not implemented")]
248 public Type GetCompiledType (string virtualPath)
250 // CompileFile + get the type based on .compiled file information
251 // Throws if virtualPath is a special virtual directory (App_Code et al)
252 throw new NotImplementedException ();
255 [MonoTODO ("Not implemented")]
256 public void GetCompilerParameters (string virtualPath,
257 out Type codeDomProviderType,
258 out CompilerParameters compilerParameters)
260 throw new NotImplementedException ();
263 [MonoTODO ("Not implemented")]
264 public string GetGeneratedFileVirtualPath (string filePath)
266 // returns empty string for any vpath. Test with real paths.
267 throw new NotImplementedException ();
270 [MonoTODO ("Not implemented")]
271 public string GetGeneratedSourceFile (string virtualPath)
273 // This one takes a directory name /xxx and /xxx/App_Code throw either
274 // a KeyNotFoundException or an InvalidOperationException
275 throw new NotImplementedException ();
278 [MonoTODO ("Not implemented")]
279 public string [] GetTopLevelAssemblyReferences (string virtualPath)
281 throw new NotImplementedException ();
284 public string [] GetVirtualCodeDirectories ()
286 // Host is created here when needed. (Unload()+GetVirtualCodeDirectories()+IsHostCreated -> true)
288 throw new NotImplementedException ();
291 public override object InitializeLifetimeService ()
296 [MonoTODO ("Not implemented")]
297 public bool IsCodeAssembly (string assemblyName)
299 // Trying all the assemblies loaded by FullName and GetName().Name yield false here :-?
300 throw new NotImplementedException ();
303 [MonoTODO ("Not implemented")]
304 public void PrecompileApplication ()
306 throw new NotImplementedException ();
309 [MonoTODO ("Not implemented")]
310 public void PrecompileApplication (ClientBuildManagerCallback callback)
312 throw new NotImplementedException ();
315 [MonoTODO ("Not implemented")]
316 public void PrecompileApplication (ClientBuildManagerCallback callback, bool forceCleanBuild)
318 throw new NotImplementedException ();
321 public bool Unload ()
325 OnAppDomainShutdown (0);
329 return true; // FIXME: may be we should do this synch. + timeout? Test!
332 public string CodeGenDir {
333 get { return Host.GetCodeGenDir (); }
336 public bool IsHostCreated {
337 get { return host != null; }
340 void IDisposable.Dispose ()