2004-05-06 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / System.XML / System.Xml.Schema / XmlSchemaSimpleContentRestriction.cs
1 // Author: Dwivedi, Ajay kumar\r
2 //            Adwiv@Yahoo.com\r
3 using System;\r
4 using System.Xml;\r
5 using System.Xml.Serialization;\r
6 \r
7 namespace System.Xml.Schema\r
8 {\r
9         /// <summary>\r
10         /// Summary description for XmlSchemaSimpleContentRestriction.\r
11         /// </summary>\r
12         public class XmlSchemaSimpleContentRestriction : XmlSchemaContent\r
13         {\r
14                 \r
15                 private XmlSchemaAnyAttribute any;\r
16                 private XmlSchemaObjectCollection attributes;\r
17                 private XmlSchemaSimpleType baseType;\r
18                 private XmlQualifiedName baseTypeName;\r
19                 private XmlSchemaObjectCollection facets;\r
20                 const string xmlname = "restriction";\r
21 \r
22                 public XmlSchemaSimpleContentRestriction()\r
23                 {\r
24                         baseTypeName = XmlQualifiedName.Empty;\r
25                         attributes       = new XmlSchemaObjectCollection();\r
26                         facets           = new XmlSchemaObjectCollection();\r
27                 }\r
28 \r
29                 [System.Xml.Serialization.XmlAttribute("base")]\r
30                 public XmlQualifiedName BaseTypeName \r
31                 {\r
32                         get{ return  baseTypeName; }\r
33                         set{ baseTypeName = value; }\r
34                 }\r
35 \r
36                 [XmlElement("simpleType",Namespace=XmlSchema.Namespace)]\r
37                 public XmlSchemaSimpleType BaseType \r
38                 { \r
39                         get{ return  baseType; } \r
40                         set{ baseType = value; } \r
41                 }\r
42                 \r
43                 [XmlElement("minExclusive",typeof(XmlSchemaMinExclusiveFacet),Namespace=XmlSchema.Namespace)]\r
44                 [XmlElement("minInclusive",typeof(XmlSchemaMinInclusiveFacet),Namespace=XmlSchema.Namespace)] \r
45                 [XmlElement("maxExclusive",typeof(XmlSchemaMaxExclusiveFacet),Namespace=XmlSchema.Namespace)]\r
46                 [XmlElement("maxInclusive",typeof(XmlSchemaMaxInclusiveFacet),Namespace=XmlSchema.Namespace)]\r
47                 [XmlElement("totalDigits",typeof(XmlSchemaTotalDigitsFacet),Namespace=XmlSchema.Namespace)]\r
48                 [XmlElement("fractionDigits",typeof(XmlSchemaFractionDigitsFacet),Namespace=XmlSchema.Namespace)]\r
49                 [XmlElement("length",typeof(XmlSchemaLengthFacet),Namespace=XmlSchema.Namespace)]\r
50                 [XmlElement("minLength",typeof(XmlSchemaMinLengthFacet),Namespace=XmlSchema.Namespace)]\r
51                 [XmlElement("maxLength",typeof(XmlSchemaMaxLengthFacet),Namespace=XmlSchema.Namespace)]\r
52                 [XmlElement("enumeration",typeof(XmlSchemaEnumerationFacet),Namespace=XmlSchema.Namespace)]\r
53                 [XmlElement("whiteSpace",typeof(XmlSchemaWhiteSpaceFacet),Namespace=XmlSchema.Namespace)]\r
54                 [XmlElement("pattern",typeof(XmlSchemaPatternFacet),Namespace=XmlSchema.Namespace)]\r
55                 public XmlSchemaObjectCollection Facets \r
56                 { \r
57                         get{ return facets; } \r
58                 }\r
59 \r
60                 [XmlElement("attribute",typeof(XmlSchemaAttribute),Namespace=XmlSchema.Namespace)]\r
61                 [XmlElement("attributeGroup",typeof(XmlSchemaAttributeGroupRef),Namespace=XmlSchema.Namespace)]\r
62                 public XmlSchemaObjectCollection Attributes \r
63                 {\r
64                         get{ return attributes; }\r
65                 }\r
66 \r
67                 [XmlElement("anyAttribute",Namespace=XmlSchema.Namespace)]\r
68                 public XmlSchemaAnyAttribute AnyAttribute \r
69                 {\r
70                         get{ return  any; }\r
71                         set{ any = value; }\r
72                 }\r
73                 \r
74                 // internal properties\r
75                 internal override bool IsExtension {\r
76                         get { return false; }\r
77                 }\r
78 \r
79                 ///<remarks>\r
80                 /// 1. Base must be present and a QName\r
81                 ///</remarks>\r
82                 internal override int Compile(ValidationEventHandler h, XmlSchema schema)\r
83                 {\r
84                         // If this is already compiled this time, simply skip.\r
85                         if (this.IsComplied (schema.CompilationId))\r
86                                 return 0;\r
87 \r
88                         if (this.isRedefinedComponent) {\r
89                                 if (Annotation != null)\r
90                                         Annotation.isRedefinedComponent = true;\r
91                                 if (AnyAttribute != null)\r
92                                         AnyAttribute.isRedefinedComponent = true;\r
93                                 foreach (XmlSchemaObject obj in Attributes)\r
94                                         obj.isRedefinedComponent = true;\r
95                         }\r
96 \r
97                         if(BaseTypeName == null || BaseTypeName.IsEmpty)\r
98                         {\r
99                                 error(h, "base must be present, as a QName");\r
100                         }\r
101                         else if(!XmlSchemaUtil.CheckQName(BaseTypeName))\r
102                                 error(h,"BaseTypeName must be a QName");\r
103 \r
104                         if(BaseType != null)\r
105                         {\r
106                                 errorCount += BaseType.Compile(h,schema);\r
107                         }\r
108 \r
109                         if(this.AnyAttribute != null)\r
110                         {\r
111                                 errorCount += AnyAttribute.Compile(h,schema);\r
112                         }\r
113 \r
114                         foreach(XmlSchemaObject obj in Attributes)\r
115                         {\r
116                                 if(obj is XmlSchemaAttribute)\r
117                                 {\r
118                                         XmlSchemaAttribute attr = (XmlSchemaAttribute) obj;\r
119                                         errorCount += attr.Compile(h,schema);\r
120                                 }\r
121                                 else if(obj is XmlSchemaAttributeGroupRef)\r
122                                 {\r
123                                         XmlSchemaAttributeGroupRef atgrp = (XmlSchemaAttributeGroupRef) obj;\r
124                                         errorCount += atgrp.Compile(h,schema);\r
125                                 }\r
126                                 else\r
127                                         error(h,obj.GetType() +" is not valid in this place::SimpleContentRestriction");\r
128                         }\r
129                         \r
130                         //TODO: Compile Facets: Looks like they are a part of datatypes. So we'll do them with the datatypes\r
131 \r
132                         \r
133                         XmlSchemaUtil.CompileID(Id,this,schema.IDCollection,h);\r
134                         this.CompilationId = schema.CompilationId;\r
135                         return errorCount;\r
136                 }\r
137                 \r
138                 internal override XmlQualifiedName GetBaseTypeName ()\r
139                 {\r
140                         return baseTypeName;\r
141                 }\r
142 \r
143                 internal override XmlSchemaParticle GetParticle ()\r
144                 {\r
145                         return null;\r
146                 }\r
147 \r
148                 internal override int Validate(ValidationEventHandler h, XmlSchema schema)\r
149                 {\r
150                         if (IsValidated (schema.ValidationId))\r
151                                 return errorCount;\r
152 \r
153                         if (baseType != null) {\r
154                                 baseType.Validate (h, schema);\r
155                                 actualBaseSchemaType = baseType;\r
156                         }\r
157                         else if (baseTypeName != XmlQualifiedName.Empty) {\r
158                                 XmlSchemaType st = schema.SchemaTypes [baseTypeName] as XmlSchemaType;\r
159                                 if (st != null) {\r
160                                         st.Validate (h, schema);\r
161                                         actualBaseSchemaType = st;\r
162                                 } else if (baseTypeName == XmlSchemaComplexType.AnyTypeName) {\r
163                                         actualBaseSchemaType = XmlSchemaComplexType.AnyType;
164                                 } else if (XmlSchemaUtil.IsBuiltInDatatypeName (baseTypeName)) {\r
165                                         actualBaseSchemaType = XmlSchemaDatatype.FromName (baseTypeName);\r
166                                         if (actualBaseSchemaType == null)\r
167                                                 error (h, "Invalid schema datatype name is specified.");\r
168                                 }\r
169                                 // otherwise, it might be missing sub components.\r
170                                 else if (!schema.IsNamespaceAbsent (baseTypeName.Namespace))\r
171                                         error (h, "Referenced base schema type " + baseTypeName + " was not found in the corresponding schema.");\r
172                         }\r
173 \r
174                         ValidationId = schema.ValidationId;\r
175                         return errorCount;\r
176                 }\r
177 \r
178                 //<restriction \r
179                 //base = QName \r
180                 //id = ID \r
181                 //{any attributes with non-schema namespace . . .}>\r
182                 //Content: (annotation?, (simpleType?, (minExclusive | minInclusive | maxExclusive | maxInclusive | totalDigits | fractionDigits | length | minLength | maxLength | enumeration | whiteSpace | pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))\r
183                 //</restriction>\r
184                 internal static XmlSchemaSimpleContentRestriction Read(XmlSchemaReader reader, ValidationEventHandler h)\r
185                 {\r
186                         XmlSchemaSimpleContentRestriction restriction = new XmlSchemaSimpleContentRestriction();\r
187                         reader.MoveToElement();\r
188 \r
189                         if(reader.NamespaceURI != XmlSchema.Namespace || reader.LocalName != xmlname)\r
190                         {\r
191                                 error(h,"Should not happen :1: XmlSchemaComplexContentRestriction.Read, name="+reader.Name,null);\r
192                                 reader.SkipToEnd();\r
193                                 return null;\r
194                         }\r
195 \r
196                         restriction.LineNumber = reader.LineNumber;\r
197                         restriction.LinePosition = reader.LinePosition;\r
198                         restriction.SourceUri = reader.BaseURI;\r
199 \r
200                         while(reader.MoveToNextAttribute())\r
201                         {\r
202                                 if(reader.Name == "base")\r
203                                 {\r
204                                         Exception innerex;\r
205                                         restriction.baseTypeName = XmlSchemaUtil.ReadQNameAttribute(reader,out innerex);\r
206                                         if(innerex != null)\r
207                                                 error(h, reader.Value + " is not a valid value for base attribute",innerex);\r
208                                 }\r
209                                 else if(reader.Name == "id")\r
210                                 {\r
211                                         restriction.Id = reader.Value;\r
212                                 }\r
213                                 else if((reader.NamespaceURI == "" && reader.Name != "xmlns") || reader.NamespaceURI == XmlSchema.Namespace)\r
214                                 {\r
215                                         error(h,reader.Name + " is not a valid attribute for restriction",null);\r
216                                 }\r
217                                 else\r
218                                 {\r
219                                         XmlSchemaUtil.ReadUnhandledAttribute(reader,restriction);\r
220                                 }\r
221                         }\r
222                         \r
223                         reader.MoveToElement();\r
224                         if(reader.IsEmptyElement)\r
225                                 return restriction;\r
226                         \r
227                         //Content:  1.annotation?, \r
228                         //                  2.simpleType?, \r
229                         //                      3.(minExclusive |...| enumeration | whiteSpace | pattern)*, \r
230                         //                      4.(attribute | attributeGroup)*, \r
231                         //                      5.anyAttribute?\r
232                         int level = 1;\r
233                         while(reader.ReadNextElement())\r
234                         {\r
235                                 if(reader.NodeType == XmlNodeType.EndElement)\r
236                                 {\r
237                                         if(reader.LocalName != xmlname)\r
238                                                 error(h,"Should not happen :2: XmlSchemaSimpleContentRestriction.Read, name="+reader.Name,null);\r
239                                         break;\r
240                                 }\r
241                                 if(level <= 1 && reader.LocalName == "annotation")\r
242                                 {\r
243                                         level = 2; //Only one annotation\r
244                                         XmlSchemaAnnotation annotation = XmlSchemaAnnotation.Read(reader,h);\r
245                                         if(annotation != null)\r
246                                                 restriction.Annotation = annotation;\r
247                                         continue;\r
248                                 }\r
249                                 if(level <=2 && reader.LocalName == "simpleType")\r
250                                 {\r
251                                         level = 3;\r
252                                         XmlSchemaSimpleType stype = XmlSchemaSimpleType.Read(reader,h);\r
253                                         if(stype != null)\r
254                                                 restriction.baseType = stype;\r
255                                         continue;\r
256                                 }\r
257                                 if(level <= 3)\r
258                                 {\r
259                                         if(reader.LocalName == "minExclusive")\r
260                                         {\r
261                                                 level = 3;\r
262                                                 XmlSchemaMinExclusiveFacet minex = XmlSchemaMinExclusiveFacet.Read(reader,h);\r
263                                                 if(minex != null)\r
264                                                         restriction.facets.Add(minex);\r
265                                                 continue;\r
266                                         }\r
267                                         else if(reader.LocalName == "minInclusive")\r
268                                         {\r
269                                                 level = 3;\r
270                                                 XmlSchemaMinInclusiveFacet mini = XmlSchemaMinInclusiveFacet.Read(reader,h);\r
271                                                 if(mini != null)\r
272                                                         restriction.facets.Add(mini);\r
273                                                 continue;\r
274                                         }\r
275                                         else if(reader.LocalName == "maxExclusive")\r
276                                         {\r
277                                                 level = 3;\r
278                                                 XmlSchemaMaxExclusiveFacet maxex = XmlSchemaMaxExclusiveFacet.Read(reader,h);\r
279                                                 if(maxex != null)\r
280                                                         restriction.facets.Add(maxex);\r
281                                                 continue;\r
282                                         }\r
283                                         else if(reader.LocalName == "maxInclusive")\r
284                                         {\r
285                                                 level = 3;\r
286                                                 XmlSchemaMaxInclusiveFacet maxi = XmlSchemaMaxInclusiveFacet.Read(reader,h);\r
287                                                 if(maxi != null)\r
288                                                         restriction.facets.Add(maxi);\r
289                                                 continue;\r
290                                         }\r
291                                         else if(reader.LocalName == "totalDigits")\r
292                                         {\r
293                                                 level = 3;\r
294                                                 XmlSchemaTotalDigitsFacet total = XmlSchemaTotalDigitsFacet.Read(reader,h);\r
295                                                 if(total != null)\r
296                                                         restriction.facets.Add(total);\r
297                                                 continue;\r
298                                         }\r
299                                         else if(reader.LocalName == "fractionDigits")\r
300                                         {\r
301                                                 level = 3;\r
302                                                 XmlSchemaFractionDigitsFacet fraction = XmlSchemaFractionDigitsFacet.Read(reader,h);\r
303                                                 if(fraction != null)\r
304                                                         restriction.facets.Add(fraction);\r
305                                                 continue;\r
306                                         }\r
307                                         else if(reader.LocalName == "length")\r
308                                         {\r
309                                                 level = 3;\r
310                                                 XmlSchemaLengthFacet length = XmlSchemaLengthFacet.Read(reader,h);\r
311                                                 if(length != null)\r
312                                                         restriction.facets.Add(length);\r
313                                                 continue;\r
314                                         }\r
315                                         else if(reader.LocalName == "minLength")\r
316                                         {\r
317                                                 level = 3;\r
318                                                 XmlSchemaMinLengthFacet minlen = XmlSchemaMinLengthFacet.Read(reader,h);\r
319                                                 if(minlen != null)\r
320                                                         restriction.facets.Add(minlen);\r
321                                                 continue;\r
322                                         }\r
323                                         else if(reader.LocalName == "maxLength")\r
324                                         {\r
325                                                 level = 3;\r
326                                                 XmlSchemaMaxLengthFacet maxlen = XmlSchemaMaxLengthFacet.Read(reader,h);\r
327                                                 if(maxlen != null)\r
328                                                         restriction.facets.Add(maxlen);\r
329                                                 continue;\r
330                                         }\r
331                                         else if(reader.LocalName == "enumeration")\r
332                                         {\r
333                                                 level = 3;\r
334                                                 XmlSchemaEnumerationFacet enumeration = XmlSchemaEnumerationFacet.Read(reader,h);\r
335                                                 if(enumeration != null)\r
336                                                         restriction.facets.Add(enumeration);\r
337                                                 continue;\r
338                                         }\r
339                                         else if(reader.LocalName == "whiteSpace")\r
340                                         {\r
341                                                 level = 3;\r
342                                                 XmlSchemaWhiteSpaceFacet ws = XmlSchemaWhiteSpaceFacet.Read(reader,h);\r
343                                                 if(ws != null)\r
344                                                         restriction.facets.Add(ws);\r
345                                                 continue;\r
346                                         }\r
347                                         else if(reader.LocalName == "pattern")\r
348                                         {\r
349                                                 level = 3;\r
350                                                 XmlSchemaPatternFacet pattern = XmlSchemaPatternFacet.Read(reader,h);\r
351                                                 if(pattern != null)\r
352                                                         restriction.facets.Add(pattern);\r
353                                                 continue;\r
354                                         }\r
355                                 }\r
356                                 if(level <= 4)\r
357                                 {\r
358                                         if(reader.LocalName == "attribute")\r
359                                         {\r
360                                                 level = 4;\r
361                                                 XmlSchemaAttribute attr = XmlSchemaAttribute.Read(reader,h);\r
362                                                 if(attr != null)\r
363                                                         restriction.Attributes.Add(attr);\r
364                                                 continue;\r
365                                         }\r
366                                         if(reader.LocalName == "attributeGroup")\r
367                                         {\r
368                                                 level = 4;\r
369                                                 XmlSchemaAttributeGroupRef attr = XmlSchemaAttributeGroupRef.Read(reader,h);\r
370                                                 if(attr != null)\r
371                                                         restriction.attributes.Add(attr);\r
372                                                 continue;\r
373                                         }\r
374                                 }\r
375                                 if(level <= 5 && reader.LocalName == "anyAttribute")\r
376                                 {\r
377                                         level = 6;\r
378                                         XmlSchemaAnyAttribute anyattr = XmlSchemaAnyAttribute.Read(reader,h);\r
379                                         if(anyattr != null)\r
380                                                 restriction.AnyAttribute = anyattr;\r
381                                         continue;\r
382                                 }\r
383                                 reader.RaiseInvalidElementError();\r
384                         }\r
385                         return restriction;\r
386                 }\r
387 \r
388         }\r
389 }\r