/// <summary> /// Creates a differential structure with all "skipped" parents filled in. /// </summary> /// <param name="differential"></param> /// <returns>The full tree structure representing the differential</returns> /// <remarks>This operation will not touch the source differential, but instead will return a new structure.</remarks> public Profile.ProfileStructureComponent MakeTree() { var diff = (Profile.ProfileStructureComponent)_source.DeepCopy(); // We're going to modify the differential if (diff.Element == null || diff.Element.Count == 0) { return(diff); // nothing to do } var index = 0; var elements = diff.Element; while (index < elements.Count) { var thisPath = elements[index].Path; var prevPath = index > 0 ? elements[index - 1].Path : String.Empty; if (thisPath.IndexOf('.') == -1) { // I am a root node, just one segment of path, I need to be the first element if (index != 0) { throw Error.InvalidOperation("Differential has multiple roots"); } // Else, I am fine, proceed index++; } else if (ElementNavigator.IsSibling(thisPath, prevPath) || ElementNavigator.IsDirectChildPath(prevPath, thisPath)) { // The previous path is a sibling, or my direct parent, so everything is alright, proceed to next node index++; } else { var parentPath = ElementNavigator.GetParentPath(thisPath); if (prevPath == String.Empty || !prevPath.StartsWith(parentPath + ".")) { // We're missing a path part, insert an empty parent var parentElement = new Profile.ElementComponent() { Path = parentPath }; elements.Insert(index, parentElement); // Now, we're not sure this parent has parents, so proceed by checking the parent we have just inserted // so -> index is untouched } else { // So, my predecessor an I share ancestry, of which I am sure it has been inserted by this algorithm // before because of my predecessor, so we're fine. index++; } } } return(diff); }
public static string GetParentNameFromPath(this Profile.ElementComponent element) { return(ElementNavigator.GetParentPath(element.Path)); }