public static ElementNavigator JumpToNameReference(this Profile.ProfileStructureComponent structure, string nameReference)
        {
            var nav = new ElementNavigator(structure);

            //TODO: In the current DSTU1 base profiles, nameReference is actually a path, not a name (to Element.Name)
            //this is a problem, since when doing slicing, the path may no longer point to a single set of constraints
            //so, we need to (temporarily) watch out for this
            if (nameReference.Contains("."))
            {
                // An incorrectly used nameReference, containing a Path, not a name
                if (nav.JumpToFirst(nameReference))
                {
                    return(nav);
                }
                else
                {
                    return(null);
                }
            }
            else
            {
                if (nav.JumpToNameReference(nameReference))
                {
                    return(nav);
                }
                else
                {
                    return(null);
                }
            }
        }
Пример #2
0
        public Profile.ProfileStructureComponent Expand(Profile.ProfileStructureComponent differential)
        {
            var baseStructure = _loader.LocateBaseStructure(differential.TypeElement);

            if (baseStructure == null)
            {
                throw Error.InvalidOperation("Could not locate the base profile for type {0}", differential.TypeElement.ToString());
            }

            var baseUri = StructureLoader.BuildBaseStructureUri(differential.TypeElement).ToString();

            var snapshot = (Profile.ProfileStructureComponent)baseStructure.DeepCopy();

            snapshot.SetStructureForm(StructureForm.Snapshot);
            snapshot.SetStructureBaseUri(baseUri.ToString());

            mergeStructure(snapshot, differential);

            var fullDifferential = new DifferentialTreeConstructor(differential).MakeTree();

            var snapNav = new ElementNavigator(snapshot);

            snapNav.MoveToFirstChild();

            var diffNav = new ElementNavigator(fullDifferential);

            diffNav.MoveToFirstChild();

            merge(snapNav, diffNav);

            //TODO: Merge search params?

            snapNav.CommitChanges();
            return(snapshot);
        }
        /// <summary>
        /// Insert the children of the current source node under the node pointed to by the destination.
        /// </summary>
        /// <param name="dest"></param>
        /// <param name="source"></param>
        /// <returns></returns>
        public static bool CopyChildren(this BaseElementNavigator dest, ElementNavigator source)
        {
            if (dest.HasChildren) return false;   // Protect children from being overwritten
            if (!source.MoveToFirstChild()) return true;    // Nothing to copy, but successful anyway

            bool firstChild = true;

            do
            {
                var copiedChild = (Profile.ElementComponent)source.Current.DeepCopy();

                if (firstChild)
                {
                    // The first time, create a new child in the destination                    
                    dest.InsertFirstChild(copiedChild);
                    firstChild = false;
                }
                else
                    // Then insert other childs after that
                    dest.InsertAfter(copiedChild);
                
                // If there are nested children in the source, insert them under
                // the newly inserted node in the destination
                if (source.HasChildren) dest.CopyChildren(source);
            }
            while (source.MoveToNext());

            // Bring both source & destination back one step to the original parents
            source.MoveToParent();
            dest.MoveToParent();

            return true;
        }
Пример #4
0
        public Profile.ProfileStructureComponent Expand(Profile.ProfileStructureComponent differential)
        {
            var baseStructure = _loader.LocateBaseStructure(differential.TypeElement);
            if (baseStructure == null) throw Error.InvalidOperation("Could not locate the base profile for type {0}", differential.TypeElement.ToString());

            var baseUri = StructureLoader.BuildBaseStructureUri(differential.TypeElement).ToString();

            var snapshot = (Profile.ProfileStructureComponent)baseStructure.DeepCopy();
            snapshot.SetStructureForm(StructureForm.Snapshot);
            snapshot.SetStructureBaseUri(baseUri.ToString());

            mergeStructure(snapshot, differential);

            var fullDifferential = new DifferentialTreeConstructor(differential).MakeTree();

            var snapNav = new ElementNavigator(snapshot);
            snapNav.MoveToFirstChild();

            var diffNav = new ElementNavigator(fullDifferential);
            diffNav.MoveToFirstChild();

            merge(snapNav, diffNav);

            //TODO: Merge search params?

            snapNav.CommitChanges();
            return snapshot;
        }
