aboutsummaryrefslogtreecommitdiffstatsci
path: root/src/IML/NodeAddress.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/IML/NodeAddress.cs')
-rw-r--r--src/IML/NodeAddress.cs76
1 files changed, 73 insertions, 3 deletions
diff --git a/src/IML/NodeAddress.cs b/src/IML/NodeAddress.cs
index 460998da..c81a7f66 100644
--- a/src/IML/NodeAddress.cs
+++ b/src/IML/NodeAddress.cs
@@ -26,13 +26,83 @@ using System.Reflection.Emit;
namespace Crow.IML
{
+ /// <summary>
+ /// Node address is a list of nodes from root to leaf defining a unique node
+ /// </summary>
public class NodeAddress : List<Node>
{
- public NodeAddress (Node[] nodes) : base(nodes) {
- }
+ #region CTOR
+ public NodeAddress (Node[] nodes) : base(nodes) {}
+ #endregion
public Type NodeType { get { return Count == 0 ? null : this[this.Count -1].CrowType; }}
+ /// <summary>
+ /// Gets the node adress from binding expression starting from this node
+ /// and return in expression remaining part
+ /// </summary>
+ public NodeAddress ResolveExpression (ref string expression){
+ int ptr = this.Count - 1;
+ string[] splitedExp = expression.Split ('/');
+
+ if (splitedExp.Length < 2)//dataSource binding
+ return null;
+
+ if (string.IsNullOrEmpty (splitedExp [0]) || splitedExp [0] == ".") {//search template root
+ ptr--;
+ while (ptr >= 0) {
+ if (typeof(TemplatedControl).IsAssignableFrom (this [ptr].CrowType))
+ break;
+ ptr--;
+ }
+ } else if (splitedExp [0] == "..") { //search starting at current node
+ int levelUp = splitedExp.Length - 1;
+ if (levelUp > ptr + 1)
+ throw new Exception ("Binding error: try to bind outside IML source");
+ ptr -= levelUp;
+ }
+ expression = splitedExp [splitedExp.Length - 1];
+ //TODO:change Template special address identified with Nodecount = 0 to something not using array count to 0,
+ //here linq is working without limits checking in compile option
+ //but defining a 0 capacity array with limits cheking enabled, cause 'out of memory' error
+ return new NodeAddress (this.Take(ptr+1).ToArray());//[ptr+1];
+ //Array.Copy (sourceAddr.ToArray (), targetNode, ptr + 1);
+ //return new NodeAddress (targetNode);
+ }
+ /// <summary>
+ /// get BindingDefinition from binding expression
+ /// </summary>
+ public BindingDefinition GetBindingDef(string sourceMember, string expression){
+ BindingDefinition bindingDef = new BindingDefinition(this, sourceMember);
+ if (string.IsNullOrEmpty (expression)) {
+ return bindingDef;
+ } else {
+ if (expression.StartsWith ("²")) {
+ bindingDef.TwoWay = true;
+ expression = expression.Substring (1);
+ }
+
+ string exp = expression;
+ bindingDef.TargetNA = this.ResolveExpression (ref exp);
+
+ string [] bindTrg = exp.Split ('.');
+
+ if (bindTrg.Length == 0)
+ throw new Exception ("invalid binding expression: " + expression);
+ if (bindTrg.Length == 1)
+ bindingDef.TargetMember = bindTrg [0];
+ else {
+ if (!string.IsNullOrEmpty(bindTrg[0]))//searchByName
+ bindingDef.TargetName = bindTrg[0];
+
+ bindingDef.TargetMember = exp.Substring (bindTrg[0].Length + 1);
+ }
+ }
+
+ return bindingDef;
+ }
+
+ #region Object overrides
public override bool Equals (object obj)
{
if (obj == null)
@@ -50,7 +120,6 @@ namespace Crow.IML
return hash;
}
}
-
public override string ToString ()
{
string tmp = "";
@@ -58,6 +127,7 @@ namespace Crow.IML
tmp += string.Format ("{0};", n.Index);
return tmp;
}
+ #endregion
}
public class NamedNodeAddress : NodeAddress {