2 // System.Web.Compilation.AppResourceAseemblyBuilder
5 // Marek Habersack (mhabersack@novell.com)
7 // (C) 2007 Novell, Inc
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:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
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.
33 using System.CodeDom.Compiler;
34 using System.Collections.Generic;
36 using System.Reflection;
38 using System.Web.Configuration;
40 namespace System.Web.Compilation
42 internal class AppResourcesAssemblyBuilder
44 CompilationSection config;
46 CodeDomProvider _provider;
47 string baseAssemblyPath;
48 string baseAssemblyDirectory;
49 string canonicAssemblyName;
50 Assembly mainAssembly;
51 AppResourcesCompiler appResourcesCompiler;
53 public CodeDomProvider Provider {
55 if (_provider == null)
56 _provider = ci.CreateProvider ();
60 if (_provider == null)
61 throw new ApplicationException ("Failed to instantiate the default compiler.");
66 public Assembly MainAssembly {
67 get { return mainAssembly; }
70 public AppResourcesAssemblyBuilder (string canonicAssemblyName, string baseAssemblyPath, AppResourcesCompiler appres)
72 this.appResourcesCompiler = appres;
73 this.baseAssemblyPath = baseAssemblyPath;
74 this.baseAssemblyDirectory = Path.GetDirectoryName (baseAssemblyPath);
75 this.canonicAssemblyName = canonicAssemblyName;
77 config = WebConfigurationManager.GetSection ("system.web/compilation") as CompilationSection;
78 if (config == null || !CodeDomProvider.IsDefinedLanguage (config.DefaultLanguage))
79 throw new ApplicationException ("Could not get the default compiler.");
80 ci = CodeDomProvider.GetCompilerInfo (config.DefaultLanguage);
81 if (ci == null || !ci.IsCodeDomProviderTypeValid)
82 throw new ApplicationException ("Failed to obtain the default compiler information.");
90 public void Build (CodeCompileUnit unit)
92 Dictionary <string, List <string>> cultures = appResourcesCompiler.CultureFiles;
93 string defaultAssemblyKey = AppResourcesCompiler.DefaultCultureKey;
95 foreach (KeyValuePair <string, List <string>> kvp in cultures)
96 BuildAssembly (kvp.Key, kvp.Value, defaultAssemblyKey, unit);
99 void BuildAssembly (string cultureName, List <string> files, string defaultAssemblyKey, CodeCompileUnit unit)
101 bool defaultAssembly = cultureName == defaultAssemblyKey;
102 AssemblyBuilder abuilder = new AssemblyBuilder (Provider);
103 if (unit != null && defaultAssembly)
104 abuilder.AddCodeCompileUnit (unit);
106 string assemblyPath = defaultAssembly ? baseAssemblyPath : BuildAssemblyPath (cultureName, abuilder);
107 CompilerParameters cp = ci.CreateDefaultCompilerParameters ();
108 cp.OutputAssembly = assemblyPath;
109 cp.GenerateExecutable = false;
110 cp.TreatWarningsAsErrors = true;
111 cp.IncludeDebugInformation = config.Debug;
113 foreach (string f in files)
114 cp.EmbeddedResources.Add (f);
116 CompilerResults results = abuilder.BuildAssembly (cp);
119 if (results.NativeCompilerReturnValue == 0) {
120 ret = results.CompiledAssembly;
121 if (defaultAssembly) {
122 BuildManager.TopLevelAssemblies.Add (ret);
126 if (HttpContext.Current.IsCustomErrorEnabled)
127 throw new ApplicationException ("An error occurred while compiling global resources.");
128 throw new CompilationException (null, results.Errors, null);
131 if (defaultAssembly) {
132 HttpRuntime.WritePreservationFile (ret, canonicAssemblyName);
133 HttpRuntime.EnableAssemblyMapping (true);
137 string BuildAssemblyPath (string cultureName, AssemblyBuilder abuilder)
139 string baseDir = Path.Combine (baseAssemblyDirectory, cultureName);
140 if (!Directory.Exists (baseDir))
141 Directory.CreateDirectory (baseDir);
143 string baseFileName = Path.GetFileNameWithoutExtension (baseAssemblyPath);
144 string fileName = String.Concat (baseFileName, ".resources.dll");
145 fileName = Path.Combine (baseDir, fileName);
147 CodeCompileUnit assemblyInfo = GenerateAssemblyInfo (cultureName);
148 if (assemblyInfo != null)
149 abuilder.AddCodeCompileUnit (assemblyInfo);
154 CodeCompileUnit GenerateAssemblyInfo (string cultureName)
156 CodeAttributeArgument[] args = new CodeAttributeArgument [1];
157 args [0] = new CodeAttributeArgument (new CodePrimitiveExpression (cultureName));
159 CodeCompileUnit unit = new CodeCompileUnit ();
160 unit.AssemblyCustomAttributes.Add (
161 new CodeAttributeDeclaration (
162 new CodeTypeReference ("System.Reflection.AssemblyCultureAttribute"),
165 args = new CodeAttributeArgument [2];
166 args [0] = new CodeAttributeArgument (new CodePrimitiveExpression ("ASP.NET"));
167 args [1] = new CodeAttributeArgument (new CodePrimitiveExpression (Environment.Version.ToString ()));
168 unit.AssemblyCustomAttributes.Add (
169 new CodeAttributeDeclaration (
170 new CodeTypeReference ("System.CodeDom.Compiler.GeneratedCodeAttribute"),