Пример #5
0
        public void MakeDifferentialTree()
        {
            var struc = new Profile.ProfileStructureComponent();
            struc.Element = new List<Profile.ElementComponent>();

            struc.Element.Add(new Profile.ElementComponent() { Path = "A.B.C1" });
            struc.Element.Add(new Profile.ElementComponent() { Path = "A.B.C1" });
            struc.Element.Add(new Profile.ElementComponent() { Path = "A.B.C2" });
            struc.Element.Add(new Profile.ElementComponent() { Path = "A.B" });
            struc.Element.Add(new Profile.ElementComponent() { Path = "A.B.C1.D" });
            struc.Element.Add(new Profile.ElementComponent() { Path = "A.D.F" });

            var tree = new DifferentialTreeConstructor(struc).MakeTree();
            Assert.IsNotNull(tree);

            var nav = new ElementNavigator(tree);
            Assert.AreEqual(10, nav.Count);

            Assert.IsTrue(nav.MoveToChild("A"));
            Assert.IsTrue(nav.MoveToChild("B"));
            Assert.IsTrue(nav.MoveToChild("C1"));
            Assert.IsTrue(nav.MoveToNext("C1"));
            Assert.IsTrue(nav.MoveToNext("C2"));

            Assert.IsTrue(nav.MoveToParent());  // 1st A.B
            Assert.IsTrue(nav.MoveToNext() && nav.Path == "A.B");  // (now) 2nd A.B
            Assert.IsTrue(nav.MoveToChild("C1"));
            Assert.IsTrue(nav.MoveToChild("D"));

            Assert.IsTrue(nav.MoveToParent());  // A.B.C1
            Assert.IsTrue(nav.MoveToParent());  // A.B (2nd)
            Assert.IsTrue(nav.MoveToNext() && nav.Path == "A.D");
            Assert.IsTrue(nav.MoveToChild("F"));
        }
        /// <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);
        }
Пример #7
0
        private void expandBaseElement(ElementNavigator snap, ElementNavigator diff)
        {
            snap.ExpandElement(_loader);

            if (!snap.HasChildren)
            {
                // Snapshot's element turns out not to be expandable, so we can't move to the desired path
                throw Error.InvalidOperation("Differential has nested constraints for node {0}, but this is a leaf node in base", diff.Path);
            }
        }
        public static bool ExpandElement(this ElementNavigator nav, StructureLoader source)
        {
            if (source == null)
            {
                throw Error.ArgumentNull("source");
            }
            if (nav.Current == null)
            {
                throw Error.ArgumentNull("Navigator is not positioned on an element");
            }

            if (nav.Current.Definition == null)
            {
                throw Error.Argument("Cannot move down into element {0} since it has no element definition information", nav.Path);
            }

            if (nav.HasChildren)
            {
                return(true);                    // already has children, we're not doing anything extra
            }
            if (nav.Current.Definition != null)
            {
                var defn = nav.Current.Definition;
                if (!String.IsNullOrEmpty(defn.NameReference))
                {
                    var sourceNav = resolveNameReference(nav.Structure, defn.NameReference);
                    nav.CopyChildren(sourceNav);
                }
                else if (defn.Type != null && defn.Type.Count > 0)
                {
                    if (defn.Type.Count > 1)
                    {
                        throw new NotImplementedException("Don't know how to implement navigation into choice types yet at node " + nav.Path);
                    }
                    else
                    {
                        var sourceNav = resolveStructureReference(source, defn.Type[0].CodeElement);

                        if (sourceNav != null)
                        {
                            sourceNav.MoveToFirstChild();
                            nav.CopyChildren(sourceNav);
                        }
                        else
                        {
                            throw new FileNotFoundException("Cannot locate base-structure for datatype " + defn.Type[0].Code);
                        }
                    }
                }

                return(true);
            }

            return(false);
        }
