2005-12-27 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / Commons.Xml.Relaxng / Commons.Xml.Relaxng / RelaxngPattern.cs
1 //\r
2 // Commons.Xml.Relaxng.RelaxngPattern.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.Xml;\r
38 using Commons.Xml.Relaxng.Derivative;\r
39 using Commons.Xml.Relaxng.Rnc;\r
40 \r
41 #if NET_2_0\r
42 using NSResolver = System.Xml.IXmlNamespaceResolver;\r
43 #else\r
44 using NSResolver = System.Xml.XmlNamespaceManager;\r
45 #endif\r
46 \r
47 namespace Commons.Xml.Relaxng\r
48 {\r
49         #region Common abstract\r
50         public abstract class RelaxngElementBase\r
51         {\r
52                 bool isCompiled;\r
53                 int lineNumber, linePosition;\r
54                 string baseUri;\r
55 \r
56                 internal bool IsCompiled {\r
57                         get { return isCompiled; }\r
58                         set { isCompiled = value; }\r
59                 }\r
60 \r
61                 public int LineNumber {\r
62                         get { return lineNumber; }\r
63                         set { lineNumber = value; }\r
64                 }\r
65 \r
66                 public int LinePosition {\r
67                         get { return linePosition; }\r
68                         set { linePosition = value; }\r
69                 }\r
70 \r
71                 public string BaseUri {\r
72                         get { return baseUri; }\r
73                         set { baseUri = value; }\r
74                 }\r
75 \r
76                 public abstract void Write (XmlWriter writer);\r
77 \r
78                 internal abstract void WriteRnc (RncWriter writer);\r
79         }\r
80 \r
81         public abstract class RelaxngSingleContentPattern : RelaxngPattern\r
82         {\r
83                 private RelaxngPatternList patterns = new RelaxngPatternList ();\r
84 \r
85                 public RelaxngPatternList Patterns {\r
86                         get { return patterns; }\r
87                 }\r
88 \r
89                 internal RdpPattern makeSingle (RelaxngGrammar g)\r
90                 {\r
91                         // Flatten patterns into RdpGroup. See 4.12.\r
92                         if (patterns.Count == 0)\r
93                                 throw new RelaxngException (this, "No pattern contents.");\r
94                         RdpPattern p = ((RelaxngPattern) patterns [0]).Compile (g);\r
95                         if (patterns.Count == 1)\r
96                                 return p;\r
97                         for (int i=1; i<patterns.Count; i++) {\r
98                                 p = new RdpGroup (p,\r
99                                         ((RelaxngPattern) patterns [i]).Compile (g));\r
100                         }\r
101                         return p;\r
102                 }\r
103 \r
104                 internal override void CheckConstraints () \r
105                 {\r
106                         foreach (RelaxngPattern p in Patterns)\r
107                                 p.CheckConstraints ();\r
108                 }\r
109         }\r
110 \r
111         public abstract class RelaxngBinaryContentPattern : RelaxngPattern\r
112         {\r
113                 private RelaxngPatternList patterns = new RelaxngPatternList ();\r
114 \r
115                 public RelaxngPatternList Patterns {\r
116                         get { return patterns; }\r
117                 }\r
118 \r
119                 internal RdpPattern makeBinary (RelaxngGrammar g)\r
120                 {\r
121                         // Flatten patterns. See 4.12.\r
122                         if (patterns.Count == 0)\r
123                                 throw new RelaxngException (this, "No pattern contents.");\r
124 \r
125                         RdpPattern p = ((RelaxngPattern) patterns [0]).Compile (g);\r
126                         if (patterns.Count == 1)\r
127                                 return p;\r
128 \r
129                         for (int i=1; i<patterns.Count; i++) {\r
130                                 RdpPattern cp =\r
131                                         ((RelaxngPattern) patterns [i]).Compile (g);\r
132                                 switch (this.PatternType) {\r
133                                 case RelaxngPatternType.Choice:\r
134                                         p = new RdpChoice (p, cp);\r
135                                         break;\r
136                                 case RelaxngPatternType.Group:\r
137                                         p = new RdpGroup (p, cp);\r
138                                         break;\r
139                                 case RelaxngPatternType.Interleave:\r
140                                         p = new RdpInterleave (p, cp);\r
141                                         break;\r
142                                 }\r
143                         }\r
144 \r
145                         return p;\r
146                 }\r
147 \r
148                 internal override void CheckConstraints () \r
149                 {\r
150                         foreach (RelaxngPattern p in Patterns)\r
151                                 p.CheckConstraints ();\r
152                 }\r
153         }\r
154         #endregion\r
155 \r
156         #region Grammatical elements\r
157         public interface IGrammarContent\r
158         {\r
159         }\r
160 \r
161         public class RelaxngStart : RelaxngElementBase, IGrammarContent\r
162         {\r
163                 RelaxngPattern p;\r
164                 string combine;\r
165 \r
166                 public RelaxngStart ()\r
167                 {\r
168                 }\r
169 \r
170                 public string Combine {\r
171                         get { return combine; }\r
172                         set { combine = value; }\r
173                 }\r
174 \r
175                 public RelaxngPattern Pattern {\r
176                         get { return p; }\r
177                         set { p = value; }\r
178                 }\r
179 \r
180                 public override void Write (XmlWriter writer)\r
181                 {\r
182                         writer.WriteStartElement ("", "start", RelaxngGrammar.NamespaceURI);\r
183                         if (combine != null)\r
184                                 writer.WriteAttributeString ("combine", combine);\r
185                         p.Write (writer);\r
186                         writer.WriteEndElement ();\r
187                 }\r
188 \r
189                 internal override void WriteRnc (RncWriter writer)\r
190                 {\r
191                         writer.WriteStart (this);\r
192                 }\r
193 \r
194                 internal RdpPattern Compile (RelaxngGrammar grammar)\r
195                 {\r
196                         return p.Compile (grammar);\r
197                 }\r
198         }\r
199 \r
200         public class RelaxngDefine : RelaxngElementBase, IGrammarContent\r
201         {\r
202                 string name;\r
203                 private RelaxngPatternList patterns = new RelaxngPatternList ();\r
204                 string combine;\r
205 \r
206                 public RelaxngDefine ()\r
207                 {\r
208                 }\r
209 \r
210                 public RelaxngPatternList Patterns {\r
211                         get { return patterns; }\r
212                 }\r
213 \r
214                 public string Combine {\r
215                         get { return combine; }\r
216                         set { combine = value; }\r
217                 }\r
218 \r
219                 public string Name {\r
220                         get { return name; }\r
221                         set { name = value; }\r
222                 }\r
223 \r
224                 public override void Write (XmlWriter writer)\r
225                 {\r
226                         writer.WriteStartElement ("", "define", RelaxngGrammar.NamespaceURI);\r
227                         writer.WriteAttributeString ("name", name);\r
228                         if (combine != null)\r
229                                 writer.WriteAttributeString ("combine", combine);\r
230                         foreach (RelaxngPattern p in Patterns)\r
231                                 p.Write (writer);\r
232                         writer.WriteEndElement ();\r
233                 }\r
234 \r
235                 internal override void WriteRnc (RncWriter writer)\r
236                 {\r
237                         writer.WriteDefine (this);\r
238                 }\r
239 \r
240                 internal RdpPattern Compile (RelaxngGrammar grammar)\r
241                 {\r
242                         return makeSingle (grammar);\r
243                 }\r
244 \r
245                 private RdpPattern makeSingle (RelaxngGrammar g)\r
246                 {\r
247                         // Flatten patterns into RdpGroup. See 4.12.\r
248                         if (patterns.Count == 0)\r
249                                 throw new RelaxngException (this, "No pattern contents.");\r
250                         RdpPattern p = ((RelaxngPattern) patterns [0]).Compile (g);\r
251                         if (patterns.Count == 1)\r
252                                 return p;\r
253                         for (int i=1; i<patterns.Count; i++) {\r
254                                 p = new RdpGroup (p,\r
255                                         ((RelaxngPattern) patterns [i]).Compile (g));\r
256                         }\r
257                         return p;\r
258                 }\r
259         }\r
260 \r
261         public class RelaxngInclude : RelaxngElementBase, IGrammarContent\r
262         {\r
263                 string href;\r
264                 RelaxngGrammarContentList starts = new RelaxngGrammarContentList ();\r
265                 RelaxngGrammarContentList defines = new RelaxngGrammarContentList ();\r
266                 RelaxngGrammarContentList divs = new RelaxngGrammarContentList ();\r
267                 string ns;\r
268 \r
269                 public RelaxngInclude ()\r
270                 {\r
271                 }\r
272 \r
273                 public string Href {\r
274                         get { return href; }\r
275                         set { href = value; }\r
276                 }\r
277 \r
278                 public RelaxngGrammarContentList Starts {\r
279                         get { return starts; }\r
280                 }\r
281 \r
282                 public RelaxngGrammarContentList Defines {\r
283                         get { return defines; }\r
284                 }\r
285 \r
286                 public RelaxngGrammarContentList Divs {\r
287                         get { return divs; }\r
288                 }\r
289 \r
290                 public string NSContext {\r
291                         get { return ns; }\r
292                         set { ns = value; }\r
293                 }\r
294 \r
295                 public override void Write (XmlWriter writer)\r
296                 {\r
297                         writer.WriteStartElement ("", "include", RelaxngGrammar.NamespaceURI);\r
298                         writer.WriteAttributeString ("href", href);\r
299                         foreach (RelaxngStart start in Starts)\r
300                                 start.Write (writer);\r
301                         foreach (RelaxngDefine define in Defines)\r
302                                 define.Write (writer);\r
303                         foreach (RelaxngDiv div in Divs)\r
304                                 div.Write (writer);\r
305                         writer.WriteEndElement ();\r
306                 }\r
307 \r
308                 internal override void WriteRnc (RncWriter writer)\r
309                 {\r
310                         writer.WriteInclude (this);\r
311                 }\r
312 \r
313                 // compile into div\r
314                 internal RelaxngDiv Compile (RelaxngGrammar grammar)\r
315                 {\r
316                         grammar.CheckIncludeRecursion (Href);\r
317                         grammar.IncludedUris.Add (Href, Href);\r
318                         if (grammar.Resolver == null)\r
319                                 throw new RelaxngException (this, "To compile 'include' element, XmlResolver is required.");\r
320                         Uri uri = grammar.Resolver.ResolveUri (BaseUri != String.Empty ? new Uri (BaseUri) : null, Href);\r
321                         XmlTextReader xtr = null;\r
322                         RelaxngGrammar g = null;\r
323                         try {\r
324                                 xtr = new XmlTextReader (uri.AbsoluteUri, (Stream) grammar.Resolver.GetEntity (uri, null, typeof (Stream)));\r
325                                 RelaxngReader r = new RelaxngReader (xtr, ns);\r
326                                 r.MoveToContent ();\r
327                                 g = r.ReadPattern () as RelaxngGrammar;\r
328                         } finally {\r
329                                 xtr.Close ();\r
330                         }\r
331                         if (g == null)\r
332                                 throw new RelaxngException (this, "Included syntax must start with \"grammar\" element.");\r
333                         g.DataProvider = grammar.Provider;\r
334 \r
335                         // process recursive inclusions.\r
336                         foreach (RelaxngInclude inc in g.Includes)\r
337                                 g.Divs.Add (inc.Compile (grammar));\r
338 \r
339                         // process this own div children.\r
340                         // each div subelements are also compiled.\r
341                         foreach (RelaxngDiv cdiv in divs)\r
342                                 cdiv.Compile (g);\r
343                         foreach (RelaxngDiv cdiv in g.Divs)\r
344                                 cdiv.Compile (g);\r
345 \r
346                         // replace redifinitions into div.\r
347                         // starts.\r
348                         if (this.Starts.Count > 0 && g.Starts.Count == 0)\r
349                                 throw new RelaxngException (this, "When the included grammar does not contain start components, this include component must not contain start components.");\r
350                         RelaxngGrammarContentList appliedStarts = (this.starts.Count > 0) ?\r
351                                 this.starts : g.Starts;\r
352 \r
353                         RelaxngDiv div = new RelaxngDiv ();\r
354                         div.BaseUri = this.BaseUri;\r
355                         div.LinePosition = this.LinePosition;\r
356                         div.LineNumber = this.LineNumber;\r
357 \r
358                         foreach (RelaxngStart start in appliedStarts)\r
359                                 div.Starts.Add (start);\r
360 \r
361                         // defines.\r
362                         Hashtable overrides = new Hashtable ();\r
363                         Hashtable originalDefs = new Hashtable ();\r
364                         foreach (RelaxngDefine def in defines) {\r
365                                 overrides.Add (def.Name, def.Name);\r
366                                 div.Defines.Add (def);\r
367                         }\r
368                         foreach (RelaxngDefine def in g.Defines) {\r
369                                 originalDefs [def.Name] = def.Name;\r
370                                 if (!overrides.ContainsKey (def.Name)) {\r
371                                         div.Defines.Add (def);\r
372                                 }\r
373                                 // else discard.\r
374                         }\r
375 \r
376                         foreach (string name in overrides.Values)\r
377                                 if (!originalDefs.ContainsKey (name))\r
378                                         throw new RelaxngException (this, "The include component must not contain define components whose name does not appear in the included grammar component.");\r
379 \r
380                         grammar.IncludedUris.Remove (Href);\r
381                         return div;\r
382                 }\r
383         }\r
384 \r
385         public class RelaxngDiv : RelaxngElementBase, IGrammarContent\r
386         {\r
387                 RelaxngGrammarContentList starts = new RelaxngGrammarContentList ();\r
388                 RelaxngGrammarContentList defines = new RelaxngGrammarContentList ();\r
389                 RelaxngGrammarContentList includes = new RelaxngGrammarContentList ();\r
390                 RelaxngGrammarContentList divs = new RelaxngGrammarContentList ();\r
391 \r
392                 public RelaxngDiv ()\r
393                 {\r
394                 }\r
395 \r
396                 public RelaxngGrammarContentList Starts {\r
397                         get { return starts; }\r
398                 }\r
399 \r
400                 public RelaxngGrammarContentList Defines {\r
401                         get { return defines; }\r
402                 }\r
403 \r
404                 public RelaxngGrammarContentList Includes {\r
405                         get { return includes; }\r
406                 }\r
407 \r
408                 public RelaxngGrammarContentList Divs {\r
409                         get { return divs; }\r
410                 }\r
411 \r
412                 public override void Write (XmlWriter writer)\r
413                 {\r
414                         writer.WriteStartElement ("", "div", RelaxngGrammar.NamespaceURI);\r
415                         foreach (RelaxngStart start in Starts)\r
416                                 start.Write (writer);\r
417                         foreach (RelaxngDefine define in Defines)\r
418                                 define.Write (writer);\r
419                         foreach (RelaxngInclude include in Includes)\r
420                                 include.Write (writer);\r
421                         foreach (RelaxngDiv div in Divs)\r
422                                 div.Write (writer);\r
423                         writer.WriteEndElement ();\r
424                 }\r
425 \r
426                 internal override void WriteRnc (RncWriter writer)\r
427                 {\r
428                         writer.WriteDiv (this);\r
429                 }\r
430 \r
431                 internal void Compile (RelaxngGrammar grammar)\r
432                 {\r
433                         foreach (RelaxngDiv div in divs)\r
434                                 div.Compile (grammar);\r
435                         foreach (RelaxngInclude inc in includes)\r
436                                 inc.Compile (grammar).Compile (grammar); // compile compiled divs\r
437                         foreach (RelaxngStart start in starts)\r
438                                 grammar.Starts.Add (start);\r
439                         foreach (RelaxngDefine define in defines)\r
440                                 grammar.Defines.Add (define);\r
441                 }\r
442         }\r
443         #endregion\r
444 \r
445         #region RelaxngPatterns\r
446         public abstract class RelaxngPattern : RelaxngElementBase\r
447         {\r
448                 // static\r
449 \r
450                 public static RelaxngPattern Read (XmlReader xmlReader)\r
451                 {\r
452                         return Read (xmlReader, null);\r
453                 }\r
454 \r
455                 public static RelaxngPattern Read (XmlReader xmlReader, RelaxngDatatypeProvider provider)\r
456                 {\r
457                         RelaxngReader r = new RelaxngReader (xmlReader, null);\r
458                         if (r.ReadState == ReadState.Initial)\r
459                                 r.Read ();\r
460                         r.MoveToContent ();\r
461                         RelaxngPattern p = r.ReadPattern ();\r
462                         p.DataProvider = provider;\r
463                         return p;\r
464                 }\r
465 \r
466                 // Private Fields\r
467                 RdpPattern startRelaxngPattern;\r
468                 RelaxngDatatypeProvider provider;\r
469                 XmlResolver resolver;\r
470                 bool nullResolver;\r
471 \r
472                 // Public\r
473                 public XmlResolver XmlResolver {\r
474                         set {\r
475                                 nullResolver = value == null;\r
476                                 resolver = value;\r
477                         }\r
478                 }\r
479 \r
480                 public abstract RelaxngPatternType PatternType { get; }\r
481                 public RelaxngDatatypeProvider DataProvider {\r
482                         get {\r
483                                 return provider; \r
484                         }\r
485                         set { \r
486                                 provider = value; \r
487                         }\r
488                 }\r
489 \r
490                 public void Compile ()\r
491                 {\r
492                         RelaxngGrammar g = null;\r
493                         if (this is RelaxngGrammar)\r
494                                 g = (RelaxngGrammar) this;\r
495                         else {\r
496                                 g = new RelaxngGrammar ();\r
497                                 g.XmlResolver = this.Resolver;\r
498                                 g.BaseUri = this.BaseUri;\r
499                                 g.LineNumber = this.LineNumber;\r
500                                 g.LinePosition = this.LinePosition;\r
501                                 RelaxngStart st = new RelaxngStart ();\r
502                                 st.BaseUri = this.BaseUri;\r
503                                 st.LineNumber = this.LineNumber;\r
504                                 st.LinePosition = this.LinePosition;\r
505                                 st.Pattern = this;\r
506                                 g.Starts.Add (st);\r
507                                 g.Provider = provider;\r
508                         }\r
509                         startRelaxngPattern = g.Compile (null);\r
510                         this.IsCompiled = true;\r
511                 }\r
512 \r
513                 public void WriteCompact (TextWriter writer)\r
514                 {\r
515                         WriteCompact (new RncWriter (writer));\r
516                 }\r
517 \r
518                 public void WriteCompact (TextWriter writer, NSResolver res)\r
519                 {\r
520                         WriteCompact (new RncWriter (writer, res));\r
521                 }\r
522 \r
523                 void WriteCompact (RncWriter writer)\r
524                 {\r
525                         RelaxngGrammar g = this as RelaxngGrammar;\r
526                         string ns = (g != null ? g.DefaultNamespace : null);\r
527                         writer.WriteNamespaces (ns);\r
528                         WriteRnc (writer);\r
529                 }\r
530 \r
531                 // Internal\r
532                 internal XmlResolver Resolver {\r
533                         get {\r
534                                 if (nullResolver)\r
535                                         return null;\r
536                                 if (resolver == null)\r
537                                         resolver = new XmlUrlResolver ();\r
538                                 return resolver;\r
539                         }\r
540                 }\r
541 \r
542                 internal abstract void CheckConstraints ();\r
543 \r
544                 protected RelaxngPattern () \r
545                 {\r
546                 }\r
547 \r
548                 internal abstract RdpPattern Compile (RelaxngGrammar grammar);\r
549 \r
550                 internal RdpPattern StartPattern {\r
551                         get { return startRelaxngPattern; }\r
552                 }\r
553         }\r
554 \r
555         public class RelaxngPatternList : CollectionBase\r
556         {\r
557                 public RelaxngPatternList ()\r
558                 {\r
559                 }\r
560 \r
561                 public void Add (RelaxngPattern p)\r
562                 {\r
563                         List.Add (p);\r
564                 }\r
565 \r
566                 public RelaxngPattern this [int i] {\r
567                         get { return this.List [i] as RelaxngPattern; }\r
568                         set { this.List [i] = value; }\r
569                 }\r
570 \r
571                 public void Insert (int pos, RelaxngPattern p)\r
572                 {\r
573                         List.Insert (pos, p);\r
574                 }\r
575 \r
576                 public void Remove (RelaxngPattern p)\r
577                 {\r
578                         List.Remove (p);\r
579                 }\r
580         }\r
581 \r
582         public class RelaxngGrammarContentList : CollectionBase\r
583         {\r
584                 public RelaxngGrammarContentList ()\r
585                 {\r
586                 }\r
587 \r
588                 public void Add (IGrammarContent p)\r
589                 {\r
590                         List.Add (p);\r
591                 }\r
592 \r
593                 public IGrammarContent this [int i] {\r
594                         get { return this.List [i] as IGrammarContent; }\r
595                         set { this.List [i] = value; }\r
596                 }\r
597 \r
598                 public void Insert (int pos, IGrammarContent p)\r
599                 {\r
600                         List.Insert (pos, p);\r
601                 }\r
602 \r
603                 public void Remove (IGrammarContent p)\r
604                 {\r
605                         List.Remove (p);\r
606                 }\r
607         }\r
608 \r
609         // strict to say, it's not a pattern ;)\r
610         public class RelaxngNotAllowed : RelaxngPattern\r
611         {\r
612                 public RelaxngNotAllowed () \r
613                 {\r
614                 }\r
615 \r
616                 public override RelaxngPatternType PatternType {\r
617                         get { return RelaxngPatternType.NotAllowed; }\r
618                 }\r
619 \r
620                 public override void Write (XmlWriter writer)\r
621                 {\r
622                         writer.WriteStartElement ("", "notAllowed", RelaxngGrammar.NamespaceURI);\r
623                         writer.WriteEndElement ();\r
624                 }\r
625 \r
626                 internal override void WriteRnc (RncWriter writer)\r
627                 {\r
628                         writer.WriteNotAllowed (this);\r
629                 }\r
630 \r
631                 internal override RdpPattern Compile (RelaxngGrammar grammar)\r
632                 {\r
633                         return RdpNotAllowed.Instance;\r
634                 }\r
635 \r
636                 internal override void CheckConstraints () \r
637                 {\r
638                         // nothing to check\r
639                 }\r
640         }\r
641 \r
642         public class RelaxngEmpty : RelaxngPattern\r
643         {\r
644                 public RelaxngEmpty ()\r
645                 {\r
646                 }\r
647 \r
648                 public override RelaxngPatternType PatternType {\r
649                         get { return RelaxngPatternType.Empty; }\r
650                 }\r
651 \r
652                 public override void Write (XmlWriter writer)\r
653                 {\r
654                         writer.WriteStartElement ("", "empty", RelaxngGrammar.NamespaceURI);\r
655                         writer.WriteEndElement ();\r
656                 }\r
657 \r
658                 internal override void WriteRnc (RncWriter writer)\r
659                 {\r
660                         writer.WriteEmpty (this);\r
661                 }\r
662 \r
663                 internal override RdpPattern Compile (RelaxngGrammar grammar)\r
664                 {\r
665                         return RdpEmpty.Instance;\r
666                 }\r
667 \r
668                 internal override void CheckConstraints () \r
669                 {\r
670                         // nothing to check\r
671                 }\r
672         }\r
673 \r
674         public class RelaxngText : RelaxngPattern\r
675         {\r
676                 public RelaxngText () \r
677                 {\r
678                 }\r
679 \r
680                 public override RelaxngPatternType PatternType {\r
681                         get { return RelaxngPatternType.Text; }\r
682                 }\r
683 \r
684                 public override void Write (XmlWriter writer)\r
685                 {\r
686                         writer.WriteStartElement ("", "text", RelaxngGrammar.NamespaceURI);\r
687                         writer.WriteEndElement ();\r
688                 }\r
689 \r
690                 internal override void WriteRnc (RncWriter writer)\r
691                 {\r
692                         writer.WriteText (this);\r
693                 }\r
694 \r
695                 internal override RdpPattern Compile (RelaxngGrammar grammar)\r
696                 {\r
697                         return RdpText.Instance;\r
698                 }\r
699 \r
700                 internal override void CheckConstraints () \r
701                 {\r
702                         // nothing to check\r
703                 }\r
704         }\r
705 \r
706         public abstract class RelaxngDataSupport : RelaxngPattern\r
707         {\r
708                 string type;\r
709                 string datatypeLibrary;\r
710 \r
711                 public string Type {\r
712                         get { return type; }\r
713                         set { type = value; }\r
714                 }\r
715 \r
716                 public string DatatypeLibrary {\r
717                         get { return datatypeLibrary; }\r
718                         set { datatypeLibrary = value; }\r
719                 }\r
720 \r
721                 internal void CheckDatatypeName ()\r
722                 {\r
723                         // Data type name check is done in RdpData(Except) derivative creation.\r
724                 }\r
725         }\r
726 \r
727         public class RelaxngData : RelaxngDataSupport\r
728         {\r
729                 RelaxngParamList paramList = new RelaxngParamList ();\r
730                 RelaxngExcept except;\r
731 \r
732                 public RelaxngData ()\r
733                 {\r
734                 }\r
735 \r
736                 public override RelaxngPatternType PatternType {\r
737                         get { return RelaxngPatternType.Data; }\r
738                 }\r
739 \r
740                 public RelaxngParamList ParamList {\r
741                         get { return paramList; }\r
742                 }\r
743 \r
744                 public RelaxngExcept Except {\r
745                         get { return except; }\r
746                         set { except = value; }\r
747                 }\r
748 \r
749                 public override void Write (XmlWriter writer)\r
750                 {\r
751                         writer.WriteStartElement ("", "data", RelaxngGrammar.NamespaceURI);\r
752                         if (DatatypeLibrary != null && DatatypeLibrary != String.Empty)\r
753                                 writer.WriteAttributeString ("datatypeLibrary", DatatypeLibrary);\r
754                         writer.WriteAttributeString ("type", Type);\r
755 \r
756                         foreach (RelaxngParam p in ParamList)\r
757                                 p.Write (writer);\r
758 \r
759                         if (Except != null)\r
760                                 Except.Write (writer);\r
761 \r
762                         writer.WriteEndElement ();\r
763                 }\r
764 \r
765                 internal override void WriteRnc (RncWriter writer)\r
766                 {\r
767                         writer.WriteData (this);\r
768                 }\r
769 \r
770                 internal override RdpPattern Compile (RelaxngGrammar grammar)\r
771                 {\r
772 //                      RdpParamList rdpl = new RdpParamList ();\r
773 //                      foreach (RelaxngParam prm in this.paramList)\r
774 //                              rdpl.Add (prm.Compile (grammar));\r
775                         RdpPattern p = null;\r
776                         if (this.except != null) {\r
777                                 if (except.Patterns.Count == 0)\r
778                                         throw new RelaxngException (this, "data except pattern have no children.");\r
779                                 p = except.Patterns [0].Compile (grammar);\r
780                                 for (int i=1; i<except.Patterns.Count; i++)\r
781                                         p = new RdpChoice (p,\r
782                                                 except.Patterns [i].Compile (grammar));\r
783                         }\r
784 \r
785                         IsCompiled = true;\r
786                         if (this.except != null)\r
787                                 return new RdpDataExcept (new RdpDatatype (DatatypeLibrary, Type, ParamList, grammar.Provider), p);\r
788                         else\r
789                                 return new RdpData (new RdpDatatype (DatatypeLibrary, Type, ParamList, grammar.Provider));\r
790                 }\r
791 \r
792                 internal override void CheckConstraints () \r
793                 {\r
794                         CheckDatatypeName ();\r
795                 }\r
796         }\r
797 \r
798         public class RelaxngValue : RelaxngDataSupport\r
799         {\r
800                 string value;\r
801 \r
802                 public override RelaxngPatternType PatternType {\r
803                         get { return RelaxngPatternType.Value; }\r
804                 }\r
805 \r
806                 public string Value {\r
807                         get { return value; }\r
808                         set { this.value = value; }\r
809                 }\r
810 \r
811                 public override void Write (XmlWriter writer)\r
812                 {\r
813                         writer.WriteStartElement ("", "value", RelaxngGrammar.NamespaceURI);\r
814                         if (Type != null) {\r
815                                 writer.WriteStartAttribute ("type", String.Empty);\r
816                                 if (DatatypeLibrary != null && DatatypeLibrary != String.Empty)\r
817                                         writer.WriteAttributeString ("datatypeLibrary", DatatypeLibrary);\r
818                                 writer.WriteAttributeString ("type", Type);\r
819                         }\r
820                         writer.WriteString (Value);\r
821                         writer.WriteEndElement ();\r
822                 }\r
823 \r
824                 internal override void WriteRnc (RncWriter writer)\r
825                 {\r
826                         writer.WriteValue (this);\r
827                 }\r
828 \r
829                 internal override RdpPattern Compile (RelaxngGrammar grammar)\r
830                 {\r
831                         IsCompiled = true;\r
832                         return new RdpValue (new RdpDatatype (DatatypeLibrary,\r
833                                 Type, null, grammar.Provider), value);\r
834                 }\r
835 \r
836                 internal override void CheckConstraints () \r
837                 {\r
838                         CheckDatatypeName ();\r
839                 }\r
840         }\r
841 \r
842         public class RelaxngList : RelaxngSingleContentPattern\r
843         {\r
844                 internal RelaxngList ()\r
845                 {\r
846                 }\r
847 \r
848                 public override RelaxngPatternType PatternType {\r
849                         get { return RelaxngPatternType.List; }\r
850                 }\r
851 \r
852                 public override void Write (XmlWriter writer)\r
853                 {\r
854                         writer.WriteStartElement ("", "list", RelaxngGrammar.NamespaceURI);\r
855                         foreach (RelaxngPattern p in Patterns)\r
856                                 p.Write (writer);\r
857                         writer.WriteEndElement ();\r
858                 }\r
859 \r
860                 internal override void WriteRnc (RncWriter writer)\r
861                 {\r
862                         writer.WriteList (this);\r
863                 }\r
864 \r
865                 internal override RdpPattern Compile (RelaxngGrammar grammar)\r
866                 {\r
867 \r
868                         IsCompiled = true;\r
869                         return new RdpList (makeSingle (grammar));\r
870                 }\r
871 \r
872                 internal override void CheckConstraints () \r
873                 {\r
874                         // nothing to check\r
875                 }\r
876         }\r
877 \r
878         public class RelaxngElement : RelaxngSingleContentPattern\r
879         {\r
880                 RelaxngNameClass nc;\r
881 \r
882                 public RelaxngElement ()\r
883                 {\r
884                 }\r
885 \r
886                 public RelaxngNameClass NameClass {\r
887                         get { return nc; }\r
888                         set { nc = value; }\r
889                 }\r
890 \r
891                 public override RelaxngPatternType PatternType {\r
892                         get { return RelaxngPatternType.Element; }\r
893                 }\r
894 \r
895                 public override void Write (XmlWriter writer)\r
896                 {\r
897                         writer.WriteStartElement ("", "element", RelaxngGrammar.NamespaceURI);\r
898                         nc.Write (writer);\r
899                         foreach (RelaxngPattern p in Patterns)\r
900                                 p.Write (writer);\r
901                         writer.WriteEndElement ();\r
902                 }\r
903 \r
904                 internal override void WriteRnc (RncWriter writer)\r
905                 {\r
906                         writer.WriteElement (this);\r
907                 }\r
908 \r
909                 internal override RdpPattern Compile (RelaxngGrammar grammar)\r
910                 {\r
911                         return new RdpElement (\r
912                                 nc.Compile (grammar), this.makeSingle (grammar));\r
913                 }\r
914 \r
915                 internal override void CheckConstraints () \r
916                 {\r
917                         NameClass.CheckConstraints (false, false);\r
918 \r
919                         foreach (RelaxngPattern p in Patterns)\r
920                                 p.CheckConstraints ();\r
921                 }\r
922         }\r
923 \r
924         public class RelaxngAttribute : RelaxngPattern\r
925         {\r
926                 RelaxngNameClass nc;\r
927                 RelaxngPattern p;\r
928 \r
929                 public RelaxngAttribute ()\r
930                 {\r
931                 }\r
932 \r
933                 public RelaxngPattern Pattern {\r
934                         get { return p; }\r
935                         set { p = value; }\r
936                 }\r
937 \r
938                 public RelaxngNameClass NameClass {\r
939                         get { return nc; }\r
940                         set { nc = value; }\r
941                 }\r
942 \r
943                 public override RelaxngPatternType PatternType {\r
944                         get { return RelaxngPatternType.Attribute; }\r
945                 }\r
946 \r
947                 public override void Write (XmlWriter writer)\r
948                 {\r
949                         writer.WriteStartElement ("", "attribute", RelaxngGrammar.NamespaceURI);\r
950                         nc.Write (writer);\r
951                         if (p != null)\r
952                                 p.Write (writer);\r
953                         writer.WriteEndElement ();\r
954                 }\r
955 \r
956                 internal override void WriteRnc (RncWriter writer)\r
957                 {\r
958                         writer.WriteAttribute (this);\r
959                 }\r
960 \r
961                 private void checkInvalidAttrNameClass (RdpNameClass nc)\r
962                 {\r
963                         string xmlnsNS = "http://www.w3.org/2000/xmlns";\r
964                         RdpNameClassChoice choice = nc as RdpNameClassChoice;\r
965                         if (choice != null) {\r
966                                 checkInvalidAttrNameClass (choice.LValue);\r
967                                 checkInvalidAttrNameClass (choice.RValue);\r
968                                 return;\r
969                         }\r
970                         RdpAnyNameExcept except = nc as RdpAnyNameExcept;\r
971                         if (except != null) {\r
972                                 checkInvalidAttrNameClass (except.ExceptNameClass);\r
973                                 return;\r
974                         }\r
975                         if (nc is RdpAnyName)\r
976                                 return;\r
977 \r
978                         RdpName n = nc as RdpName;\r
979                         if (n != null) {\r
980                                 if (n.NamespaceURI == xmlnsNS)\r
981                                         throw new RelaxngException (this, "cannot specify \"" + xmlnsNS + "\" for name of attribute.");\r
982                                 if (n.LocalName == "xmlns" && n.NamespaceURI == "")\r
983                                         throw new RelaxngException (this, "cannot specify \"xmlns\" inside empty ns context.");\r
984                         } else {\r
985                                 RdpNsName nn = nc as RdpNsName;\r
986                                 if (nn.NamespaceURI == "http://www.w3.org/2000/xmlns")\r
987                                         throw new RelaxngException (this, "cannot specify \"" + xmlnsNS + "\" for name of attribute.");\r
988                                 RdpNsNameExcept x = nc as RdpNsNameExcept;\r
989                                 if (x != null)\r
990                                         checkInvalidAttrNameClass (x.ExceptNameClass);\r
991                         }\r
992                 }\r
993 \r
994                 internal override RdpPattern Compile (RelaxngGrammar grammar)\r
995                 {\r
996                         IsCompiled = true;\r
997                         RdpNameClass cnc = nc.Compile (grammar);\r
998                         this.checkInvalidAttrNameClass (cnc);\r
999 \r
1000                         return new RdpAttribute (cnc,\r
1001                                 (p != null) ?\r
1002                                         p.Compile (grammar) :\r
1003                                         RdpText.Instance);\r
1004                 }\r
1005 \r
1006                 internal override void CheckConstraints () \r
1007                 {\r
1008                         NameClass.CheckConstraints (false, false);\r
1009 \r
1010                         if (p != null)\r
1011                                 p.CheckConstraints ();\r
1012                 }\r
1013         }\r
1014 \r
1015         internal class RdpUnresolvedRef : RdpPattern\r
1016         {\r
1017                 string name;\r
1018 //              bool parentRef;\r
1019                 RelaxngGrammar targetGrammar;\r
1020                 RdpPattern referencedPattern;\r
1021 \r
1022                 public RdpUnresolvedRef (string name, RelaxngGrammar g)\r
1023                 {\r
1024                         this.name = name;\r
1025 //                      this.parentRef = parentRef;\r
1026                         targetGrammar = g;\r
1027                 }\r
1028 \r
1029                 public string Name {\r
1030                         get { return name; }\r
1031                         set { name = value; }\r
1032                 }\r
1033 \r
1034                 public RdpPattern RefPattern {\r
1035                         get { return referencedPattern; }\r
1036                         set { referencedPattern = value; }\r
1037                 }\r
1038 \r
1039 //              public bool IsParentRef {\r
1040 //                      get { return parentRef; }\r
1041 //              }\r
1042 \r
1043                 public RelaxngGrammar TargetGrammar {\r
1044                         get { return targetGrammar; }\r
1045                 }\r
1046 \r
1047                 public override RelaxngPatternType PatternType {\r
1048                         get { return RelaxngPatternType.Ref; }\r
1049                 }\r
1050 \r
1051                 public override RdpContentType ContentType {\r
1052                         get { return RdpContentType.Empty; }\r
1053                 }\r
1054 \r
1055 \r
1056                 public override bool Nullable {\r
1057                         get {\r
1058                                 throw new InvalidOperationException ("Internal error: should not reach.");\r
1059                         }\r
1060                 }\r
1061 \r
1062                 public override void GetLabels (Hashtable elements, Hashtable attributes, bool collectNameClass)\r
1063                 {\r
1064                         // Now it could reach (CheckNameOverlap) so comment out here.\r
1065 //                      throw new InvalidOperationException ("Internal error: should not reach.");\r
1066                 }\r
1067 \r
1068                 internal override RdpPattern ExpandRef (Hashtable defs)\r
1069                 {\r
1070                         return referencedPattern.ExpandRef (defs);\r
1071                 }\r
1072 \r
1073                 internal override void MarkReachableDefs () \r
1074                 {\r
1075                         TargetGrammar.MarkReacheableDefine (this.name);\r
1076                 }\r
1077 \r
1078                 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)\r
1079                 {\r
1080                         referencedPattern =\r
1081                                 referencedPattern.ReduceEmptyAndNotAllowed (\r
1082                                 ref result, visited);\r
1083                         return this;\r
1084                 }\r
1085 \r
1086                 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept) \r
1087                 {\r
1088 //                      throw new InvalidOperationException ();\r
1089                 }\r
1090 \r
1091                 internal override bool ContainsText ()\r
1092                 {\r
1093                         return false;\r
1094 //                      throw new InvalidOperationException ();\r
1095                 }\r
1096         }\r
1097 \r
1098         public class RelaxngRef : RelaxngPattern\r
1099         {\r
1100                 string name;\r
1101 \r
1102                 public RelaxngRef ()\r
1103                 {\r
1104                 }\r
1105 \r
1106                 public string Name {\r
1107                         get { return name; }\r
1108                         set { name = value; }\r
1109                 }\r
1110 \r
1111                 public override RelaxngPatternType PatternType {\r
1112                         get { return RelaxngPatternType.Ref; }\r
1113                 }\r
1114 \r
1115                 public override void Write (XmlWriter writer)\r
1116                 {\r
1117                         writer.WriteStartElement ("", "ref", RelaxngGrammar.NamespaceURI);\r
1118                         writer.WriteAttributeString ("name", name);\r
1119                         writer.WriteEndElement ();\r
1120                 }\r
1121 \r
1122                 internal override void WriteRnc (RncWriter writer)\r
1123                 {\r
1124                         writer.WriteRef (this);\r
1125                 }\r
1126 \r
1127                 internal override RdpPattern Compile (RelaxngGrammar grammar)\r
1128                 {\r
1129                         // Important!! This compile method only generates stub.\r
1130                         IsCompiled = false;\r
1131                         return new RdpUnresolvedRef (name, grammar);\r
1132                 }\r
1133 \r
1134                 internal override void CheckConstraints () \r
1135                 {\r
1136                         // nothing to check\r
1137                 }\r
1138         }\r
1139 \r
1140         public class RelaxngParentRef : RelaxngPattern\r
1141         {\r
1142                 string name;\r
1143 \r
1144                 public RelaxngParentRef ()\r
1145                 {\r
1146                 }\r
1147 \r
1148                 public string Name {\r
1149                         get { return name; }\r
1150                         set { name = value; }\r
1151                 }\r
1152 \r
1153                 public override RelaxngPatternType PatternType {\r
1154                         get { return RelaxngPatternType.ParentRef; }\r
1155                 }\r
1156 \r
1157                 public override void Write (XmlWriter writer)\r
1158                 {\r
1159                         writer.WriteStartElement ("", "parentRef", RelaxngGrammar.NamespaceURI);\r
1160                         writer.WriteAttributeString ("name", name);\r
1161                         writer.WriteEndElement ();\r
1162                 }\r
1163 \r
1164                 internal override void WriteRnc (RncWriter writer)\r
1165                 {\r
1166                         writer.WriteParentRef (this);\r
1167                 }\r
1168 \r
1169                 internal override RdpPattern Compile (RelaxngGrammar grammar)\r
1170                 {\r
1171                         IsCompiled = false;\r
1172                         return new RdpUnresolvedRef (name, grammar.ParentGrammar);\r
1173                 }\r
1174 \r
1175                 internal override void CheckConstraints () \r
1176                 {\r
1177                         // nothing to check\r
1178                 }\r
1179         }\r
1180 \r
1181         public class RelaxngExternalRef : RelaxngPattern\r
1182         {\r
1183                 string href;\r
1184                 string ns;\r
1185 \r
1186                 public RelaxngExternalRef ()\r
1187                 {\r
1188                 }\r
1189 \r
1190                 public string Href {\r
1191                         get { return href; }\r
1192                         set { href = value; }\r
1193                 }\r
1194 \r
1195                 public string NSContext {\r
1196                         get { return ns; }\r
1197                         set { ns = value; }\r
1198                 }\r
1199 \r
1200                 public override RelaxngPatternType PatternType {\r
1201                         get { return RelaxngPatternType.ExternalRef; }\r
1202                 }\r
1203 \r
1204                 public override void Write (XmlWriter writer)\r
1205                 {\r
1206                         writer.WriteStartElement ("", "externalRef", RelaxngGrammar.NamespaceURI);\r
1207                         writer.WriteAttributeString ("href", Href);\r
1208                         writer.WriteEndElement ();\r
1209                 }\r
1210 \r
1211                 internal override void WriteRnc (RncWriter writer)\r
1212                 {\r
1213                         writer.WriteExternalRef (this);\r
1214                 }\r
1215 \r
1216                 internal override RdpPattern Compile (RelaxngGrammar grammar)\r
1217                 {\r
1218                         grammar.CheckIncludeRecursion (Href);\r
1219                         grammar.IncludedUris.Add (Href, Href);\r
1220                         if (grammar.Resolver == null)\r
1221                                 throw new RelaxngException (this, "To compile 'include' element, XmlResolver is required.");\r
1222                         Uri uri = grammar.Resolver.ResolveUri (BaseUri != String.Empty ? new Uri (BaseUri) : null, Href);\r
1223                         XmlTextReader xtr = null;\r
1224                         try {\r
1225                                 xtr = new XmlTextReader (uri.AbsoluteUri, (Stream) grammar.Resolver.GetEntity (uri, null, typeof (Stream)));\r
1226                                 RelaxngReader r = new RelaxngReader (xtr, ns);\r
1227                                 r.MoveToContent ();\r
1228                                 RelaxngPattern p = r.ReadPattern ();\r
1229                                 p.DataProvider = grammar.Provider;\r
1230 \r
1231                                 RdpPattern ret = p.Compile (grammar);\r
1232 \r
1233                                 grammar.IncludedUris.Remove (Href);\r
1234 \r
1235                                 return ret;\r
1236                         } finally {\r
1237                                 if (xtr != null)\r
1238                                         xtr.Close ();\r
1239                         }\r
1240 \r
1241                 }\r
1242 \r
1243                 internal override void CheckConstraints () \r
1244                 {\r
1245                         // nothing to check\r
1246                 }\r
1247         }\r
1248 \r
1249         public class RelaxngOneOrMore : RelaxngSingleContentPattern\r
1250         {\r
1251                 public RelaxngOneOrMore ()\r
1252                 {\r
1253                 }\r
1254 \r
1255                 public override RelaxngPatternType PatternType {\r
1256                         get { return RelaxngPatternType.OneOrMore; }\r
1257                 }\r
1258 \r
1259                 public override void Write (XmlWriter writer)\r
1260                 {\r
1261                         writer.WriteStartElement ("", "oneOrMore", RelaxngGrammar.NamespaceURI);\r
1262                         foreach (RelaxngPattern p in Patterns)\r
1263                                 p.Write (writer);\r
1264                         writer.WriteEndElement ();\r
1265                 }\r
1266 \r
1267                 internal override void WriteRnc (RncWriter writer)\r
1268                 {\r
1269                         writer.WriteOneOrMore (this);\r
1270                 }\r
1271 \r
1272                 internal override RdpPattern Compile (RelaxngGrammar grammar)\r
1273                 {\r
1274                         IsCompiled = true;\r
1275                         return new RdpOneOrMore (makeSingle (grammar));\r
1276                 }\r
1277         }\r
1278 \r
1279         public class RelaxngZeroOrMore : RelaxngSingleContentPattern\r
1280         {\r
1281                 public RelaxngZeroOrMore ()\r
1282                 {\r
1283                 }\r
1284 \r
1285                 public override RelaxngPatternType PatternType {\r
1286                         get { return RelaxngPatternType.ZeroOrMore; }\r
1287                 }\r
1288 \r
1289                 public override void Write (XmlWriter writer)\r
1290                 {\r
1291                         writer.WriteStartElement ("", "zeroOrMore", RelaxngGrammar.NamespaceURI);\r
1292                         foreach (RelaxngPattern p in Patterns)\r
1293                                 p.Write (writer);\r
1294                         writer.WriteEndElement ();\r
1295                 }\r
1296 \r
1297                 internal override void WriteRnc (RncWriter writer)\r
1298                 {\r
1299                         writer.WriteZeroOrMore (this);\r
1300                 }\r
1301 \r
1302                 internal override RdpPattern Compile (RelaxngGrammar grammar)\r
1303                 {\r
1304                         IsCompiled = true;\r
1305                         return new RdpChoice (\r
1306                                 new RdpOneOrMore (makeSingle (grammar)),\r
1307                                 RdpEmpty.Instance);\r
1308                 }\r
1309         }\r
1310 \r
1311         public class RelaxngOptional : RelaxngSingleContentPattern\r
1312         {\r
1313                 public RelaxngOptional ()\r
1314                 {\r
1315                 }\r
1316 \r
1317                 public override RelaxngPatternType PatternType {\r
1318                         get { return RelaxngPatternType.Optional; }\r
1319                 }\r
1320 \r
1321                 public override void Write (XmlWriter writer)\r
1322                 {\r
1323                         writer.WriteStartElement ("", "optional", RelaxngGrammar.NamespaceURI);\r
1324                         foreach (RelaxngPattern p in Patterns)\r
1325                                 p.Write (writer);\r
1326                         writer.WriteEndElement ();\r
1327                 }\r
1328 \r
1329                 internal override void WriteRnc (RncWriter writer)\r
1330                 {\r
1331                         writer.WriteOptional (this);\r
1332                 }\r
1333 \r
1334                 internal override RdpPattern Compile (RelaxngGrammar grammar)\r
1335                 {\r
1336                         IsCompiled = true;\r
1337                         return new RdpChoice (\r
1338                                 makeSingle (grammar), RdpEmpty.Instance);\r
1339                 }\r
1340         }\r
1341 \r
1342         public class RelaxngMixed : RelaxngSingleContentPattern\r
1343         {\r
1344                 public RelaxngMixed ()\r
1345                 {\r
1346                 }\r
1347 \r
1348                 public override RelaxngPatternType PatternType {\r
1349                         get { return RelaxngPatternType.Mixed; }\r
1350                 }\r
1351 \r
1352                 public override void Write (XmlWriter writer)\r
1353                 {\r
1354                         writer.WriteStartElement ("", "mixed", RelaxngGrammar.NamespaceURI);\r
1355                         foreach (RelaxngPattern p in Patterns)\r
1356                                 p.Write (writer);\r
1357                         writer.WriteEndElement ();\r
1358                 }\r
1359 \r
1360                 internal override void WriteRnc (RncWriter writer)\r
1361                 {\r
1362                         writer.WriteMixed (this);\r
1363                 }\r
1364 \r
1365                 internal override RdpPattern Compile (RelaxngGrammar grammar)\r
1366                 {\r
1367                         IsCompiled = true;\r
1368                         return new RdpInterleave (makeSingle (grammar), RdpText.Instance);\r
1369                 }\r
1370         }\r
1371 \r
1372         public class RelaxngChoice : RelaxngBinaryContentPattern\r
1373         {\r
1374                 public RelaxngChoice ()\r
1375                 {\r
1376                 }\r
1377 \r
1378                 public override RelaxngPatternType PatternType {\r
1379                         get { return RelaxngPatternType.Choice; }\r
1380                 }\r
1381 \r
1382                 public override void Write (XmlWriter writer)\r
1383                 {\r
1384                         writer.WriteStartElement ("", "choice", RelaxngGrammar.NamespaceURI);\r
1385                         foreach (RelaxngPattern p in Patterns)\r
1386                                 p.Write (writer);\r
1387                         writer.WriteEndElement ();\r
1388                 }\r
1389 \r
1390                 internal override void WriteRnc (RncWriter writer)\r
1391                 {\r
1392                         writer.WriteChoice (this);\r
1393                 }\r
1394 \r
1395                 internal override RdpPattern Compile (RelaxngGrammar grammar)\r
1396                 {\r
1397                         IsCompiled = true;\r
1398                         return makeBinary (grammar);\r
1399                 }\r
1400         }\r
1401 \r
1402         public class RelaxngGroup : RelaxngBinaryContentPattern\r
1403         {\r
1404                 public RelaxngGroup ()\r
1405                 {\r
1406                 }\r
1407 \r
1408                 public override RelaxngPatternType PatternType {\r
1409                         get { return RelaxngPatternType.Group; }\r
1410                 }\r
1411 \r
1412                 public override void Write (XmlWriter writer)\r
1413                 {\r
1414                         writer.WriteStartElement ("", "group", RelaxngGrammar.NamespaceURI);\r
1415                         foreach (RelaxngPattern p in Patterns)\r
1416                                 p.Write (writer);\r
1417                         writer.WriteEndElement ();\r
1418                 }\r
1419 \r
1420                 internal override void WriteRnc (RncWriter writer)\r
1421                 {\r
1422                         writer.WriteGroup (this);\r
1423                 }\r
1424 \r
1425                 internal override RdpPattern Compile (RelaxngGrammar grammar)\r
1426                 {\r
1427                         IsCompiled = true;\r
1428                         return makeBinary (grammar);\r
1429                 }\r
1430         }\r
1431 \r
1432         public class RelaxngInterleave : RelaxngBinaryContentPattern\r
1433         {\r
1434                 public RelaxngInterleave ()\r
1435                 {\r
1436                 }\r
1437 \r
1438                 public override RelaxngPatternType PatternType {\r
1439                         get { return RelaxngPatternType.Interleave; }\r
1440                 }\r
1441 \r
1442                 public override void Write (XmlWriter writer)\r
1443                 {\r
1444                         writer.WriteStartElement ("", "interleave", RelaxngGrammar.NamespaceURI);\r
1445                         foreach (RelaxngPattern p in Patterns)\r
1446                                 p.Write (writer);\r
1447                         writer.WriteEndElement ();\r
1448                 }\r
1449 \r
1450                 internal override void WriteRnc (RncWriter writer)\r
1451                 {\r
1452                         writer.WriteInterleave (this);\r
1453                 }\r
1454 \r
1455                 internal override RdpPattern Compile (RelaxngGrammar grammar)\r
1456                 {\r
1457                         IsCompiled = true;\r
1458                         return makeBinary (grammar);\r
1459                 }\r
1460         }\r
1461 \r
1462         public class RelaxngParam : RelaxngElementBase\r
1463         {\r
1464                 string name;\r
1465                 string value;\r
1466 \r
1467                 public RelaxngParam ()\r
1468                 {\r
1469                 }\r
1470 \r
1471                 public RelaxngParam (string name, string value)\r
1472                 {\r
1473                         this.name = name;\r
1474                         this.value = value;\r
1475                 }\r
1476 \r
1477                 public string Name {\r
1478                         get { return name; }\r
1479                         set { name = value; }\r
1480                 }\r
1481 \r
1482                 public string Value {\r
1483                         get { return value; }\r
1484                         set { this.value = value; }\r
1485                 }\r
1486 \r
1487                 public override void Write (XmlWriter writer)\r
1488                 {\r
1489                         writer.WriteStartElement ("", "param", RelaxngGrammar.NamespaceURI);\r
1490                         writer.WriteAttributeString ("name", name);\r
1491                         writer.WriteString (Value);\r
1492                         writer.WriteEndElement ();\r
1493                 }\r
1494 \r
1495                 internal override void WriteRnc (RncWriter writer)\r
1496                 {\r
1497                         writer.WriteParam (this);\r
1498                 }\r
1499 \r
1500                 internal RdpParam Compile (RelaxngGrammar grammar)\r
1501                 {\r
1502                         IsCompiled = true;\r
1503                         return new RdpParam (name, value);\r
1504                 }\r
1505         }\r
1506 \r
1507         public class RelaxngParamList : CollectionBase\r
1508         {\r
1509                 public RelaxngParamList ()\r
1510                 {\r
1511                 }\r
1512 \r
1513                 public void Add (RelaxngParam p)\r
1514                 {\r
1515                         List.Add (p);\r
1516                 }\r
1517 \r
1518                 public RelaxngParam this [int i] {\r
1519                         get { return this.List [i] as RelaxngParam; }\r
1520                         set { this.List [i] = value; }\r
1521                 }\r
1522 \r
1523                 public void Insert (int pos, RelaxngParam p)\r
1524                 {\r
1525                         List.Insert (pos, p);\r
1526                 }\r
1527 \r
1528                 public void Remove (RelaxngParam p)\r
1529                 {\r
1530                         List.Remove (p);\r
1531                 }\r
1532         }\r
1533 \r
1534         public class RelaxngExcept : RelaxngElementBase\r
1535         {\r
1536                 RelaxngPatternList patterns = new RelaxngPatternList ();\r
1537 \r
1538                 public RelaxngExcept ()\r
1539                 {\r
1540                 }\r
1541 \r
1542                 public RelaxngPatternList Patterns {\r
1543                         get { return patterns; }\r
1544                 }\r
1545 \r
1546                 public override void Write (XmlWriter writer)\r
1547                 {\r
1548                         writer.WriteStartElement ("", "except", RelaxngGrammar.NamespaceURI);\r
1549                         foreach (RelaxngPattern p in Patterns)\r
1550                                 p.Write (writer);\r
1551                         writer.WriteEndElement ();\r
1552                 }\r
1553 \r
1554                 internal override void WriteRnc (RncWriter writer)\r
1555                 {\r
1556                         writer.WriteDataExcept (this);\r
1557                 }\r
1558         }\r
1559 \r
1560         internal class RelaxngRefPattern\r
1561         {\r
1562                 RelaxngPattern patternRef;\r
1563                 string name;\r
1564 \r
1565                 // When we found ref, use it.\r
1566                 public RelaxngRefPattern (string name)\r
1567                 {\r
1568                         this.name = name;\r
1569                 }\r
1570 \r
1571                 // When we found define, use it.\r
1572                 public RelaxngRefPattern (RelaxngPattern patternRef)\r
1573                 {\r
1574                         this.patternRef = patternRef;\r
1575                 }\r
1576 \r
1577                 public string Name {\r
1578                         get { return name; }\r
1579                 }\r
1580 \r
1581                 public RelaxngPattern PatternRef {\r
1582                         get { return patternRef; }\r
1583                         set { patternRef = value; }\r
1584                 }\r
1585         }\r
1586         #endregion\r
1587 }\r