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;
43 namespace System.Web.Compilation {
44 public sealed class ClientBuildManager : MarshalByRefObject, IDisposable {
45 static readonly object appDomainShutdownEvent = new object ();
46 static readonly object appDomainStartedEvent = new object ();
47 static readonly object appDomainUnloadedEvent = new object ();
51 //string phys_target_dir;
52 //ClientBuildManagerParameter build_params;
53 BareApplicationHost host;
54 ApplicationManager manager;
58 EventHandlerList events = new EventHandlerList ();
60 public event BuildManagerHostUnloadEventHandler AppDomainShutdown {
61 add { events.AddHandler (appDomainShutdownEvent, value); }
62 remove { events.RemoveHandler (appDomainShutdownEvent, value); }
65 public event EventHandler AppDomainStarted {
66 add { events.AddHandler (appDomainStartedEvent, value); }
67 remove { events.RemoveHandler (appDomainStartedEvent, value); }
70 public event BuildManagerHostUnloadEventHandler AppDomainUnloaded {
71 add { events.AddHandler (appDomainUnloadedEvent, value); }
72 remove { events.RemoveHandler (appDomainUnloadedEvent, value); }
75 public ClientBuildManager (string appVirtualDir, string appPhysicalSourceDir)
77 if (appVirtualDir == null || appVirtualDir == "")
78 throw new ArgumentNullException ("appVirtualDir");
79 if (appPhysicalSourceDir == null || appPhysicalSourceDir == "")
80 throw new ArgumentNullException ("appPhysicalSourceDir");
82 virt_dir = appVirtualDir; // TODO: adjust vpath (it allows 'blah' that turns into '/blah', '////blah', '\\blah'...
83 phys_src_dir = appPhysicalSourceDir;
84 manager = ApplicationManager.GetApplicationManager ();
87 public ClientBuildManager (string appVirtualDir, string appPhysicalSourceDir,
88 string appPhysicalTargetDir)
89 : this (appVirtualDir, appPhysicalSourceDir)
91 if (appPhysicalTargetDir == null || appPhysicalTargetDir == "")
92 throw new ArgumentNullException ("appPhysicalTargetDir");
94 //phys_target_dir = appPhysicalTargetDir;
97 public ClientBuildManager (string appVirtualDir, string appPhysicalSourceDir,
98 string appPhysicalTargetDir, ClientBuildManagerParameter parameter)
99 : this (appVirtualDir, appPhysicalSourceDir, appPhysicalTargetDir)
101 //build_params = parameter;
104 BareApplicationHost Host {
109 int hashcode = virt_dir.GetHashCode ();
111 hashcode ^= Int32.Parse (app_id);
113 app_id = hashcode.ToString (CultureInfo.InvariantCulture);
114 host = manager.CreateHostWithCheck (app_id, virt_dir, phys_src_dir);
116 //cache_path = Path.Combine (Path.GetTempPath (),
117 //String.Format ("{0}-temp-aspnet-{1:x}", Environment.UserName, i));
119 int hash = virt_dir.GetHashCode () << 5 + phys_src_dir.GetHashCode ();
120 cache_path = Path.Combine (cache_path, hash.ToString (CultureInfo.InvariantCulture));
121 Directory.CreateDirectory (cache_path);
122 OnAppDomainStarted ();
127 void OnAppDomainStarted ()
129 EventHandler eh = events [appDomainStartedEvent] as EventHandler;
131 eh (this, EventArgs.Empty);
134 void OnAppDomainShutdown (ApplicationShutdownReason reason)
136 BuildManagerHostUnloadEventHandler eh = events [appDomainShutdownEvent] as BuildManagerHostUnloadEventHandler;
138 BuildManagerHostUnloadEventArgs args = new BuildManagerHostUnloadEventArgs (reason);
143 // void OnDomainUnload (object sender, EventArgs args)
145 // OnAppDomainUnloaded (0); // FIXME: set a reason?
148 // void OnAppDomainUnloaded (ApplicationShutdownReason reason)
150 // if (AppDomainUnloaded != null) {
151 // BuildManagerHostUnloadEventArgs args = new BuildManagerHostUnloadEventArgs (reason);
152 // AppDomainUnloaded (this, args);
156 [MonoTODO ("Not implemented")]
157 public void CompileApplicationDependencies ()
159 throw new NotImplementedException ();
162 public void CompileFile (string virtualPath)
164 CompileFile (virtualPath, null);
167 [MonoTODO ("Not implemented")]
168 public void CompileFile (string virtualPath, ClientBuildManagerCallback callback)
170 // 1. Creates the Host
171 // This creates a .compiled file + an assembly
172 // App_Code reported to be built *before* anything else (with progress callback)
173 throw new NotImplementedException ();
176 public IRegisteredObject CreateObject (Type type, bool failIfExists)
178 return manager.CreateObject (app_id, type, virt_dir, phys_src_dir, failIfExists);
181 [MonoTODO("Currently does not return the GeneratedCode")]
182 public string GenerateCode (string virtualPath, string virtualFileString, out IDictionary linePragmasTable)
184 // This thing generates a .ccu (CodeCompileUnit?) file (reported as TrueType font data by 'file'!)
185 // resultType=7 vs. resultType=3 for assemblies reported in the .compiled file
186 // The virtual path is just added to the dependencies list, but is checked to be an absolute path.
187 // IsHostCreated returns true after calling this method.
189 // A null file string causes virtualPath to be mapped and read to generate the code
192 if (virtualPath == null || virtualPath == "")
193 throw new ArgumentNullException ("virtualPath");
196 CompilerParameters parameters;
197 CodeCompileUnit unit = GenerateCodeCompileUnit (virtualPath, virtualFileString, out cprovider_type,
198 out parameters, out linePragmasTable);
202 [MonoTODO ("Not implemented")]
203 public CodeCompileUnit GenerateCodeCompileUnit (string virtualPath,
204 string virtualFileString,
205 out Type codeDomProviderType,
206 out CompilerParameters compilerParameters,
207 out IDictionary linePragmasTable)
209 throw new NotImplementedException ();
212 public CodeCompileUnit GenerateCodeCompileUnit (string virtualPath,
213 out Type codeDomProviderType,
214 out CompilerParameters compilerParameters,
215 out IDictionary linePragmasTable)
217 return GenerateCodeCompileUnit (virtualPath, out codeDomProviderType,
218 out compilerParameters, out linePragmasTable);
221 static string [] shutdown_directories = new string [] {
222 "bin", "App_GlobalResources", "App_Code",
223 "App_WebReferences", "App_Browsers" };
225 public string [] GetAppDomainShutdownDirectories ()
227 return shutdown_directories;
230 [MonoTODO ("Not implemented")]
231 public IDictionary GetBrowserDefinitions ()
233 throw new NotImplementedException ();
236 [MonoTODO ("Not implemented")]
237 public void GetCodeDirectoryInformation (string virtualCodeDir,
238 out Type codeDomProviderType,
239 out CompilerParameters compilerParameters,
240 out string generatedFilesDir)
242 throw new NotImplementedException ();
245 [MonoTODO ("Not implemented")]
246 public Type GetCompiledType (string virtualPath)
248 // CompileFile + get the type based on .compiled file information
249 // Throws if virtualPath is a special virtual directory (App_Code et al)
250 throw new NotImplementedException ();
253 [MonoTODO ("Not implemented")]
254 public void GetCompilerParameters (string virtualPath,
255 out Type codeDomProviderType,
256 out CompilerParameters compilerParameters)
258 throw new NotImplementedException ();
261 [MonoTODO ("Not implemented")]
262 public string GetGeneratedFileVirtualPath (string filePath)
264 // returns empty string for any vpath. Test with real paths.
265 throw new NotImplementedException ();
268 [MonoTODO ("Not implemented")]
269 public string GetGeneratedSourceFile (string virtualPath)
271 // This one takes a directory name /xxx and /xxx/App_Code throw either
272 // a KeyNotFoundException or an InvalidOperationException
273 throw new NotImplementedException ();
276 [MonoTODO ("Not implemented")]
277 public string [] GetTopLevelAssemblyReferences (string virtualPath)
279 throw new NotImplementedException ();
282 public string [] GetVirtualCodeDirectories ()
284 // Host is created here when needed. (Unload()+GetVirtualCodeDirectories()+IsHostCreated -> true)
286 throw new NotImplementedException ();
289 public override object InitializeLifetimeService ()
294 [MonoTODO ("Not implemented")]
295 public bool IsCodeAssembly (string assemblyName)
297 // Trying all the assemblies loaded by FullName and GetName().Name yield false here :-?
298 throw new NotImplementedException ();
301 [MonoTODO ("Not implemented")]
302 public void PrecompileApplication ()
304 throw new NotImplementedException ();
307 [MonoTODO ("Not implemented")]
308 public void PrecompileApplication (ClientBuildManagerCallback callback)
310 throw new NotImplementedException ();
313 [MonoTODO ("Not implemented")]
314 public void PrecompileApplication (ClientBuildManagerCallback callback, bool forceCleanBuild)
316 throw new NotImplementedException ();
319 public bool Unload ()
323 OnAppDomainShutdown (0);
327 return true; // FIXME: may be we should do this synch. + timeout? Test!
330 public string CodeGenDir {
331 get { return Host.GetCodeGenDir (); }
334 public bool IsHostCreated {
335 get { return host != null; }
338 void IDisposable.Dispose ()