// NAnt - A .NET build tool
// Copyright (C) 2001-2004 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)
// Scott Ford (sford@RJKTECH.com)
// Gert Driesen (gert.driesen@ardatis.com)
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Globalization;
using System.IO;
using System.Xml;
using NAnt.Core;
using NAnt.Core.Util;
namespace NAnt.VSNet {
public abstract class FileReferenceBase : ReferenceBase {
#region Protected Instance Constructors
protected FileReferenceBase(XmlElement xmlDefinition, ReferencesResolver referencesResolver, ProjectBase parent, GacCache gacCache) : base(referencesResolver, parent) {
if (xmlDefinition == null) {
throw new ArgumentNullException("xmlDefinition");
}
if (gacCache == null) {
throw new ArgumentNullException("gacCache");
}
_xmlDefinition = xmlDefinition;
_gacCache = gacCache;
}
#endregion Protected Instance Constructors
#region Protected Instance Properties
protected XmlElement XmlDefinition {
get { return _xmlDefinition; }
}
protected GacCache GacCache {
get { return _gacCache; }
}
#endregion Protected Instance Properties
#region Override implementation of ReferenceBase
///
/// Gets a value indicating whether the reference is managed for the
/// specified configuration.
///
/// The build configuration of the reference.
///
/// .
///
public override bool IsManaged(string config) {
return true;
}
#endregion Override implementation of ReferenceBase
#region Protected Instance Methods
///
/// Gets the complete set of output files for the specified assembly
/// and adds them to collection.
///
/// The path of the assembly to get the output files for.
/// The set of output files to be updated.
///
/// The key of the case-insensitive is the
/// full path of the output file and the value is the path relative to
/// the output directory.
///
protected void GetAssemblyOutputFiles(string assemblyFile, Hashtable outputFiles) {
if (!File.Exists(assemblyFile)) {
// no need to output warning if set of output files cannot be
// generated
return;
}
if (!outputFiles.ContainsKey(assemblyFile)) {
string[] referencedModules = GetAllReferencedModules(assemblyFile);
// get a list of the references in the output directory
foreach (string referenceFile in referencedModules) {
// skip module if module is not the assembly referenced by
// the project and is installed in GAC
if (string.Compare(referenceFile, assemblyFile, true, CultureInfo.InvariantCulture) != 0) {
// skip referenced module if the assembly referenced by
// the project is a system reference or the module itself
// is installed in the GAC
if (IsSystem || GacCache.IsAssemblyInGac(referenceFile)) {
continue;
}
}
// get list of files related to referenceFile, this will include
// referenceFile itself
GetRelatedFiles(referenceFile, outputFiles);
}
}
}
#endregion Protected Instance Methods
#region Private Instance Methods
private string[] GetAllReferencedModules(string module) {
string fullPathToModule = FileUtils.GetFullPath(module);
string moduleDirectory = Path.GetDirectoryName(fullPathToModule);
Hashtable allReferences = new Hashtable();
Hashtable unresolvedReferences = new Hashtable();
try {
allReferences.Add(fullPathToModule, null);
unresolvedReferences.Add(fullPathToModule, null);
while (unresolvedReferences.Count > 0) {
IDictionaryEnumerator unresolvedEnumerator = unresolvedReferences.GetEnumerator();
unresolvedEnumerator.MoveNext();
string referenceToResolve = (string) unresolvedEnumerator.Key;
unresolvedReferences.Remove(referenceToResolve);
ReferencesResolver.AppendReferencedModulesLocatedInGivenDirectory(
moduleDirectory, referenceToResolve, ref allReferences,
ref unresolvedReferences);
}
} catch (Exception ex) {
throw new BuildException(string.Format(CultureInfo.InvariantCulture,
"Error resolving module references of '{0}'.", fullPathToModule),
Location.UnknownLocation, ex);
}
string[] result = new string[allReferences.Keys.Count];
allReferences.Keys.CopyTo(result, 0);
return result;
}
#endregion Private Instance Methods
#region Private Instance Fields
private readonly XmlElement _xmlDefinition;
private readonly GacCache _gacCache;
#endregion Private Instance Fields
}
}