blob: d0b7d2010ad4b9b0f5646838513583c1a20d13e3 [file] [log] [blame]
using System;
using System.Collections.Generic;
using System.Text;
using NMaven.ProjectImporter.SlnParser;
using NMaven.ProjectImporter.SlnParser.Model;
using System.IO;
using NMaven.ProjectImporter.Parser.VisualStudioProjectTypes;
using System.Text.RegularExpressions;
using Microsoft.Build.BuildEngine;
using System.Xml;
/// Author: Leopoldo Lee Agdeppa III
namespace NMaven.ProjectImporter.Parser.Solution
{
public class ProjectSolutionParser
{
protected static string PROJECT_REFERENCE_REGEX;
protected static Engine BUILD_ENGINE;
static ProjectSolutionParser()
{
PROJECT_REFERENCE_REGEX = @"({(?<ProjectReferenceGUID>([^\}])*)}\|(?<ProjectReferenceDll>([^;])*);)";
// gets the directory path of mscorlib using the System.String Type Assembly path
string msBuildPath = Path.GetDirectoryName(System.Reflection.Assembly.GetAssembly(typeof(string)).Location);
BUILD_ENGINE = new Engine(msBuildPath);
}
public List<Dictionary<string, object>> Parse(FileInfo solutionFile)
{
List<Dictionary<string, object>> list = new List<Dictionary<string, object>>();
NMaven.ProjectImporter.SlnParser.Model.Solution solution = SolutionFactory.GetSolution(solutionFile);
foreach (NMaven.ProjectImporter.SlnParser.Model.Project project in solution.Projects)
{
Dictionary<string, object> dictionary = new Dictionary<string, object>();
dictionary.Add("ProjectTypeGuid", project.ProjectTypeGUID);
dictionary.Add("ProjectType", VisualStudioProjectType.GetVisualStudioProjectType(project.ProjectTypeGUID));
dictionary.Add("ProjectName", project.ProjectName);
dictionary.Add("ProjectPath", project.ProjectPath);
dictionary.Add("ProjectGUID", project.ProjectGUID);
string fullpath = Path.Combine(solutionFile.DirectoryName, project.ProjectPath);
dictionary.Add("ProjectFullPath", fullpath);
// this is for web projects
if ((VisualStudioProjectTypeEnum)dictionary["ProjectType"] == VisualStudioProjectTypeEnum.Web_Site)
{
string[] assemblies = GetWebConfigAssemblies(Path.Combine(fullpath, "web.config"));
dictionary.Add("WebConfigAssemblies", assemblies);
//@001 SERNACIO START retrieving webreference
Digest.Model.WebReferenceUrl[] webReferences = getWebReferenceUrls(fullpath);
dictionary.Add("WebReferencesUrl", webReferences);
//@001 SERNACIO END retrieving webreference
string[] binAssemblies = GetBinAssemblies(Path.Combine(fullpath, @"bin"));
dictionary.Add("BinAssemblies", binAssemblies);
//ParseInnerData(dictionary, match.Groups["projectInnerData"].ToString());
ParseProjectReferences(dictionary, project, solution);
}
// this is for normal projects
else if (
(VisualStudioProjectTypeEnum)dictionary["ProjectType"] == VisualStudioProjectTypeEnum.Windows__CSharp
|| (VisualStudioProjectTypeEnum)dictionary["ProjectType"] == VisualStudioProjectTypeEnum.Windows__VbDotNet
)
{
Microsoft.Build.BuildEngine.Project prj = new Microsoft.Build.BuildEngine.Project(BUILD_ENGINE);
prj.Load(fullpath);
//ParseInnerData(dictionary, match.Groups["projectInnerData"].ToString());
ParseProjectReferences(dictionary, project, solution);
dictionary.Add("Project", prj);
}
list.Add(dictionary);
}
return list;
}
protected void ParseProjectReferences(Dictionary<string, object> dictionary, NMaven.ProjectImporter.SlnParser.Model.Project project, NMaven.ProjectImporter.SlnParser.Model.Solution solution)
{
if (project.ProjectSections != null)
{
List<Microsoft.Build.BuildEngine.Project> projectReferenceList = new List<Microsoft.Build.BuildEngine.Project>();
foreach (ProjectSection ps in project.ProjectSections)
{
if ("WebsiteProperties".Equals(ps.Name))
{
// ProjectReferences = "{11F2FCC8-5941-418A-A0E7-42D250BA9D21}|SampleInterProject111.dll;{9F37BA7B-06F9-4B05-925D-B5BC16322E8B}|BongClassLib.dll;"
try
{
Regex regex = new Regex(PROJECT_REFERENCE_REGEX, RegexOptions.Multiline | RegexOptions.IgnoreCase);
MatchCollection matches = regex.Matches(ps.Map["ProjectReferences"]);
foreach (Match match in matches)
{
string projectReferenceGUID = match.Groups["ProjectReferenceGUID"].ToString();
string projectReferenceDll = match.Groups["ProjectReferenceDll"].ToString();
Microsoft.Build.BuildEngine.Project prj = GetMSBuildProject(solution, projectReferenceGUID);
if (prj != null)
{
projectReferenceList.Add(prj);
}
}
}
catch { }
}
else if("ProjectDependencies".Equals(ps.Name))
{
//{0D80BE11-F1CE-409E-B9AC-039D3801209F} = {0D80BE11-F1CE-409E-B9AC-039D3801209F}
foreach (string key in ps.Map.Keys)
{
Microsoft.Build.BuildEngine.Project prj = GetMSBuildProject(solution, key.Replace("{","").Replace("}", ""));
if (prj != null)
{
projectReferenceList.Add(prj);
}
}
}
}
dictionary.Add("InterProjectReferences", projectReferenceList.ToArray());
}
}
Microsoft.Build.BuildEngine.Project GetMSBuildProject(NMaven.ProjectImporter.SlnParser.Model.Solution solution, string projectGuid)
{
foreach (NMaven.ProjectImporter.SlnParser.Model.Project p in solution.Projects)
{
if (p.ProjectGUID.Equals("{" + projectGuid + "}", StringComparison.OrdinalIgnoreCase))
{
string projectReferenceName = p.ProjectName;
string projectReferencePath = p.ProjectPath;
string projectReferenceFullPath = null;
if (Path.IsPathRooted(projectReferencePath))
{
projectReferenceFullPath = Path.GetFullPath(projectReferencePath);
}
else
{
projectReferenceFullPath = Path.Combine(solution.File.Directory.FullName, projectReferencePath);
}
Microsoft.Build.BuildEngine.Project prj = new Microsoft.Build.BuildEngine.Project(BUILD_ENGINE);
prj.Load(projectReferenceFullPath);
return prj;
}
}
return null;
}
protected string[] GetWebConfigAssemblies(string webconfig)
{
List<string> list = new List<string>();
string xpath_expr = @"//configuration/system.web/compilation/assemblies/add";
FileInfo webConfigFile = new FileInfo(webconfig);
if (!webConfigFile.Exists)
{
// return empty string array
return list.ToArray();
}
XmlDocument xmldoc = new System.Xml.XmlDocument();
xmldoc.Load(webConfigFile.FullName);
XmlNodeList valueList = xmldoc.SelectNodes(xpath_expr);
foreach (System.Xml.XmlNode val in valueList)
{
string assembly = val.Attributes["assembly"].Value;
if (!string.IsNullOrEmpty(assembly))
{
list.Add(assembly);
}
}
return list.ToArray();
}
protected String[] GetBinAssemblies(string webBinDir)
{
List<string> list = new List<string>();
DirectoryInfo dir = new DirectoryInfo(webBinDir);
if (!dir.Exists)
{
// return an empty array string
return list.ToArray();
}
foreach (FileInfo dll in dir.GetFiles("*.dll"))
{
list.Add(dll.FullName);
}
return list.ToArray();
}
Digest.Model.WebReferenceUrl[] getWebReferenceUrls(string projectPath)
{
List<Digest.Model.WebReferenceUrl> returnList = new List<Digest.Model.WebReferenceUrl>();
string webPath = Path.GetFullPath(Path.Combine(projectPath, "App_WebReferences"));
if (Directory.Exists(webPath))
{
DirectoryInfo dirInfo = new DirectoryInfo(webPath);
foreach (DirectoryInfo folders in dirInfo.GetDirectories())
{
if (folders.Equals(".svn")) continue;
returnList.AddRange(getWebReferenceUrls(folders, "App_WebReferences"));
}
}
return returnList.ToArray();
}
Digest.Model.WebReferenceUrl[] getWebReferenceUrls(DirectoryInfo folder, string currentPath)
{
string relPath = Path.Combine(currentPath, folder.Name);
string url = string.Empty;
List<Digest.Model.WebReferenceUrl> webReferenceUrls = new List<Digest.Model.WebReferenceUrl>();
FileInfo[] fileInfo = folder.GetFiles("*.discomap");
if (fileInfo != null && fileInfo.Length > 0)
{
System.Xml.XPath.XPathDocument xDoc = new System.Xml.XPath.XPathDocument(fileInfo[0].FullName);
System.Xml.XPath.XPathNavigator xNav = xDoc.CreateNavigator();
string xpathExpression = @"DiscoveryClientResultsFile/Results/DiscoveryClientResult[@referenceType='System.Web.Services.Discovery.ContractReference']/@url";
System.Xml.XPath.XPathNodeIterator xIter = xNav.Select(xpathExpression);
if (xIter.MoveNext())
{
url = xIter.Current.TypedValue.ToString();
}
}
if (!string.IsNullOrEmpty(url))
{
Digest.Model.WebReferenceUrl newWebReferenceUrl = new Digest.Model.WebReferenceUrl();
newWebReferenceUrl.RelPath = relPath;
newWebReferenceUrl.UpdateFromURL = url;
webReferenceUrls.Add(newWebReferenceUrl);
}
foreach (DirectoryInfo dirInfo in folder.GetDirectories())
{
webReferenceUrls.AddRange(getWebReferenceUrls(dirInfo, relPath));
}
return webReferenceUrls.ToArray();
}
}
}