merged Sys.Web.Services 2.0 support in my branch:
[mono.git] / mcs / class / System.XML / System.Xml.Schema / XmlSchemaGroupBase.cs
1 //
2 // XmlSchemaGroupBase.cs
3 //
4 // Authors:
5 //      Dwivedi, Ajay kumar Adwiv@Yahoo.com
6 //      Atsushi Enomoto atsushi@ximian.com
7 //
8
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.
28 //
29 using System;
30 using System.Xml.Serialization;
31
32 namespace System.Xml.Schema
33 {
34         public abstract class XmlSchemaGroupBase : XmlSchemaParticle
35         {
36                 private XmlSchemaObjectCollection compiledItems;
37
38                 protected XmlSchemaGroupBase ()
39                 {
40                         compiledItems = new XmlSchemaObjectCollection ();
41                 }
42
43                 [XmlIgnore]
44                 public abstract XmlSchemaObjectCollection Items { get; }
45
46                 internal XmlSchemaObjectCollection CompiledItems 
47                 {
48                         get{ return compiledItems; }
49                 }
50
51                 internal void CopyOptimizedItems (XmlSchemaGroupBase gb)
52                 {
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);
60                         }
61                 }
62
63                 internal override bool ParticleEquals (XmlSchemaParticle other)
64                 {
65                         XmlSchemaGroupBase gb = other as XmlSchemaGroupBase;
66                         if (gb == null)
67                                 return false;
68                         if (this.GetType () != gb.GetType ())
69                                 return false;
70
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;
81                         }
82                         return true;
83                 }
84
85                 internal override void CheckRecursion (int depth, ValidationEventHandler h, XmlSchema schema)
86                 {
87                         foreach (XmlSchemaParticle p in this.Items)
88                                 p.CheckRecursion (depth, h, schema);
89                 }
90
91                 internal bool ValidateNSRecurseCheckCardinality (XmlSchemaAny any,
92                         ValidationEventHandler h, XmlSchema schema, bool raiseError)
93                 {
94                         foreach (XmlSchemaParticle p in Items)
95                                 if (!p.ValidateDerivationByRestriction (any, h, schema, raiseError))
96                                         return false;
97                         return ValidateOccurenceRangeOK (any, h, schema, raiseError);
98                 }
99
100                 internal bool ValidateRecurse (XmlSchemaGroupBase baseGroup,
101                         ValidationEventHandler h, XmlSchema schema, bool raiseError)
102                 {
103                         return ValidateSeqRecurseMapSumCommon (baseGroup, h, schema, false, false, raiseError);
104                 }
105
106                 internal bool ValidateSeqRecurseMapSumCommon (XmlSchemaGroupBase baseGroup,
107                         ValidationEventHandler h, XmlSchema schema, bool isLax, bool isMapAndSum, bool raiseError)
108                 {
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;
116                         }
117
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++;
127                                 }
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;
132                                 }
133
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;
145                                                 }
146                                                 else {
147                                                         baseOccured = 0;
148                                                         baseIndex++;
149                                                 }
150                                         } else {
151                                                 baseOccured += pb.ValidatedMinOccurs;
152                                                 if (baseOccured >= baseGroup.ValidatedMaxOccurs) {
153                                                         baseOccured = 0;
154                                                         baseIndex++;
155                                                 }
156                                                 index++;
157                                                 break;
158                                         }
159                                 }
160                         }
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;
165                         }
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;
175                                         }
176                                 }
177                         }
178                         return true;
179                 }
180         }
181 }