svn path=/branches/mono-1-1-9/mcs/; revision=51216
[mono.git] / mcs / class / System.XML / System.Xml.Schema / XmlSchemaSimpleContentExtension.cs
1 //\r
2 // System.Xml.Schema.XmlSchemaSimpleContentExtension.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
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;\r
30 using System.Xml;\r
31 using System.Xml.Serialization;\r
32 \r
33 namespace System.Xml.Schema\r
34 {\r
35         /// <summary>\r
36         /// Summary description for XmlSchemaSimpleContentExtension.\r
37         /// </summary>\r
38         public class XmlSchemaSimpleContentExtension : XmlSchemaContent\r
39         {\r
40 \r
41                 private XmlSchemaAnyAttribute any;\r
42                 private XmlSchemaObjectCollection attributes;\r
43                 private XmlQualifiedName baseTypeName;\r
44                 const string xmlname = "extension";\r
45 \r
46                 public XmlSchemaSimpleContentExtension()\r
47                 {\r
48                         baseTypeName = XmlQualifiedName.Empty;\r
49                         attributes       = new XmlSchemaObjectCollection();\r
50                 }\r
51 \r
52                 [System.Xml.Serialization.XmlAttribute("base")]\r
53                 public XmlQualifiedName BaseTypeName \r
54                 {\r
55                         get{ return  baseTypeName; }\r
56                         set{ baseTypeName = value; }\r
57                 }\r
58 \r
59                 [XmlElement("attribute",typeof(XmlSchemaAttribute))]\r
60                 [XmlElement("attributeGroup",typeof(XmlSchemaAttributeGroupRef))]\r
61                 public XmlSchemaObjectCollection Attributes \r
62                 {\r
63                         get{ return attributes; }\r
64                 }\r
65 \r
66                 [XmlElement("anyAttribute")]\r
67                 public XmlSchemaAnyAttribute AnyAttribute \r
68                 {\r
69                         get{ return  any; }\r
70                         set{ any = value; }\r
71                 }\r
72 \r
73                 // internal properties\r
74                 internal override bool IsExtension {\r
75                         get { return true; }\r
76                 }\r
77 \r
78                 ///<remarks>\r
79                 /// 1. Base must be present and a QName\r
80                 ///</remarks>\r
81                 internal override int Compile(ValidationEventHandler h, XmlSchema schema)\r
82                 {\r
83                         // If this is already compiled this time, simply skip.\r
84                         if (this.IsComplied (schema.CompilationId))\r
85                                 return 0;\r
86 \r
87 #if NET_2_0\r
88                         if (AnyAttribute != null)\r
89                                 AnyAttribute.Parent = this;\r
90                         foreach (XmlSchemaObject obj in Attributes)\r
91                                 obj.Parent = this;\r
92 #endif\r
93 \r
94                         if (this.isRedefinedComponent) {\r
95                                 if (Annotation != null)\r
96                                         Annotation.isRedefinedComponent = true;\r
97                                 if (AnyAttribute != null)\r
98                                         AnyAttribute.isRedefinedComponent = true;\r
99                                 foreach (XmlSchemaObject obj in Attributes)\r
100                                         obj.isRedefinedComponent = true;\r
101                         }\r
102 \r
103                         if(BaseTypeName == null || BaseTypeName.IsEmpty)\r
104                         {\r
105                                 error(h, "base must be present, as a QName");\r
106                         }\r
107                         else if(!XmlSchemaUtil.CheckQName(BaseTypeName))\r
108                                 error(h,"BaseTypeName must be a QName");\r
109 \r
110                         if(this.AnyAttribute != null)\r
111                         {\r
112                                 errorCount += AnyAttribute.Compile(h,schema);\r
113                         }\r
114 \r
115                         foreach(XmlSchemaObject obj in Attributes)\r
116                         {\r
117                                 if(obj is XmlSchemaAttribute)\r
118                                 {\r
119                                         XmlSchemaAttribute attr = (XmlSchemaAttribute) obj;\r
120                                         errorCount += attr.Compile(h,schema);\r
121                                 }\r
122                                 else if(obj is XmlSchemaAttributeGroupRef)\r
123                                 {\r
124                                         XmlSchemaAttributeGroupRef atgrp = (XmlSchemaAttributeGroupRef) obj;\r
125                                         errorCount += atgrp.Compile(h,schema);\r
126                                 }\r
127                                 else\r
128                                         error(h,obj.GetType() +" is not valid in this place::SimpleConentExtension");\r
129                         }\r
130                         \r
131                         XmlSchemaUtil.CompileID(Id,this,schema.IDCollection,h);\r
132 \r
133                         this.CompilationId = schema.CompilationId;\r
134                         return errorCount;\r
135                 }\r
136                 \r
137                 internal override XmlQualifiedName GetBaseTypeName ()\r
138                 {\r
139                         return baseTypeName;\r
140                 }\r
141 \r
142                 internal override XmlSchemaParticle GetParticle ()\r
143                 {\r
144                         return null;\r
145                 }\r
146 \r
147                 internal override int Validate(ValidationEventHandler h, XmlSchema schema)\r
148                 {\r
149                         if (IsValidated (schema.ValidationId))\r
150                                 return errorCount;\r
151 \r
152                         XmlSchemaType st = schema.SchemaTypes [baseTypeName] as XmlSchemaType;\r
153                         if (st != null) {\r
154                                 XmlSchemaComplexType ct = st as XmlSchemaComplexType;\r
155                                 if (ct != null && ct.ContentModel is XmlSchemaComplexContent)\r
156                                         error (h, "Specified type is complex type which contains complex content.");\r
157                                 st.Validate (h, schema);\r
158                                 actualBaseSchemaType = st;\r
159                         } else if (baseTypeName == XmlSchemaComplexType.AnyTypeName) {\r
160                                 actualBaseSchemaType = XmlSchemaComplexType.AnyType;
161                         } else if (XmlSchemaUtil.IsBuiltInDatatypeName (baseTypeName)) {\r
162                                 actualBaseSchemaType = XmlSchemaDatatype.FromName (baseTypeName);\r
163                                 if (actualBaseSchemaType == null)\r
164                                         error (h, "Invalid schema datatype name is specified.");\r
165                         }\r
166                         // otherwise, it might be missing sub components.\r
167                         else if (!schema.IsNamespaceAbsent (baseTypeName.Namespace))\r
168                                 error (h, "Referenced base schema type " + baseTypeName + " was not found in the corresponding schema.");\r
169 \r
170                         ValidationId = schema.ValidationId;\r
171                         return errorCount;\r
172                 }\r
173 \r
174                 //<extension \r
175                 //base = QName \r
176                 //id = ID \r
177                 //{any attributes with non-schema namespace . . .}>\r
178                 //Content: (annotation?, ((attribute | attributeGroup)*, anyAttribute?))\r
179                 //</extension>\r
180                 internal static XmlSchemaSimpleContentExtension Read(XmlSchemaReader reader, ValidationEventHandler h)\r
181                 {\r
182                         XmlSchemaSimpleContentExtension extension = new XmlSchemaSimpleContentExtension();\r
183                         reader.MoveToElement();\r
184 \r
185                         if(reader.NamespaceURI != XmlSchema.Namespace || reader.LocalName != xmlname)\r
186                         {\r
187                                 error(h,"Should not happen :1: XmlSchemaAttributeGroup.Read, name="+reader.Name,null);\r
188                                 reader.Skip();\r
189                                 return null;\r
190                         }\r
191 \r
192                         extension.LineNumber = reader.LineNumber;\r
193                         extension.LinePosition = reader.LinePosition;\r
194                         extension.SourceUri = reader.BaseURI;\r
195 \r
196                         while(reader.MoveToNextAttribute())\r
197                         {\r
198                                 if(reader.Name == "base")\r
199                                 {\r
200                                         Exception innerex;\r
201                                         extension.baseTypeName= XmlSchemaUtil.ReadQNameAttribute(reader,out innerex);\r
202                                         if(innerex != null)\r
203                                                 error(h, reader.Value + " is not a valid value for base attribute",innerex);\r
204                                 }\r
205                                 else if(reader.Name == "id")\r
206                                 {\r
207                                         extension.Id = reader.Value;\r
208                                 }\r
209                                 else if((reader.NamespaceURI == "" && reader.Name != "xmlns") || reader.NamespaceURI == XmlSchema.Namespace)\r
210                                 {\r
211                                         error(h,reader.Name + " is not a valid attribute for extension in this context",null);\r
212                                 }\r
213                                 else\r
214                                 {\r
215                                         XmlSchemaUtil.ReadUnhandledAttribute(reader,extension);\r
216                                 }\r
217                         }\r
218                         \r
219                         reader.MoveToElement();\r
220                         if(reader.IsEmptyElement)\r
221                                 return extension;\r
222 \r
223                         //Content: 1.annotation?, 2.(attribute | attributeGroup)*, 3.anyAttribute?\r
224                         int level = 1;\r
225                         while(reader.ReadNextElement())\r
226                         {\r
227                                 if(reader.NodeType == XmlNodeType.EndElement)\r
228                                 {\r
229                                         if(reader.LocalName != xmlname)\r
230                                                 error(h,"Should not happen :2: XmlSchemaSimpleContentExtension.Read, name="+reader.Name,null);\r
231                                         break;\r
232                                 }\r
233                                 if(level <= 1 && reader.LocalName == "annotation")\r
234                                 {\r
235                                         level = 2; //Only one annotation\r
236                                         XmlSchemaAnnotation annotation = XmlSchemaAnnotation.Read(reader,h);\r
237                                         if(annotation != null)\r
238                                                 extension.Annotation = annotation;\r
239                                         continue;\r
240                                 }\r
241                                 if(level <= 2)\r
242                                 {\r
243                                         if(reader.LocalName == "attribute")\r
244                                         {\r
245                                                 level = 2;\r
246                                                 XmlSchemaAttribute attr = XmlSchemaAttribute.Read(reader,h);\r
247                                                 if(attr != null)\r
248                                                         extension.Attributes.Add(attr);\r
249                                                 continue;\r
250                                         }\r
251                                         if(reader.LocalName == "attributeGroup")\r
252                                         {\r
253                                                 level = 2;\r
254                                                 XmlSchemaAttributeGroupRef attr = XmlSchemaAttributeGroupRef.Read(reader,h);\r
255                                                 if(attr != null)\r
256                                                         extension.attributes.Add(attr);\r
257                                                 continue;\r
258                                         }\r
259                                 }\r
260                                 if(level <= 3 && reader.LocalName == "anyAttribute")\r
261                                 {\r
262                                         level = 4;\r
263                                         XmlSchemaAnyAttribute anyattr = XmlSchemaAnyAttribute.Read(reader,h);\r
264                                         if(anyattr != null)\r
265                                                 extension.AnyAttribute = anyattr;\r
266                                         continue;\r
267                                 }\r
268                                 reader.RaiseInvalidElementError();\r
269                         }\r
270                         return extension;\r
271                 }\r
272         }\r
273 }\r