31bb36612ed9bff2ed9f6533e4627d56824adbcf
[mono.git] / mcs / class / referencesource / System.Xml / System / Xml / Serialization / XmlAttributes.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="XmlAttributes.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 // <owner current="true" primary="true">Microsoft</owner>                                                                
6 //------------------------------------------------------------------------------
7
8 namespace System.Xml.Serialization {
9     using System;
10     using System.Reflection;
11     using System.Collections;
12     using System.ComponentModel;
13
14     internal enum XmlAttributeFlags {
15         Enum = 0x1,
16         Array = 0x2,
17         Text = 0x4,
18         ArrayItems = 0x8,
19         Elements = 0x10,
20         Attribute = 0x20,
21         Root = 0x40,
22         Type = 0x80,
23         AnyElements = 0x100,
24         AnyAttribute = 0x200,
25         ChoiceIdentifier = 0x400,
26         XmlnsDeclarations = 0x800,
27     }
28
29     /// <include file='doc\XmlAttributes.uex' path='docs/doc[@for="XmlAttributes"]/*' />
30     /// <devdoc>
31     ///    <para>[To be supplied.]</para>
32     /// </devdoc>
33     public class XmlAttributes {
34         XmlElementAttributes xmlElements = new XmlElementAttributes();
35         XmlArrayItemAttributes xmlArrayItems = new XmlArrayItemAttributes();
36         XmlAnyElementAttributes xmlAnyElements = new XmlAnyElementAttributes();
37         XmlArrayAttribute xmlArray;
38         XmlAttributeAttribute xmlAttribute;
39         XmlTextAttribute xmlText;
40         XmlEnumAttribute xmlEnum;
41         bool xmlIgnore;
42         bool xmlns;
43         object xmlDefaultValue = null;
44         XmlRootAttribute xmlRoot;
45         XmlTypeAttribute xmlType;
46         XmlAnyAttributeAttribute xmlAnyAttribute;
47         XmlChoiceIdentifierAttribute xmlChoiceIdentifier;
48         static volatile Type ignoreAttributeType;
49
50
51         /// <include file='doc\XmlAttributes.uex' path='docs/doc[@for="XmlAttributes.XmlAttributes"]/*' />
52         /// <devdoc>
53         ///    <para>[To be supplied.]</para>
54         /// </devdoc>
55         public XmlAttributes() {
56         }
57
58         internal XmlAttributeFlags XmlFlags {
59             get { 
60                 XmlAttributeFlags flags = 0;
61                 if (xmlElements.Count > 0) flags |= XmlAttributeFlags.Elements;
62                 if (xmlArrayItems.Count > 0) flags |= XmlAttributeFlags.ArrayItems;
63                 if (xmlAnyElements.Count > 0) flags |= XmlAttributeFlags.AnyElements;
64                 if (xmlArray != null) flags |= XmlAttributeFlags.Array;
65                 if (xmlAttribute != null) flags |= XmlAttributeFlags.Attribute;
66                 if (xmlText != null) flags |= XmlAttributeFlags.Text;
67                 if (xmlEnum != null) flags |= XmlAttributeFlags.Enum;
68                 if (xmlRoot != null) flags |= XmlAttributeFlags.Root;
69                 if (xmlType != null) flags |= XmlAttributeFlags.Type;
70                 if (xmlAnyAttribute != null) flags |= XmlAttributeFlags.AnyAttribute;
71                 if (xmlChoiceIdentifier != null) flags |= XmlAttributeFlags.ChoiceIdentifier;
72                 if (xmlns) flags |= XmlAttributeFlags.XmlnsDeclarations;
73                 return flags;
74             }
75         }
76
77         private static Type IgnoreAttribute {
78             get {
79                 if (ignoreAttributeType == null) {
80                     ignoreAttributeType = typeof(object).Assembly.GetType("System.XmlIgnoreMemberAttribute");
81                     if (ignoreAttributeType == null) {
82                         ignoreAttributeType = typeof(XmlIgnoreAttribute);
83                     }
84                 }
85                 return ignoreAttributeType;
86             }
87         }
88
89         /// <include file='doc\XmlAttributes.uex' path='docs/doc[@for="XmlAttributes.XmlAttributes1"]/*' />
90         /// <devdoc>
91         ///    <para>[To be supplied.]</para>
92         /// </devdoc>
93         public XmlAttributes(ICustomAttributeProvider provider) {
94             object[] attrs = provider.GetCustomAttributes(false);
95
96             // most generic <any/> matches everithig 
97             XmlAnyElementAttribute wildcard = null;
98             for (int i = 0; i < attrs.Length; i++) {
99                 if (attrs[i] is XmlIgnoreAttribute || attrs[i] is ObsoleteAttribute || attrs[i].GetType() == IgnoreAttribute) {
100                     xmlIgnore = true;
101                     break;
102                 }
103                 else if (attrs[i] is XmlElementAttribute) {
104                     this.xmlElements.Add((XmlElementAttribute)attrs[i]);
105                 }
106                 else if (attrs[i] is XmlArrayItemAttribute) {
107                     this.xmlArrayItems.Add((XmlArrayItemAttribute)attrs[i]);
108                 }
109                 else if (attrs[i] is XmlAnyElementAttribute) {
110                     XmlAnyElementAttribute any = (XmlAnyElementAttribute)attrs[i];
111                     if ((any.Name == null || any.Name.Length == 0) && any.NamespaceSpecified && any.Namespace == null) {
112                         // ignore duplicate wildcards
113                         wildcard = any;
114                     }
115                     else {
116                         this.xmlAnyElements.Add((XmlAnyElementAttribute)attrs[i]);
117                     }
118                 }
119                 else if (attrs[i] is DefaultValueAttribute) {
120                     this.xmlDefaultValue = ((DefaultValueAttribute)attrs[i]).Value;
121                 }
122                 else if (attrs[i] is XmlAttributeAttribute) {
123                     this.xmlAttribute = (XmlAttributeAttribute)attrs[i];
124                 }
125                 else if (attrs[i] is XmlArrayAttribute) {
126                     this.xmlArray = (XmlArrayAttribute)attrs[i];
127                 }
128                 else if (attrs[i] is XmlTextAttribute) {
129                     this.xmlText = (XmlTextAttribute)attrs[i];
130                 }
131                 else if (attrs[i] is XmlEnumAttribute) {
132                     this.xmlEnum = (XmlEnumAttribute)attrs[i];
133                 }
134                 else if (attrs[i] is XmlRootAttribute) {
135                     this.xmlRoot = (XmlRootAttribute)attrs[i];
136                 }
137                 else if (attrs[i] is XmlTypeAttribute) {
138                     this.xmlType = (XmlTypeAttribute)attrs[i];
139                 }
140                 else if (attrs[i] is XmlAnyAttributeAttribute) {
141                     this.xmlAnyAttribute = (XmlAnyAttributeAttribute)attrs[i];
142                 }
143                 else if (attrs[i] is XmlChoiceIdentifierAttribute) {
144                     this.xmlChoiceIdentifier = (XmlChoiceIdentifierAttribute)attrs[i];
145                 }
146                 else if (attrs[i] is XmlNamespaceDeclarationsAttribute) {
147                     this.xmlns = true;
148                 }
149             }
150             if (xmlIgnore) {
151                 this.xmlElements.Clear();
152                 this.xmlArrayItems.Clear();
153                 this.xmlAnyElements.Clear();
154                 this.xmlDefaultValue = null;
155                 this.xmlAttribute = null;
156                 this.xmlArray = null;
157                 this.xmlText = null;
158                 this.xmlEnum = null;
159                 this.xmlType = null;
160                 this.xmlAnyAttribute = null;
161                 this.xmlChoiceIdentifier = null;
162                 this.xmlns = false;
163             }
164             else {
165                 if (wildcard != null) {
166                     this.xmlAnyElements.Add(wildcard);
167                 }
168             }
169         }
170
171         internal static object GetAttr(ICustomAttributeProvider provider, Type attrType) {
172             object[] attrs = provider.GetCustomAttributes(attrType, false);
173             if (attrs.Length == 0) return null;
174             return attrs[0];
175         }
176         
177         /// <include file='doc\XmlAttributes.uex' path='docs/doc[@for="XmlAttributes.XmlElements"]/*' />
178         /// <devdoc>
179         ///    <para>[To be supplied.]</para>
180         /// </devdoc>
181         public XmlElementAttributes XmlElements {
182             get { return xmlElements; }
183         }
184         
185         /// <include file='doc\XmlAttributes.uex' path='docs/doc[@for="XmlAttributes.XmlAttribute"]/*' />
186         /// <devdoc>
187         ///    <para>[To be supplied.]</para>
188         /// </devdoc>
189         public XmlAttributeAttribute XmlAttribute {
190             get { return xmlAttribute; }
191             set { xmlAttribute = value; }
192         }
193         
194         /// <include file='doc\XmlAttributes.uex' path='docs/doc[@for="XmlAttributes.XmlEnum"]/*' />
195         /// <devdoc>
196         ///    <para>[To be supplied.]</para>
197         /// </devdoc>
198         public XmlEnumAttribute XmlEnum {
199             get { return xmlEnum; }
200             set { xmlEnum = value; }
201         }
202         
203         /// <include file='doc\XmlAttributes.uex' path='docs/doc[@for="XmlAttributes.XmlText"]/*' />
204         /// <devdoc>
205         ///    <para>[To be supplied.]</para>
206         /// </devdoc>
207         public XmlTextAttribute XmlText {
208             get { return xmlText; }
209             set { xmlText = value; }
210         }
211         
212         /// <include file='doc\XmlAttributes.uex' path='docs/doc[@for="XmlAttributes.XmlArray"]/*' />
213         /// <devdoc>
214         ///    <para>[To be supplied.]</para>
215         /// </devdoc>
216         public XmlArrayAttribute XmlArray {
217             get { return xmlArray; }
218             set { xmlArray = value; }
219         }
220         
221         /// <include file='doc\XmlAttributes.uex' path='docs/doc[@for="XmlAttributes.XmlArrayItems"]/*' />
222         /// <devdoc>
223         ///    <para>[To be supplied.]</para>
224         /// </devdoc>
225         public XmlArrayItemAttributes XmlArrayItems {
226             get { return xmlArrayItems; }
227         }
228
229         /// <include file='doc\XmlAttributes.uex' path='docs/doc[@for="XmlAttributes.XmlDefaultValue"]/*' />
230         /// <devdoc>
231         ///    <para>[To be supplied.]</para>
232         /// </devdoc>
233         public object XmlDefaultValue {
234             get { return xmlDefaultValue; }
235             set { xmlDefaultValue = value; }
236         }
237
238         /// <include file='doc\XmlAttributes.uex' path='docs/doc[@for="XmlAttributes.XmlIgnore"]/*' />
239         /// <devdoc>
240         ///    <para>[To be supplied.]</para>
241         /// </devdoc>
242         public bool XmlIgnore {
243             get { return xmlIgnore; }
244             set { xmlIgnore = value; }
245         }
246
247         /// <include file='doc\XmlAttributes.uex' path='docs/doc[@for="XmlAttributes.XmlType"]/*' />
248         /// <devdoc>
249         ///    <para>[To be supplied.]</para>
250         /// </devdoc>
251         public XmlTypeAttribute XmlType {
252             get { return xmlType; }
253             set { xmlType = value; }
254         }
255
256         /// <include file='doc\XmlAttributes.uex' path='docs/doc[@for="XmlAttributes.XmlRoot"]/*' />
257         /// <devdoc>
258         ///    <para>[To be supplied.]</para>
259         /// </devdoc>
260         public XmlRootAttribute XmlRoot {
261             get { return xmlRoot; }
262             set { xmlRoot = value; }
263         }
264
265         /// <include file='doc\XmlAttributes.uex' path='docs/doc[@for="XmlAttributes.XmlAnyElement"]/*' />
266         /// <devdoc>
267         ///    <para>[To be supplied.]</para>
268         /// </devdoc>
269         public XmlAnyElementAttributes XmlAnyElements {
270             get { return xmlAnyElements; }
271         }
272
273         /// <include file='doc\XmlAttributes.uex' path='docs/doc[@for="XmlAttributes.XmlAnyAttribute"]/*' />
274         /// <devdoc>
275         ///    <para>[To be supplied.]</para>
276         /// </devdoc>
277         public XmlAnyAttributeAttribute XmlAnyAttribute {
278             get { return xmlAnyAttribute; }
279             set { xmlAnyAttribute = value; }
280         }
281
282         /// <include file='doc\XmlAttributes.uex' path='docs/doc[@for="XmlAttributes.XmlChoiceIdentifier"]/*' />
283         public XmlChoiceIdentifierAttribute XmlChoiceIdentifier {
284             get { return xmlChoiceIdentifier; }
285         }
286
287         /// <include file='doc\XmlAttributes.uex' path='docs/doc[@for="XmlAttributes.Xmlns"]/*' />
288         /// <devdoc>
289         ///    <para>[To be supplied.]</para>
290         /// </devdoc>
291         public bool Xmlns {
292             get { return xmlns; }
293             set { xmlns = value; }
294         }
295
296     }
297 }