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