New test.
[mono.git] / mcs / class / System.XML / System.Xml.Schema / XmlSchemaComplexContentExtension.cs
1 //
2 // System.Xml.Schema.XmlSchemaComplexContentExtension.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.Xml;
31 using System.Xml.Serialization;
32
33 namespace System.Xml.Schema
34 {
35         /// <summary>
36         /// Summary description for XmlSchemaComplexContentExtension.
37         /// </summary>
38         public class XmlSchemaComplexContentExtension : XmlSchemaContent
39         {
40                 private XmlSchemaAnyAttribute any;
41                 private XmlSchemaObjectCollection attributes;
42                 private XmlQualifiedName baseTypeName;
43                 private XmlSchemaParticle particle;
44                 const string xmlname = "extension";
45
46                 public XmlSchemaComplexContentExtension()
47                 {
48                         attributes = new XmlSchemaObjectCollection();
49                         baseTypeName = XmlQualifiedName.Empty;
50                 }
51                 
52                 [System.Xml.Serialization.XmlAttribute("base")]
53                 public XmlQualifiedName BaseTypeName 
54                 {
55                         get{ return  baseTypeName; }
56                         set{ baseTypeName = value; }
57                 }
58
59                 [XmlElement("group",typeof(XmlSchemaGroupRef))]
60                 [XmlElement("all",typeof(XmlSchemaAll))]
61                 [XmlElement("choice",typeof(XmlSchemaChoice))]
62                 [XmlElement("sequence",typeof(XmlSchemaSequence))]
63                 public XmlSchemaParticle Particle
64                 {
65                         get{ return  particle; }
66                         set{ particle = value; }
67                 }
68
69                 [XmlElement("attribute",typeof(XmlSchemaAttribute))]
70                 [XmlElement("attributeGroup",typeof(XmlSchemaAttributeGroupRef))]
71                 public XmlSchemaObjectCollection Attributes 
72                 {
73                         get{ return attributes; }
74                 }
75
76                 [XmlElement("anyAttribute")]
77                 public XmlSchemaAnyAttribute AnyAttribute 
78                 {
79                         get{ return any; }
80                         set{ any = value;}
81                 }
82
83                 // internal properties
84                 internal override bool IsExtension {
85                         get { return true; }
86                 }
87
88                 /// <remarks>
89                 /// </remarks>
90                 internal override int Compile(ValidationEventHandler h, XmlSchema schema)
91                 {
92                         // If this is already compiled this time, simply skip.
93                         if (CompilationId == schema.CompilationId)
94                                 return 0;
95
96 #if NET_2_0
97                         if (Particle != null)
98                                 Particle.Parent = this;
99                         if (AnyAttribute != null)
100                                 AnyAttribute.Parent = this;
101                         foreach (XmlSchemaObject obj in Attributes)
102                                 obj.Parent = this;
103 #endif
104
105                         if (this.isRedefinedComponent) {
106                                 if (Annotation != null)
107                                         Annotation.isRedefinedComponent = true;
108                                 if (AnyAttribute != null)
109                                         AnyAttribute.isRedefinedComponent  = true;
110                                 foreach (XmlSchemaObject obj in Attributes)
111                                         obj.isRedefinedComponent  = true;
112                                 if (Particle != null)
113                                         Particle.isRedefinedComponent  = true;
114                         }
115
116                         if(BaseTypeName == null || BaseTypeName.IsEmpty)
117                         {
118                                 error(h, "base must be present, as a QName");
119                         }
120                         else if(!XmlSchemaUtil.CheckQName(BaseTypeName))
121                                 error(h,"BaseTypeName is not a valid XmlQualifiedName");
122                         
123                         if(this.AnyAttribute != null)
124                         {
125                                 errorCount += AnyAttribute.Compile(h, schema);
126                         }
127
128                         foreach(XmlSchemaObject obj in Attributes)
129                         {
130                                 if(obj is XmlSchemaAttribute)
131                                 {
132                                         XmlSchemaAttribute attr = (XmlSchemaAttribute) obj;
133                                         errorCount += attr.Compile(h, schema);
134                                 }
135                                 else if(obj is XmlSchemaAttributeGroupRef)
136                                 {
137                                         XmlSchemaAttributeGroupRef atgrp = (XmlSchemaAttributeGroupRef) obj;
138                                         errorCount += atgrp.Compile(h, schema);
139                                 }
140                                 else
141                                         error(h,obj.GetType() +" is not valid in this place::ComplexConetnetExtension");
142                         }
143                         
144                         if(Particle != null)
145                         {
146                                 if(Particle is XmlSchemaGroupRef)
147                                 {
148                                         errorCount += ((XmlSchemaGroupRef)Particle).Compile(h, schema);
149                                 }
150                                 else if(Particle is XmlSchemaAll)
151                                 {
152                                         errorCount += ((XmlSchemaAll)Particle).Compile(h, schema);
153                                 }
154                                 else if(Particle is XmlSchemaChoice)
155                                 {
156                                         errorCount += ((XmlSchemaChoice)Particle).Compile(h, schema);
157                                 }
158                                 else if(Particle is XmlSchemaSequence)
159                                 {
160                                         errorCount += ((XmlSchemaSequence)Particle).Compile(h, schema);
161                                 }
162                                 else
163                                         error (h, "Particle of a restriction is limited only to group, sequence, choice and all.");
164                         }
165                         
166                         XmlSchemaUtil.CompileID(Id,this, schema.IDCollection,h);
167
168                         this.CompilationId = schema.CompilationId;
169                         return errorCount;
170                 }
171                 
172                 internal override XmlQualifiedName GetBaseTypeName ()
173                 {
174                         return baseTypeName;
175                 }
176
177                 internal override XmlSchemaParticle GetParticle ()
178                 {
179                         return particle;
180                 }
181
182                 internal override int Validate(ValidationEventHandler h, XmlSchema schema)
183                 {
184                         if (IsValidated (schema.ValidationId))
185                                 return errorCount;
186
187                         if (AnyAttribute != null)
188                                 errorCount += AnyAttribute.Validate (h, schema);
189                         foreach (XmlSchemaObject attrObj in Attributes)
190                                 errorCount += attrObj.Validate (h, schema);
191                         if (Particle != null)
192                                 errorCount += Particle.Validate (h, schema);
193
194                         ValidationId = schema.ValidationId;
195                         return errorCount;
196                 }
197                 //<extension
198                 //  base = QName
199                 //  id = ID
200                 //  {any attributes with non-schema namespace . . .}>
201                 //  Content: (annotation?, ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?)))
202                 //</extension>
203                 internal static XmlSchemaComplexContentExtension Read(XmlSchemaReader reader, ValidationEventHandler h)
204                 {
205                         XmlSchemaComplexContentExtension extension = new XmlSchemaComplexContentExtension();
206                         reader.MoveToElement();
207
208                         if(reader.NamespaceURI != XmlSchema.Namespace || reader.LocalName != xmlname)
209                         {
210                                 error(h,"Should not happen :1: XmlSchemaComplexContentExtension.Read, name="+reader.Name,null);
211                                 reader.Skip();
212                                 return null;
213                         }
214
215                         extension.LineNumber = reader.LineNumber;
216                         extension.LinePosition = reader.LinePosition;
217                         extension.SourceUri = reader.BaseURI;
218
219                         while(reader.MoveToNextAttribute())
220                         {
221                                 if(reader.Name == "base")
222                                 {
223                                         Exception innerex;
224                                         extension.baseTypeName = XmlSchemaUtil.ReadQNameAttribute(reader,out innerex);
225                                         if(innerex != null)
226                                                 error(h, reader.Value + " is not a valid value for base attribute",innerex);
227                                 }
228                                 else if(reader.Name == "id")
229                                 {
230                                         extension.Id = reader.Value;
231                                 }
232                                 else if((reader.NamespaceURI == "" && reader.Name != "xmlns") || reader.NamespaceURI == XmlSchema.Namespace)
233                                 {
234                                         error(h,reader.Name + " is not a valid attribute for extension",null);
235                                 }
236                                 else
237                                 {
238                                         XmlSchemaUtil.ReadUnhandledAttribute(reader,extension);
239                                 }
240                         }
241                         
242                         reader.MoveToElement();
243                         if(reader.IsEmptyElement)
244                                 return extension;
245                         //Content: 1. annotation?, 
246                         //                      (2.(group | all | choice | sequence)?, (3.(attribute | attributeGroup)*, 4.anyAttribute?)))
247                         int level = 1;
248                         while(reader.ReadNextElement())
249                         {
250                                 if(reader.NodeType == XmlNodeType.EndElement)
251                                 {
252                                         if(reader.LocalName != xmlname)
253                                                 error(h,"Should not happen :2: XmlSchemaComplexContentExtension.Read, name="+reader.Name,null);
254                                         break;
255                                 }
256                                 if(level <= 1 && reader.LocalName == "annotation")
257                                 {
258                                         level = 2; //Only one annotation
259                                         XmlSchemaAnnotation annotation = XmlSchemaAnnotation.Read(reader,h);
260                                         if(annotation != null)
261                                                 extension.Annotation = annotation;
262                                         continue;
263                                 }
264                                 if(level <= 2)
265                                 {
266                                         if(reader.LocalName == "group")
267                                         {
268                                                 level = 3;
269                                                 XmlSchemaGroupRef group = XmlSchemaGroupRef.Read(reader,h);
270                                                 if(group != null)
271                                                         extension.particle = group;
272                                                 continue;
273                                         }
274                                         if(reader.LocalName == "all")
275                                         {
276                                                 level = 3;
277                                                 XmlSchemaAll all = XmlSchemaAll.Read(reader,h);
278                                                 if(all != null)
279                                                         extension.particle = all;
280                                                 continue;
281                                         }
282                                         if(reader.LocalName == "choice")
283                                         {
284                                                 level = 3;
285                                                 XmlSchemaChoice choice = XmlSchemaChoice.Read(reader,h);
286                                                 if(choice != null)
287                                                         extension.particle = choice;
288                                                 continue;
289                                         }
290                                         if(reader.LocalName == "sequence")
291                                         {
292                                                 level = 3;
293                                                 XmlSchemaSequence sequence = XmlSchemaSequence.Read(reader,h);
294                                                 if(sequence != null)
295                                                         extension.particle = sequence;
296                                                 continue;
297                                         }
298                                 }
299                                 if(level <= 3)
300                                 {
301                                         if(reader.LocalName == "attribute")
302                                         {
303                                                 level = 3;
304                                                 XmlSchemaAttribute attr = XmlSchemaAttribute.Read(reader,h);
305                                                 if(attr != null)
306                                                         extension.Attributes.Add(attr);
307                                                 continue;
308                                         }
309                                         if(reader.LocalName == "attributeGroup")
310                                         {
311                                                 level = 3;
312                                                 XmlSchemaAttributeGroupRef attr = XmlSchemaAttributeGroupRef.Read(reader,h);
313                                                 if(attr != null)
314                                                         extension.attributes.Add(attr);
315                                                 continue;
316                                         }
317                                 }
318                                 if(level <= 4 && reader.LocalName == "anyAttribute")
319                                 {
320                                         level = 5;
321                                         XmlSchemaAnyAttribute anyattr = XmlSchemaAnyAttribute.Read(reader,h);
322                                         if(anyattr != null)
323                                                 extension.AnyAttribute = anyattr;
324                                         continue;
325                                 }
326                                 reader.RaiseInvalidElementError();
327                         }
328                         return extension;
329                 }
330         }
331 }