f79fb4f6d2d9798930e6deac0eb7029aca0765c0
[mono.git] / mcs / class / System.Xml.Linq / System.Xml.Linq / XObject.cs
1 //
2 // Authors:
3 //   Atsushi Enomoto
4 //
5 // Copyright 2007 Novell (http://www.novell.com)
6 //
7 // Permission is hereby granted, free of charge, to any person obtaining
8 // a copy of this software and associated documentation files (the
9 // "Software"), to deal in the Software without restriction, including
10 // without limitation the rights to use, copy, modify, merge, publish,
11 // distribute, sublicense, and/or sell copies of the Software, and to
12 // permit persons to whom the Software is furnished to do so, subject to
13 // the following conditions:
14 // 
15 // The above copyright notice and this permission notice shall be
16 // included in all copies or substantial portions of the Software.
17 // 
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 //
26
27 using System;
28 using System.Collections.Generic;
29 using System.Xml;
30
31 namespace System.Xml.Linq
32 {
33         public abstract class XObject : IXmlLineInfo
34         {
35                 internal XObject ()
36                 {
37                 }
38
39                 XContainer owner;
40                 List<object> annotations;
41                 string baseuri;
42                 int line, column;
43
44                 public event EventHandler<XObjectChangeEventArgs> Changing;
45                 public event EventHandler<XObjectChangeEventArgs> Changed;
46
47                 public string BaseUri {
48                         get { return baseuri; }
49                         internal set { baseuri = value; }
50                 }
51
52                 public XDocument Document {
53                         get {
54                                 if (this is XDocument)
55                                         return (XDocument) this;
56
57                                 for (XContainer e = owner; e != null; e = e.owner)
58                                         if (e is XDocument)
59                                                 return (XDocument) e;
60                                 return null;
61                         }
62                 }
63
64                 public abstract XmlNodeType NodeType { get; }
65
66                 public XElement Parent {
67                         get { return owner as XElement; }
68                 }
69
70                 internal XContainer Owner {
71                         get { return owner; }
72                 }
73
74                 internal void SetOwner (XContainer node)
75                 {
76                         owner = node;
77                 }
78
79                 public void AddAnnotation (object annotation)
80                 {
81                         if (annotation == null)
82                                 throw new ArgumentNullException ("annotation");
83                         if (annotations == null)
84                                 annotations = new List<object> ();
85                         annotations.Add (annotation);
86                 }
87
88                 public T Annotation<T> () where T : class
89                 {
90                         return (T) Annotation (typeof (T));
91                 }
92
93                 public object Annotation (Type type)
94                 {
95                         if (annotations != null)
96                                 foreach (object o in annotations)
97                                         if (o.GetType () == type)
98                                                 return o;
99                         throw new ArgumentException ();
100                 }
101
102                 public IEnumerable<T> Annotations<T> () where T : class
103                 {
104                         foreach (T o in Annotations (typeof (T)))
105                                 yield return o;
106                 }
107
108                 public IEnumerable<object> Annotations (Type type)
109                 {
110                         if (annotations == null)
111                                 yield break;
112                         foreach (object o in annotations)
113                                 if (o.GetType () == type)
114                                         yield return o;
115                 }
116
117                 public void RemoveAnnotations<T> () where T : class
118                 {
119                         RemoveAnnotations (typeof (T));
120                 }
121
122                 public void RemoveAnnotations (Type type)
123                 {
124                         if (annotations == null)
125                                 return;
126                         for (int i = 0; i < annotations.Count; i++)
127                                 if (annotations [i].GetType () == type)
128                                         annotations.RemoveAt (i);
129                 }
130
131                 internal int LineNumber {
132                         get { return line; }
133                         set { line = value; }
134                 }
135
136                 internal int LinePosition {
137                         get { return column; }
138                         set { column = value; }
139                 }
140
141                 int IXmlLineInfo.LineNumber {
142                         get { return LineNumber; }
143                 }
144
145                 int IXmlLineInfo.LinePosition {
146                         get { return LinePosition; }
147                 }
148
149                 bool IXmlLineInfo.HasLineInfo ()
150                 {
151                         return line > 0;
152                 }
153
154                 internal void FillLineInfoAndBaseUri (XmlReader r, LoadOptions options)
155                 {
156                         if ((options & LoadOptions.SetLineInfo) != LoadOptions.None) {
157                                 IXmlLineInfo li = r as IXmlLineInfo;
158                                 if (li != null && li.HasLineInfo ()) {
159                                         LineNumber = li.LineNumber;
160                                         LinePosition = li.LinePosition;
161                                 }
162                         }
163                         if ((options & LoadOptions.SetBaseUri) != LoadOptions.None)
164                                 BaseUri = r.BaseURI;
165                 }
166         }
167 }