New test.
[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                 public string GenerateCode (string virtualPath, string virtualFileString, out IDictionary linePragmasTable)
162                 {
163                         // This thing generates a .ccu (CodeCompileUnit?) file (reported as TrueType font data by 'file'!)
164                         // resultType=7 vs. resultType=3 for assemblies reported in the .compiled file
165                         // The virtual path is just added to the dependencies list, but is checked to be an absolute path.
166                         // IsHostCreated returns true after calling this method.
167                         //
168                         // A null file string causes virtualPath to be mapped and read to generate the code
169                         //
170
171                         if (virtualPath == null || virtualPath == "")
172                                 throw new ArgumentNullException ("virtualPath");
173
174                         CodeCompileUnit unit = null;
175                         Type cprovider_type;
176                         CompilerParameters parameters;
177                         unit = GenerateCodeCompileUnit (virtualPath, virtualFileString, out cprovider_type,
178                                                         out parameters, out linePragmasTable);
179                         return null;
180                 }
181
182                 [MonoTODO ("Not implemented")]
183                 public CodeCompileUnit GenerateCodeCompileUnit (string virtualPath,
184                                                                 string virtualFileString,
185                                                                 out Type codeDomProviderType,
186                                                                 out CompilerParameters compilerParameters,
187                                                                 out IDictionary linePragmasTable)
188                 {
189                         throw new NotImplementedException ();
190                 }
191
192                 public CodeCompileUnit GenerateCodeCompileUnit (string virtualPath,
193                                                                 out Type codeDomProviderType,
194                                                                 out CompilerParameters compilerParameters,
195                                                                 out IDictionary linePragmasTable)
196                 {
197                         return GenerateCodeCompileUnit (virtualPath, out codeDomProviderType,
198                                                         out compilerParameters, out linePragmasTable);
199                 }
200
201                 static string [] shutdown_directories = new string [] {
202                                                 "bin", "App_GlobalResources", "App_Code",
203                                                 "App_WebReferences", "App_Browsers" };
204
205                 public string [] GetAppDomainShutdownDirectories ()
206                 {
207                         return shutdown_directories;
208                 }
209
210                 [MonoTODO ("Not implemented")]
211                 public IDictionary GetBrowserDefinitions ()
212                 {
213                         throw new NotImplementedException ();
214                 }
215
216                 [MonoTODO ("Not implemented")]
217                 public void GetCodeDirectoryInformation (string virtualCodeDir,
218                                                         out Type codeDomProviderType,
219                                                         out CompilerParameters compilerParameters,
220                                                         out string generatedFilesDir)
221                 {
222                         throw new NotImplementedException ();
223                 }
224
225                 [MonoTODO ("Not implemented")]
226                 public Type GetCompiledType (string virtualPath)
227                 {
228                         // CompileFile + get the type based on .compiled file information
229                         // Throws if virtualPath is a special virtual directory (App_Code et al)
230                         throw new NotImplementedException ();
231                 }
232
233                 [MonoTODO ("Not implemented")]
234                 public void GetCompilerParameters (string virtualPath,
235                                                 out Type codeDomProviderType,
236                                                 out CompilerParameters compilerParameters)
237                 {
238                         throw new NotImplementedException ();
239                 }
240
241                 [MonoTODO ("Not implemented")]
242                 public string GetGeneratedFileVirtualPath (string filePath)
243                 {
244                         // returns empty string for any vpath. Test with real paths.
245                         throw new NotImplementedException ();
246                 }
247
248                 [MonoTODO ("Not implemented")]
249                 public string GetGeneratedSourceFile (string virtualPath)
250                 {
251                         // This one takes a directory name /xxx and /xxx/App_Code throw either
252                         // a KeyNotFoundException or an InvalidOperationException
253                         throw new NotImplementedException ();
254                 }
255
256                 [MonoTODO ("Not implemented")]
257                 public string [] GetTopLevelAssemblyReferences (string virtualPath)
258                 {
259                         throw new NotImplementedException ();
260                 }
261
262                 public string [] GetVirtualCodeDirectories ()
263                 {
264                         // Host is created here when needed. (Unload()+GetVirtualCodeDirectories()+IsHostCreated -> true)
265                         //return Host.
266                         throw new NotImplementedException ();
267                 }
268
269                 public override object InitializeLifetimeService ()
270                 {
271                         return null;
272                 }
273
274                 [MonoTODO ("Not implemented")]
275                 public bool IsCodeAssembly (string assemblyName)
276                 {
277                         // Trying all the assemblies loaded by FullName and GetName().Name yield false here :-?
278                         throw new NotImplementedException ();
279                 }
280
281                 [MonoTODO ("Not implemented")]
282                 public void PrecompileApplication ()
283                 {
284                         throw new NotImplementedException ();
285                 }
286
287                 [MonoTODO ("Not implemented")]
288                 public void PrecompileApplication (ClientBuildManagerCallback callback)
289                 {
290                         throw new NotImplementedException ();
291                 }
292
293                 [MonoTODO ("Not implemented")]
294                 public void PrecompileApplication (ClientBuildManagerCallback callback, bool forceCleanBuild)
295                 {
296                         throw new NotImplementedException ();
297                 }
298
299                 public bool Unload ()
300                 {
301                         if (host != null) {
302                                 host.Shutdown ();
303                                 OnAppDomainShutdown (0);
304                                 host = null;
305                         }
306
307                         return true; // FIXME: may be we should do this synch. + timeout? Test!
308                 }
309
310                 public string CodeGenDir {
311                         get { return Host.GetCodeGenDir (); }
312                 }
313
314                 public bool IsHostCreated {
315                         get { return host != null; }
316                 }
317
318                 void IDisposable.Dispose ()
319                 {
320                         Unload ();
321                 }
322         }
323
324 }
325 #endif
326