XmlSchemaParticle.cs 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. // Author: Dwivedi, Ajay kumar
  2. // [email protected]
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining
  5. // a copy of this software and associated documentation files (the
  6. // "Software"), to deal in the Software without restriction, including
  7. // without limitation the rights to use, copy, modify, merge, publish,
  8. // distribute, sublicense, and/or sell copies of the Software, and to
  9. // permit persons to whom the Software is furnished to do so, subject to
  10. // the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be
  13. // included in all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  18. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  19. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  20. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  21. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22. //
  23. using System;
  24. using System.Collections;
  25. using System.Globalization;
  26. using System.Xml.Serialization;
  27. namespace System.Xml.Schema
  28. {
  29. /// <summary>
  30. /// Summary description for XmlSchemaParticle.
  31. /// </summary>
  32. public abstract class XmlSchemaParticle : XmlSchemaAnnotated
  33. {
  34. internal static XmlSchemaParticle Empty {
  35. get {
  36. if (empty == null) {
  37. empty = new EmptyParticle ();
  38. }
  39. return empty;
  40. }
  41. }
  42. decimal minOccurs, maxOccurs;
  43. string minstr, maxstr;
  44. static XmlSchemaParticle empty;
  45. decimal validatedMinOccurs = 1, validatedMaxOccurs = 1;
  46. internal int recursionDepth = -1;
  47. private decimal minEffectiveTotalRange = -1;
  48. internal bool parentIsGroupDefinition;
  49. protected XmlSchemaParticle()
  50. {
  51. minOccurs = decimal.One;
  52. maxOccurs = decimal.One;
  53. }
  54. #region Attributes
  55. [System.Xml.Serialization.XmlAttribute("minOccurs")]
  56. public string MinOccursString
  57. {
  58. get{ return minstr; }
  59. set
  60. {
  61. if (value == null) {
  62. minOccurs = decimal.One;
  63. minstr = value;
  64. return;
  65. }
  66. decimal val = decimal.Parse (value, CultureInfo.InvariantCulture);
  67. if(val >= 0 && (val == Decimal.Truncate(val)))
  68. {
  69. minOccurs = val;
  70. minstr = val.ToString (CultureInfo.InvariantCulture);
  71. }
  72. else
  73. {
  74. throw new XmlSchemaException
  75. ("MinOccursString must be a non-negative number",null);
  76. }
  77. }
  78. }
  79. [System.Xml.Serialization.XmlAttribute("maxOccurs")]
  80. public string MaxOccursString
  81. {
  82. get{ return maxstr; }
  83. set
  84. {
  85. if(value == "unbounded")
  86. {
  87. maxstr = value;
  88. maxOccurs = decimal.MaxValue;
  89. }
  90. else
  91. {
  92. decimal val = decimal.Parse (value, CultureInfo.InvariantCulture);
  93. if(val >= 0 && (val == Decimal.Truncate(val)))
  94. {
  95. maxOccurs = val;
  96. maxstr = val.ToString (CultureInfo.InvariantCulture);
  97. }
  98. else
  99. {
  100. throw new XmlSchemaException
  101. ("MaxOccurs must be a non-negative integer",null);
  102. }
  103. if (val == 0 && minstr == null)
  104. minOccurs = 0;
  105. }
  106. }
  107. }
  108. #endregion
  109. #region XmlIgnore
  110. [XmlIgnore]
  111. public decimal MinOccurs
  112. {
  113. get{ return minOccurs; }
  114. set
  115. {
  116. MinOccursString = value.ToString (CultureInfo.InvariantCulture);
  117. }
  118. }
  119. [XmlIgnore]
  120. public decimal MaxOccurs
  121. {
  122. get{ return maxOccurs; }
  123. set
  124. {
  125. if (value == decimal.MaxValue)
  126. MaxOccursString = "unbounded";
  127. else
  128. MaxOccursString = value.ToString (CultureInfo.InvariantCulture);
  129. }
  130. }
  131. internal decimal ValidatedMinOccurs
  132. {
  133. get { return validatedMinOccurs; }
  134. }
  135. internal decimal ValidatedMaxOccurs
  136. {
  137. get { return validatedMaxOccurs; }
  138. // set { validatedMaxOccurs = value; }
  139. }
  140. #endregion
  141. internal XmlSchemaParticle OptimizedParticle;
  142. internal abstract XmlSchemaParticle GetOptimizedParticle (bool isTop);
  143. internal XmlSchemaParticle GetShallowClone ()
  144. {
  145. return (XmlSchemaParticle) MemberwiseClone ();
  146. }
  147. internal void CompileOccurence (ValidationEventHandler h, XmlSchema schema)
  148. {
  149. if (MinOccurs > MaxOccurs && !(MaxOccurs == 0 && MinOccursString == null))
  150. error(h,"minOccurs must be less than or equal to maxOccurs");
  151. else {
  152. if (MaxOccursString == "unbounded")
  153. this.validatedMaxOccurs = decimal.MaxValue;
  154. else
  155. this.validatedMaxOccurs = maxOccurs;
  156. if (this.validatedMaxOccurs == 0)
  157. this.validatedMinOccurs = 0;
  158. else
  159. this.validatedMinOccurs = minOccurs;
  160. }
  161. }
  162. internal override void CopyInfo (XmlSchemaParticle obj)
  163. {
  164. base.CopyInfo (obj);
  165. if (MaxOccursString == "unbounded")
  166. obj.maxOccurs = obj.validatedMaxOccurs = decimal.MaxValue;
  167. else
  168. obj.maxOccurs = obj.validatedMaxOccurs = this.ValidatedMaxOccurs;
  169. if (MaxOccurs == 0)
  170. obj.minOccurs = obj.validatedMinOccurs = 0;
  171. else
  172. obj.minOccurs = obj.validatedMinOccurs = this.ValidatedMinOccurs;
  173. if (MinOccursString != null)
  174. obj.MinOccursString = MinOccursString;
  175. if (MaxOccursString != null)
  176. obj.MaxOccursString = MaxOccursString;
  177. }
  178. internal virtual bool ValidateOccurenceRangeOK (XmlSchemaParticle other,
  179. ValidationEventHandler h, XmlSchema schema, bool raiseError)
  180. {
  181. if ((this.ValidatedMinOccurs < other.ValidatedMinOccurs) ||
  182. (other.ValidatedMaxOccurs != decimal.MaxValue &&
  183. this.ValidatedMaxOccurs > other.ValidatedMaxOccurs)) {
  184. if (raiseError)
  185. error (h, "Invalid derivation occurence range was found.");
  186. return false;
  187. }
  188. return true;
  189. }
  190. internal virtual decimal GetMinEffectiveTotalRange ()
  191. {
  192. return ValidatedMinOccurs;
  193. }
  194. internal decimal GetMinEffectiveTotalRangeAllAndSequence ()
  195. {
  196. if (minEffectiveTotalRange >= 0)
  197. return minEffectiveTotalRange;
  198. decimal product = 0; //this.ValidatedMinOccurs;
  199. XmlSchemaObjectCollection col = null;
  200. if (this is XmlSchemaAll)
  201. col = ((XmlSchemaAll) this).Items;
  202. else
  203. col = ((XmlSchemaSequence) this).Items;
  204. foreach (XmlSchemaParticle p in col)
  205. product += p.GetMinEffectiveTotalRange ();
  206. minEffectiveTotalRange = product;
  207. return product;
  208. }
  209. // 3.9.6 Particle Emptiable
  210. internal virtual bool ValidateIsEmptiable ()
  211. {
  212. return this.validatedMinOccurs == 0 || this.GetMinEffectiveTotalRange () == 0;
  213. }
  214. internal abstract bool ValidateDerivationByRestriction (XmlSchemaParticle baseParticle,
  215. ValidationEventHandler h, XmlSchema schema, bool raiseError);
  216. internal abstract void ValidateUniqueParticleAttribution (
  217. XmlSchemaObjectTable qnames, ArrayList nsNames,
  218. ValidationEventHandler h, XmlSchema schema);
  219. internal abstract void ValidateUniqueTypeAttribution (XmlSchemaObjectTable labels,
  220. ValidationEventHandler h, XmlSchema schema);
  221. // See http://www.thaiopensource.com/relaxng/simplify.html
  222. internal abstract void CheckRecursion (int depth, ValidationEventHandler h, XmlSchema schema);
  223. internal abstract bool ParticleEquals (XmlSchemaParticle other);
  224. #region Internal Class
  225. internal class EmptyParticle : XmlSchemaParticle
  226. {
  227. internal EmptyParticle ()
  228. {
  229. }
  230. internal override XmlSchemaParticle GetOptimizedParticle (bool isTop)
  231. {
  232. return this;
  233. }
  234. internal override bool ParticleEquals (XmlSchemaParticle other)
  235. {
  236. return other == this || other == XmlSchemaParticle.Empty;
  237. }
  238. internal override bool ValidateDerivationByRestriction (XmlSchemaParticle baseParticle,
  239. ValidationEventHandler h, XmlSchema schema, bool raiseError)
  240. {
  241. return true;
  242. }
  243. internal override void CheckRecursion (int depth,
  244. ValidationEventHandler h, XmlSchema schema)
  245. {
  246. // do nothing
  247. }
  248. internal override void ValidateUniqueParticleAttribution (XmlSchemaObjectTable qnames,
  249. ArrayList nsNames, ValidationEventHandler h, XmlSchema schema)
  250. {
  251. // do nothing
  252. }
  253. internal override void ValidateUniqueTypeAttribution (XmlSchemaObjectTable labels,
  254. ValidationEventHandler h, XmlSchema schema)
  255. {
  256. // do nothing
  257. }
  258. }
  259. #endregion
  260. }
  261. }