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