From: Atsushi Eno Date: Mon, 12 May 2008 10:16:06 +0000 (-0000) Subject: 2008-05-12 Atsushi Enomoto X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=a333e2b2197e00afc101bb18b7a18d3cd09f164d;p=mono.git 2008-05-12 Atsushi Enomoto * XContainer.cs, XElement.cs, XNode.cs, XUtil.cs : made several refactoring on handling "content" items in couple of Add*() methods. Attributes should be allowed in XElement.Add(), while they should be rejected in XNode.Add*Self(). Similarly, Add() and SetValue() should reject any invalid content items. Add() should also append string content to the last node when the last node is text. * XDocumentTest.cs, XElementTest.cs : Added couple of tests for Add() and AddBeforeSelf(). svn path=/trunk/mcs/; revision=102990 --- diff --git a/mcs/class/System.Xml.Linq/System.Xml.Linq/ChangeLog b/mcs/class/System.Xml.Linq/System.Xml.Linq/ChangeLog index 9bee1e7d86a..a4246b656b7 100644 --- a/mcs/class/System.Xml.Linq/System.Xml.Linq/ChangeLog +++ b/mcs/class/System.Xml.Linq/System.Xml.Linq/ChangeLog @@ -1,3 +1,14 @@ +2008-05-12 Atsushi Enomoto + + * XContainer.cs, XElement.cs, XNode.cs, XUtil.cs : + made several refactoring on handling "content" items in couple of + Add*() methods. Attributes should be allowed in XElement.Add(), + while they should be rejected in XNode.Add*Self(). + Similarly, Add() and SetValue() should reject any invalid content + items. + Add() should also append string content to the last node when the + last node is text. + 2008-05-12 Atsushi Enomoto * XUtil.cs : added ExpandArray() and marked some members as wrong. diff --git a/mcs/class/System.Xml.Linq/System.Xml.Linq/XContainer.cs b/mcs/class/System.Xml.Linq/System.Xml.Linq/XContainer.cs index 6e6586f4761..ff55569abf7 100644 --- a/mcs/class/System.Xml.Linq/System.Xml.Linq/XContainer.cs +++ b/mcs/class/System.Xml.Linq/System.Xml.Linq/XContainer.cs @@ -80,8 +80,10 @@ namespace System.Xml.Linq if (content == null) return; - foreach (XNode n in XUtil.ToNodes (content)) - AddNode (n); + foreach (object o in XUtil.ExpandArray (content)) + if (!OnAddingObject (o)) + foreach (XNode n in XUtil.ToNodes (o)) + AddNode (n); } void AddNode (XNode n) @@ -100,7 +102,9 @@ namespace System.Xml.Linq public void Add (params object [] content) { - foreach (object o in XUtil.ShrinkArray (content)) + if (content == null) + return; + foreach (object o in XUtil.ExpandArray (content)) Add (o); } @@ -109,7 +113,7 @@ namespace System.Xml.Linq if (first == null) Add (content); else - first.AddBeforeSelf (content); + AddFirst (XUtil.ExpandArray (content)); } public void AddFirst (params object [] content) @@ -119,7 +123,14 @@ namespace System.Xml.Linq if (first == null) Add (content); else - first.AddBeforeSelf (content); + foreach (object o in XUtil.ExpandArray (content)) + if (!OnAddingObject (o)) + first.AddBeforeSelf (o); + } + + internal virtual bool OnAddingObject (object o) + { + return false; } public XmlWriter CreateWriter () @@ -228,9 +239,5 @@ namespace System.Xml.Linq } } */ - - internal virtual void OnAdded (XNode item, bool addFirst) - { - } } } diff --git a/mcs/class/System.Xml.Linq/System.Xml.Linq/XElement.cs b/mcs/class/System.Xml.Linq/System.Xml.Linq/XElement.cs index 4726b650d67..afdb5bd286c 100644 --- a/mcs/class/System.Xml.Linq/System.Xml.Linq/XElement.cs +++ b/mcs/class/System.Xml.Linq/System.Xml.Linq/XElement.cs @@ -525,22 +525,26 @@ namespace System.Xml.Linq a.Remove (); } else { if (a == null) { - a = new XAttribute (name, value); - a.SetOwner (this); - if (attr_first == null) { - attr_first = a; - attr_last = a; - } else { - attr_last.NextAttribute = a; - a.PreviousAttribute = attr_last; - attr_last = a; - } + SetAttributeObject (new XAttribute (name, value)); } else a.Value = XUtil.ToString (value); } } + void SetAttributeObject (XAttribute a) + { + a.SetOwner (this); + if (attr_first == null) { + attr_first = a; + attr_last = a; + } else { + attr_last.NextAttribute = a; + a.PreviousAttribute = attr_last; + attr_last = a; + } + } + public override void WriteTo (XmlWriter w) { w.WriteStartElement (name.LocalName, name.Namespace.NamespaceName); @@ -632,14 +636,36 @@ namespace System.Xml.Linq public void SetValue (object value) { + if (value == null) + throw new ArgumentNullException ("value"); + if (value is XAttribute || value is XDocument || value is XDeclaration || value is XDocumentType) + throw new ArgumentException (String.Format ("Node type {0} is not allowed as element value", value.GetType ())); RemoveNodes (); foreach (XNode n in XUtil.ToNodes (value)) Add (n); } + internal override bool OnAddingObject (object o) + { + XAttribute a = o as XAttribute; + if (a != null) { + foreach (XAttribute ia in Attributes ()) + if (a.Name == ia.Name) + throw new InvalidOperationException (String.Format ("Duplicate attribute: {0}", a.Name)); + SetAttributeObject (a); + return true; + } + else if (o is string && LastNode is XText) { + ((XText) LastNode).Value += o as string; + return true; + } + else + return false; + } + internal override void OnAdded (XNode node, bool addFirst) { - if (node is XDocument || node is XDocumentType) + if (node is XDocument || node is XDocumentType || node is XDeclaration) throw new ArgumentException (String.Format ("A node of type {0} cannot be added as a content", node.GetType ())); } diff --git a/mcs/class/System.Xml.Linq/System.Xml.Linq/XNode.cs b/mcs/class/System.Xml.Linq/System.Xml.Linq/XNode.cs index 5191bb1c5b7..cd582250303 100644 --- a/mcs/class/System.Xml.Linq/System.Xml.Linq/XNode.cs +++ b/mcs/class/System.Xml.Linq/System.Xml.Linq/XNode.cs @@ -94,6 +94,7 @@ namespace System.Xml.Linq if (Parent == null) throw new InvalidOperationException (); foreach (XNode n in XUtil.ToNodes (content)) { + OnAdded (n, false); n.SetOwner (Parent); n.previous = this; n.next = next; @@ -121,6 +122,7 @@ namespace System.Xml.Linq if (Parent == null) throw new InvalidOperationException (); foreach (XNode n in XUtil.ToNodes (content)) { + OnAdded (n, true); n.SetOwner (Parent); n.previous = previous; n.next = this; @@ -291,5 +293,9 @@ namespace System.Xml.Linq AddAfterSelf (items); Remove (); } + + internal virtual void OnAdded (XNode item, bool addFirst) + { + } } } diff --git a/mcs/class/System.Xml.Linq/System.Xml.Linq/XUtil.cs b/mcs/class/System.Xml.Linq/System.Xml.Linq/XUtil.cs index b48efc4e54c..f9cfbc1865c 100644 --- a/mcs/class/System.Xml.Linq/System.Xml.Linq/XUtil.cs +++ b/mcs/class/System.Xml.Linq/System.Xml.Linq/XUtil.cs @@ -78,6 +78,8 @@ namespace System.Xml.Linq // FIXME: it will be removed. It makes attribute processing incorrect. public static IEnumerable ToNodes (object o) { + if (o is XAttribute) + throw new ArgumentException ("Attribute node is not allowed as argument"); XNode n = o as XNode; if (n != null) yield return n; diff --git a/mcs/class/System.Xml.Linq/Test/System.Xml.Linq/ChangeLog b/mcs/class/System.Xml.Linq/Test/System.Xml.Linq/ChangeLog index 5d9f0464bcf..213c4cbc225 100644 --- a/mcs/class/System.Xml.Linq/Test/System.Xml.Linq/ChangeLog +++ b/mcs/class/System.Xml.Linq/Test/System.Xml.Linq/ChangeLog @@ -1,3 +1,8 @@ +2008-05-12 Atsushi Enomoto + + * XDocumentTest.cs, XElementTest.cs : + Added couple of tests for Add() and AddBeforeSelf(). + 2008-05-12 Atsushi Enomoto * XStreamingElementTest.cs : new test. diff --git a/mcs/class/System.Xml.Linq/Test/System.Xml.Linq/XDocumentTest.cs b/mcs/class/System.Xml.Linq/Test/System.Xml.Linq/XDocumentTest.cs index fe3a400ca43..2e6ec5e5c89 100644 --- a/mcs/class/System.Xml.Linq/Test/System.Xml.Linq/XDocumentTest.cs +++ b/mcs/class/System.Xml.Linq/Test/System.Xml.Linq/XDocumentTest.cs @@ -93,5 +93,13 @@ namespace MonoTests.System.Xml.Linq // hence converted to a string -> error doc.Add (new XDeclaration ("1.0", null, null)); } + + [Test] + [ExpectedException (typeof (ArgumentException))] + public void AddXAttributeToDocument () + { + var doc = new XDocument (); + doc.Add (new XAttribute ("foo", " ")); + } } } diff --git a/mcs/class/System.Xml.Linq/Test/System.Xml.Linq/XElementTest.cs b/mcs/class/System.Xml.Linq/Test/System.Xml.Linq/XElementTest.cs index 83f8fddf50e..00ad22d9d38 100644 --- a/mcs/class/System.Xml.Linq/Test/System.Xml.Linq/XElementTest.cs +++ b/mcs/class/System.Xml.Linq/Test/System.Xml.Linq/XElementTest.cs @@ -206,6 +206,36 @@ namespace MonoTests.System.Xml.Linq Assert.AreEqual ("bar", bar.Name.LocalName, "#6"); } + [Test] + [ExpectedException (typeof (ArgumentException))] + public void AddAfterSelfAttribute () + { + var el = new XElement ("root", new XElement ("child")); + var el2 = el.FirstNode as XElement; + el2.AddAfterSelf (new XAttribute ("foo", "bar")); + } + + [Test] + [ExpectedException (typeof (ArgumentException))] + public void AddAfterSelfXDocument () + { + var el = new XElement ("root", new XElement ("child")); + var el2 = el.FirstNode as XElement; + el2.AddAfterSelf (new XDocument ()); + } + + [Test] + [ExpectedException (typeof (ArgumentException))] + [Category ("NotDotNet")] + [Category ("NotWorking")] + // LAMESPEC: there is no reason to not reject XDeclaration while it rejects XDocument. + public void AddAfterSelfXDeclaration () + { + var el = new XElement ("root", new XElement ("child")); + var el2 = el.FirstNode as XElement; + el2.AddAfterSelf (new XDeclaration ("1.0", null, null)); + } + [Test] public void AddBeforeSelf () { @@ -250,6 +280,29 @@ namespace MonoTests.System.Xml.Linq Assert.AreEqual ("foo", foo.Name.LocalName, "#4"); } + [Test] + public void AddJoinsStringAfterText () + { + var el = XElement.Parse ("text1"); + el.Add ("text2"); + el.Add (new XText ("text3")); + IEnumerator e = el.Nodes ().GetEnumerator (); + Assert.IsTrue (e.MoveNext (), "#1"); + Assert.AreEqual ("text1text2", e.Current.ToString (), "#2"); + Assert.IsTrue (e.MoveNext (), "#3"); + Assert.AreEqual ("text3", e.Current.ToString (), "#4"); + Assert.IsFalse (e.MoveNext (), "#5"); + } + + [Test] + [ExpectedException (typeof (InvalidOperationException))] + public void AddDuplicateAttribute () + { + var el = new XElement ("foo", + new XAttribute ("bar", "baz")); + el.Add (new XAttribute ("bar", "baz")); + } + [Test] public void ReplaceWith () { @@ -369,5 +422,37 @@ namespace MonoTests.System.Xml.Linq new XElement ("bar")); Assert.AreEqual ("Linux&Windows", a.Value); } + + [Test] + [ExpectedException (typeof (ArgumentException))] + public void SetValueXAttribute () + { + new XElement ("foo").SetValue (new XAttribute ("foo", "bar")); + } + + [Test] + [ExpectedException (typeof (ArgumentException))] + public void SetValueXDocumnent () + { + new XElement ("foo").SetValue (new XDocument ()); + } + + [Test] + // LAMESPEC: there is no reason to not reject XDeclaration while it rejects XDocument. + [ExpectedException (typeof (ArgumentException))] + [Category ("NotDotNet")] + public void SetValueXDeclaration () + { + var el = new XElement ("foo"); + el.SetValue (new XDeclaration ("1.0", null, null)); + Assert.AreEqual ("", el.Value); + } + + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void SetValueNull () + { + new XElement ("foo", "text").SetValue (null); + } } }