**** Merged r36954 from MCS ****
[mono.git] / mcs / class / System.XML / System.Xml.Schema / XmlSchemaGroup.cs
1 //\r
2 // System.Xml.Schema.XmlSchemaGroup.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.Collections;\r
31 using System.Xml.Serialization;\r
32 using System.Xml;\r
33 \r
34 namespace System.Xml.Schema\r
35 {\r
36         /// <summary>\r
37         /// refers to the named group\r
38         /// </summary>\r
39         public class XmlSchemaGroup : XmlSchemaAnnotated\r
40         {\r
41                 private string name;\r
42                 private XmlSchemaGroupBase particle;\r
43                 private XmlQualifiedName qualifiedName;\r
44                 private bool isCircularDefinition;\r
45                 \r
46                 const string xmlname = "group";\r
47 \r
48                 public XmlSchemaGroup()\r
49                 {\r
50                         qualifiedName = XmlQualifiedName.Empty;\r
51                 }\r
52 \r
53                 [System.Xml.Serialization.XmlAttribute("name")]\r
54                 public string Name \r
55                 {\r
56                         get{ return  name; } \r
57                         set{ name = value; }\r
58                 }\r
59 \r
60                 [XmlElement("all",typeof(XmlSchemaAll),Namespace=XmlSchema.Namespace)]\r
61                 [XmlElement("choice",typeof(XmlSchemaChoice),Namespace=XmlSchema.Namespace)]\r
62                 [XmlElement("sequence",typeof(XmlSchemaSequence),Namespace=XmlSchema.Namespace)]\r
63                 public XmlSchemaGroupBase Particle\r
64                 {\r
65                         get{ return  particle; }\r
66                         set{ particle = value; }\r
67                 }\r
68 \r
69                 [XmlIgnore]\r
70 #if NET_2_0\r
71                 public XmlQualifiedName QualifiedName \r
72 #else\r
73                 internal XmlQualifiedName QualifiedName \r
74 #endif\r
75                 {\r
76                         get{ return qualifiedName;}\r
77                 }\r
78 \r
79                 internal bool IsCircularDefinition\r
80                 {\r
81                         get { return isCircularDefinition; }\r
82                 }\r
83 \r
84                 // 1. name must be present\r
85                 // 2. MinOccurs & MaxOccurs of the Particle must be absent\r
86                 internal override int Compile(ValidationEventHandler h, XmlSchema schema)\r
87                 {\r
88                         // If this is already compiled this time, simply skip.\r
89                         if (this.IsComplied (schema.CompilationId))\r
90                                 return 0;\r
91 \r
92 #if NET_2_0\r
93                         if (Particle != null)\r
94                                 Particle.Parent = this;\r
95 #endif\r
96 \r
97                         if(Name == null)\r
98                                 error(h,"Required attribute name must be present");\r
99                         else if(!XmlSchemaUtil.CheckNCName(this.name)) \r
100                                 error(h,"attribute name must be NCName");\r
101                         else\r
102                                 qualifiedName = new XmlQualifiedName(Name,schema.TargetNamespace);\r
103 \r
104                         if(Particle == null)\r
105                         {\r
106                                 error(h,"Particle is required");\r
107                         }\r
108                         else \r
109                         {\r
110                                 if(Particle.MaxOccursString != null)\r
111                                         Particle.error(h,"MaxOccurs must not be present when the Particle is a child of Group");\r
112                                 if(Particle.MinOccursString != null)\r
113                                         Particle.error(h,"MinOccurs must not be present when the Particle is a child of Group");\r
114                         \r
115                                 Particle.Compile (h, schema);\r
116                         }\r
117                         \r
118                         XmlSchemaUtil.CompileID(Id,this,schema.IDCollection,h);\r
119 \r
120                         this.CompilationId = schema.CompilationId;\r
121                         return errorCount;\r
122                 }\r
123                 \r
124                 internal override int Validate(ValidationEventHandler h, XmlSchema schema)\r
125                 {\r
126                         if (this.IsValidated (schema.ValidationId))\r
127                                 return errorCount;\r
128 \r
129                         // 3.8.6 Model Group Correct :: 2. Circular group disallowed.\r
130                         if (Particle != null) { // in case of invalid schema.\r
131                                 Particle.parentIsGroupDefinition = true;\r
132 \r
133                                 try {\r
134                                         Particle.CheckRecursion (0, h, schema);\r
135                                 } catch (XmlSchemaException ex) {\r
136                                         error (h, ex.Message, ex);\r
137                                         this.isCircularDefinition = true;\r
138                                         return errorCount;\r
139                                 }\r
140                                 errorCount += Particle.Validate (h,schema);\r
141 \r
142                                 Particle.ValidateUniqueParticleAttribution (new XmlSchemaObjectTable (),\r
143                                         new ArrayList (), h, schema);\r
144                                 Particle.ValidateUniqueTypeAttribution (\r
145                                         new XmlSchemaObjectTable (), h, schema);\r
146                         }\r
147 \r
148                         this.ValidationId = schema.ValidationId;\r
149                         return errorCount;\r
150                 }\r
151 \r
152                 //From the Errata\r
153                 //<group \r
154                 //  id = ID\r
155                 //  name = NCName\r
156                 //  {any attributes with non-schema namespace . . .}>\r
157                 //  Content: (annotation?, (all | choice | sequence)?)\r
158                 //</group>\r
159                 internal static XmlSchemaGroup Read(XmlSchemaReader reader, ValidationEventHandler h)\r
160                 {\r
161                         XmlSchemaGroup group = new XmlSchemaGroup();\r
162                         reader.MoveToElement();\r
163 \r
164                         if(reader.NamespaceURI != XmlSchema.Namespace || reader.LocalName != xmlname)\r
165                         {\r
166                                 error(h,"Should not happen :1: XmlSchemaGroup.Read, name="+reader.Name,null);\r
167                                 reader.Skip();\r
168                                 return null;\r
169                         }\r
170 \r
171                         group.LineNumber = reader.LineNumber;\r
172                         group.LinePosition = reader.LinePosition;\r
173                         group.SourceUri = reader.BaseURI;\r
174 \r
175                         while(reader.MoveToNextAttribute())\r
176                         {\r
177                                 if(reader.Name == "id")\r
178                                 {\r
179                                         group.Id = reader.Value;\r
180                                 }\r
181                                 else if(reader.Name == "name")\r
182                                 {\r
183                                         group.name = reader.Value;\r
184                                 }\r
185                                 else if((reader.NamespaceURI == "" && reader.Name != "xmlns") || reader.NamespaceURI == XmlSchema.Namespace)\r
186                                 {\r
187                                         error(h,reader.Name + " is not a valid attribute for group",null);\r
188                                 }\r
189                                 else\r
190                                 {\r
191                                         XmlSchemaUtil.ReadUnhandledAttribute(reader,group);\r
192                                 }\r
193                         }\r
194                         \r
195                         reader.MoveToElement();\r
196                         if(reader.IsEmptyElement)\r
197                                 return group;\r
198 \r
199 //                       Content: (annotation?, (all | choice | sequence)?)\r
200                         int level = 1;\r
201                         while(reader.ReadNextElement())\r
202                         {\r
203                                 if(reader.NodeType == XmlNodeType.EndElement)\r
204                                 {\r
205                                         if(reader.LocalName != xmlname)\r
206                                                 error(h,"Should not happen :2: XmlSchemaGroup.Read, name="+reader.Name,null);\r
207                                         break;\r
208                                 }\r
209                                 if(level <= 1 && reader.LocalName == "annotation")\r
210                                 {\r
211                                         level = 2; //Only one annotation\r
212                                         XmlSchemaAnnotation annotation = XmlSchemaAnnotation.Read(reader,h);\r
213                                         if(annotation != null)\r
214                                                 group.Annotation = annotation;\r
215                                         continue;\r
216                                 }\r
217                                 if(level <= 2)\r
218                                 {\r
219                                         if(reader.LocalName == "all")\r
220                                         {\r
221                                                 level = 3;\r
222                                                 XmlSchemaAll all = XmlSchemaAll.Read(reader,h);\r
223                                                 if(all != null)\r
224                                                         group.Particle = all;\r
225                                                 continue;\r
226                                         }\r
227                                         if(reader.LocalName == "choice")\r
228                                         {\r
229                                                 level = 3;\r
230                                                 XmlSchemaChoice choice = XmlSchemaChoice.Read(reader,h);\r
231                                                 if(choice != null)\r
232                                                         group.Particle = choice;\r
233                                                 continue;\r
234                                         }\r
235                                         if(reader.LocalName == "sequence")\r
236                                         {\r
237                                                 level = 3;\r
238                                                 XmlSchemaSequence sequence = XmlSchemaSequence.Read(reader,h);\r
239                                                 if(sequence != null)\r
240                                                         group.Particle = sequence;\r
241                                                 continue;\r
242                                         }\r
243                                 }\r
244                                 reader.RaiseInvalidElementError();\r
245                         }\r
246                         return group;\r
247                 }\r
248         }\r
249 }\r