2002-08-16 Jason Diamond <jason@injektilo.org>
[mono.git] / mcs / class / System.XML / System.Xml.Serialization / XmlAttributes.cs
1 //
2 // XmlAttributes.cs: 
3 //
4 // Author:
5 //   John Donagher (john@webmeta.com)
6 //
7 // (C) 2002 John Donagher
8 //
9
10 using System.Reflection;
11 using System;\r
12 using System.ComponentModel;\r
13 using System.Collections;\r
14 \r
15 namespace System.Xml.Serialization\r
16 {\r
17         /// <summary>\r
18         /// Summary description for XmlAttributes.\r
19         /// </summary>\r
20         public class XmlAttributes\r
21         {\r
22                 private XmlAnyAttributeAttribute xmlAnyAttribute;\r
23                 private XmlAnyElementAttributes xmlAnyElements;\r
24                 private XmlArrayAttribute xmlArray;\r
25                 private XmlArrayItemAttributes xmlArrayItems;\r
26                 private XmlAttributeAttribute xmlAttribute;\r
27                 private XmlChoiceIdentifierAttribute xmlChoiceIdentifier;\r
28                 private object xmlDefaultValue;\r
29                 private XmlElementAttributes xmlElements;\r
30                 private XmlEnumAttribute xmlEnum;\r
31                 private bool xmlIgnore;\r
32                 private bool xmlns;\r
33                 private XmlRootAttribute xmlRoot;\r
34                 private XmlTextAttribute xmlText;\r
35                 private XmlTypeAttribute xmlType;\r
36 \r
37                 private MemberInfo minfo;\r
38                 private FieldInfo  finfo;\r
39                 private PropertyInfo pinfo;\r
40                 internal ArrayList XmlIncludes;\r
41                 //internal string ElementName;\r
42 \r
43                 //The element Order in serialization.\r
44                 internal int order;\r
45                 internal bool isAttribute;\r
46                 internal static XmlAttributes.XmlAttributesComparer attrComparer;\r
47 \r
48                 //Sorting Order of Elements: XmlNs, XmlAttributes, XmlElement\r
49                 internal class XmlAttributesComparer : IComparer\r
50                 {\r
51                         public int Compare(object x,object y)\r
52                         {\r
53                                 if(x is XmlAttributes && y is XmlAttributes)\r
54                                 {\r
55                                         XmlAttributes attx = (XmlAttributes)x;\r
56                                         XmlAttributes atty = (XmlAttributes)y;\r
57                                         if(attx.xmlns)\r
58                                                 return -1;\r
59                                         if(atty.xmlns)\r
60                                                 return 1;\r
61                                         if(attx.isAttribute)\r
62                                                 return -1;\r
63                                         if(atty.isAttribute)\r
64                                                 return 1;\r
65                                         int diff = attx.order - atty.order;\r
66                                         if(diff == 0)\r
67                                                 return 0;\r
68                                         if(diff > 0)\r
69                                                 return 1;\r
70                                         if(diff < 0)\r
71                                                 return -1;\r
72                                 }\r
73                                 if(x == null)\r
74                                         return -1;\r
75                                 if(y == null)\r
76                                         return 1;\r
77                                 throw new Exception("Should never occur. XmlAttributesComparer.Compare");\r
78                         }\r
79                 }\r
80 \r
81                 public XmlAttributes ()\r
82                 {\r
83                         xmlAnyElements = new XmlAnyElementAttributes ();\r
84                         xmlArrayItems = new XmlArrayItemAttributes ();\r
85                         xmlElements = new XmlElementAttributes ();\r
86                         XmlIncludes = new ArrayList();\r
87                 }\r
88 \r
89                 static XmlAttributes ()\r
90                 {\r
91                         attrComparer = new XmlAttributes.XmlAttributesComparer();\r
92                 }\r
93 \r
94                 public XmlAttributes (ICustomAttributeProvider provider)\r
95                 {\r
96                         object[] attributes = provider.GetCustomAttributes(false);\r
97                         foreach(object obj in attributes)\r
98                         {\r
99                                 if(obj is XmlAnyAttributeAttribute)\r
100                                         xmlAnyAttribute = (XmlAnyAttributeAttribute) obj;\r
101                                 else if(obj is XmlAnyElementAttribute)\r
102                                         xmlAnyElements.Add((XmlAnyElementAttribute) obj);\r
103                                 else if(obj is XmlArrayAttribute)\r
104                                         xmlArray = (XmlArrayAttribute) obj;\r
105                                 else if(obj is XmlArrayItemAttribute)\r
106                                         xmlArrayItems.Add((XmlArrayItemAttribute) obj);\r
107                                 else if(obj is XmlAttributeAttribute)\r
108                                         xmlAttribute = (XmlAttributeAttribute) obj;\r
109                                 else if(obj is XmlChoiceIdentifierAttribute)\r
110                                         xmlChoiceIdentifier = (XmlChoiceIdentifierAttribute) obj;\r
111                                 else if(obj is DefaultValueAttribute)\r
112                                         xmlDefaultValue = obj;\r
113                                 else if(obj is XmlElementAttribute )\r
114                                         xmlElements.Add((XmlElementAttribute ) obj);\r
115                                 else if(obj is XmlEnumAttribute)\r
116                                         xmlEnum = (XmlEnumAttribute) obj;\r
117                                 else if(obj is XmlIgnoreAttribute)\r
118                                         xmlIgnore = true;\r
119                                 else if(obj is XmlNamespaceDeclarationsAttribute)\r
120                                         xmlns = true;\r
121                                 else if(obj is XmlRootAttribute)\r
122                                         xmlRoot = (XmlRootAttribute) obj;\r
123                                 else if(obj is XmlTextAttribute)\r
124                                         xmlText = (XmlTextAttribute) obj;\r
125                                 else if(obj is XmlTypeAttribute)\r
126                                         xmlType = (XmlTypeAttribute) obj;\r
127                         }\r
128                 }\r
129 \r
130                 #region public properties\r
131                 public XmlAnyAttributeAttribute XmlAnyAttribute \r
132                 {\r
133                         get \r
134                         {
135                                 return xmlAnyAttribute;
136                         }\r
137                         set \r
138                         {
139                                 xmlAnyAttribute = value;
140                         }\r
141                 }\r
142                 public XmlAnyElementAttributes XmlAnyElements \r
143                 {\r
144                         get \r
145                         {
146                                 return xmlAnyElements;
147                         }\r
148                 }\r
149                 public XmlArrayAttribute XmlArray\r
150                 {\r
151                         get \r
152                         {
153                                 return xmlArray;
154                         }\r
155                         set \r
156                         {
157                                 xmlArray = value;
158                         }\r
159                 }\r
160                 public XmlArrayItemAttributes XmlArrayItems \r
161                 {\r
162                         get \r
163                         {
164                                 return xmlArrayItems;
165                         }\r
166                 }\r
167                 public XmlAttributeAttribute XmlAttribute \r
168                 {\r
169                         get \r
170                         {
171                                 return xmlAttribute;
172                         }\r
173                         set \r
174                         {
175                                 xmlAttribute = value;
176                         }\r
177                 }\r
178                 public XmlChoiceIdentifierAttribute XmlChoiceIdentifier \r
179                 {\r
180                         get \r
181                         {
182                                 return xmlChoiceIdentifier;
183                         }\r
184                         set \r
185                         {
186                                 xmlChoiceIdentifier = value;
187                         }\r
188                 }\r
189                 public object XmlDefaultValue \r
190                 {\r
191                         get \r
192                         {
193                                 return xmlDefaultValue;
194                         }\r
195                         set \r
196                         {
197                                 xmlDefaultValue = value;
198                         }\r
199                 }\r
200                 public XmlElementAttributes XmlElements \r
201                 {\r
202                         get \r
203                         {
204                                 return xmlElements;
205                         }\r
206                 }\r
207                 public XmlEnumAttribute XmlEnum \r
208                 {\r
209                         get \r
210                         {
211                                 return xmlEnum;
212                         }\r
213                         set \r
214                         {
215                                 xmlEnum = value;
216                         }\r
217                 }\r
218                 public bool XmlIgnore \r
219                 {\r
220                         get \r
221                         {
222                                 return xmlIgnore;
223                         }\r
224                         set \r
225                         {
226                                 xmlIgnore = value;
227                         }\r
228                 }\r
229                 public bool Xmlns \r
230                 {\r
231                         get \r
232                         {
233                                 return xmlns;
234                         }\r
235                         set \r
236                         {
237                                 xmlns = value;
238                         }\r
239                 }\r
240                 public XmlRootAttribute XmlRoot \r
241                 {\r
242                         get \r
243                         {
244                                 return xmlRoot;}\r
245                         set \r
246                         {
247                                 xmlRoot = value;
248                         }\r
249                 }\r
250                 public XmlTextAttribute XmlText \r
251                 {\r
252                         get \r
253                         {
254                                 return xmlText;
255                         }\r
256                         set \r
257                         {
258                                 xmlText = value;
259                         }\r
260                 }\r
261                 public XmlTypeAttribute XmlType \r
262                 {\r
263                         get \r
264                         {
265                                 return xmlType;
266                         }\r
267                         set \r
268                         {
269                                 xmlType = value;
270                         }\r
271                 }\r
272                 #endregion\r
273 \r
274                 #region internal properties\r
275                 internal MemberInfo MemberInfo\r
276                 {\r
277                         get { return  minfo; }\r
278                         set { minfo = value; }\r
279                 }\r
280 \r
281                 internal FieldInfo FieldInfo \r
282                 {\r
283                         get { return  finfo; }\r
284                         set { finfo = value; }\r
285                 }\r
286 \r
287                 internal PropertyInfo PropertyInfo\r
288                 {\r
289                         get { return  pinfo; }\r
290                         set { pinfo = value; }\r
291                 }\r
292                 #endregion\r
293 \r
294                 //Only permissible attributes for a class type are: XmlRoot and XmlInclude\r
295                 internal static XmlAttributes FromClass(Type classType)\r
296                 {\r
297                         XmlAttributes XmlAttr = new XmlAttributes();\r
298                         object[] attributes = classType.GetCustomAttributes(false);\r
299                         foreach(object obj in attributes)\r
300                         {\r
301                                 if(obj is XmlRootAttribute)\r
302                                         XmlAttr.xmlRoot = (XmlRootAttribute) obj;\r
303                                 else if(obj is XmlIncludeAttribute)\r
304                                         XmlAttr.XmlIncludes.Add(obj);\r
305                         }\r
306                         return XmlAttr;\r
307                 }\r
308 \r
309                 internal static XmlAttributes FromField(MemberInfo member, FieldInfo finfo)\r
310                 {\r
311                         XmlAttributes XmlAttr = new XmlAttributes();\r
312                         object[] attributes = member.GetCustomAttributes(false);\r
313                         XmlAttr.AddMemberAttributes(attributes);\r
314 \r
315                         XmlAttr.minfo = member;\r
316                         XmlAttr.finfo = finfo;\r
317 \r
318                         return XmlAttr;\r
319                 }\r
320 \r
321                 \r
322                 internal static XmlAttributes FromProperty(MemberInfo member, PropertyInfo pinfo)\r
323                 {\r
324 \r
325                         XmlAttributes XmlAttr = new XmlAttributes();\r
326                         object[] attributes = member.GetCustomAttributes(false);\r
327                         XmlAttr.AddMemberAttributes(attributes);\r
328 \r
329                         XmlAttr.minfo = member;\r
330                         XmlAttr.pinfo = pinfo;\r
331                         return XmlAttr;\r
332                 }\r
333 \r
334                 internal void AddMemberAttributes(object[] attributes)\r
335                 {\r
336                         foreach(object obj in attributes)\r
337                         {\r
338                                 if(obj is XmlAnyAttributeAttribute)\r
339                                 {\r
340                                         xmlAnyAttribute = (XmlAnyAttributeAttribute) obj;\r
341                                         isAttribute = true;     \r
342                                 }\r
343                                 else if(obj is XmlAttributeAttribute)\r
344                                 {\r
345                                         xmlAttribute = (XmlAttributeAttribute) obj;\r
346                                         isAttribute = true;\r
347                                 }\r
348                                 else if(obj is XmlNamespaceDeclarationsAttribute)\r
349                                 {\r
350                                         xmlns = true;\r
351                                         isAttribute = true;\r
352                                 }\r
353                                 else if(obj is XmlAnyElementAttribute)\r
354                                 {\r
355                                         xmlAnyElements.Add((XmlAnyElementAttribute) obj);\r
356                                         order = ((XmlAnyElementAttribute) obj).Order;\r
357                                 }\r
358                                 else if(obj is XmlArrayAttribute)\r
359                                 {\r
360                                         xmlArray = (XmlArrayAttribute) obj;\r
361                                         order = ((XmlArrayAttribute) obj).Order;\r
362                                 }\r
363                                 else if(obj is XmlArrayItemAttribute)\r
364                                 {\r
365                                         xmlArrayItems.Add((XmlArrayItemAttribute) obj);\r
366                                         order = ((XmlArrayItemAttribute) obj).Order;\r
367                                 }\r
368                                 else if(obj is XmlChoiceIdentifierAttribute)\r
369                                 {\r
370                                         xmlChoiceIdentifier = (XmlChoiceIdentifierAttribute) obj;\r
371                                         order = ((XmlChoiceIdentifierAttribute) obj).Order;\r
372                                 }\r
373                                 else if(obj is XmlTextAttribute)\r
374                                 {\r
375                                         xmlText = (XmlTextAttribute) obj;\r
376                                         order = ((XmlTextAttribute) obj).Order;\r
377                                 }\r
378                                 else if(obj is XmlElementAttribute )\r
379                                 {\r
380                                         xmlElements.Add((XmlElementAttribute ) obj);\r
381                                         order = ((XmlElementAttribute ) obj).Order;\r
382                                 }\r
383                                 else if(obj is DefaultValueAttribute)\r
384                                 {\r
385                                         xmlDefaultValue = ((DefaultValueAttribute ) obj).Value;\r
386                                 }\r
387                                 else if(obj is XmlEnumAttribute)\r
388                                 {\r
389                                         xmlEnum = (XmlEnumAttribute) obj;\r
390                                 }\r
391                                 else if(obj is XmlIgnoreAttribute)\r
392                                 {\r
393                                         xmlIgnore = true;\r
394                                 }\r
395                                 else if(obj is XmlRootAttribute)\r
396                                 {\r
397                                         throw new Exception("should never happen. XmlRoot on a member");\r
398                                 }\r
399                                 else if(obj is XmlTypeAttribute)\r
400                                 {\r
401                                         xmlType = (XmlTypeAttribute) obj;\r
402                                 }\r
403                         }\r
404                 }\r
405 \r
406                 internal string GetAttributeName(Type type, string defaultName)\r
407                 {\r
408                         if(XmlAttribute != null && XmlAttribute.AttributeName != null && XmlAttribute.AttributeName != "")\r
409                                 return XmlAttribute.AttributeName;\r
410                         return defaultName;\r
411                 }\r
412 \r
413                 internal string GetElementName(Type type, string defaultName)\r
414                 {\r
415                         foreach(XmlElementAttribute elem in XmlElements)\r
416                         {\r
417                                 if(elem.Type == type && elem.ElementName != null && elem.ElementName != "")\r
418                                         return elem.ElementName;\r
419                                 else if(elem.Type == null && elem.ElementName != null && elem.ElementName != "")\r
420                                         return elem.ElementName;\r
421                         }\r
422                         return defaultName;\r
423                 }\r
424 \r
425                 internal string GetAttributeNamespace(Type type)\r
426                 {\r
427                         if(XmlAttribute != null)\r
428                                 return XmlAttribute.Namespace;\r
429                         return null;\r
430                 }\r
431                 internal string GetElementNamespace(Type type)\r
432                 {\r
433                         foreach(XmlElementAttribute elem in XmlElements)\r
434                         {\r
435                                 if(elem.Type == type )\r
436                                         return elem.Namespace;\r
437                                 else if(elem.Type == null)\r
438                                         return elem.Namespace;\r
439                         }\r
440                         return null;\r
441                 }\r
442         }\r
443 }\r