(DISTFILES): Comment out a few missing files.
[mono-project.git] / mcs / class / System.XML / Mono.Xml.XPath / XPathDocument2Editable.cs
blobef274ad708b3cdae1ebc9eaa97f152dc2cf4f783
1 //
2 // Mono.Xml.XPath.XPathDocument2Editable
3 //
4 // Author:
5 // Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // (C)2004 Novell Inc.
8 //
9 // Yet another implementation of XPathEditableNavigator.
10 // (Even runnable under MS.NET 2.0)
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 //
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 //
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 #if NET_2_0
35 using System;
36 using System.Collections;
37 using System.ComponentModel;
38 using System.IO;
39 using System.Xml;
40 using System.Xml.Schema;
41 using System.Xml.XPath;
42 using System.Xml.Serialization;
44 namespace Mono.Xml.XPath
47 public class Driver
49 public static void Main ()
51 try {
52 #if true
53 XPathDocument2 doc = new XPathDocument2 ();
54 XPathDocument2Editable pd = new XPathDocument2Editable (doc);
55 XPathEditableNavigator nav = pd.CreateEditor ();
56 IChangeTracking xp = pd;
57 #else
58 XPathDocument doc = new XPathDocument ();
59 XPathEditableNavigator nav = doc.CreateEditor ();
60 IChangeTracking xp = doc;
61 #endif
62 doc.LoadXml ("<root/>");
63 nav.MoveToFirstChild (); // root
64 XmlWriter w = nav.AppendChild ();
65 Console.WriteLine (((IChangeTracking) xp).IsChanged);
66 w.WriteElementString ("foo", "foo_text");
67 w.WriteElementString ("bar", "bar_text");
68 w.WriteStartElement ("hoge");
69 w.WriteAttributeString ("fuga", "fugafuga");
70 w.WriteAttributeString ("unya", "unyaunya");
71 w.WriteFullEndElement ();
72 w.Close ();
74 w = nav.CreateAttributes ();
75 w.WriteStartAttribute ("namara");
76 w.WriteString ("mokera");
77 w.WriteEndAttribute ();
78 w.WriteAttributeString ("beccho", "giccho");
79 w.Close ();
81 nav.MoveToRoot ();
82 nav.MoveToFirstChild ();
83 nav.MoveToFirstChild ();
84 nav.DeleteCurrent (); // delete foo
85 Console.WriteLine (nav.Name);
86 nav.MoveToNext ();
87 Console.WriteLine (nav.Name);
88 Console.WriteLine (nav.MoveToFirstAttribute ());
89 nav.DeleteCurrent (); // delete fuga
91 doc.Save (Console.Out);
92 } catch (Exception ex) {
93 Console.WriteLine (ex);
99 public class XPathDocument2Editable
100 : IXPathNavigable, IXPathEditable,
101 IRevertibleChangeTracking, IChangeTracking, IXmlSerializable
104 XPathDocument2 document;
106 ArrayList changes = new ArrayList ();
107 bool enableChangeTracking;
109 public XPathDocument2Editable (XPathDocument2 doc)
111 document = doc;
114 #region Events
116 public event NodeChangedEventHandler ChangeRejected;
118 public event NodeChangedEventHandler ItemUpdated;
120 public event NodeChangedEventHandler ItemUpdating;
122 public event NodeChangedEventHandler ItemInserted;
124 public event NodeChangedEventHandler ItemInserting;
126 public event NodeChangedEventHandler ItemDeleted;
128 public event NodeChangedEventHandler ItemDeleting;
130 public event NodeChangedEventHandler RejectingChange;
132 #endregion // Events
134 public XmlNameTable NameTable {
135 get { return document.NameTable; }
138 public XPathNavigator CreateNavigator ()
140 return document.CreateNavigator ();
143 public XPathEditableNavigator CreateEditor ()
145 return new XomEditableNavigator (this);
148 public XmlWriter CreateWriter ()
150 return CreateEditor ().AppendChild ();
153 public bool HasChanges ()
155 return IsChanged;
158 public bool EnableChangeTracking {
159 get { return enableChangeTracking; }
160 set { enableChangeTracking = value; }
163 #region IRevertibleChangeTracking/IChangeTracking
164 public bool IsChanged {
165 get { return changes.Count != 0; }
168 public void AcceptChanges ()
170 changes.Clear ();
173 public void RejectChanges ()
175 for (int i = changes.Count - 1; i >= 0; i--) {
176 Insertion2 ins = changes [i] as Insertion2;
177 if (ins != null) {
178 ins.ParentNode.RemoveChild (ins.InsertedNode);
179 continue;
182 Removal2 rem = changes [i] as Removal2;
183 if (rem != null) {
184 if (rem.RemovedNode.NodeType == XPathNodeType.Attribute) {
185 XomElement el = (XomElement) rem.OwnerNode;
186 el.AppendAttribute ((XomAttribute) rem.RemovedNode);
188 else
189 rem.OwnerNode.InsertBefore (rem.RemovedNode, rem.NextSibling);
190 continue;
192 AttributeUpdate2 au = changes [i] as AttributeUpdate2;
193 if (au != null) {
194 au.Element.RemoveAttribute (au.NewAttribute);
195 if (au.OldAttribute != null)
196 au.Element.AppendAttribute (au.OldAttribute);
197 continue;
200 changes.Clear ();
202 #endregion
204 #region IXmlSerializable
205 public void WriteXml (XmlWriter writer)
207 throw new NotImplementedException ();
210 public void ReadXml (XmlReader reader)
212 throw new NotImplementedException ();
215 public XmlSchema GetSchema ()
217 throw new NotImplementedException ();
219 #endregion
221 internal bool DeleteNode (XomNode node)
223 Removal2 rem = new Removal2 ();
224 if (node.NodeType == XPathNodeType.Attribute) {
225 XomAttribute attr = node as XomAttribute;
226 rem.OwnerNode = attr.Parent;
227 rem.RemovedNode = node;
228 ((XomElement) attr.Parent).RemoveAttribute (attr);
229 return false;
230 } else {
231 rem.OwnerNode = node.Parent;
232 rem.NextSibling = node.NextSibling;
233 rem.RemovedNode = node;
234 node.Parent.RemoveChild (node);
235 return rem.NextSibling != null;
239 internal XmlWriter CreateInsertionWriter (XomNode owner, XomNode previousSibling)
241 return new XPathDocument2InsertionWriter (owner, previousSibling, this);
244 internal XmlWriter CreateAttributesWriter (XomNode owner)
246 return new XPathDocument2AttributeWriter (owner, this);
249 internal void AttributeUpdate2 (XomElement element, XomAttribute oldAttr, XomAttribute newAttr)
251 AttributeUpdate2 au = new AttributeUpdate2 ();
252 au.Element = element;
253 au.OldAttribute = oldAttr;
254 au.NewAttribute = newAttr;
255 changes.Add (au);
258 internal void AppendChild (XomParentNode parent, XomNode child)
260 Insertion2 ins = new Insertion2 ();
261 ins.ParentNode = parent;
262 ins.InsertedNode = child;
263 changes.Add (ins);
267 public class XPathDocument2InsertionWriter : XmlWriter
269 XomNode current;
270 XomNode previousSibling;
271 XPathDocument2Editable document;
272 Stack nodeStack = new Stack ();
274 public XPathDocument2InsertionWriter (XomNode owner, XomNode previousSibling, XPathDocument2Editable doc)
276 this.current = (XomNode) owner;
277 if (current == null)
278 throw new InvalidOperationException ();
279 this.previousSibling = previousSibling;
280 this.document = doc;
281 state = WriteState.Content;
284 WriteState state;
285 XomAttribute attribute;
287 public override WriteState WriteState {
288 get { return state; }
291 public override void Close ()
295 public override void Flush ()
299 public override string LookupPrefix (string ns)
301 return current.LookupPrefix (ns);
304 public override void WriteStartAttribute (string prefix, string name, string ns)
306 if (state != WriteState.Content)
307 throw new InvalidOperationException ("Current state is not inside element. Cannot start attribute.");
308 attribute = new XomAttribute (prefix, name, ns, String.Empty);
309 state = WriteState.Attribute;
312 public override void WriteProcessingInstruction (string name, string value)
314 XomParentNode p = current as XomParentNode;
315 if (p == null)
316 throw new InvalidOperationException ("Current writer node cannot have a child.");
317 XomPI pi = new XomPI (name, value);
318 p.AppendChild (pi);
319 document.AppendChild (p, pi);
322 public override void WriteComment (string text)
324 XomParentNode p = current as XomParentNode;
325 if (p == null)
326 throw new InvalidOperationException ("Current writer node cannot have a child.");
327 XomComment comment = new XomComment (text);
328 p.AppendChild (comment);
329 document.AppendChild (p, comment);
332 public override void WriteCData (string text)
334 if (attribute != null)
335 throw new InvalidOperationException ("Current writer node is attribute. It cannot accept CDATA section.");
337 XomParentNode p = current as XomParentNode;
338 if (p == null)
339 throw new InvalidOperationException ("Current writer node cannot have a child.");
340 XomText cdata = new XomText (text);
341 p.AppendChild (cdata);
342 document.AppendChild (p, cdata);
344 WriteString (text);
347 public override void WriteStartElement (string prefix, string name, string ns)
349 XomParentNode p = current as XomParentNode;
350 if (p == null)
351 throw new InvalidOperationException ("Current writer node cannot have a child.");
352 XomElement el = new XomElement (prefix, name, ns);
353 p.AppendChild (el);
354 document.AppendChild (p, el);
355 nodeStack.Push (current);
356 current = el;
359 public override void WriteEndElement ()
361 WriteFullEndElement ();
362 XomElement el = current as XomElement;
363 if (el != null && el.ChildCount == 0)
364 el.SetIsEmpty (true);
367 public override void WriteFullEndElement ()
369 if (nodeStack.Count == 0)
370 throw new InvalidOperationException ("No element is opened.");
371 current = nodeStack.Pop () as XomNode;
374 public override void WriteDocType (string name, string pubid, string systemId, string intsubset)
376 throw new NotSupportedException ();
379 public override void WriteStartDocument ()
381 throw new NotSupportedException ();
384 public override void WriteStartDocument (bool standalone)
386 throw new NotSupportedException ();
389 public override void WriteEndDocument ()
391 throw new NotSupportedException ();
394 public override void WriteBase64 (byte [] data, int start, int length)
396 WriteString (Convert.ToBase64String (data, start, length));
399 public override void WriteRaw (char [] raw, int start, int length)
401 throw new NotSupportedException ();
404 public override void WriteRaw (string raw)
406 throw new NotSupportedException ();
409 public override void WriteSurrogateCharEntity (char msb, char lsb)
411 throw new NotSupportedException ();
414 public override void WriteCharEntity (char c)
416 throw new NotSupportedException ();
419 public override void WriteEntityRef (string entname)
421 throw new NotSupportedException ();
424 public override void WriteChars (char [] data, int start, int length)
426 WriteString (new string (data, start, length));
429 public override void WriteString (string text)
431 if (attribute != null)
432 attribute.Value += text;
433 else {
434 XomParentNode p = current as XomParentNode;
435 if (p == null)
436 throw new InvalidOperationException ("Current writer node cannot have a child.");
438 XomText xt = new XomText (text);
439 p.AppendChild (xt);
440 document.AppendChild (p, xt);
444 public override void WriteWhitespace (string text)
446 if (attribute != null)
447 attribute.Value += text;
448 else {
449 XomParentNode p = current as XomParentNode;
450 if (p == null)
451 throw new InvalidOperationException ("Current writer node cannot have a child.");
453 XomWhitespace ws = new XomWhitespace (text);
454 p.AppendChild (ws);
455 document.AppendChild (p, ws);
459 public override void WriteEndAttribute ()
461 XomElement element = current as XomElement;
462 if (state != WriteState.Attribute || element == null)
463 throw new InvalidOperationException ("Current state is not inside attribute. Cannot close attribute.");
464 XomAttribute old = element.GetAttribute (attribute.LocalName, attribute.Namespace);
465 element.AppendAttribute (attribute);
466 document.AttributeUpdate2 (element, old, attribute);
467 attribute = null;
468 state = WriteState.Content;
472 public class XPathDocument2AttributeWriter : XmlWriter
474 XomElement element;
475 XPathDocument2Editable document;
477 public XPathDocument2AttributeWriter (XomNode owner, XPathDocument2Editable doc)
479 element = owner as XomElement;
480 if (element == null)
481 throw new ArgumentException ("To write attributes, current node must be an element.");
482 state = WriteState.Content;
483 document = doc;
486 WriteState state;
487 XomAttribute attribute;
489 public override WriteState WriteState {
490 get { return state; }
493 public override void Close ()
497 public override void Flush ()
501 public override string LookupPrefix (string ns)
503 return element.LookupPrefix (ns);
506 public override void WriteStartAttribute (string prefix, string name, string ns)
508 if (state != WriteState.Content)
509 throw new InvalidOperationException ("Current state is not inside element. Cannot start attribute.");
510 attribute = new XomAttribute (prefix, name, ns, String.Empty);
511 state = WriteState.Attribute;
514 public override void WriteProcessingInstruction (string name, string value)
516 throw new NotSupportedException ();
519 public override void WriteComment (string text)
521 throw new NotSupportedException ();
524 public override void WriteCData (string text)
526 throw new NotSupportedException ();
529 public override void WriteStartElement (string prefix, string name, string ns)
531 throw new NotSupportedException ();
534 public override void WriteEndElement ()
536 throw new NotSupportedException ();
539 public override void WriteFullEndElement ()
541 throw new NotSupportedException ();
544 public override void WriteDocType (string name, string pubid, string systemId, string intsubset)
546 throw new NotSupportedException ();
549 public override void WriteStartDocument ()
551 throw new NotSupportedException ();
554 public override void WriteStartDocument (bool standalone)
556 throw new NotSupportedException ();
559 public override void WriteEndDocument ()
561 throw new NotSupportedException ();
564 public override void WriteBase64 (byte [] data, int start, int length)
566 throw new NotSupportedException ();
569 public override void WriteRaw (char [] raw, int start, int length)
571 throw new NotSupportedException ();
574 public override void WriteRaw (string raw)
576 throw new NotSupportedException ();
579 public override void WriteSurrogateCharEntity (char msb, char lsb)
581 throw new NotSupportedException ();
584 public override void WriteCharEntity (char c)
586 throw new NotSupportedException ();
589 public override void WriteEntityRef (string entname)
591 throw new NotSupportedException ();
594 public override void WriteChars (char [] data, int start, int length)
596 WriteString (new string (data, start, length));
599 public override void WriteString (string text)
601 if (state != WriteState.Attribute)
602 throw new InvalidOperationException ("Current state is not inside attribute. Cannot write attribute value.");
603 attribute.Value += text;
606 public override void WriteWhitespace (string text)
608 if (state != WriteState.Attribute)
609 throw new InvalidOperationException ("Current state is not inside attribute. Cannot write attribute value.");
610 else
611 attribute.Value += text;
614 public override void WriteEndAttribute ()
616 if (state != WriteState.Attribute)
617 throw new InvalidOperationException ("Current state is not inside attribute. Cannot close attribute.");
618 XomAttribute old = element.GetAttribute (attribute.LocalName, attribute.Namespace);
619 element.AppendAttribute (attribute);
620 document.AttributeUpdate2 (element, old, attribute);
621 attribute = null;
622 state = WriteState.Content;
626 public class Insertion2
628 // AppendChild : last child / true
629 // InsertBefore : current node / false
630 // InsertAfter : current node / true
631 // PrependChild : first child / false
632 public XomParentNode ParentNode;
633 public XomNode InsertedNode;
634 public bool Afterward;
637 public class Removal2
639 public XomParentNode OwnerNode;
640 public XomNode NextSibling;
641 public XomNode RemovedNode;
644 public class AttributeUpdate2
646 public XomElement Element;
647 public XomAttribute NewAttribute;
648 public XomAttribute OldAttribute;
651 public class XomEditableNavigator : XPathEditableNavigator, IHasXomNode
653 XPathDocument2Editable document;
654 XPathNavigator navigator;
656 public XomEditableNavigator (XPathDocument2Editable doc)
658 document = doc;
659 navigator = doc.CreateNavigator ();
662 public XomEditableNavigator (XomEditableNavigator nav)
664 document = nav.document;
665 navigator = nav.navigator.Clone ();
668 public override string BaseURI {
669 get { return navigator.BaseURI; }
672 public override bool IsEmptyElement {
673 get { return navigator.IsEmptyElement; }
676 public override string LocalName {
677 get { return navigator.LocalName; }
680 public override XmlNameTable NameTable {
681 get { return navigator.NameTable; }
684 public override string Name {
685 get { return navigator.Name; }
688 public override string NamespaceURI {
689 get { return navigator.NamespaceURI; }
692 public override XPathNodeType NodeType {
693 get { return navigator.NodeType; }
696 public override string Prefix {
697 get { return navigator.Prefix; }
700 public override string Value {
701 get { return navigator.Value; }
704 public override XPathNavigator Clone ()
706 return new XomEditableNavigator (this);
709 public override XPathNavigator CreateNavigator ()
711 return navigator.Clone ();
714 public XomNode GetNode ()
716 return ((IHasXomNode) navigator).GetNode ();
719 public override bool IsSamePosition (XPathNavigator other)
721 XomEditableNavigator nav = other as XomEditableNavigator;
722 if (nav != null)
723 return navigator.IsSamePosition (nav.navigator);
724 else
725 return navigator.IsSamePosition (nav);
728 public override bool MoveTo (XPathNavigator other)
730 XomEditableNavigator nav = other as XomEditableNavigator;
731 if (nav != null)
732 return navigator.MoveTo (nav.navigator);
733 else
734 return navigator.MoveTo (nav);
737 public override bool MoveToFirstAttribute ()
739 return navigator.MoveToFirstAttribute ();
742 public override bool MoveToFirstChild ()
744 return navigator.MoveToFirstChild ();
747 public override bool MoveToFirstNamespace (XPathNamespaceScope scope)
749 return navigator.MoveToFirstNamespace (scope);
752 public override bool MoveToId (string id)
754 return navigator.MoveToId (id);
757 public override bool MoveToNext ()
759 return navigator.MoveToNext ();
762 public override bool MoveToNextAttribute ()
764 return navigator.MoveToNextAttribute ();
767 public override bool MoveToNextNamespace (XPathNamespaceScope scope)
769 return navigator.MoveToNextNamespace (scope);
772 public override bool MoveToParent ()
774 return navigator.MoveToParent ();
777 public override bool MoveToPrevious ()
779 return navigator.MoveToPrevious ();
782 public override void Validate (XmlSchemaSet schemas, ValidationEventHandler handler)
784 throw new NotImplementedException ();
786 // FIXME: use handler
787 XmlReaderSettings settings = new XmlReaderSettings ();
788 settings.Schemas.Add (schemas);
789 settings.NameTable = this.NameTable;
790 settings.XsdValidate = true;
791 settings.DtdValidate = false;
792 XmlReader xvr = XmlReader.Create (new XPathNavigatorReader (this), settings);
793 while (!xvr.EOF)
794 xvr.Read ();
798 public override XmlWriter AppendChild ()
800 XomNode n = ((IHasXomNode) navigator).GetNode ();
801 if (n == null)
802 throw new InvalidOperationException ("Should not happen.");
803 return document.CreateInsertionWriter (n, null);
806 public override XmlWriter InsertBefore ()
808 XomNode n = ((IHasXomNode) navigator).GetNode ();
809 return document.CreateInsertionWriter (n.Parent, n.PreviousSibling);
812 public override XmlWriter CreateAttributes ()
814 XomNode n = ((IHasXomNode) navigator).GetNode ();
815 return document.CreateAttributesWriter (n);
818 public override bool DeleteCurrent ()
820 XomNode n = ((IHasXomNode) navigator).GetNode ();
821 if (!navigator.MoveToNext ())
822 navigator.MoveToParent ();
823 return document.DeleteNode (n);
826 public override void SetValue (object value)
828 XomNode n = ((IHasXomNode) navigator).GetNode ();
829 int count = n.ChildCount;
830 while (n.FirstChild != null)
831 document.DeleteNode (n.FirstChild);
832 XmlWriter w = document.CreateInsertionWriter (n, null);
833 w.WriteValue (value);
834 w.Close ();
839 #endif