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