68fe0bd770904f0882f8a04c9d5c7e81a1747dce
[mono.git] / mcs / class / System.Web / System.Web.Compilation / BuildProvider.cs
1 //
2 // System.Web.Compilation.BuildProvider
3 //
4 // Authors:
5 //      Chris Toshok (toshok@ximian.com)
6 //      Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 //
8 // (C) 2006-2009 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 using System;
33 using System.CodeDom;
34 using System.CodeDom.Compiler;
35 using System.Collections;
36 using System.Collections.Generic;
37 using System.Collections.Specialized;
38 using System.IO;
39 using System.Reflection;
40 using System.Web.Configuration;
41 using System.Web.Hosting;
42 using System.Web.Util;
43
44 namespace System.Web.Compilation
45 {
46         public abstract class BuildProvider
47         {
48 #if NET_4_0
49                 static Dictionary <string, Type> registeredBuildProviderTypes;
50 #endif
51                 ArrayList ref_assemblies;
52                 
53                 ICollection vpath_deps;
54                 CompilationSection compilationSection;
55
56                 VirtualPath vpath;
57                 
58                 CompilationSection CompilationConfig {
59                         get {
60                                 if (compilationSection == null)
61                                         compilationSection = WebConfigurationManager.GetWebApplicationSection ("system.web/compilation") as CompilationSection;
62                                 return compilationSection;
63                         }
64                 }
65                 
66                 internal virtual string LanguageName {
67                         get { return CompilationConfig.DefaultLanguage; }
68                 }
69                 
70                 protected BuildProvider()
71                 {
72                         ref_assemblies = new ArrayList ();
73                 }
74
75                 internal void SetVirtualPath (VirtualPath virtualPath)
76                 {
77                         vpath = virtualPath;
78                 }
79
80                 internal virtual void GenerateCode ()
81                 {
82                 }
83
84                 internal virtual IDictionary <string, bool> ExtractDependencies ()
85                 {
86                         return null;
87                 }
88                 
89                 public virtual void GenerateCode (AssemblyBuilder assemblyBuilder)
90                 {
91                 }
92
93                 public virtual string GetCustomString (CompilerResults results)
94                 {
95                         return null;
96                 }
97
98                 protected CompilerType GetDefaultCompilerType ()
99                 {
100                         return BuildManager.GetDefaultCompilerTypeForLanguage (CompilationConfig.DefaultLanguage, CompilationConfig);
101                 }
102                 
103                 protected CompilerType GetDefaultCompilerTypeForLanguage (string language)
104                 {
105                         return BuildManager.GetDefaultCompilerTypeForLanguage (language, null);
106                 }
107
108                 public virtual Type GetGeneratedType (CompilerResults results)
109                 {
110                         return null;
111                 }
112
113                 public virtual BuildProviderResultFlags GetResultFlags (CompilerResults results)
114                 {
115                         return BuildProviderResultFlags.Default;
116                 }
117
118                 protected TextReader OpenReader ()
119                 {
120                         return OpenReader (VirtualPath);
121                 }
122
123                 protected TextReader OpenReader (string virtualPath)
124                 {
125                         Stream st = OpenStream (virtualPath);
126                         return new StreamReader (st, WebEncoding.FileEncoding);
127                 }
128
129                 protected Stream OpenStream ()
130                 {
131                         return OpenStream (VirtualPath);
132                 }
133
134                 protected Stream OpenStream (string virtualPath)
135                 {
136                         // MS also throws a NullReferenceException here when not hosted.
137                         return VirtualPathProvider.OpenFile (virtualPath);
138                 }
139 #if NET_4_0
140                 public static void RegisterBuildProvider (string extension, Type providerType)
141                 {
142                         if (String.IsNullOrEmpty (extension))
143                                 throw new ArgumentException ("The string parameter 'extension' cannot be null or empty.", "extension");
144
145                         if (providerType == null)
146                                 throw new ArgumentNullException ("providerType");
147
148                         if (!typeof (BuildProvider).IsAssignableFrom (providerType))
149                                 throw new ArgumentException ("The parameter 'providerType' is invalid", "providerType");
150
151                         BuildManager.AssertPreStartMethodsRunning ();
152
153                         if (registeredBuildProviderTypes == null)
154                                 registeredBuildProviderTypes = new Dictionary <string, Type> (StringComparer.OrdinalIgnoreCase);
155
156                         registeredBuildProviderTypes [extension] = providerType;
157                 }
158
159                 internal static Type GetProviderTypeForExtension (string extension)
160                 {
161                         if (String.IsNullOrEmpty (extension))
162                                 return null;
163
164                         Type type = null;
165                         if (registeredBuildProviderTypes == null || !registeredBuildProviderTypes.TryGetValue (extension, out type) || type == null) {
166                                 var cs = WebConfigurationManager.GetSection ("system.web/compilation") as CompilationSection;
167                                 BuildProviderCollection bpcoll = cs != null ? cs.BuildProviders : null;
168                                 global::System.Web.Configuration.BuildProvider bpcfg = bpcoll != null ? bpcoll [extension] : null;
169                                 if (bpcfg != null)
170                                         type = HttpApplication.LoadType (bpcfg.Type);
171                         }
172
173                         return type;
174                 }
175                 
176                 internal static BuildProvider GetProviderInstanceForExtension (string extension)
177                 {
178                         Type type = GetProviderTypeForExtension (extension);
179                         if (type == null)
180                                 return null;
181                         
182                         return Activator.CreateInstance (type, null) as global::System.Web.Compilation.BuildProvider;
183                 }
184 #endif
185                 public virtual CompilerType CodeCompilerType {
186                         get { return null; } // Documented to return null
187                 }
188
189                 protected ICollection ReferencedAssemblies {
190                         get { return ref_assemblies; }
191                 }
192
193                 protected internal string VirtualPath {
194                         get { return vpath != null ? vpath.Absolute : null; }
195                 }
196
197                 internal VirtualPath VirtualPathInternal {
198                         get { return vpath; }
199                 }
200                 
201                 public virtual ICollection VirtualPathDependencies {
202                         get {
203                                 if (vpath_deps == null)
204                                         vpath_deps = new OneNullCollection ();
205
206                                 return vpath_deps;
207                         }
208                 }
209
210                 internal virtual CodeCompileUnit CodeUnit {
211                         get { return null; }
212                 }
213         }
214
215         class OneNullCollection : ICollection {
216                 public int Count {
217                         get { return 1; }
218                 }
219
220                 public bool IsSynchronized {
221                         get { return false; }
222                 }
223
224                 public object SyncRoot {
225                         get { return this; }
226                 }
227
228                 public void CopyTo (Array array, int index)
229                 {
230                         if (array == null)
231                                 throw new ArgumentNullException ();
232
233                         if (index < 0)
234                                 throw new ArgumentOutOfRangeException ();
235
236                         if (array.Rank > 1)
237                                 throw new ArgumentException ();
238
239                         int length = array.Length;
240                         if (index >= length || index > length - 1)
241                                 throw new ArgumentException ();
242
243                         array.SetValue (null, index);
244                 }
245
246                 public IEnumerator GetEnumerator ()
247                 {
248                         yield return null;
249                 }
250         }
251 }
252
253