// 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
}
}