/// <summary> /// Gets the parent of target element level or root if reached /// </summary> /// <param name="source">The source.</param> /// <param name="level">The level.</param> /// <param name="getLastParent">if set to <c>true</c> [get last parent].</param> /// <param name="nullForNotFound">if set to <c>true</c> [null for not found].</param> /// <param name="limit">The limit.</param> /// <returns></returns> public static IObjectWithParent getParentOfLevel(this IObjectWithParent source, reportElementLevel level, Boolean getLastParent = false, Boolean nullForNotFound = true, Int32 limit = 100) { IObjectWithParent output = source; IObjectWithReportLevel head = output as IObjectWithReportLevel; Int32 c = 0; if (limit == -1) { limit = PATHSEARCH_MAX_LIMIT; } do { head = head.parent as IObjectWithReportLevel; if (getLastParent) { if (head.elementLevel == level) { IObjectWithReportLevel parent = head.parent as IObjectWithReportLevel; if (parent != null) { if (!(parent.elementLevel == level)) { return(head); } } else { return(head); } } else { } } else { if (getElementLevel(head) == level) { return(head); } } c++; if ((c > limit) || (c > PATHSEARCH_MAX_LIMIT)) { break; } } while ((head != null)); if (head == null) { if (nullForNotFound) { } else { } } return(head); }
//public static IObjectWithPathAndChildSelector getMemberByPath(this IObjectWithPathAndChildSelector shead, ) /// <summary> /// Get member by resolving relative or absolute <c>path</c> over <c>shead</c> starting object. /// </summary> /// <remarks> /// Path supports: absolute (starts with <c>PATHSPLITER</c>, go to parent <c>..</c>, ordinal selectors <c>[1]</c> and sequential child <c>name</c> selection /// </remarks> /// <param name="shead">Start head - object to start from</param> /// <param name="path">The path: accepts go to parent syntax.</param> /// <returns></returns> /// <exception cref="System.Exception">getChild() STACK OVERFLOW [".o(c).a("] metaContentBase")</exception> public static IObjectWithChildSelector getChildByPath(this IObjectWithChildSelector shead, string path) { if (path.StartsWith(PATHSPLITER)) { if (shead is IObjectWithRoot) { IObjectWithRoot sroot = shead as IObjectWithRoot; shead = sroot.root as IObjectWithChildSelector; } path = imbSciStringExtensions.removeStartsWith(path, PATHSPLITER); } List <string> prts = path.SplitSmart(PATHSPLITER); //.getPathParts(); IObjectWithChildSelector head = shead; Int32 c = 0; foreach (String pt in prts) { IObjectWithChildSelector nhead; Int32 ord = getOrdinalPathPart(pt); if (ord > -1) { if (ord >= head.Count()) { ord = head.Count() - 1; } nhead = head[ord] as IObjectWithChildSelector; } else if (pt.StartsWith(PATHGO_PARENT)) { IObjectWithParent phead = head as IObjectWithParent; if (phead != null) { nhead = phead.parent as IObjectWithPathAndChildSelector; } else { throw new ArgumentException("Go to parent path syntax found but head is not IObjectWithParent!!"); // [".o(c).a("] metaContentBase")); } } else { nhead = head[pt] as IObjectWithChildSelector; } if (nhead == head) { // logSystem.log("tmp"); //break; } else { head = nhead; } c++; if (c > 100) { throw new ArgumentException("getChild() would lead to STACK OVERFLOW - the limit was breached"); // aceGeneralException("getChild() STACK OVERFLOW [".o(c).a("] metaContentBase")); } } return(head); }
/// <summary> /// Gets a member from parent-chain: a) Nth parent according to limit. b) parent on <c>targetPath</c>, c) parent of <c>target</c> type or simply d) root if no more parents. /// </summary> /// <param name="source">The source - objects to start search from</param> /// <param name="target">The target Type - what type will triger return of current head</param> /// <param name="limit">The limit of depth. For -1: unlimited, For 1: it will return source.parent, For 0: it will return source, for 50: it will return 50th parent in parent-chain.</param> /// <param name="targetPath">Once head reach this path it will trigger return of head. Disabled if empty or null.</param> /// <returns>Parent in parent chain or root</returns> /// \ingroup_disabled ace_ext_path public static IObjectWithParent getParentOrRoot(this IObjectWithParent source, String targetPath = "", Type target = null, Int32 limit = 100) { IObjectWithParent head = source; Int32 c = 0; Boolean p_testOn = (!imbSciStringExtensions.isNullOrEmptyString(targetPath) || (source is IObjectWithPath)); Boolean t_testOn = (target != null); if (limit == -1) { limit = PATHSEARCH_MAX_LIMIT; } do { IObjectWithParent nhead = head.parent as IObjectWithParent; if (nhead == null) { return(head); } if (nhead == head) { throw new ArgumentException("IObjectWithParent.parent is the object it self! getParentOrRoot [" + c + "]"); // logSystem.log("tmp"); break; } else { head = nhead; } if (t_testOn) { if (head.GetType() == target) { return(head); } } if (p_testOn) { IObjectWithPath p_head = head as IObjectWithPath; if (p_head != null) { if (p_head.path == targetPath) { return(head); } } } c++; if ((c > limit) || (c > PATHSEARCH_MAX_LIMIT)) { return(head); // } } while (head.parent != null); return(head); }