Example #1
0
 public void testTyping()
 {
     Model.ElementDefinition ed = new Model.ElementDefinition();
     ed.Binding = new Model.ElementDefinition.BindingComponent();
     ed.Binding.setValueSet(new UriType("http://test.org"));
     testBoolean(null, ed.Binding.getValueSet(), "ElementDefinition.binding.valueSetUri", "startsWith('http:') or startsWith('https') or startsWith('urn:')", true);
 }
        /// <summary>
        /// Creates a differential structure with all "skipped" parents filled in.
        /// </summary>
        /// <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 List<ElementDefinition> MakeTree()
        {
            var diff = new List<ElementDefinition>(_source.DeepCopy());   // We're going to modify the differential

            if (diff.Count == 0 ) return diff;        // nothing to do

            var index = 0;

            while (index < diff.Count)
            {
                var thisPath = diff[index].Path;
                var prevPath = index > 0 ? diff[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 at " + thisPath);

                    // 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 ElementDefinition() { Path = parentPath };
                        diff.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 bool AppendChild(this BaseElementNavigator nav, ElementDefinition child)
        {
            var bm = nav.Bookmark();

            if (nav.MoveToFirstChild())
            {
                while (nav.MoveToNext()) ;
                var result = nav.InsertAfter(child);
                
                if(!result) nav.ReturnToBookmark(bm);
                return result;
            }
            else
            {
                return nav.InsertFirstChild(child);
            }
        }
        public void TestChildAlterations()
        {
            var nav = createTestNav();

            var newENode = new ElementDefinition() { Path = "X.Y.E" };
            var newC3Node = new ElementDefinition() { Path = "X.Y.C3" };

            Assert.IsTrue(nav.JumpToFirst("A.B.C1.D"));
            Assert.IsTrue(nav.InsertFirstChild(newENode));
            Assert.AreEqual(8,nav.OrdinalPosition);
            Assert.IsTrue(nav.MoveToParent());
            Assert.AreEqual("A.B.C1.D", nav.Path);
            Assert.IsTrue(nav.MoveToFirstChild());
            Assert.IsTrue(nav.Delete());   
            Assert.AreEqual("A.B.C1.D", nav.Path);  // should have moved back to parent (single child deleted)

            Assert.IsTrue(nav.JumpToFirst("A.D"));
            Assert.IsTrue(nav.InsertFirstChild(newENode));
            Assert.AreEqual(9,nav.OrdinalPosition);
            Assert.IsTrue(nav.MoveToParent());
            Assert.AreEqual("A.D", nav.Path);
            Assert.IsTrue(nav.MoveToFirstChild());
            Assert.IsTrue(nav.Delete());   
            Assert.AreEqual("A.D", nav.Path);  // should have moved back to parent (single child deleted)

            nav.Reset();
            Assert.IsTrue(nav.MoveToFirstChild());
            Assert.IsTrue(nav.MoveToFirstChild()); // A.B
            Assert.IsTrue(nav.AppendChild(newC3Node));
            Assert.AreEqual("A.B.C3",nav.Path);
            Assert.AreEqual(4, nav.OrdinalPosition);

            Assert.IsTrue(nav.Delete());
            Assert.AreEqual(3, nav.OrdinalPosition);
            Assert.IsTrue(nav.MoveToPrevious());        // A.B.C1
            Assert.IsTrue(nav.Delete());
            Assert.AreEqual(2, nav.OrdinalPosition);
            Assert.IsTrue(nav.Delete());
            Assert.AreEqual(1, nav.OrdinalPosition);    // Moved back to parent?
        }
        public void TestSiblingAlterations()
        {
            var nav = createTestNav();
            var newCNode = new ElementDefinition() { Path = "X.C" };

            Assert.AreEqual(9, nav.Count);

            nav.MoveToFirstChild();
            Assert.IsTrue(nav.MoveToChild("D"));
            Assert.IsTrue(nav.InsertBefore(newCNode));
            Assert.AreEqual("A.C", nav.Path);
            Assert.AreEqual(8, nav.OrdinalPosition);
            Assert.AreEqual(10, nav.Count);

            Assert.IsTrue(nav.Delete());    // delete new "C" node we just created
            Assert.AreEqual(8, nav.OrdinalPosition);
            Assert.AreEqual(9, nav.Count);

            Assert.IsTrue(nav.MoveToPrevious()); // 3rd "A.B" node
            Assert.IsTrue(nav.InsertAfter(newCNode));
            Assert.AreEqual("A.C", nav.Path);
            Assert.AreEqual(8, nav.OrdinalPosition);
            Assert.AreEqual(10, nav.Count);

            Assert.IsTrue(nav.Delete());    // delete new "C" node we just created
            Assert.AreEqual(8, nav.OrdinalPosition); 
            Assert.AreEqual(9, nav.Count);

            Assert.IsTrue(nav.InsertAfter(newCNode));
            Assert.AreEqual("A.C", nav.Path);
            Assert.AreEqual(9, nav.OrdinalPosition);
            Assert.AreEqual(10, nav.Count);

            Assert.IsTrue(nav.Delete());    // delete new "C" node we just created
            Assert.AreEqual(8, nav.OrdinalPosition);
            Assert.AreEqual(9, nav.Count);

            Assert.IsTrue(nav.MoveToParent());
            Assert.IsTrue(nav.MoveToFirstChild());
            Assert.IsTrue(nav.InsertBefore(newCNode));
            Assert.AreEqual("A.C", nav.Path);
            Assert.AreEqual(1, nav.OrdinalPosition);
            Assert.AreEqual(10, nav.Count);
        }
        /// <summary>
        /// Inserts the element passed in as a child of the element the navigator is currently on. 
        /// The navigator will move to the inserted element.
        /// </summary>
        /// <param name="child"></param>
        /// <returns></returns>
        /// <remarks>You can only insert a child for an element does not have children yet.</remarks>
        public override bool InsertFirstChild(ElementDefinition child)
        {
            if(Count == 0)
            {
                // Special case, insert a new root
                Elements.Add(child);
                child.Path = child.GetNameFromPath();
                OrdinalPosition = 0;
                return true;
            }
            else if(HasChildren)
                return false;       // Cannot insert another child, there's already one.
            else
            {
                var newSiblingPath = Path + "." + child.GetNameFromPath();
                
                if (OrdinalPosition == Count - 1) // At last position
                    Elements.Add(child);
                else
                    Elements.Insert(OrdinalPosition.Value + 1, child);

                // Set the name to be a true child -> this actually creates a child
                child.Path = newSiblingPath;

                // Navigate to newly inserted child
                OrdinalPosition += 1;

                return true;
            }
        }
        /// <summary>
        /// Inserts the element passed in as a sibling to the element the navigator is currently on. 
        /// The navigator will move to the inserted element.
        /// </summary>
        /// <param name="sibling"></param>
        /// <returns></returns>
        public override bool InsertAfter(ElementDefinition sibling)
        {
            if (!canInsertSiblingHere()) return false;

            var insertPosition = positionAfter();
            var newSiblingPath = ParentPath + "." + sibling.GetNameFromPath();

            if (insertPosition == Count) // At last position
                Elements.Add(sibling);
            else
                Elements.Insert(insertPosition, sibling);

            // Adjust the sibling's path so it's parent is the same as the current node
            sibling.Path = newSiblingPath;

            // Navigate to newly inserted node
            OrdinalPosition = insertPosition;

            return true;
        }
//----------------------------------
//
// Methods that alter the list of elements
// 
//----------------------------------
        
        /// <summary>
        /// Inserts the element passed in as a sibling to the element the navigator is currently on. 
        /// The navigator will move to the inserted element.
        /// </summary>
        /// <param name="sibling"></param>
        /// <returns></returns>
        public override bool InsertBefore(ElementDefinition sibling)
        {
            if (!canInsertSiblingHere()) return false;

            var newSiblingPath = ParentPath + "." + sibling.GetNameFromPath();

            Elements.Insert(OrdinalPosition.Value, sibling);

            // Adjust the sibling's path so it's parent is the same as the current node
            sibling.Path = newSiblingPath;

            // Note: we're now positioned on the newly inserted element

            return true;
        }
 public abstract bool InsertFirstChild(ElementDefinition child);
Example #10
0
        private static ElementDefinition createExtensionSlicingEntry()
        {
            // Create a pre-fab extension slice, filled with sensible defaults
            var slicingDiff = new ElementDefinition();
            slicingDiff.Slicing = new ElementDefinition.SlicingComponent();
            slicingDiff.Slicing.Discriminator = new[] { "url" };
            slicingDiff.Slicing.Ordered = false;
            slicingDiff.Slicing.Rules = ElementDefinition.SlicingRules.Open;

            return slicingDiff;
        }
 public abstract bool InsertAfter(ElementDefinition sibling);
//----------------------------------
//
// Methods that alter the list of elements
// 
//----------------------------------

        public abstract bool InsertBefore(ElementDefinition sibling);
        private ElementDefinition createExtensionSlicingEntry(string path, ElementDefinition template)
        {
            // Create a pre-fab extension slice, filled with sensible defaults
            var slicingDiff = new ElementDefinition();
            slicingDiff.Slicing = new ElementDefinition.ElementDefinitionSlicingComponent();
            slicingDiff.Slicing.Discriminator = new[] { "url" };
            slicingDiff.Slicing.Ordered = false;
            slicingDiff.Slicing.Rules = ElementDefinition.SlicingRules.Open;

            var result = createSliceEntry(template, slicingDiff);

            return result;
        }
        private ElementDefinition createSliceEntry(ElementDefinition baseDefn, ElementDefinition diff)
        {
            var slicingEntry = (ElementDefinition)baseDefn.DeepCopy();

            (new ElementDefnMerger(_markChanges)).Merge(slicingEntry, diff);

            return slicingEntry;
        }
 private static bool isSlicedToOne(ElementDefinition element)
 {
     return element.Slicing != null && element.Max == "1";
 }