2004-05-06 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / System.XML / System.Xml.Schema / XmlSchemaParticle.cs
1 // Author: Dwivedi, Ajay kumar\r
2 //            Adwiv@Yahoo.com\r
3 using System;\r
4 using System.Collections;\r
5 using System.Xml.Serialization;\r
6 \r
7 namespace System.Xml.Schema\r
8 {\r
9         /// <summary>\r
10         /// Summary description for XmlSchemaParticle.\r
11         /// </summary>\r
12         public abstract class XmlSchemaParticle : XmlSchemaAnnotated\r
13         {\r
14                 internal static XmlSchemaParticle Empty {\r
15                         get {\r
16                                 if (empty == null) {\r
17                                         empty = new EmptyParticle ();\r
18                                 }\r
19                                 return empty;\r
20                         }\r
21                 }\r
22 \r
23                 decimal minOccurs, maxOccurs;\r
24                 string  minstr, maxstr;\r
25                 static XmlSchemaParticle empty;\r
26                 decimal validatedMinOccurs = 1, validatedMaxOccurs = 1;\r
27                 internal int recursionDepth = -1;\r
28                 private decimal minEffectiveTotalRange = -1;\r
29                 internal bool parentIsGroupDefinition;\r
30 \r
31                 protected XmlSchemaParticle()\r
32                 {\r
33                         minOccurs = decimal.One;\r
34                         maxOccurs = decimal.One;\r
35                 }\r
36 \r
37                 #region Attributes\r
38 \r
39                 [System.Xml.Serialization.XmlAttribute("minOccurs")]\r
40                 public string MinOccursString\r
41                 {\r
42                         get{ return minstr; }\r
43                         set\r
44                         {\r
45                                 if (value == null) {\r
46                                         minOccurs = decimal.One;\r
47                                         minstr = value;\r
48                                         return;\r
49                                 }\r
50 \r
51                                 decimal val = decimal.Parse(value);\r
52                                 if(val >= 0 && (val == Decimal.Truncate(val)))\r
53                                 {\r
54                                         minOccurs = val;\r
55                                         minstr   = val.ToString();\r
56                                 }\r
57                                 else\r
58                                 {\r
59                                         throw new XmlSchemaException\r
60                                                 ("MinOccursString must be a non-negative number",null);                                         \r
61                                 }\r
62                         }\r
63                 }\r
64 \r
65                 [System.Xml.Serialization.XmlAttribute("maxOccurs")]\r
66                 public string MaxOccursString\r
67                 {\r
68                         get{ return maxstr; }\r
69                         set\r
70                         {\r
71                                 if(value == "unbounded")\r
72                                 {\r
73                                         maxstr = value;\r
74                                         maxOccurs = decimal.MaxValue;\r
75                                 }\r
76                                 else\r
77                                 {\r
78                                         decimal val = decimal.Parse(value);\r
79                                         if(val >= 0 && (val == Decimal.Truncate(val)))\r
80                                         {\r
81                                                 maxOccurs = val;\r
82                                                 maxstr = val.ToString();\r
83                                         }\r
84                                         else\r
85                                         {\r
86                                                 throw new XmlSchemaException\r
87                                                         ("MaxOccurs must be a non-negative integer",null);\r
88                                         }\r
89                                         if (val == 0 && minstr == null)\r
90                                                 minOccurs = 0;\r
91                                 }\r
92                         }\r
93                 }\r
94 \r
95                 #endregion\r
96 \r
97                 #region XmlIgnore\r
98 \r
99                 [XmlIgnore]\r
100                 public decimal MinOccurs\r
101                 {\r
102                         get{ return  minOccurs; }\r
103                         set\r
104                         {\r
105                                 MinOccursString = value.ToString ();\r
106                         }\r
107                 }\r
108 \r
109                 [XmlIgnore]\r
110                 public decimal MaxOccurs \r
111                 {\r
112                         get{ return  maxOccurs; } \r
113                         set\r
114                         {\r
115                                 MaxOccursString = value.ToString ();\r
116                         }\r
117                 }\r
118 \r
119                 internal decimal ValidatedMinOccurs\r
120                 {\r
121                         get { return validatedMinOccurs; }\r
122                 }\r
123 \r
124                 internal decimal ValidatedMaxOccurs\r
125                 {\r
126                         get { return validatedMaxOccurs; }\r
127                 }\r
128                 #endregion\r
129 \r
130                 internal XmlSchemaParticle OptimizedParticle;\r
131 \r
132                 internal abstract XmlSchemaParticle GetOptimizedParticle (bool isTop);\r
133 \r
134                 internal XmlSchemaParticle GetShallowClone ()\r
135                 {\r
136                         return (XmlSchemaParticle) MemberwiseClone ();\r
137                 }\r
138 \r
139                 internal void CompileOccurence (ValidationEventHandler h, XmlSchema schema)\r
140                 {\r
141                         if (MinOccurs > MaxOccurs && !(MaxOccurs == 0 && MinOccursString == null))\r
142                                 error(h,"minOccurs must be less than or equal to maxOccurs");\r
143                         else {\r
144                                 if (MaxOccursString == "unbounded")\r
145                                         this.validatedMaxOccurs = decimal.MaxValue;\r
146                                 else\r
147                                         this.validatedMaxOccurs = maxOccurs;\r
148                                 if (this.validatedMaxOccurs == 0)\r
149                                         this.validatedMinOccurs = 0;\r
150                                 else\r
151                                         this.validatedMinOccurs = minOccurs;\r
152                         }\r
153                 }\r
154 \r
155                 internal override void CopyInfo (XmlSchemaParticle obj)\r
156                 {\r
157                         base.CopyInfo (obj);\r
158                         if (MaxOccursString == "unbounded")\r
159                                 obj.maxOccurs = obj.validatedMaxOccurs = decimal.MaxValue;\r
160                         else \r
161                                 obj.maxOccurs = obj.validatedMaxOccurs = this.ValidatedMaxOccurs;\r
162                         if (MaxOccurs == 0)\r
163                                 obj.minOccurs = obj.validatedMinOccurs = 0;\r
164                         else\r
165                                 obj.minOccurs = obj.validatedMinOccurs = this.ValidatedMinOccurs;\r
166                         if (MinOccursString != null)\r
167                                 obj.MinOccursString = MinOccursString;\r
168                         if (MaxOccursString != null)\r
169                                 obj.MaxOccursString = MaxOccursString;\r
170                 }\r
171 \r
172                 internal virtual bool ValidateOccurenceRangeOK (XmlSchemaParticle other,\r
173                         ValidationEventHandler h, XmlSchema schema, bool raiseError)\r
174                 {\r
175                         if ((this.ValidatedMinOccurs < other.ValidatedMinOccurs) ||\r
176                                 (other.ValidatedMaxOccurs != decimal.MaxValue &&\r
177                                 this.ValidatedMaxOccurs > other.ValidatedMaxOccurs)) {\r
178                                 if (raiseError)\r
179                                         error (h, "Invalid derivation occurence range was found.");\r
180                                 return false;\r
181                         }\r
182                         return true;\r
183                 }\r
184 \r
185                 internal virtual decimal GetMinEffectiveTotalRange ()\r
186                 {\r
187                         return ValidatedMinOccurs;\r
188                 }\r
189 \r
190                 internal decimal GetMinEffectiveTotalRangeAllAndSequence ()\r
191                 {\r
192                         if (minEffectiveTotalRange >= 0)\r
193                                 return minEffectiveTotalRange;\r
194 \r
195                         decimal product = 0; //this.ValidatedMinOccurs;\r
196                         XmlSchemaObjectCollection col = null;\r
197                         if (this is XmlSchemaAll)\r
198                                 col = ((XmlSchemaAll) this).Items;\r
199                         else\r
200                                 col = ((XmlSchemaSequence) this).Items;\r
201                         foreach (XmlSchemaParticle p in col)\r
202                                 product += p.GetMinEffectiveTotalRange ();\r
203 \r
204                         minEffectiveTotalRange = product;\r
205                         return product;\r
206                 }\r
207 \r
208                 // 3.9.6 Particle Emptiable\r
209                 internal virtual bool ValidateIsEmptiable ()\r
210                 {\r
211                         return this.validatedMinOccurs == 0 || this.GetMinEffectiveTotalRange () == 0;\r
212                 }\r
213 \r
214                 internal abstract bool ValidateDerivationByRestriction (XmlSchemaParticle baseParticle,\r
215                         ValidationEventHandler h, XmlSchema schema, bool raiseError);\r
216 \r
217                 internal abstract void ValidateUniqueParticleAttribution (\r
218                         XmlSchemaObjectTable qnames, ArrayList nsNames,\r
219                         ValidationEventHandler h, XmlSchema schema);\r
220 \r
221                 internal abstract void ValidateUniqueTypeAttribution (XmlSchemaObjectTable labels,\r
222                         ValidationEventHandler h, XmlSchema schema);\r
223 \r
224                 // See http://www.thaiopensource.com/relaxng/simplify.html\r
225                 internal abstract void CheckRecursion (int depth, ValidationEventHandler h, XmlSchema schema);\r
226 \r
227                 internal abstract bool ParticleEquals (XmlSchemaParticle other);\r
228 \r
229                 #region Internal Class\r
230                 internal class EmptyParticle : XmlSchemaParticle\r
231                 {\r
232                         internal EmptyParticle ()\r
233                         {\r
234                         }\r
235 \r
236                         internal override XmlSchemaParticle GetOptimizedParticle (bool isTop)\r
237                         {\r
238                                 return this;\r
239                         }\r
240 \r
241                         internal override bool ParticleEquals (XmlSchemaParticle other)\r
242                         {\r
243                                 return other == this || other == XmlSchemaParticle.Empty;\r
244                         }\r
245 \r
246                         internal override bool ValidateDerivationByRestriction (XmlSchemaParticle baseParticle,\r
247                                 ValidationEventHandler h, XmlSchema schema, bool raiseError)\r
248                         {\r
249                                 return true;\r
250                         }\r
251 \r
252                         internal override void CheckRecursion (int depth, \r
253                                 ValidationEventHandler h, XmlSchema schema)\r
254                         {\r
255                                 // do nothing\r
256                         }\r
257 \r
258                         internal override void ValidateUniqueParticleAttribution (XmlSchemaObjectTable qnames,\r
259                                 ArrayList nsNames, ValidationEventHandler h, XmlSchema schema)\r
260                         {\r
261                                 // do nothing\r
262                         }\r
263 \r
264                         internal override void ValidateUniqueTypeAttribution (XmlSchemaObjectTable labels,\r
265                                 ValidationEventHandler h, XmlSchema schema)\r
266                         {\r
267                                 // do nothing\r
268                         }\r
269 \r
270                 }\r
271                 #endregion\r
272         }\r
273 }