Пример #9
0
        private static bool childNameRepeats(ElementNavigator diff)
        {
            var isSliced = false;

            var currentPath = diff.PathName;

            if (diff.MoveToNext())
            {
                // check whether the next sibling in the differential has the same name,
                // that means we're looking at a slice
                isSliced = diff.PathName == currentPath;
                diff.MoveToPrevious();
            }

            return(isSliced);
        }
Пример #10
0
        private void merge(ElementNavigator snap, ElementNavigator diff)
        {
            mergeElementAttributes(snap.Current, diff.Current);

            // If there are children, move into them, and recursively merge them
            if (diff.MoveToFirstChild())
            {
                if (!snap.HasChildren)
                {
                    // The differential moves into an element that has no children in the base.
                    // This is allowable if the base's element has a nameReference or a TypeRef,
                    // in which case needs to be expanded before we can move to the path indicated
                    // by the differential
                    expandBaseElement(snap, diff);
                }

                // Due to how MoveToFirstChild() works, we have to move to the first matching *child*
                // when entering the loop for the first time, after that we can look for the next
                // matching *sibling*.
                bool firstEntry = true;

                do
                {
                    if ((firstEntry && !snap.MoveToChild(diff.PathName)) ||
                        (!firstEntry && !snap.MoveToNext(diff.PathName)))
                    {
                        throw Error.InvalidOperation("Differential has a constraint for path {0}, which does not exist in its base", diff.PathName);
                    }
                    firstEntry = false;

                    // Child found in both, merge them
                    if (childNameRepeats(diff) || diff.Current.IsExtension())
                    {
                        // The child in the diff repeats or we recognize it as an extension slice -> we're on the first element of a slice!
                        mergeSlice(snap, diff);
                    }
                    else
                    {
                        merge(snap, diff);
                    }
                }while (diff.MoveToNext());

                // After the merge, return the diff and snapho back to their original position
                diff.MoveToParent();
                snap.MoveToParent();
            }
        }
        /// <summary>
        /// Rewrites the Path's of the elements in a structure so they are based on the given path: the root
        /// of the given structure will become the given path, it's children will be relocated below that path
        /// </summary>
        /// <param name="root">The structure that will be rebased on the path</param>
        /// <param name="path">The path to rebase the structure on</param>
        public static void Rebase(this Profile.ProfileStructureComponent root, string path)
        {
            var nav = new ElementNavigator(root);

            if (nav.MoveToFirstChild())
            {
                var newPaths = new List<string>();
                newPaths.Add(path);

                rebaseChildren(nav, path, newPaths);

                // Can only change the paths after navigating the tree, otherwise the
                // navigation functions (which are based on the paths) won't function correctly
                for (var i = 0; i < root.Element.Count; i++)
                    root.Element[i].Path = newPaths[i];
            }
        }
