// NAnt - A .NET build tool // Copyright (C) 2001-2003 Gerry Shaw // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // Matthew Mastracci (matt@aclaro.com) using System; using System.Collections.Specialized; using System.Globalization; using System.IO; using NAnt.Core.Util; using NAnt.DotNet.Tasks; using NAnt.DotNet.Types; using NAnt.VSNet.Tasks; namespace NAnt.VSNet { public class Resource { #region Public Instance Constructors public Resource(ManagedProjectBase project, FileInfo resourceSourceFile, string resourceSourceFileRelativePath, string dependentFile, SolutionTask solutionTask, GacCache gacCache) { _project = project; _resourceSourceFile = resourceSourceFile; _resourceSourceFileRelativePath = resourceSourceFileRelativePath; _dependentFile = dependentFile; _solutionTask = solutionTask; _culture = CompilerBase.GetResourceCulture(resourceSourceFile.FullName, dependentFile); } #endregion Public Instance Constructors #region Public Instance Properties public CultureInfo Culture { get { return _culture; } } /// /// Gets a representing the physical location /// of the resource file. /// public FileInfo InputFile { get { return _resourceSourceFile; } } public ManagedProjectBase Project { get { return _project; } } /// /// Gets a representing the logical location /// of the resource file in the project. /// /// /// When the resource file is not linked, this matches the /// . /// public FileInfo LogicalFile { get { return new FileInfo(FileUtils.CombinePaths(Path.GetDirectoryName( Project.ProjectPath), _resourceSourceFileRelativePath)); } } /// /// Gets a value indicating whether the resource is in fact a ResX file. /// /// /// if the resource is a ResX file; otherwise, /// . /// public bool IsResX { get { return InputFile.Extension.ToLower(CultureInfo.InvariantCulture) == ".resx"; } } #endregion Public Instance Properties #region Public Instance Methods /// /// Compiles the resource file. /// /// The solution configuration that is built. /// /// A representing the compiled resource file. /// public FileInfo Compile(string solutionConfiguration) { FileInfo compiledResourceFile = null; switch (InputFile.Extension.ToLower(CultureInfo.InvariantCulture)) { case ".resx": compiledResourceFile = CompileResx(solutionConfiguration); break; case ".licx": compiledResourceFile = CompileLicx(solutionConfiguration); break; default: compiledResourceFile = CompileResource(solutionConfiguration); break; } return compiledResourceFile; } /// /// Returns a representing the compiled resource /// file. /// /// The solution configuration that is built. /// /// A representing the compiled resource file. /// /// /// Calling this method does not force compilation of the resource file. /// public FileInfo GetCompiledResourceFile(string solutionConfiguration) { string compiledResourceFile = null; // obtain project configuration (corresponding with solution configuration) ConfigurationSettings config = (ConfigurationSettings) Project.BuildConfigurations[solutionConfiguration]; switch (InputFile.Extension.ToLower(CultureInfo.InvariantCulture)) { case ".resx": compiledResourceFile = FileUtils.CombinePaths(config.ObjectDir.FullName, GetManifestResourceName(solutionConfiguration)); break; case ".licx": compiledResourceFile = FileUtils.CombinePaths(config.ObjectDir.FullName, Project.ProjectSettings.OutputFileName + ".licenses"); break; default: compiledResourceFile = InputFile.FullName; break; } return new FileInfo(compiledResourceFile); } public string GetManifestResourceName(string solutionConfiguration) { // obtain project configuration (corresponding with solution configuration) ConfigurationSettings projectConfig = (ConfigurationSettings) Project.BuildConfigurations[solutionConfiguration]; switch (Project.Type) { case ProjectType.CSharp: return GetManifestResourceNameCSharp(projectConfig, _dependentFile); case ProjectType.VB: return GetManifestResourceNameVB(projectConfig, _dependentFile); case ProjectType.JSharp: return GetManifestResourceNameJSharp(projectConfig, _dependentFile); default: throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "Unsupported project type '{0}'.", Project.Type)); } } #endregion Public Instance Methods #region Private Instance Methods private string GetManifestResourceNameCSharp(ConfigurationSettings configSetting, string dependentFile) { // defer to the resource management code in CscTask CscTask csc = new CscTask(); csc.Project = _solutionTask.Project; csc.NamespaceManager = _solutionTask.NamespaceManager; csc.OutputFile = new FileInfo(FileUtils.CombinePaths(configSetting.OutputDir.FullName, Project.ProjectSettings.OutputFileName)); // set-up resource fileset ResourceFileSet resources = new ResourceFileSet(); resources.Project = _solutionTask.Project; resources.NamespaceManager = _solutionTask.NamespaceManager; resources.Parent = csc; resources.BaseDirectory = new DirectoryInfo(Path.GetDirectoryName(Project.ProjectPath)); resources.Prefix = Project.ProjectSettings.RootNamespace; resources.DynamicPrefix = true; // bug #1042917: use logical location of resource file to determine // manifest resource name return csc.GetManifestResourceName(resources, InputFile.FullName, LogicalFile.FullName, dependentFile); } private string GetManifestResourceNameVB(ConfigurationSettings configSetting, string dependentFile) { // defer to the resource management code in VbcTask VbcTask vbc = new VbcTask(); vbc.Project = _solutionTask.Project; vbc.NamespaceManager = _solutionTask.NamespaceManager; vbc.OutputFile = new FileInfo(FileUtils.CombinePaths(configSetting.OutputDir.FullName, Project.ProjectSettings.OutputFileName)); vbc.RootNamespace = Project.ProjectSettings.RootNamespace; // set-up resource fileset ResourceFileSet resources = new ResourceFileSet(); resources.Project = _solutionTask.Project; resources.NamespaceManager = _solutionTask.NamespaceManager; resources.Parent = vbc; resources.BaseDirectory = new DirectoryInfo(Path.GetDirectoryName(Project.ProjectPath)); resources.Prefix = Project.ProjectSettings.RootNamespace; resources.DynamicPrefix = false; // bug #1042917: use logical location of resource file to determine // manifest resource name return vbc.GetManifestResourceName(resources, InputFile.FullName, LogicalFile.FullName, dependentFile); } private string GetManifestResourceNameJSharp(ConfigurationSettings configSetting, string dependentFile) { // defer to the resource management code in VjcTask VjcTask vjc = new VjcTask(); vjc.Project = _solutionTask.Project; vjc.NamespaceManager = _solutionTask.NamespaceManager; vjc.OutputFile = new FileInfo(FileUtils.CombinePaths(configSetting.OutputDir.FullName, Project.ProjectSettings.OutputFileName)); // set-up resource fileset ResourceFileSet resources = new ResourceFileSet(); resources.Project = _solutionTask.Project; resources.NamespaceManager = _solutionTask.NamespaceManager; resources.Parent = vjc; resources.BaseDirectory = new DirectoryInfo(Path.GetDirectoryName( Project.ProjectPath)); resources.Prefix = Project.ProjectSettings.RootNamespace; resources.DynamicPrefix = true; // bug #1042917: use logical location of resource file to determine // manifest resource name return vjc.GetManifestResourceName(resources, InputFile.FullName, LogicalFile.FullName, dependentFile); } private FileInfo CompileResource(string solutionConfiguration) { return GetCompiledResourceFile(solutionConfiguration); } private FileInfo CompileLicx(string solutionConfiguration) { // create instance of License task LicenseTask lt = new LicenseTask(); // inherit project from solution task lt.Project = _solutionTask.Project; // inherit namespace manager from solution task lt.NamespaceManager = _solutionTask.NamespaceManager; // parent is solution task lt.Parent = _solutionTask; // inherit verbose setting from solution task lt.Verbose = _solutionTask.Verbose; // make sure framework specific information is set lt.InitializeTaskConfiguration(); // set parent of child elements lt.Assemblies.Parent = lt; // inherit project from solution task from parent task lt.Assemblies.Project = lt.Project; // inherit namespace manager from parent task lt.Assemblies.NamespaceManager = lt.NamespaceManager; // set base directory for filesets lt.Assemblies.BaseDirectory = new DirectoryInfo(Path.GetDirectoryName(Project.ProjectPath)); // set task properties lt.InputFile = InputFile; lt.OutputFile = GetCompiledResourceFile(solutionConfiguration); // convert target to uppercase to match VS.NET lt.Target = Path.GetFileName(Project.ProjectSettings.OutputFileName). ToUpper(CultureInfo.InvariantCulture); // inherit assembly references from project foreach (ReferenceBase reference in Project.References) { StringCollection assemblyReferences = reference.GetAssemblyReferences( solutionConfiguration); foreach (string assemblyFile in assemblyReferences) { lt.Assemblies.Includes.Add(assemblyFile); } } // increment indentation level lt.Project.Indent(); try { // execute task lt.Execute(); } finally { // restore indentation level lt.Project.Unindent(); } return lt.OutputFile; } private FileInfo CompileResx(string solutionConfiguration) { // for performance reasons, compilation of resx files is done in // batch using the ResGen task in ManagedProjectBase throw new InvalidOperationException(); } #endregion Private Instance Methods #region Private Instance Fields private readonly CultureInfo _culture; private readonly FileInfo _resourceSourceFile; private readonly string _dependentFile; private readonly string _resourceSourceFileRelativePath; private readonly ManagedProjectBase _project; private readonly SolutionTask _solutionTask; #endregion Private Instance Fields } }