2004-05-31 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 \r
10 using System;\r
11 using System.Collections;\r
12 using System.IO;\r
13 using System.Net;\r
14 using System.Xml;\r
15 using Commons.Xml.Relaxng.Derivative;\r
16 \r
17 namespace Commons.Xml.Relaxng\r
18 {\r
19         public class RelaxngNameClassList : CollectionBase\r
20         {\r
21                 public RelaxngNameClassList ()\r
22                 {\r
23                 }\r
24 \r
25                 public void Add (RelaxngNameClass p)\r
26                 {\r
27                         List.Add (p);\r
28                 }\r
29 \r
30                 public RelaxngNameClass this [int i] {\r
31                         get { return this.List [i] as RelaxngNameClass; }\r
32                         set { this.List [i] = value; }\r
33                 }\r
34 \r
35                 public void Insert (int pos, RelaxngNameClass p)\r
36                 {\r
37                         List.Insert (pos, p);\r
38                 }\r
39 \r
40                 public void Remove (RelaxngNameClass p)\r
41                 {\r
42                         List.Remove (p);\r
43                 }\r
44         }\r
45 \r
46         public abstract class RelaxngNameClass : RelaxngElementBase\r
47         {\r
48                 protected RelaxngNameClass ()\r
49                 {\r
50                 }\r
51 \r
52                 internal abstract RdpNameClass Compile (RelaxngGrammar g);\r
53 \r
54                 internal abstract void CheckConstraints (bool rejectAnyName, bool rejectNsName);\r
55 \r
56                 internal bool FindInvalidType (RdpNameClass nc, bool allowNsName)\r
57                 {\r
58                         RdpNameClassChoice choice = nc as RdpNameClassChoice;\r
59                         if (choice != null)\r
60                                 return FindInvalidType (choice.LValue, allowNsName)\r
61                                         || FindInvalidType (choice.RValue, allowNsName);\r
62                         else if (nc is RdpAnyName)\r
63                                 return true;\r
64                         else if (nc is RdpNsName && !allowNsName)\r
65                                 return true;\r
66                         else\r
67                                 return false;\r
68                 }\r
69         }\r
70 \r
71         public class RelaxngAnyName : RelaxngNameClass\r
72         {\r
73                 RelaxngExceptNameClass except;\r
74                 public RelaxngAnyName ()\r
75                 {\r
76                 }\r
77 \r
78                 public RelaxngExceptNameClass Except {\r
79                         get { return except; }\r
80                         set { except = value; }\r
81                 }\r
82 \r
83                 public override void Write (XmlWriter writer)\r
84                 {\r
85                         writer.WriteStartElement ("", "anyName", RelaxngGrammar.NamespaceURI);\r
86                         if (except != null)\r
87                                 except.Write (writer);\r
88                         writer.WriteEndElement ();\r
89                 }\r
90 \r
91                 internal override RdpNameClass Compile (RelaxngGrammar g)\r
92                 {\r
93                         if (except != null) {\r
94                                 RdpNameClass exc = except.Compile (g);\r
95                                 if (FindInvalidType (exc, true))\r
96                                         throw new RelaxngException ("anyName except cannot have anyName children.");\r
97                                 return new RdpAnyNameExcept (exc);\r
98                         } else\r
99                                 return RdpAnyName.Instance;\r
100                 }\r
101 \r
102                 internal override void CheckConstraints (bool rejectAnyName, bool rejectNsName) \r
103                 {\r
104                         if (rejectAnyName)\r
105                                 throw new RelaxngException ("Not allowed anyName was found.");\r
106                         if (except != null)\r
107                                 foreach (RelaxngNameClass nc in except.Names)\r
108                                         nc.CheckConstraints (true, rejectNsName);\r
109                 }\r
110 \r
111         }\r
112 \r
113         public class RelaxngNsName : RelaxngNameClass\r
114         {\r
115                 string ns;\r
116                 RelaxngExceptNameClass except;\r
117                 public RelaxngNsName ()\r
118                 {\r
119                 }\r
120 \r
121                 public string Namespace {\r
122                         get { return ns; }\r
123                         set { ns = value; }\r
124                 }\r
125 \r
126                 public RelaxngExceptNameClass Except {\r
127                         get { return except; }\r
128                         set { except = value; }\r
129                 }\r
130 \r
131                 public override void Write (XmlWriter writer)\r
132                 {\r
133                         writer.WriteStartElement ("", "nsName", RelaxngGrammar.NamespaceURI);\r
134                         if (except != null)\r
135                                 except.Write (writer);\r
136                         writer.WriteEndElement ();\r
137                 }\r
138 \r
139                 internal override RdpNameClass Compile (RelaxngGrammar g)\r
140                 {\r
141                         if (except != null) {\r
142                                 RdpNameClass exc = except.Compile (g);\r
143                                 if (FindInvalidType (exc, false))\r
144                                         throw new RelaxngException ("nsName except cannot have anyName nor nsName children.");\r
145                                 return new RdpNsNameExcept (ns, exc);\r
146                         } else {\r
147                                 return new RdpNsName (ns);\r
148                         }\r
149                 }\r
150 \r
151                 internal override void CheckConstraints (bool rejectAnyName, bool rejectNsName) \r
152                 {\r
153                         if (rejectNsName)\r
154                                 throw new RelaxngException ("Not allowed nsName was found.");\r
155                         if (except != null)\r
156                                 foreach (RelaxngNameClass nc in except.Names)\r
157                                         nc.CheckConstraints (true, true);\r
158                 }\r
159 \r
160         }\r
161 \r
162         public class RelaxngName : RelaxngNameClass\r
163         {\r
164                 string ns;\r
165                 string ncname;\r
166 \r
167                 public RelaxngName ()\r
168                 {\r
169                 }\r
170 \r
171                 public RelaxngName (string ncname, string ns)\r
172                 {\r
173                         XmlConvert.VerifyNCName (ncname);\r
174                         this.ncname = ncname;\r
175                         this.ns = ns;\r
176                 }\r
177 \r
178                 public string LocalName {\r
179                         get { return ncname; }\r
180                         set {\r
181                                 XmlConvert.VerifyNCName (value);\r
182                                 ncname = value;\r
183                         }\r
184                 }\r
185 \r
186                 public string Namespace {\r
187                         get { return ns; }\r
188                         set { ns = value; }\r
189                 }\r
190 \r
191                 public override void Write (XmlWriter writer)\r
192                 {\r
193                         writer.WriteStartElement ("", "name", RelaxngGrammar.NamespaceURI);\r
194                         writer.WriteAttributeString ("ns", ns);\r
195                         // Here we just skip qname\r
196                         writer.WriteString (ncname);\r
197                         writer.WriteEndElement ();\r
198                 }\r
199 \r
200                 internal override RdpNameClass Compile (RelaxngGrammar g)\r
201                 {\r
202                         return new RdpName (ncname, ns);\r
203                 }\r
204 \r
205                 internal override void CheckConstraints (bool rejectAnyName, bool rejectNsName) \r
206                 {\r
207                         // no error\r
208                 }\r
209         }\r
210 \r
211         public class RelaxngNameChoice : RelaxngNameClass\r
212         {\r
213                 RelaxngNameClassList names = new RelaxngNameClassList ();\r
214 \r
215                 public RelaxngNameChoice ()\r
216                 {\r
217                 }\r
218 \r
219                 public RelaxngNameClassList Children {\r
220                         get { return names; }\r
221                         set { names = value; }\r
222                 }\r
223 \r
224                 public override void Write (XmlWriter writer)\r
225                 {\r
226                         writer.WriteStartElement ("", "choice", RelaxngGrammar.NamespaceURI);\r
227                         foreach (RelaxngNameClass nc in Children)\r
228                                 nc.Write (writer);\r
229                         writer.WriteEndElement ();\r
230                 }\r
231 \r
232                 internal override RdpNameClass Compile (RelaxngGrammar g)\r
233                 {\r
234                         // Flatten names into RdpChoice. See 4.12.\r
235                         if (names.Count == 0)\r
236                                 return null;\r
237                         RdpNameClass p = ((RelaxngNameClass) names [0]).Compile (g);\r
238                         if (names.Count == 1)\r
239                                 return p;\r
240 \r
241                         for (int i=1; i<names.Count; i++)\r
242                                 p = new RdpNameClassChoice (p, ((RelaxngNameClass) names [i]).Compile (g));\r
243                         return p;\r
244                 }\r
245 \r
246                 internal override void CheckConstraints (bool rejectAnyName, bool rejectNsName) \r
247                 {\r
248                         foreach (RelaxngNameClass nc in names)\r
249                                 nc.CheckConstraints (rejectAnyName, rejectNsName);\r
250                 }\r
251         }\r
252 \r
253         public class RelaxngExceptNameClass : RelaxngElementBase\r
254         {\r
255                 RelaxngNameClassList names = new RelaxngNameClassList ();\r
256 \r
257                 public RelaxngExceptNameClass ()\r
258                 {\r
259                 }\r
260 \r
261                 public RelaxngNameClassList Names {\r
262                         get { return names; }\r
263                 }\r
264 \r
265                 public override void Write (XmlWriter writer)\r
266                 {\r
267                         writer.WriteStartElement ("", "except", RelaxngGrammar.NamespaceURI);\r
268                         foreach (RelaxngNameClass nc in Names)\r
269                                 nc.Write (writer);\r
270                         writer.WriteEndElement ();\r
271                 }\r
272 \r
273                 internal RdpNameClass Compile (RelaxngGrammar g)\r
274                 {\r
275                         // Flatten names into RdpGroup. See 4.12.\r
276                         if (names.Count == 0)\r
277                                 return null;\r
278                         RdpNameClass p = ((RelaxngNameClass) names [0]).Compile (g);\r
279                         for (int i=1; i<names.Count; i++) {\r
280                                 p = new RdpNameClassChoice (\r
281                                         ((RelaxngNameClass) names [i]).Compile (g),\r
282                                         p);\r
283                         }\r
284                         return p;\r
285                 }\r
286         }\r
287 }\r