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