2005-01-26 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 NSResoler = 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                         WriteRnc (new RncWriter (writer));\r
516                 }\r
517 \r
518                 public void WriteCompact (TextWriter writer, NSResolver res)\r
519                 {\r
520                         WriteRnc (new RncWriter (writer, res));\r
521                 }\r
522 \r
523                 // Internal\r
524                 internal XmlResolver Resolver {\r
525                         get {\r
526                                 if (nullResolver)\r
527                                         return null;\r
528                                 if (resolver == null)\r
529                                         resolver = new XmlUrlResolver ();\r
530                                 return resolver;\r
531                         }\r
532                 }\r
533 \r
534                 internal abstract void CheckConstraints ();\r
535 \r
536                 protected RelaxngPattern () \r
537                 {\r
538                 }\r
539 \r
540                 internal abstract RdpPattern Compile (RelaxngGrammar grammar);\r
541 \r
542                 internal RdpPattern StartPattern {\r
543                         get { return startRelaxngPattern; }\r
544                 }\r
545         }\r
546 \r
547         public class RelaxngPatternList : CollectionBase\r
548         {\r
549                 public RelaxngPatternList ()\r
550                 {\r
551                 }\r
552 \r
553                 public void Add (RelaxngPattern p)\r
554                 {\r
555                         List.Add (p);\r
556                 }\r
557 \r
558                 public RelaxngPattern this [int i] {\r
559                         get { return this.List [i] as RelaxngPattern; }\r
560                         set { this.List [i] = value; }\r
561                 }\r
562 \r
563                 public void Insert (int pos, RelaxngPattern p)\r
564                 {\r
565                         List.Insert (pos, p);\r
566                 }\r
567 \r
568                 public void Remove (RelaxngPattern p)\r
569                 {\r
570                         List.Remove (p);\r
571                 }\r
572         }\r
573 \r
574         public class RelaxngGrammarContentList : CollectionBase\r
575         {\r
576                 public RelaxngGrammarContentList ()\r
577                 {\r
578                 }\r
579 \r
580                 public void Add (IGrammarContent p)\r
581                 {\r
582                         List.Add (p);\r
583                 }\r
584 \r
585                 public IGrammarContent this [int i] {\r
586                         get { return this.List [i] as IGrammarContent; }\r
587                         set { this.List [i] = value; }\r
588                 }\r
589 \r
590                 public void Insert (int pos, IGrammarContent p)\r
591                 {\r
592                         List.Insert (pos, p);\r
593                 }\r
594 \r
595                 public void Remove (IGrammarContent p)\r
596                 {\r
597                         List.Remove (p);\r
598                 }\r
599         }\r
600 \r
601         // strict to say, it's not a pattern ;)\r
602         public class RelaxngNotAllowed : RelaxngPattern\r
603         {\r
604                 public RelaxngNotAllowed () \r
605                 {\r
606                 }\r
607 \r
608                 public override RelaxngPatternType PatternType {\r
609                         get { return RelaxngPatternType.NotAllowed; }\r
610                 }\r
611 \r
612                 public override void Write (XmlWriter writer)\r
613                 {\r
614                         writer.WriteStartElement ("", "notAllowed", RelaxngGrammar.NamespaceURI);\r
615                         writer.WriteEndElement ();\r
616                 }\r
617 \r
618                 internal override void WriteRnc (RncWriter writer)\r
619                 {\r
620                         writer.WriteNotAllowed (this);\r
621                 }\r
622 \r
623                 internal override RdpPattern Compile (RelaxngGrammar grammar)\r
624                 {\r
625                         return RdpNotAllowed.Instance;\r
626                 }\r
627 \r
628                 internal override void CheckConstraints () \r
629                 {\r
630                         // nothing to check\r
631                 }\r
632         }\r
633 \r
634         public class RelaxngEmpty : RelaxngPattern\r
635         {\r
636                 public RelaxngEmpty ()\r
637                 {\r
638                 }\r
639 \r
640                 public override RelaxngPatternType PatternType {\r
641                         get { return RelaxngPatternType.Empty; }\r
642                 }\r
643 \r
644                 public override void Write (XmlWriter writer)\r
645                 {\r
646                         writer.WriteStartElement ("", "empty", RelaxngGrammar.NamespaceURI);\r
647                         writer.WriteEndElement ();\r
648                 }\r
649 \r
650                 internal override void WriteRnc (RncWriter writer)\r
651                 {\r
652                         writer.WriteEmpty (this);\r
653                 }\r
654 \r
655                 internal override RdpPattern Compile (RelaxngGrammar grammar)\r
656                 {\r
657                         return RdpEmpty.Instance;\r
658                 }\r
659 \r
660                 internal override void CheckConstraints () \r
661                 {\r
662                         // nothing to check\r
663                 }\r
664         }\r
665 \r
666         public class RelaxngText : RelaxngPattern\r
667         {\r
668                 public RelaxngText () \r
669                 {\r
670                 }\r
671 \r
672                 public override RelaxngPatternType PatternType {\r
673                         get { return RelaxngPatternType.Text; }\r
674                 }\r
675 \r
676                 public override void Write (XmlWriter writer)\r
677                 {\r
678                         writer.WriteStartElement ("", "text", RelaxngGrammar.NamespaceURI);\r
679                         writer.WriteEndElement ();\r
680                 }\r
681 \r
682                 internal override void WriteRnc (RncWriter writer)\r
683                 {\r
684                         writer.WriteText (this);\r
685                 }\r
686 \r
687                 internal override RdpPattern Compile (RelaxngGrammar grammar)\r
688                 {\r
689                         return RdpText.Instance;\r
690                 }\r
691 \r
692                 internal override void CheckConstraints () \r
693                 {\r
694                         // nothing to check\r
695                 }\r
696         }\r
697 \r
698         public abstract class RelaxngDataSupport : RelaxngPattern\r
699         {\r
700                 string type;\r
701                 string datatypeLibrary;\r
702 \r
703                 public string Type {\r
704                         get { return type; }\r
705                         set { type = value; }\r
706                 }\r
707 \r
708                 public string DatatypeLibrary {\r
709                         get { return datatypeLibrary; }\r
710                         set { datatypeLibrary = value; }\r
711                 }\r
712 \r
713                 internal void CheckDatatypeName ()\r
714                 {\r
715                         // Data type name check is done in RdpData(Except) derivative creation.\r
716                 }\r
717         }\r
718 \r
719         public class RelaxngData : RelaxngDataSupport\r
720         {\r
721                 RelaxngParamList paramList = new RelaxngParamList ();\r
722                 RelaxngExcept except;\r
723 \r
724                 public RelaxngData ()\r
725                 {\r
726                 }\r
727 \r
728                 public override RelaxngPatternType PatternType {\r
729                         get { return RelaxngPatternType.Data; }\r
730                 }\r
731 \r
732                 public RelaxngParamList ParamList {\r
733                         get { return paramList; }\r
734                 }\r
735 \r
736                 public RelaxngExcept Except {\r
737                         get { return except; }\r
738                         set { except = value; }\r
739                 }\r
740 \r
741                 public override void Write (XmlWriter writer)\r
742                 {\r
743                         writer.WriteStartElement ("", "data", RelaxngGrammar.NamespaceURI);\r
744                         if (DatatypeLibrary != null && DatatypeLibrary != String.Empty)\r
745                                 writer.WriteAttributeString ("xmlns", "data", "http://www.w3.org/2000/xmlns/", DatatypeLibrary);\r
746                         writer.WriteStartAttribute ("type", String.Empty);\r
747                         writer.WriteQualifiedName (Type, DatatypeLibrary);\r
748                         writer.WriteEndAttribute ();\r
749 \r
750                         foreach (RelaxngParam p in ParamList)\r
751                                 p.Write (writer);\r
752 \r
753                         if (Except != null)\r
754                                 Except.Write (writer);\r
755 \r
756                         writer.WriteEndElement ();\r
757                 }\r
758 \r
759                 internal override void WriteRnc (RncWriter writer)\r
760                 {\r
761                         writer.WriteData (this);\r
762                 }\r
763 \r
764                 internal override RdpPattern Compile (RelaxngGrammar grammar)\r
765                 {\r
766 //                      RdpParamList rdpl = new RdpParamList ();\r
767 //                      foreach (RelaxngParam prm in this.paramList)\r
768 //                              rdpl.Add (prm.Compile (grammar));\r
769                         RdpPattern p = null;\r
770                         if (this.except != null) {\r
771                                 if (except.Patterns.Count == 0)\r
772                                         throw new RelaxngException (this, "data except pattern have no children.");\r
773                                 p = except.Patterns [0].Compile (grammar);\r
774                                 for (int i=1; i<except.Patterns.Count; i++)\r
775                                         p = new RdpChoice (p,\r
776                                                 except.Patterns [i].Compile (grammar));\r
777                         }\r
778 \r
779                         IsCompiled = true;\r
780                         if (this.except != null)\r
781                                 return new RdpDataExcept (new RdpDatatype (DatatypeLibrary, Type, ParamList, grammar.Provider), p);\r
782                         else\r
783                                 return new RdpData (new RdpDatatype (DatatypeLibrary, Type, ParamList, grammar.Provider));\r
784                 }\r
785 \r
786                 internal override void CheckConstraints () \r
787                 {\r
788                         CheckDatatypeName ();\r
789                 }\r
790         }\r
791 \r
792         public class RelaxngValue : RelaxngDataSupport\r
793         {\r
794                 string value;\r
795 \r
796                 public override RelaxngPatternType PatternType {\r
797                         get { return RelaxngPatternType.Value; }\r
798                 }\r
799 \r
800                 public string Value {\r
801                         get { return value; }\r
802                         set { this.value = value; }\r
803                 }\r
804 \r
805                 public override void Write (XmlWriter writer)\r
806                 {\r
807                         writer.WriteStartElement ("", "value", RelaxngGrammar.NamespaceURI);\r
808                         if (Type != null) {\r
809                                 writer.WriteStartAttribute ("type", String.Empty);\r
810                                 if (DatatypeLibrary != null && DatatypeLibrary != String.Empty)\r
811                                         writer.WriteAttributeString ("xmlns", "data", "http://www.w3.org/2000/xmlns/", DatatypeLibrary);\r
812                                 writer.WriteQualifiedName (Type, DatatypeLibrary);\r
813                                 writer.WriteEndAttribute ();\r
814                         }\r
815                         writer.WriteString (Value);\r
816                         writer.WriteEndElement ();\r
817                 }\r
818 \r
819                 internal override void WriteRnc (RncWriter writer)\r
820                 {\r
821                         writer.WriteValue (this);\r
822                 }\r
823 \r
824                 internal override RdpPattern Compile (RelaxngGrammar grammar)\r
825                 {\r
826                         IsCompiled = true;\r
827                         return new RdpValue (new RdpDatatype (DatatypeLibrary,\r
828                                 Type, null, grammar.Provider), value);\r
829                 }\r
830 \r
831                 internal override void CheckConstraints () \r
832                 {\r
833                         CheckDatatypeName ();\r
834                 }\r
835         }\r
836 \r
837         public class RelaxngList : RelaxngSingleContentPattern\r
838         {\r
839                 internal RelaxngList ()\r
840                 {\r
841                 }\r
842 \r
843                 public override RelaxngPatternType PatternType {\r
844                         get { return RelaxngPatternType.List; }\r
845                 }\r
846 \r
847                 public override void Write (XmlWriter writer)\r
848                 {\r
849                         writer.WriteStartElement ("", "list", RelaxngGrammar.NamespaceURI);\r
850                         foreach (RelaxngPattern p in Patterns)\r
851                                 p.Write (writer);\r
852                         writer.WriteEndElement ();\r
853                 }\r
854 \r
855                 internal override void WriteRnc (RncWriter writer)\r
856                 {\r
857                         writer.WriteList (this);\r
858                 }\r
859 \r
860                 internal override RdpPattern Compile (RelaxngGrammar grammar)\r
861                 {\r
862 \r
863                         IsCompiled = true;\r
864                         return new RdpList (makeSingle (grammar));\r
865                 }\r
866 \r
867                 internal override void CheckConstraints () \r
868                 {\r
869                         // nothing to check\r
870                 }\r
871         }\r
872 \r
873         public class RelaxngElement : RelaxngSingleContentPattern\r
874         {\r
875                 RelaxngNameClass nc;\r
876 \r
877                 public RelaxngElement ()\r
878                 {\r
879                 }\r
880 \r
881                 public RelaxngNameClass NameClass {\r
882                         get { return nc; }\r
883                         set { nc = value; }\r
884                 }\r
885 \r
886                 public override RelaxngPatternType PatternType {\r
887                         get { return RelaxngPatternType.Element; }\r
888                 }\r
889 \r
890                 public override void Write (XmlWriter writer)\r
891                 {\r
892                         writer.WriteStartElement ("", "element", RelaxngGrammar.NamespaceURI);\r
893                         nc.Write (writer);\r
894                         foreach (RelaxngPattern p in Patterns)\r
895                                 p.Write (writer);\r
896                         writer.WriteEndElement ();\r
897                 }\r
898 \r
899                 internal override void WriteRnc (RncWriter writer)\r
900                 {\r
901                         writer.WriteElement (this);\r
902                 }\r
903 \r
904                 internal override RdpPattern Compile (RelaxngGrammar grammar)\r
905                 {\r
906                         return new RdpElement (\r
907                                 nc.Compile (grammar), this.makeSingle (grammar));\r
908                 }\r
909 \r
910                 internal override void CheckConstraints () \r
911                 {\r
912                         NameClass.CheckConstraints (false, false);\r
913 \r
914                         foreach (RelaxngPattern p in Patterns)\r
915                                 p.CheckConstraints ();\r
916                 }\r
917         }\r
918 \r
919         public class RelaxngAttribute : RelaxngPattern\r
920         {\r
921                 RelaxngNameClass nc;\r
922                 RelaxngPattern p;\r
923 \r
924                 public RelaxngAttribute ()\r
925                 {\r
926                 }\r
927 \r
928                 public RelaxngPattern Pattern {\r
929                         get { return p; }\r
930                         set { p = value; }\r
931                 }\r
932 \r
933                 public RelaxngNameClass NameClass {\r
934                         get { return nc; }\r
935                         set { nc = value; }\r
936                 }\r
937 \r
938                 public override RelaxngPatternType PatternType {\r
939                         get { return RelaxngPatternType.Attribute; }\r
940                 }\r
941 \r
942                 public override void Write (XmlWriter writer)\r
943                 {\r
944                         writer.WriteStartElement ("", "attribute", RelaxngGrammar.NamespaceURI);\r
945                         nc.Write (writer);\r
946                         if (p != null)\r
947                                 p.Write (writer);\r
948                         writer.WriteEndElement ();\r
949                 }\r
950 \r
951                 internal override void WriteRnc (RncWriter writer)\r
952                 {\r
953                         writer.WriteAttribute (this);\r
954                 }\r
955 \r
956                 private void checkInvalidAttrNameClass (RdpNameClass nc)\r
957                 {\r
958                         string xmlnsNS = "http://www.w3.org/2000/xmlns";\r
959                         RdpNameClassChoice choice = nc as RdpNameClassChoice;\r
960                         if (choice != null) {\r
961                                 checkInvalidAttrNameClass (choice.LValue);\r
962                                 checkInvalidAttrNameClass (choice.RValue);\r
963                                 return;\r
964                         }\r
965                         RdpAnyNameExcept except = nc as RdpAnyNameExcept;\r
966                         if (except != null) {\r
967                                 checkInvalidAttrNameClass (except.ExceptNameClass);\r
968                                 return;\r
969                         }\r
970                         if (nc is RdpAnyName)\r
971                                 return;\r
972 \r
973                         RdpName n = nc as RdpName;\r
974                         if (n != null) {\r
975                                 if (n.NamespaceURI == xmlnsNS)\r
976                                         throw new RelaxngException (this, "cannot specify \"" + xmlnsNS + "\" for name of attribute.");\r
977                                 if (n.LocalName == "xmlns" && n.NamespaceURI == "")\r
978                                         throw new RelaxngException (this, "cannot specify \"xmlns\" inside empty ns context.");\r
979                         } else {\r
980                                 RdpNsName nn = nc as RdpNsName;\r
981                                 if (nn.NamespaceURI == "http://www.w3.org/2000/xmlns")\r
982                                         throw new RelaxngException (this, "cannot specify \"" + xmlnsNS + "\" for name of attribute.");\r
983                                 RdpNsNameExcept x = nc as RdpNsNameExcept;\r
984                                 if (x != null)\r
985                                         checkInvalidAttrNameClass (x.ExceptNameClass);\r
986                         }\r
987                 }\r
988 \r
989                 internal override RdpPattern Compile (RelaxngGrammar grammar)\r
990                 {\r
991                         IsCompiled = true;\r
992                         RdpNameClass cnc = nc.Compile (grammar);\r
993                         this.checkInvalidAttrNameClass (cnc);\r
994 \r
995                         return new RdpAttribute (cnc,\r
996                                 (p != null) ?\r
997                                         p.Compile (grammar) :\r
998                                         RdpText.Instance);\r
999                 }\r
1000 \r
1001                 internal override void CheckConstraints () \r
1002                 {\r
1003                         NameClass.CheckConstraints (false, false);\r
1004 \r
1005                         if (p != null)\r
1006                                 p.CheckConstraints ();\r
1007                 }\r
1008         }\r
1009 \r
1010         internal class RdpUnresolvedRef : RdpPattern\r
1011         {\r
1012                 string name;\r
1013 //              bool parentRef;\r
1014                 RelaxngGrammar targetGrammar;\r
1015                 RdpPattern referencedPattern;\r
1016 \r
1017                 public RdpUnresolvedRef (string name, RelaxngGrammar g)\r
1018                 {\r
1019                         this.name = name;\r
1020 //                      this.parentRef = parentRef;\r
1021                         targetGrammar = g;\r
1022                 }\r
1023 \r
1024                 public string Name {\r
1025                         get { return name; }\r
1026                         set { name = value; }\r
1027                 }\r
1028 \r
1029                 public RdpPattern RefPattern {\r
1030                         get { return referencedPattern; }\r
1031                         set { referencedPattern = value; }\r
1032                 }\r
1033 \r
1034 //              public bool IsParentRef {\r
1035 //                      get { return parentRef; }\r
1036 //              }\r
1037 \r
1038                 public RelaxngGrammar TargetGrammar {\r
1039                         get { return targetGrammar; }\r
1040                 }\r
1041 \r
1042                 public override RelaxngPatternType PatternType {\r
1043                         get { return RelaxngPatternType.Ref; }\r
1044                 }\r
1045 \r
1046                 public override RdpContentType ContentType {\r
1047                         get { return RdpContentType.Empty; }\r
1048                 }\r
1049 \r
1050 \r
1051                 public override bool Nullable {\r
1052                         get {\r
1053                                 throw new InvalidOperationException ("Internal error: should not reach.");\r
1054                         }\r
1055                 }\r
1056 \r
1057                 public override void GetLabels (Hashtable elements, Hashtable attributes)\r
1058                 {\r
1059                         throw new InvalidOperationException ("Internal error: should not reach.");\r
1060                 }\r
1061 \r
1062                 internal override RdpPattern ExpandRef (Hashtable defs)\r
1063                 {\r
1064                         return referencedPattern.ExpandRef (defs);\r
1065                 }\r
1066 \r
1067                 internal override void MarkReachableDefs () \r
1068                 {\r
1069                         TargetGrammar.MarkReacheableDefine (this.name);\r
1070                 }\r
1071 \r
1072                 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept) \r
1073                 {\r
1074 //                      throw new InvalidOperationException ();\r
1075                 }\r
1076 \r
1077                 internal override bool ContainsText ()\r
1078                 {\r
1079                         return false;\r
1080 //                      throw new InvalidOperationException ();\r
1081                 }\r
1082         }\r
1083 \r
1084         public class RelaxngRef : RelaxngPattern\r
1085         {\r
1086                 string name;\r
1087 \r
1088                 public RelaxngRef ()\r
1089                 {\r
1090                 }\r
1091 \r
1092                 public string Name {\r
1093                         get { return name; }\r
1094                         set { name = value; }\r
1095                 }\r
1096 \r
1097                 public override RelaxngPatternType PatternType {\r
1098                         get { return RelaxngPatternType.Ref; }\r
1099                 }\r
1100 \r
1101                 public override void Write (XmlWriter writer)\r
1102                 {\r
1103                         writer.WriteStartElement ("", "ref", RelaxngGrammar.NamespaceURI);\r
1104                         writer.WriteAttributeString ("name", name);\r
1105                         writer.WriteEndElement ();\r
1106                 }\r
1107 \r
1108                 internal override void WriteRnc (RncWriter writer)\r
1109                 {\r
1110                         writer.WriteRef (this);\r
1111                 }\r
1112 \r
1113                 internal override RdpPattern Compile (RelaxngGrammar grammar)\r
1114                 {\r
1115                         // Important!! This compile method only generates stub.\r
1116                         IsCompiled = false;\r
1117                         return new RdpUnresolvedRef (name, grammar);\r
1118                 }\r
1119 \r
1120                 internal override void CheckConstraints () \r
1121                 {\r
1122                         // nothing to check\r
1123                 }\r
1124         }\r
1125 \r
1126         public class RelaxngParentRef : RelaxngPattern\r
1127         {\r
1128                 string name;\r
1129 \r
1130                 public RelaxngParentRef ()\r
1131                 {\r
1132                 }\r
1133 \r
1134                 public string Name {\r
1135                         get { return name; }\r
1136                         set { name = value; }\r
1137                 }\r
1138 \r
1139                 public override RelaxngPatternType PatternType {\r
1140                         get { return RelaxngPatternType.ParentRef; }\r
1141                 }\r
1142 \r
1143                 public override void Write (XmlWriter writer)\r
1144                 {\r
1145                         writer.WriteStartElement ("", "parentRef", RelaxngGrammar.NamespaceURI);\r
1146                         writer.WriteAttributeString ("name", name);\r
1147                         writer.WriteEndElement ();\r
1148                 }\r
1149 \r
1150                 internal override void WriteRnc (RncWriter writer)\r
1151                 {\r
1152                         writer.WriteParentRef (this);\r
1153                 }\r
1154 \r
1155                 internal override RdpPattern Compile (RelaxngGrammar grammar)\r
1156                 {\r
1157                         IsCompiled = false;\r
1158                         return new RdpUnresolvedRef (name, grammar.ParentGrammar);\r
1159                 }\r
1160 \r
1161                 internal override void CheckConstraints () \r
1162                 {\r
1163                         // nothing to check\r
1164                 }\r
1165         }\r
1166 \r
1167         public class RelaxngExternalRef : RelaxngPattern\r
1168         {\r
1169                 string href;\r
1170                 string ns;\r
1171 \r
1172                 public RelaxngExternalRef ()\r
1173                 {\r
1174                 }\r
1175 \r
1176                 public string Href {\r
1177                         get { return href; }\r
1178                         set { href = value; }\r
1179                 }\r
1180 \r
1181                 public string NSContext {\r
1182                         get { return ns; }\r
1183                         set { ns = value; }\r
1184                 }\r
1185 \r
1186                 public override RelaxngPatternType PatternType {\r
1187                         get { return RelaxngPatternType.ExternalRef; }\r
1188                 }\r
1189 \r
1190                 public override void Write (XmlWriter writer)\r
1191                 {\r
1192                         writer.WriteStartElement ("", "externalRef", RelaxngGrammar.NamespaceURI);\r
1193                         writer.WriteAttributeString ("href", Href);\r
1194                         writer.WriteEndElement ();\r
1195                 }\r
1196 \r
1197                 internal override void WriteRnc (RncWriter writer)\r
1198                 {\r
1199                         writer.WriteExternalRef (this);\r
1200                 }\r
1201 \r
1202                 internal override RdpPattern Compile (RelaxngGrammar grammar)\r
1203                 {\r
1204                         grammar.CheckIncludeRecursion (Href);\r
1205                         grammar.IncludedUris.Add (Href, Href);\r
1206                         if (grammar.Resolver == null)\r
1207                                 throw new RelaxngException (this, "To compile 'include' element, XmlResolver is required.");\r
1208                         Uri uri = grammar.Resolver.ResolveUri (BaseUri != String.Empty ? new Uri (BaseUri) : null, Href);\r
1209                         XmlTextReader xtr = null;\r
1210                         try {\r
1211                                 xtr = new XmlTextReader (uri.AbsoluteUri, (Stream) grammar.Resolver.GetEntity (uri, null, typeof (Stream)));\r
1212                                 RelaxngReader r = new RelaxngReader (xtr, ns);\r
1213                                 r.MoveToContent ();\r
1214                                 RelaxngPattern p = r.ReadPattern ();\r
1215                                 p.DataProvider = grammar.Provider;\r
1216 \r
1217                                 RdpPattern ret = p.Compile (grammar);\r
1218 \r
1219                                 grammar.IncludedUris.Remove (Href);\r
1220 \r
1221                                 return ret;\r
1222                         } finally {\r
1223                                 if (xtr != null)\r
1224                                         xtr.Close ();\r
1225                         }\r
1226 \r
1227                 }\r
1228 \r
1229                 internal override void CheckConstraints () \r
1230                 {\r
1231                         // nothing to check\r
1232                 }\r
1233         }\r
1234 \r
1235         public class RelaxngOneOrMore : RelaxngSingleContentPattern\r
1236         {\r
1237                 public RelaxngOneOrMore ()\r
1238                 {\r
1239                 }\r
1240 \r
1241                 public override RelaxngPatternType PatternType {\r
1242                         get { return RelaxngPatternType.OneOrMore; }\r
1243                 }\r
1244 \r
1245                 public override void Write (XmlWriter writer)\r
1246                 {\r
1247                         writer.WriteStartElement ("", "oneOrMore", RelaxngGrammar.NamespaceURI);\r
1248                         foreach (RelaxngPattern p in Patterns)\r
1249                                 p.Write (writer);\r
1250                         writer.WriteEndElement ();\r
1251                 }\r
1252 \r
1253                 internal override void WriteRnc (RncWriter writer)\r
1254                 {\r
1255                         writer.WriteOneOrMore (this);\r
1256                 }\r
1257 \r
1258                 internal override RdpPattern Compile (RelaxngGrammar grammar)\r
1259                 {\r
1260                         IsCompiled = true;\r
1261                         return new RdpOneOrMore (makeSingle (grammar));\r
1262                 }\r
1263         }\r
1264 \r
1265         public class RelaxngZeroOrMore : RelaxngSingleContentPattern\r
1266         {\r
1267                 public RelaxngZeroOrMore ()\r
1268                 {\r
1269                 }\r
1270 \r
1271                 public override RelaxngPatternType PatternType {\r
1272                         get { return RelaxngPatternType.ZeroOrMore; }\r
1273                 }\r
1274 \r
1275                 public override void Write (XmlWriter writer)\r
1276                 {\r
1277                         writer.WriteStartElement ("", "zeroOrMore", RelaxngGrammar.NamespaceURI);\r
1278                         foreach (RelaxngPattern p in Patterns)\r
1279                                 p.Write (writer);\r
1280                         writer.WriteEndElement ();\r
1281                 }\r
1282 \r
1283                 internal override void WriteRnc (RncWriter writer)\r
1284                 {\r
1285                         writer.WriteZeroOrMore (this);\r
1286                 }\r
1287 \r
1288                 internal override RdpPattern Compile (RelaxngGrammar grammar)\r
1289                 {\r
1290                         IsCompiled = true;\r
1291                         return new RdpChoice (\r
1292                                 new RdpOneOrMore (makeSingle (grammar)),\r
1293                                 RdpEmpty.Instance);\r
1294                 }\r
1295         }\r
1296 \r
1297         public class RelaxngOptional : RelaxngSingleContentPattern\r
1298         {\r
1299                 public RelaxngOptional ()\r
1300                 {\r
1301                 }\r
1302 \r
1303                 public override RelaxngPatternType PatternType {\r
1304                         get { return RelaxngPatternType.Optional; }\r
1305                 }\r
1306 \r
1307                 public override void Write (XmlWriter writer)\r
1308                 {\r
1309                         writer.WriteStartElement ("", "optional", RelaxngGrammar.NamespaceURI);\r
1310                         foreach (RelaxngPattern p in Patterns)\r
1311                                 p.Write (writer);\r
1312                         writer.WriteEndElement ();\r
1313                 }\r
1314 \r
1315                 internal override void WriteRnc (RncWriter writer)\r
1316                 {\r
1317                         writer.WriteOptional (this);\r
1318                 }\r
1319 \r
1320                 internal override RdpPattern Compile (RelaxngGrammar grammar)\r
1321                 {\r
1322                         IsCompiled = true;\r
1323                         return new RdpChoice (\r
1324                                 makeSingle (grammar), RdpEmpty.Instance);\r
1325                 }\r
1326         }\r
1327 \r
1328         public class RelaxngMixed : RelaxngSingleContentPattern\r
1329         {\r
1330                 public RelaxngMixed ()\r
1331                 {\r
1332                 }\r
1333 \r
1334                 public override RelaxngPatternType PatternType {\r
1335                         get { return RelaxngPatternType.Mixed; }\r
1336                 }\r
1337 \r
1338                 public override void Write (XmlWriter writer)\r
1339                 {\r
1340                         writer.WriteStartElement ("", "mixed", RelaxngGrammar.NamespaceURI);\r
1341                         foreach (RelaxngPattern p in Patterns)\r
1342                                 p.Write (writer);\r
1343                         writer.WriteEndElement ();\r
1344                 }\r
1345 \r
1346                 internal override void WriteRnc (RncWriter writer)\r
1347                 {\r
1348                         writer.WriteMixed (this);\r
1349                 }\r
1350 \r
1351                 internal override RdpPattern Compile (RelaxngGrammar grammar)\r
1352                 {\r
1353                         IsCompiled = true;\r
1354                         return new RdpInterleave (makeSingle (grammar), RdpText.Instance);\r
1355                 }\r
1356         }\r
1357 \r
1358         public class RelaxngChoice : RelaxngBinaryContentPattern\r
1359         {\r
1360                 public RelaxngChoice ()\r
1361                 {\r
1362                 }\r
1363 \r
1364                 public override RelaxngPatternType PatternType {\r
1365                         get { return RelaxngPatternType.Choice; }\r
1366                 }\r
1367 \r
1368                 public override void Write (XmlWriter writer)\r
1369                 {\r
1370                         writer.WriteStartElement ("", "choice", RelaxngGrammar.NamespaceURI);\r
1371                         foreach (RelaxngPattern p in Patterns)\r
1372                                 p.Write (writer);\r
1373                         writer.WriteEndElement ();\r
1374                 }\r
1375 \r
1376                 internal override void WriteRnc (RncWriter writer)\r
1377                 {\r
1378                         writer.WriteChoice (this);\r
1379                 }\r
1380 \r
1381                 internal override RdpPattern Compile (RelaxngGrammar grammar)\r
1382                 {\r
1383                         IsCompiled = true;\r
1384                         return makeBinary (grammar);\r
1385                 }\r
1386         }\r
1387 \r
1388         public class RelaxngGroup : RelaxngBinaryContentPattern\r
1389         {\r
1390                 public RelaxngGroup ()\r
1391                 {\r
1392                 }\r
1393 \r
1394                 public override RelaxngPatternType PatternType {\r
1395                         get { return RelaxngPatternType.Group; }\r
1396                 }\r
1397 \r
1398                 public override void Write (XmlWriter writer)\r
1399                 {\r
1400                         writer.WriteStartElement ("", "group", RelaxngGrammar.NamespaceURI);\r
1401                         foreach (RelaxngPattern p in Patterns)\r
1402                                 p.Write (writer);\r
1403                         writer.WriteEndElement ();\r
1404                 }\r
1405 \r
1406                 internal override void WriteRnc (RncWriter writer)\r
1407                 {\r
1408                         writer.WriteGroup (this);\r
1409                 }\r
1410 \r
1411                 internal override RdpPattern Compile (RelaxngGrammar grammar)\r
1412                 {\r
1413                         IsCompiled = true;\r
1414                         return makeBinary (grammar);\r
1415                 }\r
1416         }\r
1417 \r
1418         public class RelaxngInterleave : RelaxngBinaryContentPattern\r
1419         {\r
1420                 public RelaxngInterleave ()\r
1421                 {\r
1422                 }\r
1423 \r
1424                 public override RelaxngPatternType PatternType {\r
1425                         get { return RelaxngPatternType.Interleave; }\r
1426                 }\r
1427 \r
1428                 public override void Write (XmlWriter writer)\r
1429                 {\r
1430                         writer.WriteStartElement ("", "interleave", RelaxngGrammar.NamespaceURI);\r
1431                         foreach (RelaxngPattern p in Patterns)\r
1432                                 p.Write (writer);\r
1433                         writer.WriteEndElement ();\r
1434                 }\r
1435 \r
1436                 internal override void WriteRnc (RncWriter writer)\r
1437                 {\r
1438                         writer.WriteInterleave (this);\r
1439                 }\r
1440 \r
1441                 internal override RdpPattern Compile (RelaxngGrammar grammar)\r
1442                 {\r
1443                         IsCompiled = true;\r
1444                         return makeBinary (grammar);\r
1445                 }\r
1446         }\r
1447 \r
1448         public class RelaxngParam : RelaxngElementBase\r
1449         {\r
1450                 string name;\r
1451                 string value;\r
1452 \r
1453                 public RelaxngParam ()\r
1454                 {\r
1455                 }\r
1456 \r
1457                 public RelaxngParam (string name, string value)\r
1458                 {\r
1459                         this.name = name;\r
1460                         this.value = value;\r
1461                 }\r
1462 \r
1463                 public string Name {\r
1464                         get { return name; }\r
1465                         set { name = value; }\r
1466                 }\r
1467 \r
1468                 public string Value {\r
1469                         get { return value; }\r
1470                         set { this.value = value; }\r
1471                 }\r
1472 \r
1473                 public override void Write (XmlWriter writer)\r
1474                 {\r
1475                         writer.WriteStartElement ("", "param", RelaxngGrammar.NamespaceURI);\r
1476                         writer.WriteAttributeString ("name", name);\r
1477                         writer.WriteString (Value);\r
1478                         writer.WriteEndElement ();\r
1479                 }\r
1480 \r
1481                 internal override void WriteRnc (RncWriter writer)\r
1482                 {\r
1483                         writer.WriteParam (this);\r
1484                 }\r
1485 \r
1486                 internal RdpParam Compile (RelaxngGrammar grammar)\r
1487                 {\r
1488                         IsCompiled = true;\r
1489                         return new RdpParam (name, value);\r
1490                 }\r
1491         }\r
1492 \r
1493         public class RelaxngParamList : CollectionBase\r
1494         {\r
1495                 public RelaxngParamList ()\r
1496                 {\r
1497                 }\r
1498 \r
1499                 public void Add (RelaxngParam p)\r
1500                 {\r
1501                         List.Add (p);\r
1502                 }\r
1503 \r
1504                 public RelaxngParam this [int i] {\r
1505                         get { return this.List [i] as RelaxngParam; }\r
1506                         set { this.List [i] = value; }\r
1507                 }\r
1508 \r
1509                 public void Insert (int pos, RelaxngParam p)\r
1510                 {\r
1511                         List.Insert (pos, p);\r
1512                 }\r
1513 \r
1514                 public void Remove (RelaxngParam p)\r
1515                 {\r
1516                         List.Remove (p);\r
1517                 }\r
1518         }\r
1519 \r
1520         public class RelaxngExcept : RelaxngElementBase\r
1521         {\r
1522                 RelaxngPatternList patterns = new RelaxngPatternList ();\r
1523 \r
1524                 public RelaxngExcept ()\r
1525                 {\r
1526                 }\r
1527 \r
1528                 public RelaxngPatternList Patterns {\r
1529                         get { return patterns; }\r
1530                 }\r
1531 \r
1532                 public override void Write (XmlWriter writer)\r
1533                 {\r
1534                         writer.WriteStartElement ("", "except", RelaxngGrammar.NamespaceURI);\r
1535                         foreach (RelaxngPattern p in Patterns)\r
1536                                 p.Write (writer);\r
1537                         writer.WriteEndElement ();\r
1538                 }\r
1539 \r
1540                 internal override void WriteRnc (RncWriter writer)\r
1541                 {\r
1542                         writer.WriteDataExcept (this);\r
1543                 }\r
1544         }\r
1545 \r
1546         internal class RelaxngRefPattern\r
1547         {\r
1548                 RelaxngPattern patternRef;\r
1549                 string name;\r
1550 \r
1551                 // When we found ref, use it.\r
1552                 public RelaxngRefPattern (string name)\r
1553                 {\r
1554                         this.name = name;\r
1555                 }\r
1556 \r
1557                 // When we found define, use it.\r
1558                 public RelaxngRefPattern (RelaxngPattern patternRef)\r
1559                 {\r
1560                         this.patternRef = patternRef;\r
1561                 }\r
1562 \r
1563                 public string Name {\r
1564                         get { return name; }\r
1565                 }\r
1566 \r
1567                 public RelaxngPattern PatternRef {\r
1568                         get { return patternRef; }\r
1569                         set { patternRef = value; }\r
1570                 }\r
1571         }\r
1572         #endregion\r
1573 }\r