Handle more type conversion.
[mono.git] / mcs / class / System.XML / System.Xml.Schema / XmlSchemaAny.cs
1 //
2 // System.Xml.Schema.XmlSchemaAny.cs
3 //
4 // Author:
5 //      Dwivedi, Ajay kumar  Adwiv@Yahoo.com
6 //      Atsushi Enomoto  ginga@kit.hi-ho.ne.jp
7 //
8
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 // 
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 // 
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29 using System;
30 using System.Collections;
31 using System.Collections.Specialized;
32 using System.Xml;
33 using System.Xml.Serialization;
34 using System.ComponentModel;
35 using Mono.Xml.Schema;
36
37 namespace System.Xml.Schema
38 {
39         /// <summary>
40         /// Summary description for XmlSchemaAny.
41         /// </summary>
42         public class XmlSchemaAny : XmlSchemaParticle
43         {
44                 static XmlSchemaAny anyTypeContent;
45                 internal static XmlSchemaAny AnyTypeContent {
46                         get {
47                                 if (anyTypeContent == null) {
48                                         anyTypeContent = new XmlSchemaAny ();
49                                         anyTypeContent.MaxOccursString = "unbounded";
50                                         anyTypeContent.MinOccurs = 0;
51                                         anyTypeContent.CompileOccurence (null, null);
52                                         anyTypeContent.Namespace = "##any";
53                                         anyTypeContent.wildcard.HasValueAny = true;
54                                         anyTypeContent.wildcard.ResolvedNamespaces = new StringCollection ();
55                                         // It is not documented by W3C but it should be.
56                                         anyTypeContent.wildcard.ResolvedProcessing =
57                                                 anyTypeContent.ProcessContents = XmlSchemaContentProcessing.Lax;
58                                         anyTypeContent.wildcard.SkipCompile = true;
59                                 }
60                                 return anyTypeContent;
61                         }
62                 }
63
64                 private string nameSpace;
65                 private XmlSchemaContentProcessing processing;
66                 const string xmlname = "any";
67
68                 private XsdWildcard wildcard;
69
70                 public XmlSchemaAny()
71                 {
72                         wildcard = new XsdWildcard (this);
73                 }
74
75                 [System.Xml.Serialization.XmlAttribute("namespace")]
76                 public string Namespace 
77                 {
78                         get{ return  nameSpace; } 
79                         set{ nameSpace = value; }
80                 }
81                 
82                 [DefaultValue(XmlSchemaContentProcessing.None)]
83                 [System.Xml.Serialization.XmlAttribute("processContents")]
84                 public XmlSchemaContentProcessing ProcessContents
85                 { 
86                         get{ return processing; } 
87                         set{ processing = value; }
88                 }
89
90                 // Post Compilation Schema Infoset
91                 internal bool HasValueAny {
92                         get { return wildcard.HasValueAny; }
93                 }
94
95                 internal bool HasValueLocal {
96                         get { return wildcard.HasValueLocal; }
97                 }
98
99                 internal bool HasValueOther {
100                         get { return wildcard.HasValueOther; }
101                 }
102
103                 internal bool HasValueTargetNamespace {
104                         get { return wildcard.HasValueTargetNamespace; }
105                 }
106
107                 internal StringCollection ResolvedNamespaces {
108                         get { return wildcard.ResolvedNamespaces; }
109                 }
110
111                 internal XmlSchemaContentProcessing ResolvedProcessContents 
112                 { 
113                         get{ return wildcard.ResolvedProcessing; } 
114                 }
115
116                 internal string TargetNamespace
117                 {
118                         get { return wildcard.TargetNamespace; }
119                 }
120
121                 /// <remarks>
122                 /// 1. id must be of type ID
123                 /// 2. namespace can have one of the following values:
124                 ///             a) ##any or ##other
125                 ///             b) list of anyURI and ##targetNamespace and ##local
126                 /// </remarks>
127                 internal override int Compile(ValidationEventHandler h, XmlSchema schema)
128                 {
129                         // If this is already compiled this time, simply skip.
130                         if (CompilationId == schema.CompilationId)
131                                 return 0;
132
133                         errorCount = 0;
134
135                         XmlSchemaUtil.CompileID(Id,this, schema.IDCollection,h);
136                         wildcard.TargetNamespace = AncestorSchema.TargetNamespace;
137                         if (wildcard.TargetNamespace == null)
138                                 wildcard.TargetNamespace = "";
139                         CompileOccurence (h, schema);
140
141                         wildcard.Compile (Namespace, h, schema);
142
143                         if (processing == XmlSchemaContentProcessing.None)
144                                 wildcard.ResolvedProcessing = XmlSchemaContentProcessing.Strict;
145                         else
146                                 wildcard.ResolvedProcessing = processing;
147
148                         this.CompilationId = schema.CompilationId;
149                         return errorCount;
150                 }
151
152                 internal override XmlSchemaParticle GetOptimizedParticle (bool isTop)
153                 {
154                         if (OptimizedParticle != null)
155                                 return OptimizedParticle;
156                         // Uncommenting this causes incorrect validation. 
157                         // It will prevent UPA e.g. msxsdtest/Particles/particlesJf006.xsd
158 //                      if (ValidatedMaxOccurs == 0) {
159 //                              OptimizedParticle = XmlSchemaParticle.Empty;
160 //                              return OptimizedParticle;
161 //                      }
162
163                         XmlSchemaAny any = new XmlSchemaAny ();
164                         CopyInfo (any);
165                         any.CompileOccurence (null, null);
166                         any.wildcard = this.wildcard;
167                         OptimizedParticle = any;
168
169                         // properties which never contribute to validation
170                         any.Namespace = Namespace;
171                         any.ProcessContents = ProcessContents;
172                         any.Annotation = Annotation;
173                         any.UnhandledAttributes = UnhandledAttributes;
174
175                         return OptimizedParticle;
176                 }
177                 
178                 internal override int Validate(ValidationEventHandler h, XmlSchema schema)
179                 {
180                         return errorCount;
181                 }
182
183                 internal override bool ParticleEquals (XmlSchemaParticle other)
184                 {
185                         XmlSchemaAny any = other as XmlSchemaAny;
186                         if (any == null)
187                                 return false;
188                         if (this.HasValueAny != any.HasValueAny ||
189                                 this.HasValueLocal != any.HasValueLocal ||
190                                 this.HasValueOther != any.HasValueOther ||
191                                 this.HasValueTargetNamespace != any.HasValueTargetNamespace ||
192                                 this.ResolvedProcessContents != any.ResolvedProcessContents ||
193                                 this.ValidatedMaxOccurs != any.ValidatedMaxOccurs ||
194                                 this.ValidatedMinOccurs != any.ValidatedMinOccurs ||
195                                 this.ResolvedNamespaces.Count != any.ResolvedNamespaces.Count)
196                                 return false;
197                         for (int i = 0; i < ResolvedNamespaces.Count; i++)
198                                 if (ResolvedNamespaces [i] != any.ResolvedNamespaces [i])
199                                         return false;
200                         return true;
201                 }
202
203
204                 // 3.8.6. Attribute Wildcard Intersection
205                 // Only try to examine if their intersection is expressible, and
206                 // returns if the result is empty.
207                 internal bool ExamineAttributeWildcardIntersection (XmlSchemaAny other,
208                         ValidationEventHandler h, XmlSchema schema)
209                 {
210                         return wildcard.ExamineAttributeWildcardIntersection (other, h, schema);
211                 }
212
213                 internal override bool ValidateDerivationByRestriction (XmlSchemaParticle baseParticle, 
214                         ValidationEventHandler h, XmlSchema schema, bool raiseError)
215                 {
216                         XmlSchemaAny baseAny = baseParticle as XmlSchemaAny;
217                         if (baseAny == null) {
218                                 if (raiseError)
219                                         error (h, "Invalid particle derivation by restriction was found.");
220                                 return false;
221                         }
222                         // 3.9.6 Particle Derivation OK (Any:Any - NSSubset)
223                         if (!ValidateOccurenceRangeOK (baseParticle, h, schema, raiseError))
224                                 return false;
225                         return wildcard.ValidateWildcardSubset (baseAny.wildcard, h, schema, raiseError);
226                 }
227
228
229                 internal override void CheckRecursion (int depth, ValidationEventHandler h, XmlSchema schema)
230                 {
231                         // do nothing
232                 }
233
234                 internal override void ValidateUniqueParticleAttribution (
235                         XmlSchemaObjectTable qnames, ArrayList nsNames,
236                         ValidationEventHandler h, XmlSchema schema)
237                 {
238                         // Wildcard Intersection check.
239                         foreach (XmlSchemaAny other in nsNames)
240                                 if (!ExamineAttributeWildcardIntersection (other, h, schema))
241                                         error (h, "Ambiguous -any- particle was found.");
242                         nsNames.Add (this);
243                 }
244
245                 internal override void ValidateUniqueTypeAttribution (XmlSchemaObjectTable labels,
246                         ValidationEventHandler h, XmlSchema schema)
247                 {
248                         // do nothing
249                 }
250
251                 // 3.10.4 Wildcard Allows Namespace Name. (In fact it is almost copy...)
252                 internal bool ValidateWildcardAllowsNamespaceName (string ns,
253                         ValidationEventHandler h, XmlSchema schema, bool raiseError)
254                 {
255                         return wildcard.ValidateWildcardAllowsNamespaceName (ns, h, schema, raiseError);
256                 }
257
258                 //<any
259                 //  id = ID
260                 //  maxOccurs =  (nonNegativeInteger | unbounded)  : 1
261                 //  minOccurs = nonNegativeInteger : 1
262                 //  namespace = ((##any | ##other) | List of (anyURI | (##targetNamespace | ##local)) )  : ##any
263                 //  processContents = (lax | skip | strict) : strict
264                 //  {any attributes with non-schema namespace . . .}>
265                 //  Content: (annotation?)
266                 //</any>
267                 internal static XmlSchemaAny Read(XmlSchemaReader reader, ValidationEventHandler h)
268                 {
269                         XmlSchemaAny any = new XmlSchemaAny();
270                         reader.MoveToElement();
271
272                         if(reader.NamespaceURI != XmlSchema.Namespace || reader.LocalName != xmlname)
273                         {
274                                 error(h,"Should not happen :1: XmlSchemaAny.Read, name="+reader.Name,null);
275                                 reader.SkipToEnd();
276                                 return null;
277                         }
278
279                         any.LineNumber = reader.LineNumber;
280                         any.LinePosition = reader.LinePosition;
281                         any.SourceUri = reader.BaseURI;
282
283                         while(reader.MoveToNextAttribute())
284                         {
285                                 if(reader.Name == "id")
286                                 {
287                                         any.Id = reader.Value;
288                                 }
289                                 else if(reader.Name == "maxOccurs")
290                                 {
291                                         try
292                                         {
293                                                 any.MaxOccursString = reader.Value;
294                                         }
295                                         catch(Exception e)
296                                         {
297                                                 error(h,reader.Value + " is an invalid value for maxOccurs",e);
298                                         }
299                                 }
300                                 else if(reader.Name == "minOccurs")
301                                 {
302                                         try
303                                         {
304                                                 any.MinOccursString = reader.Value;
305                                         }
306                                         catch(Exception e)
307                                         {
308                                                 error(h,reader.Value + " is an invalid value for minOccurs", e);
309                                         }
310                                 }
311                                 else if(reader.Name == "namespace")
312                                 {
313                                         any.nameSpace = reader.Value;
314                                 }
315                                 else if(reader.Name == "processContents")
316                                 {
317                                         Exception innerex;
318                                         any.processing = XmlSchemaUtil.ReadProcessingAttribute(reader,out innerex);
319                                         if(innerex != null)
320                                                 error(h, reader.Value + " is not a valid value for processContents",innerex);
321                                 }
322                                 else if((reader.NamespaceURI == "" && reader.Name != "xmlns") || reader.NamespaceURI == XmlSchema.Namespace)
323                                 {
324                                         error(h,reader.Name + " is not a valid attribute for any",null);
325                                 }
326                                 else
327                                 {
328                                         XmlSchemaUtil.ReadUnhandledAttribute(reader,any);
329                                 }
330                         }
331                         
332                         reader.MoveToElement();
333                         if(reader.IsEmptyElement)
334                                 return any;
335                         
336                         //  Content: (annotation?)
337                         int level = 1;
338                         while(reader.ReadNextElement())
339                         {
340                                 if(reader.NodeType == XmlNodeType.EndElement)
341                                 {
342                                         if(reader.LocalName != xmlname)
343                                                 error(h,"Should not happen :2: XmlSchemaAny.Read, name="+reader.Name,null);
344                                         break;
345                                 }
346                                 if(level <= 1 && reader.LocalName == "annotation")
347                                 {
348                                         level = 2;      //Only one annotation
349                                         XmlSchemaAnnotation annotation = XmlSchemaAnnotation.Read(reader,h);
350                                         if(annotation != null)
351                                                 any.Annotation = annotation;
352                                         continue;
353                                 }
354                                 reader.RaiseInvalidElementError();
355                         }                       
356                         return any;
357                 }
358         }
359 }