updating to the latest module.
[mono.git] / mcs / class / Commons.Xml.Relaxng / Commons.Xml.Nvdl / NvdlFilteredXmlReader.cs
1 using System;
2 using System.Collections;
3 using System.IO;
4 using System.Xml;
5
6 namespace Commons.Xml.Nvdl
7 {
8 #if false
9         internal class NvdlFilteredXmlReader : XmlDefaultReader
10         {
11                 public NvdlFilteredXmlReader (XmlReader reader,
12                         NvdlValidateInterp validate)
13                         : base (reader)
14                 {
15                 }
16
17                 public bool Read ()
18                 {
19                         return !Reader.EOF;
20                 }
21
22                 public void AttachPlaceHolder ()
23                 {
24                 }
25
26                 public void DetachPlaceHolder ()
27                 {
28                 }
29         }
30 #else
31         internal class NvdlFilteredXmlReader : XmlReader
32         {
33                 int placeHolderDepth = -1;
34                 XmlNodeType nextPlaceHolder;
35                 XmlNodeType placeHolder;
36                 bool placeHolderLocalNameAttr;
37                 Stack placeHolderDepthStack;
38                 NvdlValidateInterp validate;
39                 XmlReader reader;
40
41                 AttributeInfo [] attributes = new AttributeInfo [10];
42                 int attributeCount;
43
44                 // PlanAtt validation cache.
45                 Hashtable attributeValidators = new Hashtable ();
46
47                 class AttributeInfo
48                 {
49                         public string LocalName;
50                         public string NamespaceURI;
51                 }
52
53                 public NvdlFilteredXmlReader (XmlReader reader,
54                         NvdlValidateInterp validate)
55                 {
56                         this.reader = reader;
57                         this.validate = validate;
58                 }
59
60                 public void AttachPlaceHolder ()
61                 {
62                         if (placeHolderDepthStack == null)
63                                 placeHolderDepthStack = new Stack ();
64                         else
65                                 placeHolderDepthStack.Push (placeHolderDepth);
66                         placeHolderDepth = reader.Depth;
67                         nextPlaceHolder = XmlNodeType.Element;
68                 }
69
70                 public void DetachPlaceHolder ()
71                 {
72                         if (placeHolderDepthStack.Count > 0)
73                                 placeHolderDepth = (int) placeHolderDepthStack.Pop ();
74                         else
75                                 placeHolderDepth = -1;
76                         nextPlaceHolder = XmlNodeType.EndElement;
77                 }
78
79                 private void AddAttribute ()
80                 {
81                         if (attributes.Length == attributeCount) {
82                                 AttributeInfo [] newArr =
83                                         new AttributeInfo [attributeCount * 2];
84                                 Array.Copy (attributes, newArr, attributeCount);
85                         }
86                         AttributeInfo ai = attributes [attributeCount];
87                         if (ai == null) {
88                                 ai = new AttributeInfo ();
89                                 attributes [attributeCount] = ai;
90                         }
91                         ai.LocalName = reader.LocalName;
92                         ai.NamespaceURI = reader.NamespaceURI;
93                         attributeCount++;
94                 }
95
96                 private SimpleRule FindAttributeRule (string ns, SimpleMode mode)
97                 {
98                         SimpleRule any = null;
99                         foreach (SimpleRule rule in mode.AttributeRules) {
100                                 if (!rule.MatchNS (ns))
101                                         continue;
102                                 if (!rule.IsAny)
103                                         return rule;
104                                 any = rule;
105                         }
106                         if (any != null)
107                                 return any;
108                         throw new NvdlValidationException ("NVDL internal error: should not happen. No matching rule was found.", reader as IXmlLineInfo);
109                 }
110
111                 // Public overrides
112
113                 public override bool Read ()
114                 {
115                         // This class itself never proceeds, just checks if
116                         // the reader is placed on EOF.
117                         if (reader.EOF)
118                                 return false;
119
120                         MoveToElement ();
121                         attributeCount = 0;
122
123                         if (nextPlaceHolder != XmlNodeType.None) {
124                                 placeHolder = nextPlaceHolder;
125                                 nextPlaceHolder = XmlNodeType.None;
126                                 return true;
127                         }
128
129                         if (!reader.MoveToFirstAttribute ())
130                                 return true;
131
132                         // Attribute rule application
133                         attributeValidators.Clear ();
134                         do {
135                                 // FIXME: could be more efficient
136                                 SimpleRule rule = FindAttributeRule (
137                                         reader.NamespaceURI,
138                                         validate.CreatedMode);
139                                 foreach (SimpleAction a in rule.Actions) {
140                                         SimpleResultAction ra =
141                                                 a as SimpleResultAction;
142                                         if (ra != null &&
143                                                 ra.ResultType == NvdlResultType.Attach)
144                                                 AddAttribute ();
145                                         if (ra != null)
146                                                 continue;
147                                         attributeValidators [reader.NamespaceURI] = a;
148                                 }
149                         } while (reader.MoveToNextAttribute ());
150                         reader.MoveToElement ();
151
152                         if (attributeValidators.Count > 0) {
153                                 foreach (string ns in attributeValidators.Keys) {
154                                         ((SimpleValidate) attributeValidators [
155                                                 ns]).ValidateAttributes (reader, ns);
156                                 }
157                         }
158
159                         return true;
160                 }
161
162                 public override int AttributeCount {
163                         get {
164                                 switch (placeHolder) {
165                                 case XmlNodeType.Element:
166                                 case XmlNodeType.Attribute: // ns or localName attribute on placeHolder element
167                                 case XmlNodeType.Text: // attribute value of ns or localName attribute on placeHolder element
168                                         return 2;
169                                 case XmlNodeType.EndElement:
170                                         return 0;
171                                 default:
172                                         return attributeCount;
173                                 }
174                         }
175                 }
176
177                 public override string BaseURI {
178                         get { return reader.BaseURI; }
179                 }
180
181                 public override int Depth {
182                         get {
183                                 if (placeHolderDepth < 0)
184                                         return reader.Depth;
185                                 int basis = reader.Depth + placeHolderDepthStack.Count + 1;
186                                 switch (placeHolder) {
187                                 case XmlNodeType.Text:
188                                         return basis + 2;
189                                 case XmlNodeType.Attribute:
190                                         return basis + 1;
191                                 default:
192                                         return basis;
193                                 }
194                         }
195                 }
196
197                 public override bool EOF {
198                         get { return reader.EOF && placeHolder != XmlNodeType.None; }
199                 }
200
201                 public override bool HasValue {
202                         get {
203                                 switch (placeHolder) {
204                                 case XmlNodeType.Attribute:
205                                 case XmlNodeType.Text:
206                                         return true;
207                                 case XmlNodeType.Element:
208                                 case XmlNodeType.EndElement:
209                                         return false;
210                                 default:
211                                         return reader.HasValue;
212                                 }
213                         }
214                 }
215
216                 public override bool IsDefault {
217                         get {
218                                 return placeHolder == XmlNodeType.None &&
219                                         reader.IsDefault;
220                         }
221                 }
222
223                 public override bool IsEmptyElement {
224                         get {
225                                 return placeHolder == XmlNodeType.None &&
226                                         reader.IsEmptyElement; 
227                         }
228                 }
229
230                 public override string LocalName {
231                         get {
232                                 switch (placeHolder) {
233                                 case XmlNodeType.Element:
234                                 case XmlNodeType.EndElement:
235                                         return "placeHolder";
236                                 case XmlNodeType.Attribute:
237                                         return placeHolderLocalNameAttr ?
238                                                 "localName" : "ns";
239                                 case XmlNodeType.Text:
240                                         return String.Empty;
241                                 default:
242                                         return reader.LocalName;
243                                 }
244                         }
245                 }
246
247                 public override string Name {
248                         get {
249                                 switch (placeHolder) {
250                                 case XmlNodeType.Element:
251                                 case XmlNodeType.EndElement:
252                                         return "placeHolder";
253                                 case XmlNodeType.Attribute:
254                                         return placeHolderLocalNameAttr ?
255                                                 "localName" : "ns";
256                                 case XmlNodeType.Text:
257                                         return String.Empty;
258                                 default:
259                                         return reader.Name;
260                                 }
261                         }
262                 }
263
264                 public override string NamespaceURI {
265                         get {
266                                 switch (placeHolder) {
267                                 case XmlNodeType.Element:
268                                 case XmlNodeType.EndElement:
269                                         return Nvdl.InstanceNamespace;
270                                 case XmlNodeType.Attribute:
271                                         return placeHolderLocalNameAttr ?
272                                                 "localName" : "ns";
273                                 case XmlNodeType.Text:
274                                         return String.Empty;
275                                 default:
276                                         return reader.NamespaceURI;
277                                 }
278                         }
279                 }
280
281                 public override XmlNameTable NameTable {
282                         get { return reader.NameTable; }
283                 }
284
285                 public override XmlNodeType NodeType {
286                         get {
287                                 return placeHolder != XmlNodeType.None ?
288                                         placeHolder : reader.NodeType; 
289                         }
290                 }
291
292                 public override string Prefix {
293                         get {
294                                 return placeHolder != XmlNodeType.None ?
295                                         String.Empty : reader.Name; 
296                         }
297                 }
298
299                 public override char QuoteChar {
300                         get { return reader.QuoteChar; }
301                 }
302
303                 public override ReadState ReadState {
304                         get { 
305                                 return placeHolder != XmlNodeType.None &&
306                                         reader.ReadState != ReadState.Error ? 
307                                         ReadState.Interactive :
308                                         reader.ReadState; 
309                         }
310                 }
311
312                 public override string Value {
313                         get {
314                                 switch (placeHolder) {
315                                 case XmlNodeType.Element:
316                                 case XmlNodeType.EndElement:
317                                         return String.Empty;
318                                 case XmlNodeType.Attribute:
319                                 case XmlNodeType.Text:
320                                         return placeHolderLocalNameAttr ?
321                                                 reader.LocalName :
322                                                 reader.NamespaceURI;
323                                 default:
324                                         return reader.Value;
325                                 }
326                         }
327                 }
328
329                 // FIXME: xml:lang might have been filtered
330                 public override string XmlLang {
331                         get { return reader.XmlLang; }
332                 }
333
334                 // FIXME: xml:space might have been filtered
335                 public override XmlSpace XmlSpace {
336                         get { return reader.XmlSpace; }
337                 }
338
339                 public override string this [int i] {
340                         get { return GetAttribute (i); }
341                 }
342
343                 public override string this [string name] {
344                         get { return GetAttribute (name); }
345                 }
346
347                 public override string this [string localName, string ns] {
348                         get { return GetAttribute (localName, ns); }
349                 }
350
351                 public override string GetAttribute (int i)
352                 {
353                         if (placeHolder == XmlNodeType.Element)
354                                 return placeHolderLocalNameAttr ?
355                                         reader.LocalName : reader.NamespaceURI;
356                         else
357                                 return reader.GetAttribute (
358                                         attributes [i].LocalName,
359                                         attributes [i].NamespaceURI);
360                 }
361
362                 public override string GetAttribute (string name)
363                 {
364                         if (placeHolder == XmlNodeType.Element) {
365                                 switch (name) {
366                                 case "localName":
367                                         return reader.LocalName;
368                                 case "ns":
369                                         return reader.NamespaceURI;
370                                 default:
371                                         return null;
372                                 }
373                         }
374                         return reader.GetAttribute (name);
375                 }
376
377                 public override string GetAttribute (string localName, string ns)
378                 {
379                         if (placeHolder == XmlNodeType.Element) {
380                                 if (ns != String.Empty)
381                                         return null;
382                                 return GetAttribute (localName);
383                         }
384                         return reader.GetAttribute (localName, ns);
385                 }
386
387                 public override void ResolveEntity ()
388                 {
389                         if (placeHolder != XmlNodeType.None)
390                                 throw new XmlException ("Current node is not an EntityReference.");
391                         reader.ResolveEntity ();
392                 }
393
394                 public override void Close ()
395                 {
396                         // do nothing.
397                 }
398
399                 public override string LookupNamespace (string prefix)
400                 {
401                         // For placeHolder element, we treat them as to have
402                         // empty prefix. So we have to handle empty prefix as if
403                         // it was mapped to the namespace.
404                         if (placeHolder != XmlNodeType.None && prefix == String.Empty)
405                                 return Nvdl.InstanceNamespace;
406                         return reader.LookupNamespace (prefix);
407                 }
408
409                 public override bool MoveToElement ()
410                 {
411                         switch (placeHolder) {
412                         case XmlNodeType.Element:
413                         case XmlNodeType.EndElement:
414                                 return false;
415                         case XmlNodeType.Attribute:
416                         case XmlNodeType.Text:
417                                 placeHolder = XmlNodeType.Element;
418                                 placeHolderLocalNameAttr = false;
419                                 return true;
420                         default:
421                                 return reader.MoveToElement ();
422                         }
423                 }
424
425                 public override bool MoveToFirstAttribute ()
426                 {
427                         switch (placeHolder) {
428                         case XmlNodeType.Element:
429                                 placeHolder = XmlNodeType.Attribute;
430                                 placeHolderLocalNameAttr = true;
431                                 return true;
432                         case XmlNodeType.EndElement:
433                                 return false;
434                         case XmlNodeType.Attribute:
435                         case XmlNodeType.Text:
436                                 placeHolder = XmlNodeType.Attribute;
437                                 placeHolderLocalNameAttr = true;
438                                 return true;
439                         default:
440                                 if (attributeCount == 0)
441                                         return false;
442                                 return reader.MoveToAttribute (
443                                         attributes [0].LocalName,
444                                         attributes [0].NamespaceURI);
445                         }
446                 }
447
448                 public override bool MoveToNextAttribute ()
449                 {
450                         switch (placeHolder) {
451                         case XmlNodeType.Element:
452                         case XmlNodeType.EndElement:
453                                 return false;
454                         case XmlNodeType.Attribute:
455                         case XmlNodeType.Text:
456                                 if (!placeHolderLocalNameAttr)
457                                         return false;
458                                 placeHolderLocalNameAttr = false;
459                                 placeHolder = XmlNodeType.Attribute;
460                                 return true;
461                         default:
462                                 if (reader.NodeType == XmlNodeType.Element)
463                                         return false;
464                                 for (int i = 0; i < attributeCount - 1; i++) {
465                                         if (attributes [i].LocalName != reader.LocalName ||
466                                                 attributes [i].NamespaceURI != reader.NamespaceURI)
467                                                 continue;
468                                         reader.MoveToAttribute (
469                                                 attributes [i + 1].LocalName,
470                                                 attributes [i + 1].NamespaceURI);
471                                         return true;
472                                 }
473                                 return false;
474                         }
475                 }
476
477                 public override bool ReadAttributeValue ()
478                 {
479                         switch (placeHolder) {
480                         case XmlNodeType.Element:
481                         case XmlNodeType.EndElement:
482                         case XmlNodeType.Text:
483                                 return false;
484                         case XmlNodeType.Attribute:
485                                 placeHolder = XmlNodeType.Text;
486                                 return true;
487                         default:
488                                 return reader.ReadAttributeValue ();
489                         }
490                 }
491
492                 public override void MoveToAttribute (int i)
493                 {
494                         switch (placeHolder) {
495                         case XmlNodeType.EndElement:
496                                 throw new IndexOutOfRangeException ();
497                         case XmlNodeType.Element:
498                         case XmlNodeType.Attribute:
499                         case XmlNodeType.Text:
500                                 switch (i) {
501                                 case 0:
502                                         placeHolderLocalNameAttr = true;
503                                         return;
504                                 case 1:
505                                         placeHolderLocalNameAttr = false;
506                                         return;
507                                 }
508                                 throw new IndexOutOfRangeException ();
509                         default:
510                                 if (i < 0 || attributeCount <= i)
511                                         throw new IndexOutOfRangeException ();
512                                 reader.MoveToAttribute (
513                                         attributes [i].LocalName,
514                                         attributes [i].NamespaceURI);
515                                 break;
516                         }
517                 }
518
519                 public override bool MoveToAttribute (string qname)
520                 {
521                         int index = qname.IndexOf (':');
522                         if (index < 0)
523                                 return MoveToAttribute (qname, String.Empty);
524                         return MoveToAttribute (qname.Substring (index + 1),
525                                 LookupNamespace (qname.Substring (0, index)));
526                 }
527
528                 public override bool MoveToAttribute (string localName, string ns)
529                 {
530                         switch (placeHolder) {
531                         case XmlNodeType.EndElement:
532                                 return false;
533                         case XmlNodeType.Element:
534                         case XmlNodeType.Attribute:
535                         case XmlNodeType.Text:
536                                 if (ns != String.Empty)
537                                         return false;
538                                 switch (localName) {
539                                 case "localName":
540                                         MoveToAttribute (0);
541                                         return true;
542                                 case "ns":
543                                         MoveToAttribute (1);
544                                         return true;
545                                 default:
546                                         return false;
547                                 }
548                         default:
549                                 for (int i = 0; i < attributeCount; i++) {
550                                         if (attributes [i].LocalName != localName ||
551                                                 attributes [i].NamespaceURI != ns)
552                                                 continue;
553                                         return reader.MoveToAttribute (localName, ns);
554                                 }
555                                 return false;
556                         }
557                 }
558         }
559 #endif
560 }
561