Пример #12
0
        private void merge(ElementNavigator snap, ElementNavigator diff)
        {
            mergeElementAttributes(snap.Current, diff.Current);

            // If there are children, move into them, and recursively merge them
            if (diff.MoveToFirstChild())
            {
                if (!snap.HasChildren)
                {
                    // The differential moves into an element that has no children in the base.
                    // This is allowable if the base's element has a nameReference or a TypeRef,
                    // in which case needs to be expanded before we can move to the path indicated
                    // by the differential
                    expandBaseElement(snap, diff);
                }

                // Due to how MoveToFirstChild() works, we have to move to the first matching *child*
                // when entering the loop for the first time, after that we can look for the next
                // matching *sibling*.
                bool firstEntry = true;

                do
                {
                    if( (firstEntry && !snap.MoveToChild(diff.PathName)) ||
                        (!firstEntry && !snap.MoveToNext(diff.PathName)) )
                             throw Error.InvalidOperation("Differential has a constraint for path {0}, which does not exist in its base", diff.PathName);                   
                    firstEntry = false;

                    // Child found in both, merge them
                    if (childNameRepeats(diff) || diff.Current.IsExtension())
                    {
                        // The child in the diff repeats or we recognize it as an extension slice -> we're on the first element of a slice!
                        mergeSlice(snap, diff); 
                    }
                    else
                        merge(snap, diff);
                }
                while (diff.MoveToNext());

                // After the merge, return the diff and snapho back to their original position
                diff.MoveToParent();
                snap.MoveToParent();
            }
        }
        /// <summary>
        /// Rewrites the Path's of the elements in a structure so they are based on the given path: the root
        /// of the given structure will become the given path, it's children will be relocated below that path
        /// </summary>
        /// <param name="root">The structure that will be rebased on the path</param>
        /// <param name="path">The path to rebase the structure on</param>
        public static void Rebase(this Profile.ProfileStructureComponent root, string path)
        {
            var nav = new ElementNavigator(root);

            if (nav.MoveToFirstChild())
            {
                var newPaths = new List <string>();
                newPaths.Add(path);

                rebaseChildren(nav, path, newPaths);

                // Can only change the paths after navigating the tree, otherwise the
                // navigation functions (which are based on the paths) won't function correctly
                for (var i = 0; i < root.Element.Count; i++)
                {
                    root.Element[i].Path = newPaths[i];
                }
            }
        }
        /// <summary>
        /// Insert the children of the current source node under the node pointed to by the destination.
        /// </summary>
        /// <param name="dest"></param>
        /// <param name="source"></param>
        /// <returns></returns>
        public static bool CopyChildren(this BaseElementNavigator dest, ElementNavigator source)
        {
            if (dest.HasChildren)
            {
                return(false);                    // Protect children from being overwritten
            }
            if (!source.MoveToFirstChild())
            {
                return(true);                               // Nothing to copy, but successful anyway
            }
            bool firstChild = true;

            do
            {
                var copiedChild = (Profile.ElementComponent)source.Current.DeepCopy();

                if (firstChild)
                {
                    // The first time, create a new child in the destination
                    dest.InsertFirstChild(copiedChild);
                    firstChild = false;
                }
                else
                {
                    // Then insert other childs after that
                    dest.InsertAfter(copiedChild);
                }

                // If there are nested children in the source, insert them under
                // the newly inserted node in the destination
                if (source.HasChildren)
                {
                    dest.CopyChildren(source);
                }
            }while (source.MoveToNext());

            // Bring both source & destination back one step to the original parents
            source.MoveToParent();
            dest.MoveToParent();

            return(true);
        }
        public static ElementNavigator JumpToNameReference(this Profile.ProfileStructureComponent structure, string nameReference)
        {
            var nav = new ElementNavigator(structure);

            //TODO: In the current DSTU1 base profiles, nameReference is actually a path, not a name (to Element.Name)
            //this is a problem, since when doing slicing, the path may no longer point to a single set of constraints
            //so, we need to (temporarily) watch out for this
            if (nameReference.Contains("."))
            {
                // An incorrectly used nameReference, containing a Path, not a name
                if (nav.JumpToFirst(nameReference))
                    return nav;
                else
                    return null;
            }
            else
            {
                if (nav.JumpToNameReference(nameReference))
                    return nav;
                else
                    return null;
            }                

        }
Пример #16
0
        public void CopyChildTree()
        {
            var dest = createTestNav();

            var struc = new Profile.ProfileStructureComponent();
            struc.Element = new List<Profile.ElementComponent>();
            struc.Element.Add(new Profile.ElementComponent() { Path = "X" });
            struc.Element.Add(new Profile.ElementComponent() { Path = "X.Y1" });
            struc.Element.Add(new Profile.ElementComponent() { Path = "X.Y2" });
            struc.Element.Add(new Profile.ElementComponent() { Path = "X.Y2.Z1" });
            struc.Element.Add(new Profile.ElementComponent() { Path = "X.Y2.Z2" });
            var source = new ElementNavigator(struc);

            Assert.IsTrue(dest.JumpToFirst("A.D"));
            var dstPos = dest.OrdinalPosition;

            source.MoveToFirstChild();
            var srcPos = source.OrdinalPosition;

            Assert.IsTrue(dest.CopyChildren(source));
            Assert.AreEqual(srcPos, source.OrdinalPosition, "source did not remain on original position");
            Assert.AreEqual(dstPos, dest.OrdinalPosition, "dest did not remain on original position");

            Assert.IsTrue(dest.MoveToFirstChild());
            Assert.AreEqual("Y1", dest.PathName);
            Assert.IsTrue(dest.MoveToNext());
            Assert.AreEqual("Y2", dest.PathName);
            Assert.IsFalse(dest.MoveToNext());
            Assert.IsTrue(dest.MoveToFirstChild());
            Assert.AreEqual("Z1", dest.PathName);
            Assert.IsTrue(dest.MoveToNext());
            Assert.AreEqual("Z2", dest.PathName);
            Assert.IsFalse(dest.MoveToNext());
        }
