2008-12-08 Atsushi Enomoto <atsushi@ximian.com>
[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                 internal override void SetParent (XmlSchemaObject parent)
89                 {
90                         base.SetParent (parent);
91                         if (Particle != null)
92                                 Particle.SetParent (this);
93                         if (AnyAttribute != null)
94                                 AnyAttribute.SetParent (this);
95                         foreach (XmlSchemaObject obj in Attributes)
96                                 obj.SetParent (this);
97                 }
98
99                 /// <remarks>
100                 /// </remarks>
101                 internal override int Compile(ValidationEventHandler h, XmlSchema schema)
102                 {
103                         // If this is already compiled this time, simply skip.
104                         if (CompilationId == schema.CompilationId)
105                                 return 0;
106
107                         if (this.isRedefinedComponent) {
108                                 if (Annotation != null)
109                                         Annotation.isRedefinedComponent = true;
110                                 if (AnyAttribute != null)
111                                         AnyAttribute.isRedefinedComponent  = true;
112                                 foreach (XmlSchemaObject obj in Attributes)
113                                         obj.isRedefinedComponent  = true;
114                                 if (Particle != null)
115                                         Particle.isRedefinedComponent  = true;
116                         }
117
118                         if(BaseTypeName == null || BaseTypeName.IsEmpty)
119                         {
120                                 error(h, "base must be present, as a QName");
121                         }
122                         else if(!XmlSchemaUtil.CheckQName(BaseTypeName))
123                                 error(h,"BaseTypeName is not a valid XmlQualifiedName");
124                         
125                         if(this.AnyAttribute != null)
126                         {
127                                 errorCount += AnyAttribute.Compile(h, schema);
128                         }
129
130                         foreach(XmlSchemaObject obj in Attributes)
131                         {
132                                 if(obj is XmlSchemaAttribute)
133                                 {
134                                         XmlSchemaAttribute attr = (XmlSchemaAttribute) obj;
135                                         errorCount += attr.Compile(h, schema);
136                                 }
137                                 else if(obj is XmlSchemaAttributeGroupRef)
138                                 {
139                                         XmlSchemaAttributeGroupRef atgrp = (XmlSchemaAttributeGroupRef) obj;
140                                         errorCount += atgrp.Compile(h, schema);
141                                 }
142                                 else
143                                         error(h,obj.GetType() +" is not valid in this place::ComplexConetnetExtension");
144                         }
145                         
146                         if(Particle != null)
147                         {
148                                 if(Particle is XmlSchemaGroupRef)
149                                 {
150                                         errorCount += ((XmlSchemaGroupRef)Particle).Compile(h, schema);
151                                 }
152                                 else if(Particle is XmlSchemaAll)
153                                 {
154                                         errorCount += ((XmlSchemaAll)Particle).Compile(h, schema);
155                                 }
156                                 else if(Particle is XmlSchemaChoice)
157                                 {
158                                         errorCount += ((XmlSchemaChoice)Particle).Compile(h, schema);
159                                 }
160                                 else if(Particle is XmlSchemaSequence)
161                                 {
162                                         errorCount += ((XmlSchemaSequence)Particle).Compile(h, schema);
163                                 }
164                                 else
165                                         error (h, "Particle of a restriction is limited only to group, sequence, choice and all.");
166                         }
167                         
168                         XmlSchemaUtil.CompileID(Id,this, schema.IDCollection,h);
169
170                         this.CompilationId = schema.CompilationId;
171                         return errorCount;
172                 }
173                 
174                 internal override XmlQualifiedName GetBaseTypeName ()
175                 {
176                         return baseTypeName;
177                 }
178
179                 internal override XmlSchemaParticle GetParticle ()
180                 {
181                         return particle;
182                 }
183
184                 internal override int Validate(ValidationEventHandler h, XmlSchema schema)
185                 {
186                         if (IsValidated (schema.ValidationId))
187                                 return errorCount;
188
189                         if (AnyAttribute != null)
190                                 errorCount += AnyAttribute.Validate (h, schema);
191                         foreach (XmlSchemaObject attrObj in Attributes)
192                                 errorCount += attrObj.Validate (h, schema);
193                         if (Particle != null)
194                                 errorCount += Particle.Validate (h, schema);
195
196                         ValidationId = schema.ValidationId;
197                         return errorCount;
198                 }
199                 //<extension
200                 //  base = QName
201                 //  id = ID
202                 //  {any attributes with non-schema namespace . . .}>
203                 //  Content: (annotation?, ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?)))
204                 //</extension>
205                 internal static XmlSchemaComplexContentExtension Read(XmlSchemaReader reader, ValidationEventHandler h)
206                 {
207                         XmlSchemaComplexContentExtension extension = new XmlSchemaComplexContentExtension();
208                         reader.MoveToElement();
209
210                         if(reader.NamespaceURI != XmlSchema.Namespace || reader.LocalName != xmlname)
211                         {
212                                 error(h,"Should not happen :1: XmlSchemaComplexContentExtension.Read, name="+reader.Name,null);
213                                 reader.Skip();
214                                 return null;
215                         }
216
217                         extension.LineNumber = reader.LineNumber;
218                         extension.LinePosition = reader.LinePosition;
219                         extension.SourceUri = reader.BaseURI;
220
221                         while(reader.MoveToNextAttribute())
222                         {
223                                 if(reader.Name == "base")
224                                 {
225                                         Exception innerex;
226                                         extension.baseTypeName = XmlSchemaUtil.ReadQNameAttribute(reader,out innerex);
227                                         if(innerex != null)
228                                                 error(h, reader.Value + " is not a valid value for base attribute",innerex);
229                                 }
230                                 else if(reader.Name == "id")
231                                 {
232                                         extension.Id = reader.Value;
233                                 }
234                                 else if((reader.NamespaceURI == "" && reader.Name != "xmlns") || reader.NamespaceURI == XmlSchema.Namespace)
235                                 {
236                                         error(h,reader.Name + " is not a valid attribute for extension",null);
237                                 }
238                                 else
239                                 {
240                                         XmlSchemaUtil.ReadUnhandledAttribute(reader,extension);
241                                 }
242                         }
243                         
244                         reader.MoveToElement();
245                         if(reader.IsEmptyElement)
246                                 return extension;
247                         //Content: 1. annotation?, 
248                         //                      (2.(group | all | choice | sequence)?, (3.(attribute | attributeGroup)*, 4.anyAttribute?)))
249                         int level = 1;
250                         while(reader.ReadNextElement())
251                         {
252                                 if(reader.NodeType == XmlNodeType.EndElement)
253                                 {
254                                         if(reader.LocalName != xmlname)
255                                                 error(h,"Should not happen :2: XmlSchemaComplexContentExtension.Read, name="+reader.Name,null);
256                                         break;
257                                 }
258                                 if(level <= 1 && reader.LocalName == "annotation")
259                                 {
260                                         level = 2; //Only one annotation
261                                         XmlSchemaAnnotation annotation = XmlSchemaAnnotation.Read(reader,h);
262                                         if(annotation != null)
263                                                 extension.Annotation = annotation;
264                                         continue;
265                                 }
266                                 if(level <= 2)
267                                 {
268                                         if(reader.LocalName == "group")
269                                         {
270                                                 level = 3;
271                                                 XmlSchemaGroupRef group = XmlSchemaGroupRef.Read(reader,h);
272                                                 if(group != null)
273                                                         extension.particle = group;
274                                                 continue;
275                                         }
276                                         if(reader.LocalName == "all")
277                                         {
278                                                 level = 3;
279                                                 XmlSchemaAll all = XmlSchemaAll.Read(reader,h);
280                                                 if(all != null)
281                                                         extension.particle = all;
282                                                 continue;
283                                         }
284                                         if(reader.LocalName == "choice")
285                                         {
286                                                 level = 3;
287                                                 XmlSchemaChoice choice = XmlSchemaChoice.Read(reader,h);
288                                                 if(choice != null)
289                                                         extension.particle = choice;
290                                                 continue;
291                                         }
292                                         if(reader.LocalName == "sequence")
293                                         {
294                                                 level = 3;
295                                                 XmlSchemaSequence sequence = XmlSchemaSequence.Read(reader,h);
296                                                 if(sequence != null)
297                                                         extension.particle = sequence;
298                                                 continue;
299                                         }
300                                 }
301                                 if(level <= 3)
302                                 {
303                                         if(reader.LocalName == "attribute")
304                                         {
305                                                 level = 3;
306                                                 XmlSchemaAttribute attr = XmlSchemaAttribute.Read(reader,h);
307                                                 if(attr != null)
308                                                         extension.Attributes.Add(attr);
309                                                 continue;
310                                         }
311                                         if(reader.LocalName == "attributeGroup")
312                                         {
313                                                 level = 3;
314                                                 XmlSchemaAttributeGroupRef attr = XmlSchemaAttributeGroupRef.Read(reader,h);
315                                                 if(attr != null)
316                                                         extension.attributes.Add(attr);
317                                                 continue;
318                                         }
319                                 }
320                                 if(level <= 4 && reader.LocalName == "anyAttribute")
321                                 {
322                                         level = 5;
323                                         XmlSchemaAnyAttribute anyattr = XmlSchemaAnyAttribute.Read(reader,h);
324                                         if(anyattr != null)
325                                                 extension.AnyAttribute = anyattr;
326                                         continue;
327                                 }
328                                 reader.RaiseInvalidElementError();
329                         }
330                         return extension;
331                 }
332         }
333 }