/// <summary> /// Remove loops from pluglet /// </summary> /// <param name="pluglet"></param> /// <param name="canonicalPluglet"></param> /// <returns></returns> public static Pluglet RemoveLoops(this IPluglet pluglet, IPluglet canonicalPluglet) { if (pluglet == null) { throw new ArgumentNullException("pluglet"); } Pluglet resultPluglet = pluglet.Clone(false); if (pluglet.Children != null && pluglet.Children.Count > 0) { int childIndex; IPluglet prevChild, mergedChild, canonicalChildPluglet = null; prevChild = mergedChild = canonicalChildPluglet = null; for (childIndex = 0; childIndex < pluglet.Children.Count; childIndex++) { canonicalChildPluglet = canonicalPluglet.Children.First(p => p.Name == pluglet.Children[childIndex].Name); pluglet.Children[childIndex] = pluglet.Children[childIndex].RemoveLoops(canonicalChildPluglet); if (prevChild != null) { if (string.Equals(prevChild.Name, pluglet.Children[childIndex].Name, StringComparison.OrdinalIgnoreCase)) { mergedChild = mergedChild.Merge(pluglet.Children[childIndex], canonicalChildPluglet); } else { resultPluglet.Children.Add(mergedChild); mergedChild = null; } } prevChild = pluglet.Children[childIndex]; if (mergedChild == null) { mergedChild = pluglet.Children[childIndex]; } } if (mergedChild == null) { mergedChild = pluglet.Children[childIndex - 1]; } resultPluglet.Children.Add(mergedChild); } return(resultPluglet); }
/// <summary> /// Merge pluglet and newPluglet and return merged pluglet. /// Assumption: pluglet and newPluglet does not have loops /// </summary> /// <param name="pluglet"></param> /// <param name="newPluglet"></param> /// <param name="canonicalPluglet"></param> /// <returns></returns> public static Pluglet Merge(this IPluglet pluglet, IPluglet newPluglet, IPluglet canonicalPluglet) { if (pluglet == null) { throw new ArgumentNullException("pluglet"); } if (newPluglet == null) { throw new ArgumentNullException("newPluglet"); } if (canonicalPluglet == null) { throw new ArgumentNullException("canonicalPluglet"); } Pluglet mergedPluglet; // Make sure that both pluglet has same name if (string.Equals(pluglet.Name, newPluglet.Name, StringComparison.OrdinalIgnoreCase) == false) { throw new PlugDataModelException( string.Format("Merge operation is invalid: pluglet ({0}) and newpluglet({1}) does not match.", pluglet.Name, newPluglet.Name)); } if (string.Equals(pluglet.Name, canonicalPluglet.Name, StringComparison.OrdinalIgnoreCase) == false) { throw new PlugDataModelException(string.Format("Merge operation params are invalid: {0} and {1}", pluglet.Name, canonicalPluglet.Name)); } // If one of the pluglet does not have children then assign non-null to tempPluglet, clone it with // childrens and return IPluglet tempPluglet = null; if (pluglet.Children == null || newPluglet.Children == null) { tempPluglet = pluglet ?? newPluglet; } if (tempPluglet != null) { mergedPluglet = tempPluglet.Clone(true); } else { mergedPluglet = pluglet.Clone(false); int plugletChildIndex, newPlugletChildIndex; bool plugletChildExist, newPlugletChildExist; plugletChildIndex = newPlugletChildIndex = 0; foreach (IPluglet child in canonicalPluglet.Children) { plugletChildExist = newPlugletChildExist = false; if (plugletChildIndex < pluglet.Children.Count && string.Equals(child.Name, pluglet.Children[plugletChildIndex].Name, StringComparison.OrdinalIgnoreCase)) { plugletChildExist = true; } if (newPlugletChildIndex < newPluglet.Children.Count && string.Equals(child.Name, newPluglet.Children[newPlugletChildIndex].Name, StringComparison.OrdinalIgnoreCase)) { newPlugletChildExist = true; } // If both pluglet has same child then call Merge if (plugletChildExist && newPlugletChildExist) { // TODO: Perf optimization - We don't need to call Merge if child does not have childrens mergedPluglet.Children.Add(pluglet.Children[plugletChildIndex].Merge(newPluglet.Children[newPlugletChildIndex], child)); plugletChildIndex++; newPlugletChildIndex++; } // If only one pluglet has child then clone it with childrens else if (plugletChildExist == true) { mergedPluglet.Children.Add(pluglet.Children[plugletChildIndex].Clone(true)); plugletChildIndex++; } else if (newPlugletChildExist == true) { mergedPluglet.Children.Add(newPluglet.Children[newPlugletChildIndex].Clone(true)); newPlugletChildIndex++; } if (plugletChildIndex == pluglet.Children.Count && newPlugletChildIndex == newPluglet.Children.Count) { break; } } } return(mergedPluglet); }