Skip to content

Commit

Permalink
adding tasks programmatically
Browse files Browse the repository at this point in the history
  • Loading branch information
ArsenShnurkov committed Jan 15, 2017
1 parent be5ac7d commit 863a5dd
Show file tree
Hide file tree
Showing 20 changed files with 904 additions and 100 deletions.
21 changes: 21 additions & 0 deletions mpt-core/03_msbuild/ICan.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System.Collections.Generic;
using System.Xml;

public interface IHaveUnderlyingNode
{
XmlNode UnderlyingNode { get; }
}

public interface ICanHaveProperties : IHaveUnderlyingNode
{
}

public interface ICanHaveItems : IHaveUnderlyingNode
{
}

public interface ICanBeConditional
{
string Condition { get; set; }
}

232 changes: 232 additions & 0 deletions mpt-core/03_msbuild/MSBuildFile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
using System;
using System.Collections.Generic;
using System.Xml.XPath;
using System.Xml;

public class MSBuildFile : IDisposable
{
public const string NamespaceName = "http://schemas.microsoft.com/developer/msbuild/2003";
XmlDocument doc;
bool bSaveRequired = false;
string filename = null;
List<MSBuildImport> importNodes = new List<MSBuildImport>();
List<MSBuildTarget> targetNodes = new List<MSBuildTarget>();
public XmlDocument UnderlyingObject
{
get
{
return doc;
}
}
public string FileName
{
get
{
return filename;
}
set
{
filename = value;
}
}

public MSBuildFile(XmlDocument d)
{
this.doc = d;
}
public MSBuildFile(string filename)
{
XmlDocument d = new XmlDocument();
d.Load(filename);
this.doc = d;
FindAllImports();
FindAllTargets();
}

public void Dispose()
{
if (bSaveRequired && String.IsNullOrWhiteSpace(filename) == false)
{
doc.Save(filename);
}
}

public void AddTarget(MSBuildTarget target)
{
// it does not automatically add the new object to the document tree.
// To add the new object, one must explicitly call one of the node insert methods.
XmlNode n = target.UnderlyingObject;
XPathNavigator locator = doc.CreateNavigator();
locator.MoveToRoot();
XmlNode root = locator.UnderlyingObject as XmlNode;
if (locator.MoveToFirstChild() == false)
{
root.AppendChild(n);
}
else
{
while (locator.MoveToNext()) { };
XmlNode sibling = locator.UnderlyingObject as XmlNode;
root.InsertAfter(n, sibling);
}
bSaveRequired = true;
}

static bool IsAlreadyExists(string import_name, XmlNamespaceManager xmlNamespaceManager, XPathNavigator navigator)
{
var xpath1 = "/ns:Project/ns:Import[@Project='" + import_name + "']";
XPathExpression expr1 = navigator.Compile(xpath1);
expr1.SetContext(xmlNamespaceManager);
var nodeIterator1 = navigator.Select(expr1);
if (nodeIterator1.Count > 0)
{
return true;
}
return false;
}

public MSBuildImport CreateImport()
{
var result = new MSBuildImport(this);
return result;
}

public void FindAllImports()
{
var xmlNamespaceManager = new XmlNamespaceManager(new NameTable());
xmlNamespaceManager.AddNamespace("ns", MSBuildFile.NamespaceName);

XPathNavigator navigator = doc.CreateNavigator();
navigator.MoveToRoot();

var xpath = "/ns:Project/ns:Import[@Project]";
XPathExpression expr = navigator.Compile(xpath);
expr.SetContext(xmlNamespaceManager);

var nodeIterator = navigator.Select(expr);
if (nodeIterator.Count == 0)
{
return;
}
do
{
if (nodeIterator.Current is IHasXmlNode)
{
XmlElement node = (XmlElement)((IHasXmlNode)nodeIterator.Current).GetNode();
MSBuildImport wrapperObject = new MSBuildImport(this, node);
importNodes.Add(wrapperObject);
}
}
while (nodeIterator.MoveNext()); // see also https://weblogs.asp.net/cazzu/86609
}

// locate if there is import of Microsoft.CSharp.targets
public MSBuildImport FindImport(string v)
{
foreach (MSBuildImport item in this.importNodes)
{
if (string.Compare(item.Project, v) == 0)
{
return item;
}
}
return null;
}

public void InsertImport(MSBuildImport newImport)
{
if (FindImport(newImport.Project) != null)
{
return;
}

// запомнить у себя
this.importNodes.Add(newImport);

// у тебя в руках узел, но оне вставленный в XML-документ
XmlElement newXmlElement = newImport.UnderlyingObject;

XPathNavigator navigator = doc.CreateNavigator();
navigator.MoveToRoot();

XmlElement root = (XmlElement)navigator.UnderlyingObject;
root.AppendChild(newXmlElement);
}

public void InsertImportAfter(MSBuildImport existingImport, MSBuildImport newImport)
{
// запомнить у себя
this.importNodes.Add(newImport);
// вставить в нижележащий слой
XmlElement existingElement = existingImport.UnderlyingObject;
XmlElement newElement = newImport.UnderlyingObject;
existingElement.ParentNode.InsertAfter(existingElement, newElement);
}

public MSBuildTarget CreateTarget()
{
var result = new MSBuildTarget(this);
return result;
}

public void FindAllTargets()
{
var xmlNamespaceManager = new XmlNamespaceManager(new NameTable());
xmlNamespaceManager.AddNamespace("ns", MSBuildFile.NamespaceName);

XPathNavigator navigator = doc.CreateNavigator();
navigator.MoveToRoot();

var xpath = "/ns:Project/ns:Target[@Name]";
XPathExpression expr = navigator.Compile(xpath);
expr.SetContext(xmlNamespaceManager);

var nodeIterator = navigator.Select(expr);
if (nodeIterator.Count == 0)
{
return;
}
do
{
if (nodeIterator.Current is IHasXmlNode)
{
XmlElement node = (XmlElement)((IHasXmlNode)nodeIterator.Current).GetNode();
MSBuildTarget wrapperObject = new MSBuildTarget(this, node);
targetNodes.Add(wrapperObject);
}
}
while (nodeIterator.MoveNext()); // see also https://weblogs.asp.net/cazzu/86609
}

public MSBuildTarget FindTarget(string v)
{
foreach (MSBuildTarget item in this.targetNodes)
{
if (string.Compare(item.Name, v) == 0)
{
return item;
}
}
return null;
}

public void InsertTarget(MSBuildTarget newTarget)
{
if (FindTarget(newTarget.Name) != null)
{
return;
}

// запомнить у себя
this.targetNodes.Add(newTarget);

// у тебя в руках узел, но оне вставленный в XML-документ
XmlElement newXmlElement = newTarget.UnderlyingObject;

XPathNavigator navigator = doc.CreateNavigator();
navigator.MoveToRoot();

XmlElement root = (XmlElement)navigator.UnderlyingObject;
root.AppendChild(newXmlElement);
}
}
32 changes: 32 additions & 0 deletions mpt-core/03_msbuild/MSBuildImport.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Xml;

