2010-04-06 Jb Evain <jbevain@novell.com>
[mcs.git] / class / System.XML / System.Xml.Schema / XmlSchemaParticle.cs
blobef2b058cd0c0aa4147ea18acad0bb32300b3d546
1 // Author: Dwivedi, Ajay kumar
2 // Adwiv@Yahoo.com
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.
24 using System;
25 using System.Collections;
26 using System.Globalization;
27 using System.Xml.Serialization;
29 namespace System.Xml.Schema
31 /// <summary>
32 /// Summary description for XmlSchemaParticle.
33 /// </summary>
34 public abstract class XmlSchemaParticle : XmlSchemaAnnotated
36 internal static XmlSchemaParticle Empty {
37 get {
38 if (empty == null) {
39 empty = new EmptyParticle ();
41 return empty;
45 decimal minOccurs, maxOccurs;
46 string minstr, maxstr;
47 static XmlSchemaParticle empty;
48 decimal validatedMinOccurs = 1, validatedMaxOccurs = 1;
49 internal int recursionDepth = -1;
50 private decimal minEffectiveTotalRange = -1;
51 internal bool parentIsGroupDefinition;
53 protected XmlSchemaParticle()
55 minOccurs = decimal.One;
56 maxOccurs = decimal.One;
59 #region Attributes
61 [System.Xml.Serialization.XmlAttribute("minOccurs")]
62 public string MinOccursString
64 get{ return minstr; }
65 set
67 if (value == null) {
68 minOccurs = decimal.One;
69 minstr = value;
70 return;
73 decimal val = decimal.Parse (value, CultureInfo.InvariantCulture);
74 if(val >= 0 && (val == Decimal.Truncate(val)))
76 minOccurs = val;
77 minstr = val.ToString (CultureInfo.InvariantCulture);
79 else
81 throw new XmlSchemaException
82 ("MinOccursString must be a non-negative number",null);
87 [System.Xml.Serialization.XmlAttribute("maxOccurs")]
88 public string MaxOccursString
90 get{ return maxstr; }
91 set
93 if(value == "unbounded")
95 maxstr = value;
96 maxOccurs = decimal.MaxValue;
98 else
100 decimal val = decimal.Parse (value, CultureInfo.InvariantCulture);
101 if(val >= 0 && (val == Decimal.Truncate(val)))
103 maxOccurs = val;
104 maxstr = val.ToString (CultureInfo.InvariantCulture);
106 else
108 throw new XmlSchemaException
109 ("MaxOccurs must be a non-negative integer",null);
111 if (val == 0 && minstr == null)
112 minOccurs = 0;
117 #endregion
119 #region XmlIgnore
121 [XmlIgnore]
122 public decimal MinOccurs
124 get{ return minOccurs; }
127 MinOccursString = value.ToString (CultureInfo.InvariantCulture);
131 [XmlIgnore]
132 public decimal MaxOccurs
134 get{ return maxOccurs; }
137 if (value == decimal.MaxValue)
138 MaxOccursString = "unbounded";
139 else
140 MaxOccursString = value.ToString (CultureInfo.InvariantCulture);
144 internal decimal ValidatedMinOccurs
146 get { return validatedMinOccurs; }
149 internal decimal ValidatedMaxOccurs
151 get { return validatedMaxOccurs; }
152 // set { validatedMaxOccurs = value; }
154 #endregion
156 internal XmlSchemaParticle OptimizedParticle;
158 internal virtual XmlSchemaParticle GetOptimizedParticle (bool isTop)
160 return null;
163 internal XmlSchemaParticle GetShallowClone ()
165 return (XmlSchemaParticle) MemberwiseClone ();
168 internal void CompileOccurence (ValidationEventHandler h, XmlSchema schema)
170 if (MinOccurs > MaxOccurs && !(MaxOccurs == 0 && MinOccursString == null))
171 error(h,"minOccurs must be less than or equal to maxOccurs");
172 else {
173 if (MaxOccursString == "unbounded")
174 this.validatedMaxOccurs = decimal.MaxValue;
175 else
176 this.validatedMaxOccurs = maxOccurs;
177 if (this.validatedMaxOccurs == 0)
178 this.validatedMinOccurs = 0;
179 else
180 this.validatedMinOccurs = minOccurs;
184 internal override void CopyInfo (XmlSchemaParticle obj)
186 base.CopyInfo (obj);
187 if (MaxOccursString == "unbounded")
188 obj.maxOccurs = obj.validatedMaxOccurs = decimal.MaxValue;
189 else
190 obj.maxOccurs = obj.validatedMaxOccurs = this.ValidatedMaxOccurs;
191 if (MaxOccurs == 0)
192 obj.minOccurs = obj.validatedMinOccurs = 0;
193 else
194 obj.minOccurs = obj.validatedMinOccurs = this.ValidatedMinOccurs;
195 if (MinOccursString != null)
196 obj.MinOccursString = MinOccursString;
197 if (MaxOccursString != null)
198 obj.MaxOccursString = MaxOccursString;
201 internal virtual bool ValidateOccurenceRangeOK (XmlSchemaParticle other,
202 ValidationEventHandler h, XmlSchema schema, bool raiseError)
204 if ((this.ValidatedMinOccurs < other.ValidatedMinOccurs) ||
205 (other.ValidatedMaxOccurs != decimal.MaxValue &&
206 this.ValidatedMaxOccurs > other.ValidatedMaxOccurs)) {
207 if (raiseError)
208 error (h, "Invalid derivation occurence range was found.");
209 return false;
211 return true;
214 internal virtual decimal GetMinEffectiveTotalRange ()
216 return ValidatedMinOccurs;
219 internal decimal GetMinEffectiveTotalRangeAllAndSequence ()
221 if (minEffectiveTotalRange >= 0)
222 return minEffectiveTotalRange;
224 decimal product = 0; //this.ValidatedMinOccurs;
225 XmlSchemaObjectCollection col = null;
226 if (this is XmlSchemaAll)
227 col = ((XmlSchemaAll) this).Items;
228 else
229 col = ((XmlSchemaSequence) this).Items;
230 foreach (XmlSchemaParticle p in col)
231 product += p.GetMinEffectiveTotalRange ();
233 minEffectiveTotalRange = product;
234 return product;
237 // 3.9.6 Particle Emptiable
238 internal virtual bool ValidateIsEmptiable ()
240 return this.validatedMinOccurs == 0 || this.GetMinEffectiveTotalRange () == 0;
243 internal virtual bool ValidateDerivationByRestriction (XmlSchemaParticle baseParticle,
244 ValidationEventHandler h, XmlSchema schema, bool raiseError)
246 return false;
249 internal virtual void ValidateUniqueParticleAttribution (
250 XmlSchemaObjectTable qnames, ArrayList nsNames,
251 ValidationEventHandler h, XmlSchema schema)
255 internal virtual void ValidateUniqueTypeAttribution (XmlSchemaObjectTable labels,
256 ValidationEventHandler h, XmlSchema schema)
260 // See http://www.thaiopensource.com/relaxng/simplify.html
261 internal virtual void CheckRecursion (int depth, ValidationEventHandler h, XmlSchema schema)
265 internal virtual bool ParticleEquals (XmlSchemaParticle other)
267 return false;
270 #region Internal Class
271 internal class EmptyParticle : XmlSchemaParticle
273 internal EmptyParticle ()
277 internal override XmlSchemaParticle GetOptimizedParticle (bool isTop)
279 return this;
282 internal override bool ParticleEquals (XmlSchemaParticle other)
284 return other == this || other == XmlSchemaParticle.Empty;
287 internal override bool ValidateDerivationByRestriction (XmlSchemaParticle baseParticle,
288 ValidationEventHandler h, XmlSchema schema, bool raiseError)
290 return true;
293 internal override void CheckRecursion (int depth,
294 ValidationEventHandler h, XmlSchema schema)
296 // do nothing
299 internal override void ValidateUniqueParticleAttribution (XmlSchemaObjectTable qnames,
300 ArrayList nsNames, ValidationEventHandler h, XmlSchema schema)
302 // do nothing
305 internal override void ValidateUniqueTypeAttribution (XmlSchemaObjectTable labels,
306 ValidationEventHandler h, XmlSchema schema)
308 // do nothing
312 #endregion