2
0

ClientBuildManager.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. //
  2. // System.Web.Compilation.ClientBuildManager
  3. //
  4. // Authors:
  5. // Chris Toshok ([email protected])
  6. // Gonzalo Paniagua Javier ([email protected])
  7. //
  8. // (C) 2006-2009 Novell, Inc (http://www.novell.com)
  9. //
  10. //
  11. // Permission is hereby granted, free of charge, to any person obtaining
  12. // a copy of this software and associated documentation files (the
  13. // "Software"), to deal in the Software without restriction, including
  14. // without limitation the rights to use, copy, modify, merge, publish,
  15. // distribute, sublicense, and/or sell copies of the Software, and to
  16. // permit persons to whom the Software is furnished to do so, subject to
  17. // the following conditions:
  18. //
  19. // The above copyright notice and this permission notice shall be
  20. // included in all copies or substantial portions of the Software.
  21. //
  22. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  23. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  24. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  25. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  26. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  27. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  28. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  29. //
  30. using System;
  31. using System.CodeDom;
  32. using System.CodeDom.Compiler;
  33. using System.ComponentModel;
  34. using System.Collections;
  35. using System.Globalization;
  36. using System.IO;
  37. using System.Web;
  38. using System.Web.Hosting;
  39. using System.Web.Util;
  40. namespace System.Web.Compilation
  41. {
  42. public sealed class ClientBuildManager : MarshalByRefObject, IDisposable
  43. {
  44. static readonly object appDomainShutdownEvent = new object ();
  45. static readonly object appDomainStartedEvent = new object ();
  46. static readonly object appDomainUnloadedEvent = new object ();
  47. string virt_dir;
  48. string phys_src_dir;
  49. //string phys_target_dir;
  50. //ClientBuildManagerParameter build_params;
  51. BareApplicationHost host;
  52. ApplicationManager manager;
  53. string app_id;
  54. string cache_path;
  55. EventHandlerList events = new EventHandlerList ();
  56. public event BuildManagerHostUnloadEventHandler AppDomainShutdown {
  57. add { events.AddHandler (appDomainShutdownEvent, value); }
  58. remove { events.RemoveHandler (appDomainShutdownEvent, value); }
  59. }
  60. public event EventHandler AppDomainStarted {
  61. add { events.AddHandler (appDomainStartedEvent, value); }
  62. remove { events.RemoveHandler (appDomainStartedEvent, value); }
  63. }
  64. public event BuildManagerHostUnloadEventHandler AppDomainUnloaded {
  65. add { events.AddHandler (appDomainUnloadedEvent, value); }
  66. remove { events.RemoveHandler (appDomainUnloadedEvent, value); }
  67. }
  68. public ClientBuildManager (string appVirtualDir, string appPhysicalSourceDir)
  69. {
  70. if (appVirtualDir == null || appVirtualDir == "")
  71. throw new ArgumentNullException ("appVirtualDir");
  72. if (appPhysicalSourceDir == null || appPhysicalSourceDir == "")
  73. throw new ArgumentNullException ("appPhysicalSourceDir");
  74. virt_dir = appVirtualDir; // TODO: adjust vpath (it allows 'blah' that turns into '/blah', '////blah', '\\blah'...
  75. phys_src_dir = appPhysicalSourceDir;
  76. manager = ApplicationManager.GetApplicationManager ();
  77. }
  78. public ClientBuildManager (string appVirtualDir, string appPhysicalSourceDir,
  79. string appPhysicalTargetDir)
  80. : this (appVirtualDir, appPhysicalSourceDir)
  81. {
  82. if (appPhysicalTargetDir == null || appPhysicalTargetDir == "")
  83. throw new ArgumentNullException ("appPhysicalTargetDir");
  84. //phys_target_dir = appPhysicalTargetDir;
  85. }
  86. public ClientBuildManager (string appVirtualDir, string appPhysicalSourceDir,
  87. string appPhysicalTargetDir, ClientBuildManagerParameter parameter)
  88. : this (appVirtualDir, appPhysicalSourceDir, appPhysicalTargetDir)
  89. {
  90. //build_params = parameter;
  91. }
  92. BareApplicationHost Host {
  93. get {
  94. if (host != null)
  95. return host;
  96. int hashcode = virt_dir.GetHashCode ();
  97. if (app_id != null)
  98. hashcode ^= Int32.Parse (app_id);
  99. app_id = hashcode.ToString (Helpers.InvariantCulture);
  100. host = manager.CreateHostWithCheck (app_id, virt_dir, phys_src_dir);
  101. cache_path = "";
  102. //cache_path = Path.Combine (Path.GetTempPath (),
  103. //String.Format ("{0}-temp-aspnet-{1:x}", Environment.UserName, i));
  104. int hash = virt_dir.GetHashCode () << 5 + phys_src_dir.GetHashCode ();
  105. cache_path = Path.Combine (cache_path, hash.ToString (Helpers.InvariantCulture));
  106. Directory.CreateDirectory (cache_path);
  107. OnAppDomainStarted ();
  108. return host;
  109. }
  110. }
  111. void OnAppDomainStarted ()
  112. {
  113. EventHandler eh = events [appDomainStartedEvent] as EventHandler;
  114. if (eh != null)
  115. eh (this, EventArgs.Empty);
  116. }
  117. void OnAppDomainShutdown (ApplicationShutdownReason reason)
  118. {
  119. BuildManagerHostUnloadEventHandler eh = events [appDomainShutdownEvent] as BuildManagerHostUnloadEventHandler;
  120. if (eh != null) {
  121. BuildManagerHostUnloadEventArgs args = new BuildManagerHostUnloadEventArgs (reason);
  122. eh (this, args);
  123. }
  124. }
  125. // void OnDomainUnload (object sender, EventArgs args)
  126. // {
  127. // OnAppDomainUnloaded (0); // FIXME: set a reason?
  128. // }
  129. //
  130. // void OnAppDomainUnloaded (ApplicationShutdownReason reason)
  131. // {
  132. // if (AppDomainUnloaded != null) {
  133. // BuildManagerHostUnloadEventArgs args = new BuildManagerHostUnloadEventArgs (reason);
  134. // AppDomainUnloaded (this, args);
  135. // }
  136. // }
  137. [MonoTODO ("Not implemented")]
  138. public void CompileApplicationDependencies ()
  139. {
  140. throw new NotImplementedException ();
  141. }
  142. public void CompileFile (string virtualPath)
  143. {
  144. CompileFile (virtualPath, null);
  145. }
  146. [MonoTODO ("Not implemented")]
  147. public void CompileFile (string virtualPath, ClientBuildManagerCallback callback)
  148. {
  149. // 1. Creates the Host
  150. // This creates a .compiled file + an assembly
  151. // App_Code reported to be built *before* anything else (with progress callback)
  152. throw new NotImplementedException ();
  153. }
  154. public IRegisteredObject CreateObject (Type type, bool failIfExists)
  155. {
  156. return manager.CreateObject (app_id, type, virt_dir, phys_src_dir, failIfExists);
  157. }
  158. [MonoTODO("Currently does not return the GeneratedCode")]
  159. public string GenerateCode (string virtualPath, string virtualFileString, out IDictionary linePragmasTable)
  160. {
  161. // This thing generates a .ccu (CodeCompileUnit?) file (reported as TrueType font data by 'file'!)
  162. // resultType=7 vs. resultType=3 for assemblies reported in the .compiled file
  163. // The virtual path is just added to the dependencies list, but is checked to be an absolute path.
  164. // IsHostCreated returns true after calling this method.
  165. //
  166. // A null file string causes virtualPath to be mapped and read to generate the code
  167. //
  168. if (String.IsNullOrEmpty (virtualPath))
  169. throw new ArgumentNullException ("virtualPath");
  170. Type cprovider_type;
  171. CompilerParameters parameters;
  172. GenerateCodeCompileUnit (virtualPath, virtualFileString, out cprovider_type,
  173. out parameters, out linePragmasTable);
  174. return null;
  175. }
  176. [MonoTODO ("Not implemented")]
  177. public CodeCompileUnit GenerateCodeCompileUnit (string virtualPath,
  178. string virtualFileString,
  179. out Type codeDomProviderType,
  180. out CompilerParameters compilerParameters,
  181. out IDictionary linePragmasTable)
  182. {
  183. throw new NotImplementedException ();
  184. }
  185. public CodeCompileUnit GenerateCodeCompileUnit (string virtualPath,
  186. out Type codeDomProviderType,
  187. out CompilerParameters compilerParameters,
  188. out IDictionary linePragmasTable)
  189. {
  190. return GenerateCodeCompileUnit (virtualPath, out codeDomProviderType,
  191. out compilerParameters, out linePragmasTable);
  192. }
  193. static string [] shutdown_directories = new string [] {
  194. "bin", "App_GlobalResources", "App_Code",
  195. "App_WebReferences", "App_Browsers" };
  196. public string [] GetAppDomainShutdownDirectories ()
  197. {
  198. return shutdown_directories;
  199. }
  200. [MonoTODO ("Not implemented")]
  201. public IDictionary GetBrowserDefinitions ()
  202. {
  203. throw new NotImplementedException ();
  204. }
  205. [MonoTODO ("Not implemented")]
  206. public void GetCodeDirectoryInformation (string virtualCodeDir,
  207. out Type codeDomProviderType,
  208. out CompilerParameters compilerParameters,
  209. out string generatedFilesDir)
  210. {
  211. throw new NotImplementedException ();
  212. }
  213. [MonoTODO ("Not implemented")]
  214. public Type GetCompiledType (string virtualPath)
  215. {
  216. // CompileFile + get the type based on .compiled file information
  217. // Throws if virtualPath is a special virtual directory (App_Code et al)
  218. throw new NotImplementedException ();
  219. }
  220. [MonoTODO ("Not implemented")]
  221. public void GetCompilerParameters (string virtualPath,
  222. out Type codeDomProviderType,
  223. out CompilerParameters compilerParameters)
  224. {
  225. throw new NotImplementedException ();
  226. }
  227. [MonoTODO ("Not implemented")]
  228. public string GetGeneratedFileVirtualPath (string filePath)
  229. {
  230. // returns empty string for any vpath. Test with real paths.
  231. throw new NotImplementedException ();
  232. }
  233. [MonoTODO ("Not implemented")]
  234. public string GetGeneratedSourceFile (string virtualPath)
  235. {
  236. // This one takes a directory name /xxx and /xxx/App_Code throw either
  237. // a KeyNotFoundException or an InvalidOperationException
  238. throw new NotImplementedException ();
  239. }
  240. [MonoTODO ("Not implemented")]
  241. public string [] GetTopLevelAssemblyReferences (string virtualPath)
  242. {
  243. throw new NotImplementedException ();
  244. }
  245. public string [] GetVirtualCodeDirectories ()
  246. {
  247. // Host is created here when needed. (Unload()+GetVirtualCodeDirectories()+IsHostCreated -> true)
  248. //return Host.
  249. throw new NotImplementedException ();
  250. }
  251. public override object InitializeLifetimeService ()
  252. {
  253. return null;
  254. }
  255. [MonoTODO ("Not implemented")]
  256. public bool IsCodeAssembly (string assemblyName)
  257. {
  258. // Trying all the assemblies loaded by FullName and GetName().Name yield false here :-?
  259. throw new NotImplementedException ();
  260. }
  261. [MonoTODO ("Not implemented")]
  262. public void PrecompileApplication ()
  263. {
  264. throw new NotImplementedException ();
  265. }
  266. [MonoTODO ("Not implemented")]
  267. public void PrecompileApplication (ClientBuildManagerCallback callback)
  268. {
  269. throw new NotImplementedException ();
  270. }
  271. [MonoTODO ("Not implemented")]
  272. public void PrecompileApplication (ClientBuildManagerCallback callback, bool forceCleanBuild)
  273. {
  274. throw new NotImplementedException ();
  275. }
  276. public bool Unload ()
  277. {
  278. if (host != null) {
  279. host.Shutdown ();
  280. OnAppDomainShutdown (0);
  281. host = null;
  282. }
  283. return true; // FIXME: may be we should do this synch. + timeout? Test!
  284. }
  285. public string CodeGenDir {
  286. get { return Host.GetCodeGenDir (); }
  287. }
  288. public bool IsHostCreated {
  289. get { return host != null; }
  290. }
  291. void IDisposable.Dispose ()
  292. {
  293. Unload ();
  294. }
  295. }
  296. }