public class MSBuildImport
{
MSBuildFile file;
XmlElement uo;

public XmlElement UnderlyingObject
{
get
{
return uo;
}
}

public string Project { get { return uo.Attributes["Project"].Value; } set { uo.Attributes["Project"].Value = value; } }

public MSBuildImport(MSBuildFile f, XmlElement el)
{
this.file = f;
uo = el;
}

public MSBuildImport(MSBuildFile f)
{
this.file = f;
// string element = "<Import Project=\"" + import_name + "\" />";
uo = (XmlElement)file.UnderlyingObject.CreateNode(XmlNodeType.Element, "Import", this.uo.NamespaceURI);
}
}
16 changes: 16 additions & 0 deletions mpt-core/03_msbuild/MSBuildItem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;
using System.Xml;

public class MSBuildItem
{
XmlElement uo;

public XmlElement UnderlyingObject { get { return uo; } }

public MSBuildItem(MSBuildItemGroup parent)
{
XmlDocument doc = parent.UnderlyingObject.OwnerDocument;
uo = (XmlElement)doc.CreateNode(XmlNodeType.Element, "UndefilnedItemName", doc.NamespaceURI);
}
}

32 changes: 32 additions & 0 deletions mpt-core/03_msbuild/MSBuildItemGroup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Xml;

public class MSBuildItemGroup
{
XmlElement uo;

public XmlElement UnderlyingObject { get { return uo; } }

IEnumerable<MSBuildItem> Items { get; }

//ICanHaveItems parent;

public MSBuildItemGroup(ICanHaveItems parent)
{
//this.parent = parent;
XmlDocument doc = parent.UnderlyingNode.OwnerDocument;
uo = (XmlElement)doc.CreateNode(XmlNodeType.Element, "UndefilnedItemName", doc.NamespaceURI);
}

public MSBuildItem CreateItem()
{
MSBuildItem res = new MSBuildItem(this);
return res;
}
public void AppendItem(MSBuildItem item)
{
throw new NotImplementedException();
}
}

41 changes: 41 additions & 0 deletions mpt-core/03_msbuild/MSBuildProperty.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using System;
using System.Xml;

public class MSBuildProperty
{
XmlElement uo;

public XmlElement UnderlyingObject { get { return uo; } }

public string Name { get { return uo.LocalName; } set { SetName(value); } }
public string Value { get { return uo.Value; } set { uo.Value = value; } }

public MSBuildProperty(MSBuildPropertyGroup parent)
{
XmlDocument doc = parent.UnderlyingObject.OwnerDocument;
uo = (XmlElement)doc.CreateNode(XmlNodeType.Element, "UndefilnedPropertyName", doc.NamespaceURI);
}

void SetName(string name)
{
// replace underlaying object to change it's name
XmlElement oldItem = uo;
XmlDocument doc = oldItem.OwnerDocument;
// replace name
uo = (XmlElement)doc.CreateNode(XmlNodeType.Element, name, doc.NamespaceURI);
uo.Value = oldItem.Value;
// copy attributes
foreach (XmlAttribute a in oldItem.Attributes)
{
uo.Attributes.Append((XmlAttribute)a.CloneNode(true));
}
// copy childs
for (XmlNode child = oldItem.FirstChild; child != null; child = child.NextSibling)
{
uo.AppendChild(child.CloneNode(true));
}
// what about node's text content ?
//uo.Value = oldItem.Value;
oldItem.ParentNode.ReplaceChild(uo, oldItem);
}
}
Loading

0 comments on commit 863a5dd

Please sign in to comment.