2004-05-06 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / System.XML / System.Xml.Schema / XmlSchemaGroupBase.cs
1 //\r
2 // XmlSchemaGroupBase.cs\r
3 //\r
4 // Authors:\r
5 //      Dwivedi, Ajay kumar Adwiv@Yahoo.com\r
6 //      Atsushi Enomoto atsushi@ximian.com\r
7 //\r
8 using System;\r
9 using System.Xml.Serialization;\r
10 \r
11 namespace System.Xml.Schema\r
12 {\r
13         public abstract class XmlSchemaGroupBase : XmlSchemaParticle\r
14         {\r
15                 private XmlSchemaObjectCollection compiledItems;\r
16 \r
17                 protected XmlSchemaGroupBase ()\r
18                 {\r
19                         compiledItems = new XmlSchemaObjectCollection ();\r
20                 }\r
21 \r
22                 [XmlIgnore]\r
23                 public abstract XmlSchemaObjectCollection Items { get; }\r
24 \r
25                 internal XmlSchemaObjectCollection CompiledItems \r
26                 {\r
27                         get{ return compiledItems; }\r
28                 }\r
29 \r
30                 internal void CopyOptimizedItems (XmlSchemaGroupBase gb)\r
31                 {\r
32                         for (int i = 0; i < Items.Count; i++) {\r
33                                 XmlSchemaParticle p = Items [i] as XmlSchemaParticle;\r
34                                 p = p.GetOptimizedParticle (false);\r
35                                 if (p == XmlSchemaParticle.Empty)\r
36                                         continue;\r
37                                 gb.Items.Add (p);\r
38                                 gb.CompiledItems.Add (p);\r
39                         }\r
40                 }\r
41 \r
42                 internal override bool ParticleEquals (XmlSchemaParticle other)\r
43                 {\r
44                         XmlSchemaGroupBase gb = other as XmlSchemaGroupBase;\r
45                         if (gb == null)\r
46                                 return false;\r
47                         if (this.GetType () != gb.GetType ())\r
48                                 return false;\r
49 \r
50                         if (this.ValidatedMaxOccurs != gb.ValidatedMaxOccurs ||\r
51                                 this.ValidatedMinOccurs != gb.ValidatedMinOccurs)\r
52                                 return false;\r
53                         if (this.CompiledItems.Count != gb.CompiledItems.Count)\r
54                                 return false;\r
55                         for (int i = 0; i < CompiledItems.Count; i++) {\r
56                                 XmlSchemaParticle p1 = this.CompiledItems [i] as XmlSchemaParticle;\r
57                                 XmlSchemaParticle p2 = gb.CompiledItems [i] as XmlSchemaParticle;\r
58                                 if (!p1.ParticleEquals (p2))\r
59                                         return false;\r
60                         }\r
61                         return true;\r
62                 }\r
63 \r
64                 internal override void CheckRecursion (int depth, ValidationEventHandler h, XmlSchema schema)\r
65                 {\r
66                         foreach (XmlSchemaParticle p in this.Items)\r
67                                 p.CheckRecursion (depth, h, schema);\r
68                 }\r
69 \r
70                 internal bool ValidateNSRecurseCheckCardinality (XmlSchemaAny any,\r
71                         ValidationEventHandler h, XmlSchema schema, bool raiseError)\r
72                 {\r
73                         foreach (XmlSchemaParticle p in Items)\r
74                                 if (!p.ValidateDerivationByRestriction (any, h, schema, raiseError))\r
75                                         return false;\r
76                         return ValidateOccurenceRangeOK (any, h, schema, raiseError);\r
77                 }\r
78 \r
79                 internal bool ValidateRecurse (XmlSchemaGroupBase baseGroup,\r
80                         ValidationEventHandler h, XmlSchema schema, bool raiseError)\r
81                 {\r
82                         return ValidateSeqRecurseMapSumCommon (baseGroup, h, schema, false, false, raiseError);\r
83                 }\r
84 \r
85                 internal bool ValidateSeqRecurseMapSumCommon (XmlSchemaGroupBase baseGroup,\r
86                         ValidationEventHandler h, XmlSchema schema, bool isLax, bool isMapAndSum, bool raiseError)\r
87                 {\r
88                         int index = 0;\r
89                         int baseIndex = 0;\r
90                         decimal baseOccured = 0;\r
91                         if (baseGroup.CompiledItems.Count == 0 && this.CompiledItems.Count > 0) {\r
92                                 if (raiseError)\r
93                                         error (h, "Invalid particle derivation by restriction was found. base particle does not contain particles.");\r
94                                 return false;\r
95                         }\r
96 \r
97                         for (int i = 0; i < CompiledItems.Count; i++) {\r
98                                 // get non-empty derived particle\r
99                                 XmlSchemaParticle pd = null;\r
100                                 while (this.CompiledItems.Count > index) {\r
101                                         pd = ((XmlSchemaParticle) this.CompiledItems [index]);//.GetOptimizedParticle (false);\r
102                                         if (pd != XmlSchemaParticle.Empty)// && pd.ValidatedMaxOccurs > 0)\r
103                                                 break;\r
104                                         else\r
105                                                 index++;\r
106                                 }\r
107                                 if (index >= CompiledItems.Count) {\r
108                                         if (raiseError)\r
109                                                 error (h, "Invalid particle derivation by restriction was found. Cannot be mapped to base particle.");\r
110                                         return false;\r
111                                 }\r
112 \r
113                                 // get non-empty base particle\r
114                                 XmlSchemaParticle pb = null;\r
115                                 while (baseGroup.CompiledItems.Count > baseIndex) {\r
116                                         pb = ((XmlSchemaParticle) baseGroup.CompiledItems [baseIndex]);//.GetOptimizedParticle (false);\r
117                                         if (pb == XmlSchemaParticle.Empty && pb.ValidatedMaxOccurs > 0)\r
118                                                 continue;\r
119                                         if (!pd.ValidateDerivationByRestriction (pb, h, schema, false)) {\r
120                                                 if (!isLax && !isMapAndSum && pb.MinOccurs > baseOccured && !pb.ValidateIsEmptiable ()) {\r
121                                                         if (raiseError)\r
122                                                                 error (h, "Invalid particle derivation by restriction was found. Invalid sub-particle derivation was found.");\r
123                                                         return false;\r
124                                                 }\r
125                                                 else {\r
126                                                         baseOccured = 0;\r
127                                                         baseIndex++;\r
128                                                 }\r
129                                         } else {\r
130                                                 baseOccured += pb.ValidatedMinOccurs;\r
131                                                 if (baseOccured >= baseGroup.ValidatedMaxOccurs) {\r
132                                                         baseOccured = 0;\r
133                                                         baseIndex++;\r
134                                                 }\r
135                                                 index++;\r
136                                                 break;\r
137                                         }\r
138                                 }\r
139                         }\r
140                         if (this.CompiledItems.Count > 0 && index != this.CompiledItems.Count) {\r
141                                 if (raiseError)\r
142                                         error (h, "Invalid particle derivation by restriction was found. Extraneous derived particle was found.");\r
143                                 return false;\r
144                         }\r
145                         if (!isLax && !isMapAndSum) {\r
146                                 if (baseOccured > 0)\r
147                                         baseIndex++;\r
148                                 for (int i = baseIndex; i < baseGroup.CompiledItems.Count; i++) {\r
149                                         XmlSchemaParticle p = baseGroup.CompiledItems [i] as XmlSchemaParticle;\r
150                                         if (!p.ValidateIsEmptiable ()) {\r
151                                                 if (raiseError)\r
152                                                         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.");\r
153                                                 return false;\r
154                                         }\r
155                                 }\r
156                         }\r
157                         return true;\r
158                 }\r
159         }\r
160 }\r