2005-12-27 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / Commons.Xml.Relaxng / Commons.Xml.Relaxng / RelaxngNameClass.cs
1 //\r
2 // Commons.Xml.Relaxng.RelaxngNameClass.cs\r
3 //\r
4 // Author:\r
5 //      Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>\r
6 //\r
7 // 2003 Atsushi Enomoto "No rights reserved."\r
8 //\r
9 // Copyright (c) 2004 Novell Inc.\r
10 // All rights reserved\r
11 //\r
12
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 // 
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 // 
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 //
33 \r
34 using System;\r
35 using System.Collections;\r
36 using System.IO;\r
37 using System.Net;\r
38 using System.Xml;\r
39 using Commons.Xml.Relaxng.Derivative;\r
40 using Commons.Xml.Relaxng.Rnc;\r
41 \r
42 namespace Commons.Xml.Relaxng\r
43 {\r
44         public class RelaxngNameClassList : CollectionBase\r
45         {\r
46                 public RelaxngNameClassList ()\r
47                 {\r
48                 }\r
49 \r
50                 public void Add (RelaxngNameClass p)\r
51                 {\r
52                         List.Add (p);\r
53                 }\r
54 \r
55                 public RelaxngNameClass this [int i] {\r
56                         get { return this.List [i] as RelaxngNameClass; }\r
57                         set { this.List [i] = value; }\r
58                 }\r
59 \r
60                 public void Insert (int pos, RelaxngNameClass p)\r
61                 {\r
62                         List.Insert (pos, p);\r
63                 }\r
64 \r
65                 public void Remove (RelaxngNameClass p)\r
66                 {\r
67                         List.Remove (p);\r
68                 }\r
69         }\r
70 \r
71         public abstract class RelaxngNameClass : RelaxngElementBase\r
72         {\r
73                 protected RelaxngNameClass ()\r
74                 {\r
75                 }\r
76 \r
77                 internal abstract RdpNameClass Compile (RelaxngGrammar g);\r
78 \r
79                 internal abstract void CheckConstraints (bool rejectAnyName, bool rejectNsName);\r
80 \r
81                 internal bool FindInvalidType (RdpNameClass nc, bool allowNsName)\r
82                 {\r
83                         RdpNameClassChoice choice = nc as RdpNameClassChoice;\r
84                         if (choice != null)\r
85                                 return FindInvalidType (choice.LValue, allowNsName)\r
86                                         || FindInvalidType (choice.RValue, allowNsName);\r
87                         else if (nc is RdpAnyName)\r
88                                 return true;\r
89                         else if (nc is RdpNsName && !allowNsName)\r
90                                 return true;\r
91                         else\r
92                                 return false;\r
93                 }\r
94         }\r
95 \r
96         public class RelaxngAnyName : RelaxngNameClass\r
97         {\r
98                 RelaxngExceptNameClass except;\r
99                 public RelaxngAnyName ()\r
100                 {\r
101                 }\r
102 \r
103                 public RelaxngExceptNameClass Except {\r
104                         get { return except; }\r
105                         set { except = value; }\r
106                 }\r
107 \r
108                 public override void Write (XmlWriter writer)\r
109                 {\r
110                         writer.WriteStartElement ("", "anyName", RelaxngGrammar.NamespaceURI);\r
111                         if (except != null)\r
112                                 except.Write (writer);\r
113                         writer.WriteEndElement ();\r
114                 }\r
115 \r
116                 internal override void WriteRnc (RncWriter writer)\r
117                 {\r
118                         writer.WriteAnyName (this);\r
119                 }\r
120 \r
121                 internal override RdpNameClass Compile (RelaxngGrammar g)\r
122                 {\r
123                         if (except != null) {\r
124                                 RdpNameClass exc = except.Compile (g);\r
125                                 if (FindInvalidType (exc, true))\r
126                                         throw new RelaxngException (except, "anyName except cannot have anyName children.");\r
127                                 return new RdpAnyNameExcept (exc);\r
128                         } else\r
129                                 return RdpAnyName.Instance;\r
130                 }\r
131 \r
132                 internal override void CheckConstraints (bool rejectAnyName, bool rejectNsName) \r
133                 {\r
134                         if (rejectAnyName)\r
135                                 throw new RelaxngException (this, "Not allowed anyName was found.");\r
136                         if (except != null)\r
137                                 foreach (RelaxngNameClass nc in except.Names)\r
138                                         nc.CheckConstraints (true, rejectNsName);\r
139                 }\r
140 \r
141         }\r
142 \r
143         public class RelaxngNsName : RelaxngNameClass\r
144         {\r
145                 string ns;\r
146                 RelaxngExceptNameClass except;\r
147                 public RelaxngNsName ()\r
148                 {\r
149                 }\r
150 \r
151                 public string Namespace {\r
152                         get { return ns; }\r
153                         set { ns = value; }\r
154                 }\r
155 \r
156                 public RelaxngExceptNameClass Except {\r
157                         get { return except; }\r
158                         set { except = value; }\r
159                 }\r
160 \r
161                 public override void Write (XmlWriter writer)\r
162                 {\r
163                         writer.WriteStartElement ("", "nsName", RelaxngGrammar.NamespaceURI);\r
164                         if (except != null)\r
165                                 except.Write (writer);\r
166                         writer.WriteEndElement ();\r
167                 }\r
168 \r
169                 internal override void WriteRnc (RncWriter writer)\r
170                 {\r
171                         writer.WriteNsName (this);\r
172                 }\r
173 \r
174                 internal override RdpNameClass Compile (RelaxngGrammar g)\r
175                 {\r
176                         if (except != null) {\r
177                                 RdpNameClass exc = except.Compile (g);\r
178                                 if (FindInvalidType (exc, false))\r
179                                         throw new RelaxngException (except, "nsName except cannot have anyName nor nsName children.");\r
180                                 return new RdpNsNameExcept (ns, exc);\r
181                         } else {\r
182                                 return new RdpNsName (ns);\r
183                         }\r
184                 }\r
185 \r
186                 internal override void CheckConstraints (bool rejectAnyName, bool rejectNsName) \r
187                 {\r
188                         if (rejectNsName)\r
189                                 throw new RelaxngException (this, "Not allowed nsName was found.");\r
190                         if (except != null)\r
191                                 foreach (RelaxngNameClass nc in except.Names)\r
192                                         nc.CheckConstraints (true, true);\r
193                 }\r
194 \r
195         }\r
196 \r
197         public class RelaxngName : RelaxngNameClass\r
198         {\r
199                 string ns;\r
200                 string ncname;\r
201 \r
202                 public RelaxngName ()\r
203                 {\r
204                 }\r
205 \r
206                 public RelaxngName (string ncname, string ns)\r
207                 {\r
208                         XmlConvert.VerifyNCName (ncname);\r
209                         this.ncname = ncname;\r
210                         this.ns = ns;\r
211                 }\r
212 \r
213                 public string LocalName {\r
214                         get { return ncname; }\r
215                         set {\r
216                                 XmlConvert.VerifyNCName (value);\r
217                                 ncname = value;\r
218                         }\r
219                 }\r
220 \r
221                 public string Namespace {\r
222                         get { return ns; }\r
223                         set { ns = value; }\r
224                 }\r
225 \r
226                 public override void Write (XmlWriter writer)\r
227                 {\r
228                         writer.WriteStartElement ("", "name", RelaxngGrammar.NamespaceURI);\r
229                         writer.WriteAttributeString ("ns", ns);\r
230                         // Here we just skip qname\r
231                         writer.WriteString (ncname);\r
232                         writer.WriteEndElement ();\r
233                 }\r
234 \r
235                 internal override void WriteRnc (RncWriter writer)\r
236                 {\r
237                         writer.WriteName (this);\r
238                 }\r
239 \r
240                 internal override RdpNameClass Compile (RelaxngGrammar g)\r
241                 {\r
242                         return new RdpName (ncname, ns);\r
243                 }\r
244 \r
245                 internal override void CheckConstraints (bool rejectAnyName, bool rejectNsName) \r
246                 {\r
247                         // no error\r
248                 }\r
249         }\r
250 \r
251         public class RelaxngNameChoice : RelaxngNameClass\r
252         {\r
253                 RelaxngNameClassList names = new RelaxngNameClassList ();\r
254 \r
255                 public RelaxngNameChoice ()\r
256                 {\r
257                 }\r
258 \r
259                 public RelaxngNameClassList Children {\r
260                         get { return names; }\r
261                         set { names = value; }\r
262                 }\r
263 \r
264                 public override void Write (XmlWriter writer)\r
265                 {\r
266                         writer.WriteStartElement ("", "choice", RelaxngGrammar.NamespaceURI);\r
267                         foreach (RelaxngNameClass nc in Children)\r
268                                 nc.Write (writer);\r
269                         writer.WriteEndElement ();\r
270                 }\r
271 \r
272                 internal override void WriteRnc (RncWriter writer)\r
273                 {\r
274                         writer.WriteNameChoice (this);\r
275                 }\r
276 \r
277                 internal override RdpNameClass Compile (RelaxngGrammar g)\r
278                 {\r
279                         // Flatten names into RdpChoice. See 4.12.\r
280                         if (names.Count == 0)\r
281                                 return null;\r
282                         RdpNameClass p = ((RelaxngNameClass) names [0]).Compile (g);\r
283                         if (names.Count == 1)\r
284                                 return p;\r
285 \r
286                         for (int i=1; i<names.Count; i++)\r
287                                 p = new RdpNameClassChoice (p, ((RelaxngNameClass) names [i]).Compile (g));\r
288                         return p;\r
289                 }\r
290 \r
291                 internal override void CheckConstraints (bool rejectAnyName, bool rejectNsName) \r
292                 {\r
293                         foreach (RelaxngNameClass nc in names)\r
294                                 nc.CheckConstraints (rejectAnyName, rejectNsName);\r
295                 }\r
296         }\r
297 \r
298         public class RelaxngExceptNameClass : RelaxngElementBase\r
299         {\r
300                 RelaxngNameClassList names = new RelaxngNameClassList ();\r
301 \r
302                 public RelaxngExceptNameClass ()\r
303                 {\r
304                 }\r
305 \r
306                 public RelaxngNameClassList Names {\r
307                         get { return names; }\r
308                 }\r
309 \r
310                 public override void Write (XmlWriter writer)\r
311                 {\r
312                         writer.WriteStartElement ("", "except", RelaxngGrammar.NamespaceURI);\r
313                         foreach (RelaxngNameClass nc in Names)\r
314                                 nc.Write (writer);\r
315                         writer.WriteEndElement ();\r
316                 }\r
317 \r
318                 internal override void WriteRnc (RncWriter writer)\r
319                 {\r
320                         writer.WriteNameExcept (this);\r
321                 }\r
322 \r
323                 internal RdpNameClass Compile (RelaxngGrammar g)\r
324                 {\r
325                         // Flatten names into RdpGroup. See 4.12.\r
326                         if (names.Count == 0)\r
327                                 return null;\r
328                         RdpNameClass p = ((RelaxngNameClass) names [0]).Compile (g);\r
329                         for (int i=1; i<names.Count; i++) {\r
330                                 p = new RdpNameClassChoice (\r
331                                         ((RelaxngNameClass) names [i]).Compile (g),\r
332                                         p);\r
333                         }\r
334                         return p;\r
335                 }\r
336         }\r
337 }\r