Merge pull request #554 from deplinenoise/ppc_fixes
[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.Linq;
30 using System.Xml;
31
32 namespace System.Xml.Linq
33 {
34         public abstract class XObject : IXmlLineInfo
35         {
36                 internal XObject ()
37                 {
38                 }
39
40                 XContainer owner;
41                 List<object> annotations;
42                 string baseuri;
43                 int line, column;
44
45                 public event EventHandler<XObjectChangeEventArgs> Changing;
46                 public event EventHandler<XObjectChangeEventArgs> Changed;
47
48                 public string BaseUri {
49                         get { return baseuri; }
50                         internal set { baseuri = value; }
51                 }
52
53                 public XDocument Document {
54                         get {
55                                 if (this is XDocument)
56                                         return (XDocument) this;
57
58                                 for (XContainer e = owner; e != null; e = e.owner)
59                                         if (e is XDocument)
60                                                 return (XDocument) e;
61                                 return null;
62                         }
63                 }
64
65                 public abstract XmlNodeType NodeType { get; }
66
67                 public XElement Parent {
68                         get { return owner as XElement; }
69                 }
70
71                 internal XContainer Owner {
72                         get { return owner; }
73                 }
74
75                 internal void SetOwner (XContainer node)
76                 {
77                         owner = node;
78                 }
79
80                 public void AddAnnotation (object annotation)
81                 {
82                         if (annotation == null)
83                                 throw new ArgumentNullException ("annotation");
84                         if (annotations == null)
85                                 annotations = new List<object> ();
86                         annotations.Add (annotation);
87                 }
88
89                 public T Annotation<T> () where T : class
90                 {
91                         return (T) Annotation (typeof (T));
92                 }
93
94                 public object Annotation (Type type)
95                 {
96                         return Annotations (type).FirstOrDefault ();
97                 }
98
99                 public IEnumerable<T> Annotations<T> () where T : class
100                 {
101                         foreach (T o in Annotations (typeof (T)))
102                                 yield return o;
103                 }
104
105                 public IEnumerable<object> Annotations (Type type)
106                 {
107                         if (type == null)
108                                 throw new ArgumentNullException ("type");
109                         if (annotations == null)
110                                 yield break;
111                         foreach (object o in annotations)
112                                 if (type.IsAssignableFrom (o.GetType ()))
113                                         yield return o;
114                 }
115
116                 public void RemoveAnnotations<T> () where T : class
117                 {
118                         RemoveAnnotations (typeof (T));
119                 }
120
121                 public void RemoveAnnotations (Type type)
122                 {
123                         if (annotations == null)
124                                 return;
125                         for (int i = 0; i < annotations.Count; i++)
126                                 if (type.IsAssignableFrom (annotations [i].GetType ()))
127                                         annotations.RemoveAt (i);
128                 }
129
130                 internal int LineNumber {
131                         get { return line; }
132                         set { line = value; }
133                 }
134
135                 internal int LinePosition {
136                         get { return column; }
137                         set { column = value; }
138                 }
139
140                 int IXmlLineInfo.LineNumber {
141                         get { return LineNumber; }
142                 }
143
144                 int IXmlLineInfo.LinePosition {
145                         get { return LinePosition; }
146                 }
147
148                 bool IXmlLineInfo.HasLineInfo ()
149                 {
150                         return line > 0;
151                 }
152
153                 internal void FillLineInfoAndBaseUri (XmlReader r, LoadOptions options)
154                 {
155                         if ((options & LoadOptions.SetLineInfo) != LoadOptions.None) {
156                                 IXmlLineInfo li = r as IXmlLineInfo;
157                                 if (li != null && li.HasLineInfo ()) {
158                                         LineNumber = li.LineNumber;
159                                         LinePosition = li.LinePosition;
160                                 }
161                         }
162                         if ((options & LoadOptions.SetBaseUri) != LoadOptions.None)
163                                 BaseUri = r.BaseURI;
164                 }
165                 
166                 internal void OnAddingObject (object addedObject)
167                 {
168                         OnChanging (addedObject, new XObjectChangeEventArgs (XObjectChange.Add));
169                 }
170
171                 internal void OnAddedObject (object addedObject)
172                 {
173                         OnChanged (addedObject, new XObjectChangeEventArgs (XObjectChange.Add));
174                 }
175
176                 internal void OnNameChanging (object renamedObject)
177                 {
178                         OnChanging (renamedObject, new XObjectChangeEventArgs (System.Xml.Linq.XObjectChange.Name));
179                 }
180
181                 internal void OnNameChanged (object renamedObject)
182                 {
183                         OnChanged (renamedObject, new XObjectChangeEventArgs (System.Xml.Linq.XObjectChange.Name));
184                 }
185                 
186                 internal void OnRemovingObject (object removedObject)
187                 {
188                         OnChanging (removedObject, new XObjectChangeEventArgs (XObjectChange.Remove));
189                 }
190
191                 internal void OnRemovedObject (object removedObject)
192                 {
193                         OnChanged (removedObject, new XObjectChangeEventArgs (XObjectChange.Remove));
194                 }
195
196                 internal void OnValueChanging (object changedObject)
197                 {
198                         OnChanging (changedObject, new XObjectChangeEventArgs (XObjectChange.Value));
199                 }
200
201                 internal void OnValueChanged (object changedObject)
202                 {
203                         OnChanged (changedObject, new XObjectChangeEventArgs (XObjectChange.Value));
204                 }
205
206                 
207                 void OnChanging (object sender, XObjectChangeEventArgs args)
208                 {
209                         if (Changing != null)
210                                 Changing (sender, args);
211                         if (Parent != null)
212                                 Parent.OnChanging (sender, args);
213                 }
214
215                 void OnChanged (object sender, XObjectChangeEventArgs args)
216                 {
217                         if (Changed != null)
218                                 Changed (sender, args);
219                         if (Parent != null)
220                                 Parent.OnChanged (sender, args);
221                 }
222         }
223 }