2007-05-07 Marek Habersack <mhabersack@novell.com>
[mono.git] / mcs / class / System.Web / System.Web.Compilation / ClientBuildManager.cs
1 //
2 // System.Web.Compilation.ClientBuildManager
3 //
4 // Authors:
5 //      Chris Toshok (toshok@ximian.com)
6 //      Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 //
8 // (C) 2006 Novell, Inc (http://www.novell.com)
9 //
10
11 //
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:
19 // 
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 // 
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.
30 //
31
32 #if NET_2_0
33 using System;
34 using System.CodeDom;
35 using System.CodeDom.Compiler;
36 using System.Collections;
37 using System.Globalization;
38 using System.IO;
39 using System.Web;
40 using System.Web.Hosting;
41
42 namespace System.Web.Compilation {
43         public sealed class ClientBuildManager : MarshalByRefObject, IDisposable {
44                 string virt_dir;
45                 string phys_src_dir;
46                 //string phys_target_dir;
47                 //ClientBuildManagerParameter build_params;
48                 BareApplicationHost host;
49                 ApplicationManager manager;
50                 string app_id;
51                 string cache_path;
52
53                 public ClientBuildManager (string appVirtualDir, string appPhysicalSourceDir)
54                 {
55                         if (appVirtualDir == null || appVirtualDir == "")
56                                 throw new ArgumentNullException ("appVirtualDir");
57                         if (appPhysicalSourceDir == null || appPhysicalSourceDir == "")
58                                 throw new ArgumentNullException ("appPhysicalSourceDir");
59
60                         virt_dir = appVirtualDir; // TODO: adjust vpath (it allows 'blah' that turns into '/blah', '////blah', '\\blah'...
61                         phys_src_dir = appPhysicalSourceDir;
62                         manager = ApplicationManager.GetApplicationManager ();
63                 }
64
65                 public ClientBuildManager (string appVirtualDir, string appPhysicalSourceDir,
66                                            string appPhysicalTargetDir)
67                         : this (appVirtualDir, appPhysicalSourceDir)
68                 {
69                         if (appPhysicalTargetDir == null || appPhysicalTargetDir == "")
70                                 throw new ArgumentNullException ("appPhysicalTargetDir");
71
72                         //phys_target_dir = appPhysicalTargetDir;
73                 }
74
75                 public ClientBuildManager (string appVirtualDir, string appPhysicalSourceDir,
76                                         string appPhysicalTargetDir, ClientBuildManagerParameter parameter)
77                         : this (appVirtualDir, appPhysicalSourceDir, appPhysicalTargetDir)
78                 {
79                         //build_params = parameter;
80                 }
81
82                 public event BuildManagerHostUnloadEventHandler AppDomainShutdown;
83                 public event EventHandler AppDomainStarted;
84                 public event BuildManagerHostUnloadEventHandler AppDomainUnloaded;
85
86                 BareApplicationHost Host {
87                         get {
88                                 if (host != null)
89                                         return host;
90
91                                 int hashcode = virt_dir.GetHashCode ();
92                                 if (app_id != null)
93                                         hashcode ^= Int32.Parse (app_id);
94
95                                 app_id = hashcode.ToString (CultureInfo.InvariantCulture);
96                                 host = manager.CreateHostWithCheck (app_id, virt_dir, phys_src_dir);
97                                 cache_path = "";
98                                 //cache_path = Path.Combine (Path.GetTempPath (),
99                                         //String.Format ("{0}-temp-aspnet-{1:x}", Environment.UserName, i));
100
101                                 int hash = virt_dir.GetHashCode () << 5 + phys_src_dir.GetHashCode ();
102                                 cache_path = Path.Combine (cache_path, hash.ToString (CultureInfo.InvariantCulture));
103                                 Directory.CreateDirectory (cache_path);
104                                 OnAppDomainStarted ();
105                                 return host;
106                         }
107                 }
108
109                 void OnAppDomainStarted ()
110                 {
111                         if (AppDomainStarted != null)
112                                 AppDomainStarted (this, EventArgs.Empty);
113                 }
114
115                 void OnAppDomainShutdown (ApplicationShutdownReason reason)
116                 {
117                         if (AppDomainShutdown != null) {
118                                 BuildManagerHostUnloadEventArgs args = new BuildManagerHostUnloadEventArgs (reason);
119                                 AppDomainShutdown (this, args);
120                         }
121                 }
122
123 //              void OnDomainUnload (object sender, EventArgs args)
124 //              {
125 //                      OnAppDomainUnloaded (0); // FIXME: set a reason?
126 //              }
127 //
128 //              void OnAppDomainUnloaded (ApplicationShutdownReason reason)
129 //              {
130 //                      if (AppDomainUnloaded != null) {
131 //                              BuildManagerHostUnloadEventArgs args = new BuildManagerHostUnloadEventArgs (reason);
132 //                              AppDomainUnloaded (this, args);
133 //                      }
134 //              }
135
136                 [MonoTODO ("Not implemented")]
137                 public void CompileApplicationDependencies ()
138                 {
139                         throw new NotImplementedException ();
140                 }
141
142                 public void CompileFile (string virtualPath)
143                 {
144                         CompileFile (virtualPath, null);
145                 }
146
147                 [MonoTODO ("Not implemented")]
148                 public void CompileFile (string virtualPath, ClientBuildManagerCallback callback)
149                 {
150                         // 1. Creates the Host
151                         // This creates a .compiled file + an assembly
152                         // App_Code reported to be built *before* anything else (with progress callback)
153                         throw new NotImplementedException ();
154                 }
155
156                 public IRegisteredObject CreateObject (Type type, bool failIfExists)
157                 {
158                         return manager.CreateObject (app_id, type, virt_dir, phys_src_dir, failIfExists);
159                 }
160
161                 [MonoTODO("Currently does not return the GeneratedCode")]
162                 public string GenerateCode (string virtualPath, string virtualFileString, out IDictionary linePragmasTable)
163                 {
164                         // This thing generates a .ccu (CodeCompileUnit?) file (reported as TrueType font data by 'file'!)
165                         // resultType=7 vs. resultType=3 for assemblies reported in the .compiled file
166                         // The virtual path is just added to the dependencies list, but is checked to be an absolute path.
167                         // IsHostCreated returns true after calling this method.
168                         //
169                         // A null file string causes virtualPath to be mapped and read to generate the code
170                         //
171
172                         if (virtualPath == null || virtualPath == "")
173                                 throw new ArgumentNullException ("virtualPath");
174
175                         CodeCompileUnit unit = null;
176                         Type cprovider_type;
177                         CompilerParameters parameters;
178                         unit = GenerateCodeCompileUnit (virtualPath, virtualFileString, out cprovider_type,
179                                                         out parameters, out linePragmasTable);
180                         return null;
181                 }
182
183                 [MonoTODO ("Not implemented")]
184                 public CodeCompileUnit GenerateCodeCompileUnit (string virtualPath,
185                                                                 string virtualFileString,
186                                                                 out Type codeDomProviderType,
187                                                                 out CompilerParameters compilerParameters,
188                                                                 out IDictionary linePragmasTable)
189                 {
190                         throw new NotImplementedException ();
191                 }
192
193                 public CodeCompileUnit GenerateCodeCompileUnit (string virtualPath,
194                                                                 out Type codeDomProviderType,
195                                                                 out CompilerParameters compilerParameters,
196                                                                 out IDictionary linePragmasTable)
197                 {
198                         return GenerateCodeCompileUnit (virtualPath, out codeDomProviderType,
199                                                         out compilerParameters, out linePragmasTable);
200                 }
201
202                 static string [] shutdown_directories = new string [] {
203                                                 "bin", "App_GlobalResources", "App_Code",
204                                                 "App_WebReferences", "App_Browsers" };
205
206                 public string [] GetAppDomainShutdownDirectories ()
207                 {
208                         return shutdown_directories;
209                 }
210
211                 [MonoTODO ("Not implemented")]
212                 public IDictionary GetBrowserDefinitions ()
213                 {
214                         throw new NotImplementedException ();
215                 }
216
217                 [MonoTODO ("Not implemented")]
218                 public void GetCodeDirectoryInformation (string virtualCodeDir,
219                                                         out Type codeDomProviderType,
220                                                         out CompilerParameters compilerParameters,
221                                                         out string generatedFilesDir)
222                 {
223                         throw new NotImplementedException ();
224                 }
225
226                 [MonoTODO ("Not implemented")]
227                 public Type GetCompiledType (string virtualPath)
228                 {
229                         // CompileFile + get the type based on .compiled file information
230                         // Throws if virtualPath is a special virtual directory (App_Code et al)
231                         throw new NotImplementedException ();
232                 }
233
234                 [MonoTODO ("Not implemented")]
235                 public void GetCompilerParameters (string virtualPath,
236                                                 out Type codeDomProviderType,
237                                                 out CompilerParameters compilerParameters)
238                 {
239                         throw new NotImplementedException ();
240                 }
241
242                 [MonoTODO ("Not implemented")]
243                 public string GetGeneratedFileVirtualPath (string filePath)
244                 {
245                         // returns empty string for any vpath. Test with real paths.
246                         throw new NotImplementedException ();
247                 }
248
249                 [MonoTODO ("Not implemented")]
250                 public string GetGeneratedSourceFile (string virtualPath)
251                 {
252                         // This one takes a directory name /xxx and /xxx/App_Code throw either
253                         // a KeyNotFoundException or an InvalidOperationException
254                         throw new NotImplementedException ();
255                 }
256
257                 [MonoTODO ("Not implemented")]
258                 public string [] GetTopLevelAssemblyReferences (string virtualPath)
259                 {
260                         throw new NotImplementedException ();
261                 }
262
263                 public string [] GetVirtualCodeDirectories ()
264                 {
265                         // Host is created here when needed. (Unload()+GetVirtualCodeDirectories()+IsHostCreated -> true)
266                         //return Host.
267                         throw new NotImplementedException ();
268                 }
269
270                 public override object InitializeLifetimeService ()
271                 {
272                         return null;
273                 }
274
275                 [MonoTODO ("Not implemented")]
276                 public bool IsCodeAssembly (string assemblyName)
277                 {
278                         // Trying all the assemblies loaded by FullName and GetName().Name yield false here :-?
279                         throw new NotImplementedException ();
280                 }
281
282                 [MonoTODO ("Not implemented")]
283                 public void PrecompileApplication ()
284                 {
285                         throw new NotImplementedException ();
286                 }
287
288                 [MonoTODO ("Not implemented")]
289                 public void PrecompileApplication (ClientBuildManagerCallback callback)
290                 {
291                         throw new NotImplementedException ();
292                 }
293
294                 [MonoTODO ("Not implemented")]
295                 public void PrecompileApplication (ClientBuildManagerCallback callback, bool forceCleanBuild)
296                 {
297                         throw new NotImplementedException ();
298                 }
299
300                 public bool Unload ()
301                 {
302                         if (host != null) {
303                                 host.Shutdown ();
304                                 OnAppDomainShutdown (0);
305                                 host = null;
306                         }
307
308                         return true; // FIXME: may be we should do this synch. + timeout? Test!
309                 }
310
311                 public string CodeGenDir {
312                         get { return Host.GetCodeGenDir (); }
313                 }
314
315                 public bool IsHostCreated {
316                         get { return host != null; }
317                 }
318
319                 void IDisposable.Dispose ()
320                 {
321                         Unload ();
322                 }
323         }
324
325 }
326 #endif
327