**** Merged from MCS ****
[mono-project.git] / mcs / class / System.XML / System.Xml.Schema / XmlSchemaGroupBase.cs
blob80d64157678ae08c739a26cdb8e47e008ffc3868
1 //
2 // XmlSchemaGroupBase.cs
3 //
4 // Authors:
5 // Dwivedi, Ajay kumar Adwiv@Yahoo.com
6 // Atsushi Enomoto atsushi@ximian.com
7 //
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.
29 using System;
30 using System.Xml.Serialization;
32 namespace System.Xml.Schema
34 public abstract class XmlSchemaGroupBase : XmlSchemaParticle
36 private XmlSchemaObjectCollection compiledItems;
38 protected XmlSchemaGroupBase ()
40 compiledItems = new XmlSchemaObjectCollection ();
43 [XmlIgnore]
44 public abstract XmlSchemaObjectCollection Items { get; }
46 internal XmlSchemaObjectCollection CompiledItems
48 get{ return compiledItems; }
51 internal void CopyOptimizedItems (XmlSchemaGroupBase gb)
53 for (int i = 0; i < Items.Count; i++) {
54 XmlSchemaParticle p = Items [i] as XmlSchemaParticle;
55 p = p.GetOptimizedParticle (false);
56 if (p == XmlSchemaParticle.Empty)
57 continue;
58 gb.Items.Add (p);
59 gb.CompiledItems.Add (p);
63 internal override bool ParticleEquals (XmlSchemaParticle other)
65 XmlSchemaGroupBase gb = other as XmlSchemaGroupBase;
66 if (gb == null)
67 return false;
68 if (this.GetType () != gb.GetType ())
69 return false;
71 if (this.ValidatedMaxOccurs != gb.ValidatedMaxOccurs ||
72 this.ValidatedMinOccurs != gb.ValidatedMinOccurs)
73 return false;
74 if (this.CompiledItems.Count != gb.CompiledItems.Count)
75 return false;
76 for (int i = 0; i < CompiledItems.Count; i++) {
77 XmlSchemaParticle p1 = this.CompiledItems [i] as XmlSchemaParticle;
78 XmlSchemaParticle p2 = gb.CompiledItems [i] as XmlSchemaParticle;
79 if (!p1.ParticleEquals (p2))
80 return false;
82 return true;
85 internal override void CheckRecursion (int depth, ValidationEventHandler h, XmlSchema schema)
87 foreach (XmlSchemaParticle p in this.Items)
88 p.CheckRecursion (depth, h, schema);
91 internal bool ValidateNSRecurseCheckCardinality (XmlSchemaAny any,
92 ValidationEventHandler h, XmlSchema schema, bool raiseError)
94 foreach (XmlSchemaParticle p in Items)
95 if (!p.ValidateDerivationByRestriction (any, h, schema, raiseError))
96 return false;
97 return ValidateOccurenceRangeOK (any, h, schema, raiseError);
100 internal bool ValidateRecurse (XmlSchemaGroupBase baseGroup,
101 ValidationEventHandler h, XmlSchema schema, bool raiseError)
103 return ValidateSeqRecurseMapSumCommon (baseGroup, h, schema, false, false, raiseError);
106 internal bool ValidateSeqRecurseMapSumCommon (XmlSchemaGroupBase baseGroup,
107 ValidationEventHandler h, XmlSchema schema, bool isLax, bool isMapAndSum, bool raiseError)
109 int index = 0;
110 int baseIndex = 0;
111 decimal baseOccured = 0;
112 if (baseGroup.CompiledItems.Count == 0 && this.CompiledItems.Count > 0) {
113 if (raiseError)
114 error (h, "Invalid particle derivation by restriction was found. base particle does not contain particles.");
115 return false;
118 for (int i = 0; i < CompiledItems.Count; i++) {
119 // get non-empty derived particle
120 XmlSchemaParticle pd = null;
121 while (this.CompiledItems.Count > index) {
122 pd = ((XmlSchemaParticle) this.CompiledItems [index]);//.GetOptimizedParticle (false);
123 if (pd != XmlSchemaParticle.Empty)// && pd.ValidatedMaxOccurs > 0)
124 break;
125 else
126 index++;
128 if (index >= CompiledItems.Count) {
129 if (raiseError)
130 error (h, "Invalid particle derivation by restriction was found. Cannot be mapped to base particle.");
131 return false;
134 // get non-empty base particle
135 XmlSchemaParticle pb = null;
136 while (baseGroup.CompiledItems.Count > baseIndex) {
137 pb = ((XmlSchemaParticle) baseGroup.CompiledItems [baseIndex]);//.GetOptimizedParticle (false);
138 if (pb == XmlSchemaParticle.Empty && pb.ValidatedMaxOccurs > 0)
139 continue;
140 if (!pd.ValidateDerivationByRestriction (pb, h, schema, false)) {
141 if (!isLax && !isMapAndSum && pb.MinOccurs > baseOccured && !pb.ValidateIsEmptiable ()) {
142 if (raiseError)
143 error (h, "Invalid particle derivation by restriction was found. Invalid sub-particle derivation was found.");
144 return false;
146 else {
147 baseOccured = 0;
148 baseIndex++;
150 } else {
151 baseOccured += pb.ValidatedMinOccurs;
152 if (baseOccured >= baseGroup.ValidatedMaxOccurs) {
153 baseOccured = 0;
154 baseIndex++;
156 index++;
157 break;
161 if (this.CompiledItems.Count > 0 && index != this.CompiledItems.Count) {
162 if (raiseError)
163 error (h, "Invalid particle derivation by restriction was found. Extraneous derived particle was found.");
164 return false;
166 if (!isLax && !isMapAndSum) {
167 if (baseOccured > 0)
168 baseIndex++;
169 for (int i = baseIndex; i < baseGroup.CompiledItems.Count; i++) {
170 XmlSchemaParticle p = baseGroup.CompiledItems [i] as XmlSchemaParticle;
171 if (!p.ValidateIsEmptiable ()) {
172 if (raiseError)
173 error (h, "Invalid particle derivation by restriction was found. There is a base particle which does not have mapped derived particle and is not emptiable.");
174 return false;
178 return true;