Пример #17
0
        public void TestModificationResilience()
        {
            var nav = createTestNav();

            Assert.IsTrue(nav.JumpToFirst("A.D"));

            var nav2 = new ElementNavigator(nav);

            // Delete A.D in nav
            Assert.IsTrue(nav.Delete()); 

            // Should still be there in nav2
            Assert.IsFalse(nav.JumpToFirst("A.D"));
            Assert.IsTrue(nav2.JumpToFirst("A.D"));
        }
 public static string GetParentNameFromPath(this Profile.ElementComponent element)
 {
     return(ElementNavigator.GetParentPath(element.Path));
 }
Пример #19
0
        private static bool childNameRepeats(ElementNavigator diff)
        {
            var isSliced = false;

            var currentPath = diff.PathName;
            if (diff.MoveToNext())
            {
                // check whether the next sibling in the differential has the same name,
                // that means we're looking at a slice
                isSliced = diff.PathName == currentPath;
                diff.MoveToPrevious();
            }

            return isSliced;
        }
Пример #20
0
 public ElementNavigator(ElementNavigator other)
 {
     setupElems(other._elements);
     Structure = other.Structure;
     OrdinalPosition = other.OrdinalPosition;
 }
Пример #21
0
 public ElementNavigator(ElementNavigator other)
 {
     setupElems(other._elements);
     Structure       = other.Structure;
     OrdinalPosition = other.OrdinalPosition;
 }
Пример #22
0
        private void mergeSlice(ElementNavigator snap, ElementNavigator diff)
        {
            // diff is now located at the first repeat of a slice, which is (possibly) the slice entry
            // snap is located at the base definition of the element that will become sliced. But snap is not yet sliced.

            // Before we start, is the base element sliceable?
            if (!snap.Current.IsRepeating() && !isSlicedToOne(diff.Current))
                throw Error.InvalidOperation("The slicing entry in the differential at {0} indicates an unbounded slice, but the base element is not a repeating element",
                   diff.Current.Path);
           
            Profile.ElementComponent slicingEntry;

            // Yes, so, first, add the slicing entry to the snapshot. 
            if (diff.Current.Slicing != null)
            {
                slicingEntry = createSliceEntry(snap.Current, diff.Current);
                snap.InsertBefore(slicingEntry);

                if (!diff.MoveToNext(diff.PathName))
                    throw Error.InvalidOperation("Slicing has no elements beyond the slicing entry");  // currently impossible to happen
            }
            else
            {
                // Mmmm....no slicing entry in the differential. This is only alloweable for extension slices, as a shorthand notation.                 
                if (!snap.Current.IsExtension())
                    throw Error.InvalidOperation("The slice group at {0} does not start with a slice entry element", diff.Current.Path);

                // In this case we insert a "prefab" extension slice.
                slicingEntry = createExtensionSlicingEntry(snap.Path);
                snap.InsertBefore(slicingEntry);
            }

            snap.MoveToNext();  

            // The differential and the snapshot are now both positioned on the first "real" slicing content element
            // Start by getting an unaltered copy of the current base definition, we need to re-insert a fresh copy
            // of it every time we encounter a new slice in the differential

            var slicingTemplate = (Profile.ElementComponent)snap.Current.DeepCopy();
            var slicingName = snap.PathName;
            var first = true;

            do
            {
                if(first)
                {
                    // The first time, we still have the original base definition available to slice
                    first = false;
                }
                else
                {
                    snap.InsertAfter((Profile.ElementComponent)slicingTemplate.DeepCopy());
                    //snap.MoveToNext();
                }

                merge(snap, diff);
            }
            while (diff.MoveToNext(slicingName));

            if (slicingEntry.Slicing.Rules != Profile.SlicingRules.Closed)
            {
                // Slices that are open in some form need to repeat the original "base" definition,
                // so that the open slices have a place to "fit in"
                snap.InsertAfter((Profile.ElementComponent)slicingTemplate.DeepCopy());
            }

            //TODO: update/check the slice entry's min/max property to match what we've found in the slice group
        }
