public class Project {
bool buildEnabled;
- //IDictionary conditionedProperties;
Dictionary <string, List <string>> conditionedProperties;
string[] defaultTargets;
Encoding encoding;
string firstTargetName;
string fullFileName;
BuildPropertyGroup globalProperties;
- GroupingCollection groups;
+ GroupingCollection groupingCollection;
bool isDirty;
bool isValidated;
BuildItemGroupCollection itemGroups;
XmlDocument xmlDocument;
bool unloaded;
+ static XmlNamespaceManager manager;
+ static string ns = "http://schemas.microsoft.com/developer/msbuild/2003";
+
public Project ()
: this (Engine.GlobalEngine)
{
public Project (Engine engine)
{
+ buildEnabled = engine.BuildEnabled;
parentEngine = engine;
xmlDocument = new XmlDocument ();
- groups = new GroupingCollection ();
- imports = new ImportCollection (this);
+ groupingCollection = new GroupingCollection (this);
+ imports = new ImportCollection (groupingCollection);
usingTasks = new UsingTaskCollection (this);
- itemGroups = new BuildItemGroupCollection (groups);
- propertyGroups = new BuildPropertyGroupCollection (groups);
+ itemGroups = new BuildItemGroupCollection (groupingCollection);
+ propertyGroups = new BuildPropertyGroupCollection (groupingCollection);
targets = new TargetCollection (this);
taskDatabase = new TaskDatabase ();
- if (engine.DefaultTasksRegistered == true)
+ if (engine.DefaultTasksRegistered) {
taskDatabase.CopyTasks (engine.DefaultTasks);
+ }
globalProperties = new BuildPropertyGroup ();
fullFileName = String.Empty;
[MonoTODO]
public bool Build (string targetName)
{
- if (targets.Exists (targetName) == false)
- throw new Exception ("Target specified to build does not exist.");
-
- return this.targets [targetName].Build ();
+ return Build (new string [1] { targetName });
}
[MonoTODO]
public bool Build (string[] targetNames)
{
- return Build (targetNames, new Hashtable ());
+ return Build (targetNames, null);
}
[MonoTODO]
public bool Build (string[] targetNames,
IDictionary targetOutputs)
{
- return Build (targetNames, new Hashtable (), BuildSettings.None);
+ return Build (targetNames, targetOutputs, BuildSettings.None);
}
[MonoTODO]
{
CheckUnloaded ();
+
if (targetNames.Length == 0) {
- if (defaultTargets.Length != 0) {
+ if (defaultTargets != null && defaultTargets.Length != 0)
targetNames = defaultTargets;
- }
- else if (firstTargetName != null) {
+ else if (firstTargetName != null)
targetNames = new string [1] { firstTargetName};
- }
else
return false;
}
+
foreach (string target in targetNames) {
- if (Build (target) == false) {
+ if (!targets.Exists (target))
+ // FIXME: test if it's logged
+ return false;
+
+ if (!targets [target].Build ())
return false;
- }
}
+
return true;
}
if (evaluatedItemsByName.ContainsKey (itemName))
return evaluatedItemsByName [itemName];
else
- return null;
+ return new BuildItemGroup ();
}
public BuildItemGroup GetEvaluatedItemsByNameIgnoringCondition (string itemName)
if (evaluatedItemsByNameIgnoringCondition.ContainsKey (itemName))
return evaluatedItemsByNameIgnoringCondition [itemName];
else
- return null;
+ return new BuildItemGroup ();
}
public string GetEvaluatedProperty (string propertyName)
{
- return (string) evaluatedProperties [propertyName];
- }
+ if (propertyName == null)
+ throw new ArgumentNullException ("propertyName");
- [MonoTODO]
- public string GetProjectExtensions (string id)
- {
- throw new NotImplementedException ();
+ BuildProperty bp = evaluatedProperties [propertyName];
+
+ return bp == null ? null : (string) bp;
}
- // Does the actual loading.
- private void DoLoad (TextReader textReader)
+ public string GetProjectExtensions (string id)
{
- ParentEngine.RemoveLoadedProject (this);
-
- XmlReaderSettings settings = new XmlReaderSettings ();
+ if (id == null || id == String.Empty)
+ return String.Empty;
- if (SchemaFile != null) {
- settings.Schemas.Add (null, SchemaFile);
- settings.ValidationType = ValidationType.Schema;
- settings.ValidationEventHandler += new ValidationEventHandler (ValidationCallBack);
- }
+ XmlNode node = xmlDocument.SelectSingleNode (String.Format ("/tns:Project/tns:ProjectExtensions/tns:{0}", id), XmlNamespaceManager);
- XmlReader xmlReader = XmlReader.Create (textReader, settings);
- xmlDocument.Load (xmlReader);
-
- if (xmlDocument.DocumentElement.GetAttribute ("xmlns") != "http://schemas.microsoft.com/developer/msbuild/2003") {
- throw new InvalidProjectFileException (
- @"The default XML namespace of the project must be the MSBuild XML namespace." +
- " If the project is authored in the MSBuild 2003 format, please add " +
- "xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\" to the <Project> element. " +
- "If the project has been authored in the old 1.0 or 1.2 format, please convert it to MSBuild 2003 format. ");
- }
- ProcessXml ();
- ParentEngine.AddLoadedProject (this);
+ if (node == null)
+ return String.Empty;
+ else
+ return node.InnerXml;
}
+
public void Load (string projectFileName)
{
this.fullFileName = Path.GetFullPath (projectFileName);
{
fullFileName = String.Empty;
DoLoad (new StringReader (projectXml));
+ MarkProjectAsDirty ();
}
- internal void Unload ()
- {
- unloaded = true;
- }
-
- internal void CheckUnloaded ()
- {
- if (unloaded)
- throw new InvalidOperationException ("This project object is no longer valid.");
- }
-
- private void ProcessXml ()
- {
- XmlElement xmlElement = xmlDocument.DocumentElement;
- if (xmlElement.Name != "Project")
- throw new InvalidProjectFileException ("Invalid root element.");
- if (xmlElement.GetAttributeNode ("DefaultTargets") != null)
- defaultTargets = xmlElement.GetAttribute ("DefaultTargets").Split (';');
- else
- defaultTargets = new string [0];
-
- ProcessElements (xmlElement, null);
-
- isDirty = false;
- Evaluate ();
- }
-
- private void InitializeProperties ()
- {
- BuildProperty bp;
-
- foreach (BuildProperty gp in GlobalProperties) {
- bp = new BuildProperty (gp.Name, gp.Value, PropertyType.Global);
- EvaluatedProperties.AddProperty (bp);
- }
-
- foreach (DictionaryEntry de in Environment.GetEnvironmentVariables ()) {
- bp = new BuildProperty ((string) de.Key, (string) de.Value, PropertyType.Environment);
- EvaluatedProperties.AddProperty (bp);
- }
-
- bp = new BuildProperty ("MSBuildBinPath", parentEngine.BinPath, PropertyType.Reserved);
- EvaluatedProperties.AddProperty (bp);
- }
-
- internal void Evaluate ()
- {
- evaluatedItems = new BuildItemGroup (null, this);
- evaluatedItemsIgnoringCondition = new BuildItemGroup (null, this);
- evaluatedItemsByName = new Dictionary <string, BuildItemGroup> (StringComparer.InvariantCultureIgnoreCase);
- evaluatedItemsByNameIgnoringCondition = new Dictionary <string, BuildItemGroup> (StringComparer.InvariantCultureIgnoreCase);
- evaluatedProperties = new BuildPropertyGroup ();
-
- InitializeProperties ();
-
- // FIXME: questionable order of evaluation
-
- foreach (Import import in Imports)
- import.Evaluate ();
-
- foreach (BuildPropertyGroup bpg in PropertyGroups) {
- if (bpg.Condition == String.Empty)
- bpg.Evaluate ();
- else {
- ConditionExpression ce = ConditionParser.ParseCondition (bpg.Condition);
- if (ce.BoolEvaluate (this))
- bpg.Evaluate ();
- }
- }
-
- foreach (BuildItemGroup big in ItemGroups) {
- if (big.Condition == String.Empty)
- big.Evaluate ();
- else {
- ConditionExpression ce = ConditionParser.ParseCondition (big.Condition);
- if (ce.BoolEvaluate (this))
- big.Evaluate ();
- }
- }
-
- foreach (UsingTask usingTask in UsingTasks)
- usingTask.Evaluate ();
- }
public void MarkProjectAsDirty ()
{
isDirty = true;
+ timeOfLastDirty = DateTime.Now;
}
[MonoTODO]
xmlDocument.Save (outTextWriter);
}
- [MonoTODO]
public void SetImportedProperty (string propertyName,
string propertyValue,
string condition,
PropertyPosition.UseExistingOrCreateAfterLastPropertyGroup);
}
- [MonoTODO]
public void SetImportedProperty (string propertyName,
string propertyValue,
string condition,
throw new NotImplementedException ();
}
- [MonoTODO]
public void SetProjectExtensions (string id, string xmlText)
{
- throw new NotImplementedException ();
+ XmlNode projectExtensions, node;
+
+ if (id == null || id == String.Empty || xmlText == null)
+ return;
+
+ projectExtensions = xmlDocument.SelectSingleNode ("/tns:Project/tns:ProjectExtensions", XmlNamespaceManager);
+
+
+ if (projectExtensions == null) {
+ projectExtensions = xmlDocument.CreateElement ("ProjectExtensions", XmlNamespace);
+ xmlDocument.DocumentElement.AppendChild (projectExtensions);
+
+ node = xmlDocument.CreateElement (id, XmlNamespace);
+ node.InnerXml = xmlText;
+ projectExtensions.AppendChild (node);
+ } else {
+ node = xmlDocument.SelectSingleNode (String.Format ("/tns:Project/tns:ProjectExtensions/tns:{0}", id), XmlNamespaceManager);
+
+ if (node == null) {
+ node = xmlDocument.CreateElement (id, XmlNamespace);
+ projectExtensions.AppendChild (node);
+ }
+
+ node.InnerXml = xmlText;
+
+ }
+
+ MarkProjectAsDirty ();
}
[MonoTODO]
throw new NotImplementedException ();
}
+ internal void Unload ()
+ {
+ unloaded = true;
+ }
+
+ internal void CheckUnloaded ()
+ {
+ if (unloaded)
+ throw new InvalidOperationException ("This project object has been unloaded from the MSBuild engine and is no longer valid.");
+ }
+
+ // Does the actual loading.
+ void DoLoad (TextReader textReader)
+ {
+ try {
+ ParentEngine.RemoveLoadedProject (this);
+
+ XmlReaderSettings settings = new XmlReaderSettings ();
+
+ if (SchemaFile != null) {
+ settings.Schemas.Add (null, SchemaFile);
+ settings.ValidationType = ValidationType.Schema;
+ settings.ValidationEventHandler += new ValidationEventHandler (ValidationCallBack);
+ }
+
+ XmlReader xmlReader = XmlReader.Create (textReader, settings);
+ xmlDocument.Load (xmlReader);
+
+ if (xmlDocument.DocumentElement.Name != "Project") {
+ throw new InvalidProjectFileException (String.Format (
+ "The element <{0}> is unrecognized, or not supported in this context.", xmlDocument.DocumentElement.Name));
+ }
+
+ if (xmlDocument.DocumentElement.GetAttribute ("xmlns") != ns) {
+ throw new InvalidProjectFileException (
+ @"The default XML namespace of the project must be the MSBuild XML namespace." +
+ " If the project is authored in the MSBuild 2003 format, please add " +
+ "xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\" to the <Project> element. " +
+ "If the project has been authored in the old 1.0 or 1.2 format, please convert it to MSBuild 2003 format. ");
+ }
+ ProcessXml ();
+ ParentEngine.AddLoadedProject (this);
+ } catch (Exception e) {
+ throw new InvalidProjectFileException (e.Message, e);
+ }
+ }
+
+ void ProcessXml ()
+ {
+ XmlElement xmlElement = xmlDocument.DocumentElement;
+ if (xmlElement.Name != "Project")
+ throw new InvalidProjectFileException ("Invalid root element.");
+ if (xmlElement.GetAttributeNode ("DefaultTargets") != null)
+ defaultTargets = xmlElement.GetAttribute ("DefaultTargets").Split (';');
+ else
+ defaultTargets = new string [0];
+
+ ProcessElements (xmlElement, null);
+
+ isDirty = false;
+ Evaluate ();
+ }
+
internal void ProcessElements (XmlElement rootElement, ImportedProject ip)
{
foreach (XmlNode xn in rootElement.ChildNodes) {
AddImport (xe, ip);
break;
case "ItemGroup":
- AddItemGroup (xe);
+ AddItemGroup (xe, ip);
break;
case "PropertyGroup":
- AddPropertyGroup (xe);
+ AddPropertyGroup (xe, ip);
break;
case "Choose":
AddChoose (xe);
}
}
- private void AddProjectExtensions (XmlElement xmlElement)
+ internal void Evaluate ()
{
- if (xmlElement == null)
- throw new ArgumentNullException ("xmlElement");
+ evaluatedItems = new BuildItemGroup (null, this, null);
+ evaluatedItemsIgnoringCondition = new BuildItemGroup (null, this, null);
+ evaluatedItemsByName = new Dictionary <string, BuildItemGroup> (StringComparer.InvariantCultureIgnoreCase);
+ evaluatedItemsByNameIgnoringCondition = new Dictionary <string, BuildItemGroup> (StringComparer.InvariantCultureIgnoreCase);
+ evaluatedProperties = new BuildPropertyGroup ();
+
+ InitializeProperties ();
+
+ groupingCollection.Evaluate ();
+
+ //FIXME: UsingTasks aren't really evaluated. (shouldn't use expressions or anything)
+ foreach (UsingTask usingTask in UsingTasks)
+ usingTask.Evaluate ();
+ }
+
+ private void InitializeProperties ()
+ {
+ BuildProperty bp;
+
+ foreach (BuildProperty gp in GlobalProperties) {
+ bp = new BuildProperty (gp.Name, gp.Value, PropertyType.Global);
+ EvaluatedProperties.AddProperty (bp);
+ }
+
+ foreach (DictionaryEntry de in Environment.GetEnvironmentVariables ()) {
+ bp = new BuildProperty ((string) de.Key, (string) de.Value, PropertyType.Environment);
+ EvaluatedProperties.AddProperty (bp);
+ }
+
+ bp = new BuildProperty ("MSBuildBinPath", parentEngine.BinPath, PropertyType.Reserved);
+ EvaluatedProperties.AddProperty (bp);
}
- private void AddMessage (XmlElement xmlElement)
+ void AddProjectExtensions (XmlElement xmlElement)
{
- if (xmlElement == null)
- throw new ArgumentNullException ("xmlElement");
}
- private void AddTarget (XmlElement xmlElement, ImportedProject importedProject)
+ void AddMessage (XmlElement xmlElement)
{
- if (xmlElement == null)
- throw new ArgumentNullException ("xmlElement");
- Target target = new Target (xmlElement, this);
+ }
+
+ void AddTarget (XmlElement xmlElement, ImportedProject importedProject)
+ {
+ Target target = new Target (xmlElement, this, importedProject);
targets.AddTarget (target);
- if (importedProject == null) {
- target.IsImported = false;
- if (firstTargetName == null)
- firstTargetName = target.Name;
- } else
- target.IsImported = true;
+
+ if (firstTargetName == null)
+ firstTargetName = target.Name;
}
- private void AddUsingTask (XmlElement xmlElement, ImportedProject importedProject)
+ void AddUsingTask (XmlElement xmlElement, ImportedProject importedProject)
{
UsingTask usingTask;
UsingTasks.Add (usingTask);
}
- private void AddImport (XmlElement xmlElement, ImportedProject importingProject)
+ void AddImport (XmlElement xmlElement, ImportedProject importingProject)
{
Import import;
Imports.Add (import);
}
- private void AddItemGroup (XmlElement xmlElement)
+ void AddItemGroup (XmlElement xmlElement, ImportedProject importedProject)
{
- if (xmlElement == null)
- throw new ArgumentNullException ("xmlElement");
- BuildItemGroup big = new BuildItemGroup (xmlElement, this);
+ BuildItemGroup big = new BuildItemGroup (xmlElement, this, importedProject);
ItemGroups.Add (big);
- //big.Evaluate ();
}
- private void AddPropertyGroup (XmlElement xmlElement)
+ void AddPropertyGroup (XmlElement xmlElement, ImportedProject importedProject)
{
- if (xmlElement == null)
- throw new ArgumentNullException ("xmlElement");
- BuildPropertyGroup bpg = new BuildPropertyGroup (xmlElement, this);
+ BuildPropertyGroup bpg = new BuildPropertyGroup (xmlElement, this, importedProject);
PropertyGroups.Add (bpg);
- //bpg.Evaluate ();
}
- private void AddChoose (XmlElement xmlElement)
+ void AddChoose (XmlElement xmlElement)
{
- if (xmlElement == null)
- throw new ArgumentNullException ("xmlElement");
-
BuildChoose bc = new BuildChoose (xmlElement, this);
- groups.Add (bc);
+ groupingCollection.Add (bc);
}
- private static void ValidationCallBack (object sender, ValidationEventArgs e)
+ static void ValidationCallBack (object sender, ValidationEventArgs e)
{
Console.WriteLine ("Validation Error: {0}", e.Message);
}
get { return evaluatedItemsIgnoringCondition; }
}
- internal IDictionary EvaluatedItemsByName {
+ internal IDictionary <string, BuildItemGroup> EvaluatedItemsByName {
get { return evaluatedItemsByName; }
}
- internal IDictionary EvaluatedItemsByNameIgnoringCondition {
+ internal IDictionary <string, BuildItemGroup> EvaluatedItemsByNameIgnoringCondition {
get { return evaluatedItemsByNameIgnoringCondition; }
}
get { return xmlDocument.InnerXml; }
}
+ internal static XmlNamespaceManager XmlNamespaceManager {
+ get {
+ if (manager == null) {
+ manager = new XmlNamespaceManager (new NameTable ());
+ manager.AddNamespace ("tns", ns);
+ }
+
+ return manager;
+ }
+ }
+
internal TaskDatabase TaskDatabase {
get { return taskDatabase; }
}
+
+ internal XmlDocument XmlDocument {
+ get { return xmlDocument; }
+ }
+
+ internal static string XmlNamespace {
+ get { return ns; }
+ }
}
}