* roottypes.cs: Rename from tree.cs.
[mono.git] / mcs / class / System.XML / System.Xml.Schema / XmlSchemaParticle.cs
1 // Author: Dwivedi, Ajay kumar\r
2 //            Adwiv@Yahoo.com\r
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;\r
25 using System.Collections;\r
26 using System.Globalization;
27 using System.Xml.Serialization;\r
28 \r
29 namespace System.Xml.Schema\r
30 {\r
31         /// <summary>\r
32         /// Summary description for XmlSchemaParticle.\r
33         /// </summary>\r
34         public abstract class XmlSchemaParticle : XmlSchemaAnnotated\r
35         {\r
36                 internal static XmlSchemaParticle Empty {\r
37                         get {\r
38                                 if (empty == null) {\r
39                                         empty = new EmptyParticle ();\r
40                                 }\r
41                                 return empty;\r
42                         }\r
43                 }\r
44 \r
45                 decimal minOccurs, maxOccurs;\r
46                 string  minstr, maxstr;\r
47                 static XmlSchemaParticle empty;\r
48                 decimal validatedMinOccurs = 1, validatedMaxOccurs = 1;\r
49                 internal int recursionDepth = -1;\r
50                 private decimal minEffectiveTotalRange = -1;\r
51                 internal bool parentIsGroupDefinition;\r
52 \r
53                 protected XmlSchemaParticle()\r
54                 {\r
55                         minOccurs = decimal.One;\r
56                         maxOccurs = decimal.One;\r
57                 }\r
58 \r
59                 #region Attributes\r
60 \r
61                 [System.Xml.Serialization.XmlAttribute("minOccurs")]\r
62                 public string MinOccursString\r
63                 {\r
64                         get{ return minstr; }\r
65                         set\r
66                         {\r
67                                 if (value == null) {\r
68                                         minOccurs = decimal.One;\r
69                                         minstr = value;\r
70                                         return;\r
71                                 }\r
72 \r
73                                 decimal val = decimal.Parse (value, CultureInfo.InvariantCulture);\r
74                                 if(val >= 0 && (val == Decimal.Truncate(val)))\r
75                                 {\r
76                                         minOccurs = val;\r
77                                         minstr   = val.ToString (CultureInfo.InvariantCulture);\r
78                                 }\r
79                                 else\r
80                                 {\r
81                                         throw new XmlSchemaException\r
82                                                 ("MinOccursString must be a non-negative number",null);                                         \r
83                                 }\r
84                         }\r
85                 }\r
86 \r
87                 [System.Xml.Serialization.XmlAttribute("maxOccurs")]\r
88                 public string MaxOccursString\r
89                 {\r
90                         get{ return maxstr; }\r
91                         set\r
92                         {\r
93                                 if(value == "unbounded")\r
94                                 {\r
95                                         maxstr = value;\r
96                                         maxOccurs = decimal.MaxValue;\r
97                                 }\r
98                                 else\r
99                                 {\r
100                                         decimal val = decimal.Parse (value, CultureInfo.InvariantCulture);\r
101                                         if(val >= 0 && (val == Decimal.Truncate(val)))\r
102                                         {\r
103                                                 maxOccurs = val;\r
104                                                 maxstr = val.ToString (CultureInfo.InvariantCulture);\r
105                                         }\r
106                                         else\r
107                                         {\r
108                                                 throw new XmlSchemaException\r
109                                                         ("MaxOccurs must be a non-negative integer",null);\r
110                                         }\r
111                                         if (val == 0 && minstr == null)\r
112                                                 minOccurs = 0;\r
113                                 }\r
114                         }\r
115                 }\r
116 \r
117                 #endregion\r
118 \r
119                 #region XmlIgnore\r
120 \r
121                 [XmlIgnore]\r
122                 public decimal MinOccurs\r
123                 {\r
124                         get{ return  minOccurs; }\r
125                         set\r
126                         {\r
127                                 MinOccursString = value.ToString (CultureInfo.InvariantCulture);\r
128                         }\r
129                 }\r
130 \r
131                 [XmlIgnore]\r
132                 public decimal MaxOccurs \r
133                 {\r
134                         get{ return  maxOccurs; } \r
135                         set\r
136                         {
137                                 if (value == decimal.MaxValue)
138                                         MaxOccursString = "unbounded";\r
139                                 else\r
140                                         MaxOccursString = value.ToString (CultureInfo.InvariantCulture);\r
141                         }\r
142                 }\r
143 \r
144                 internal decimal ValidatedMinOccurs\r
145                 {\r
146                         get { return validatedMinOccurs; }\r
147                 }\r
148 \r
149                 internal decimal ValidatedMaxOccurs\r
150                 {\r
151                         get { return validatedMaxOccurs; }\r
152 //                      set { validatedMaxOccurs = value; }\r
153                 }\r
154                 #endregion\r
155 \r
156                 internal XmlSchemaParticle OptimizedParticle;\r
157 \r
158                 internal virtual XmlSchemaParticle GetOptimizedParticle (bool isTop)\r
159                 {\r
160                         return null;\r
161                 }\r
162 \r
163                 internal XmlSchemaParticle GetShallowClone ()\r
164                 {\r
165                         return (XmlSchemaParticle) MemberwiseClone ();\r
166                 }\r
167 \r
168                 internal void CompileOccurence (ValidationEventHandler h, XmlSchema schema)\r
169                 {\r
170                         if (MinOccurs > MaxOccurs && !(MaxOccurs == 0 && MinOccursString == null))\r
171                                 error(h,"minOccurs must be less than or equal to maxOccurs");\r
172                         else {\r
173                                 if (MaxOccursString == "unbounded")\r
174                                         this.validatedMaxOccurs = decimal.MaxValue;\r
175                                 else\r
176                                         this.validatedMaxOccurs = maxOccurs;\r
177                                 if (this.validatedMaxOccurs == 0)\r
178                                         this.validatedMinOccurs = 0;\r
179                                 else\r
180                                         this.validatedMinOccurs = minOccurs;\r
181                         }\r
182                 }\r
183 \r
184                 internal override void CopyInfo (XmlSchemaParticle obj)\r
185                 {\r
186                         base.CopyInfo (obj);\r
187                         if (MaxOccursString == "unbounded")\r
188                                 obj.maxOccurs = obj.validatedMaxOccurs = decimal.MaxValue;\r
189                         else \r
190                                 obj.maxOccurs = obj.validatedMaxOccurs = this.ValidatedMaxOccurs;\r
191                         if (MaxOccurs == 0)\r
192                                 obj.minOccurs = obj.validatedMinOccurs = 0;\r
193                         else\r
194                                 obj.minOccurs = obj.validatedMinOccurs = this.ValidatedMinOccurs;\r
195                         if (MinOccursString != null)\r
196                                 obj.MinOccursString = MinOccursString;\r
197                         if (MaxOccursString != null)\r
198                                 obj.MaxOccursString = MaxOccursString;\r
199                 }\r
200 \r
201                 internal virtual bool ValidateOccurenceRangeOK (XmlSchemaParticle other,\r
202                         ValidationEventHandler h, XmlSchema schema, bool raiseError)\r
203                 {\r
204                         if ((this.ValidatedMinOccurs < other.ValidatedMinOccurs) ||\r
205                                 (other.ValidatedMaxOccurs != decimal.MaxValue &&\r
206                                 this.ValidatedMaxOccurs > other.ValidatedMaxOccurs)) {\r
207                                 if (raiseError)\r
208                                         error (h, "Invalid derivation occurence range was found.");\r
209                                 return false;\r
210                         }\r
211                         return true;\r
212                 }\r
213 \r
214                 internal virtual decimal GetMinEffectiveTotalRange ()\r
215                 {\r
216                         return ValidatedMinOccurs;\r
217                 }\r
218 \r
219                 internal decimal GetMinEffectiveTotalRangeAllAndSequence ()\r
220                 {\r
221                         if (minEffectiveTotalRange >= 0)\r
222                                 return minEffectiveTotalRange;\r
223 \r
224                         decimal product = 0; //this.ValidatedMinOccurs;\r
225                         XmlSchemaObjectCollection col = null;\r
226                         if (this is XmlSchemaAll)\r
227                                 col = ((XmlSchemaAll) this).Items;\r
228                         else\r
229                                 col = ((XmlSchemaSequence) this).Items;\r
230                         foreach (XmlSchemaParticle p in col)\r
231                                 product += p.GetMinEffectiveTotalRange ();\r
232 \r
233                         minEffectiveTotalRange = product;\r
234                         return product;\r
235                 }\r
236 \r
237                 // 3.9.6 Particle Emptiable\r
238                 internal virtual bool ValidateIsEmptiable ()\r
239                 {\r
240                         return this.validatedMinOccurs == 0 || this.GetMinEffectiveTotalRange () == 0;\r
241                 }\r
242 \r
243                 internal virtual bool ValidateDerivationByRestriction (XmlSchemaParticle baseParticle,\r
244                         ValidationEventHandler h, XmlSchema schema, bool raiseError)\r
245                 {\r
246                         return false;\r
247                 }\r
248 \r
249                 internal virtual void ValidateUniqueParticleAttribution (\r
250                         XmlSchemaObjectTable qnames, ArrayList nsNames,\r
251                         ValidationEventHandler h, XmlSchema schema)\r
252                 {\r
253                 }\r
254 \r
255                 internal virtual void ValidateUniqueTypeAttribution (XmlSchemaObjectTable labels,\r
256                         ValidationEventHandler h, XmlSchema schema)\r
257                 {\r
258                 }\r
259 \r
260                 // See http://www.thaiopensource.com/relaxng/simplify.html\r
261                 internal virtual void CheckRecursion (int depth, ValidationEventHandler h, XmlSchema schema)\r
262                 {\r
263                 }\r
264 \r
265                 internal virtual bool ParticleEquals (XmlSchemaParticle other)\r
266                 {\r
267                         return false;\r
268                 }\r
269 \r
270                 #region Internal Class\r
271                 internal class EmptyParticle : XmlSchemaParticle\r
272                 {\r
273                         internal EmptyParticle ()\r
274                         {\r
275                         }\r
276 \r
277                         internal override XmlSchemaParticle GetOptimizedParticle (bool isTop)\r
278                         {\r
279                                 return this;\r
280                         }\r
281 \r
282                         internal override bool ParticleEquals (XmlSchemaParticle other)\r
283                         {\r
284                                 return other == this || other == XmlSchemaParticle.Empty;\r
285                         }\r
286 \r
287                         internal override bool ValidateDerivationByRestriction (XmlSchemaParticle baseParticle,\r
288                                 ValidationEventHandler h, XmlSchema schema, bool raiseError)\r
289                         {\r
290                                 return true;\r
291                         }\r
292 \r
293                         internal override void CheckRecursion (int depth, \r
294                                 ValidationEventHandler h, XmlSchema schema)\r
295                         {\r
296                                 // do nothing\r
297                         }\r
298 \r
299                         internal override void ValidateUniqueParticleAttribution (XmlSchemaObjectTable qnames,\r
300                                 ArrayList nsNames, ValidationEventHandler h, XmlSchema schema)\r
301                         {\r
302                                 // do nothing\r
303                         }\r
304 \r
305                         internal override void ValidateUniqueTypeAttribution (XmlSchemaObjectTable labels,\r
306                                 ValidationEventHandler h, XmlSchema schema)\r
307                         {\r
308                                 // do nothing\r
309                         }\r
310 \r
311                 }\r
312                 #endregion\r
313         }\r
314 }