Пример #23
0
        public void TestExpandChild()
        {
            var loader = new StructureLoader(ArtifactResolver.CreateDefault());
            var profStruct = loader.Locate(new Uri("http://hl7.org/fhir/Profile/Profile"), new Code("Profile"));

            var nav = new ElementNavigator(profStruct);
            
            nav.JumpToFirst("Profile.telecom");
            Assert.IsTrue(nav.ExpandElement(loader));
            Assert.IsTrue(nav.MoveToChild("period"));

            nav.JumpToFirst("Profile.extensionDefn.definition");
            Assert.IsTrue(nav.ExpandElement(loader));
            Assert.IsTrue(nav.MoveToChild("max"));
        }
Пример #24
0
        private void mergeSlice(ElementNavigator snap, ElementNavigator diff)
        {
            // diff is now located at the first repeat of a slice, which is (possibly) the slice entry
            // snap is located at the base definition of the element that will become sliced. But snap is not yet sliced.

            // Before we start, is the base element sliceable?
            if (!snap.Current.IsRepeating() && !isSlicedToOne(diff.Current))
            {
                throw Error.InvalidOperation("The slicing entry in the differential at {0} indicates an unbounded slice, but the base element is not a repeating element",
                                             diff.Current.Path);
            }

            Profile.ElementComponent slicingEntry;

            // Yes, so, first, add the slicing entry to the snapshot.
            if (diff.Current.Slicing != null)
            {
                slicingEntry = createSliceEntry(snap.Current, diff.Current);
                snap.InsertBefore(slicingEntry);

                if (!diff.MoveToNext(diff.PathName))
                {
                    throw Error.InvalidOperation("Slicing has no elements beyond the slicing entry");  // currently impossible to happen
                }
            }
            else
            {
                // Mmmm....no slicing entry in the differential. This is only alloweable for extension slices, as a shorthand notation.
                if (!snap.Current.IsExtension())
                {
                    throw Error.InvalidOperation("The slice group at {0} does not start with a slice entry element", diff.Current.Path);
                }

                // In this case we insert a "prefab" extension slice.
                slicingEntry = createExtensionSlicingEntry(snap.Path);
                snap.InsertBefore(slicingEntry);
            }

            snap.MoveToNext();

            // The differential and the snapshot are now both positioned on the first "real" slicing content element
            // Start by getting an unaltered copy of the current base definition, we need to re-insert a fresh copy
            // of it every time we encounter a new slice in the differential

            var slicingTemplate = (Profile.ElementComponent)snap.Current.DeepCopy();
            var slicingName     = snap.PathName;
            var first           = true;

            do
            {
                if (first)
                {
                    // The first time, we still have the original base definition available to slice
                    first = false;
                }
                else
                {
                    snap.InsertAfter((Profile.ElementComponent)slicingTemplate.DeepCopy());
                    //snap.MoveToNext();
                }

                merge(snap, diff);
            }while (diff.MoveToNext(slicingName));

            if (slicingEntry.Slicing.Rules != Profile.SlicingRules.Closed)
            {
                // Slices that are open in some form need to repeat the original "base" definition,
                // so that the open slices have a place to "fit in"
                snap.InsertAfter((Profile.ElementComponent)slicingTemplate.DeepCopy());
            }

            //TODO: update/check the slice entry's min/max property to match what we've found in the slice group
        }
Пример #25
0
        private void expandBaseElement(ElementNavigator snap, ElementNavigator diff)
        {
            snap.ExpandElement(_loader);

            if (!snap.HasChildren)
            {
                // Snapshot's element turns out not to be expandable, so we can't move to the desired path
                throw Error.InvalidOperation("Differential has nested constraints for node {0}, but this is a leaf node in base", diff.Path);
            }
        }