merge -r 53370:58178
[mono.git] / mcs / class / Commons.Xml.Relaxng / Commons.Xml.Nvdl / NvdlReader.cs
1 using System;
2 using System.Collections;
3 using System.Xml;
4 using Commons.Xml.Relaxng;
5
6 namespace Commons.Xml.Nvdl
7 {
8         public class NvdlReader
9         {
10                 public static NvdlRules Read (XmlReader reader)
11                 {
12                         return new NvdlReader (reader).ReadRules ();
13                 }
14
15                 XmlReader reader;
16                 IXmlLineInfo lineInfo;
17                 XmlDocument doc = new XmlDocument ();
18
19                 private NvdlReader (XmlReader reader)
20                 {
21                         // FIXME: use .rnc validation.
22                         this.reader = reader;
23                         this.lineInfo = reader as IXmlLineInfo;
24                         reader.MoveToContent ();
25                 }
26
27                 private void FillForeignAttribute (NvdlAttributable el)
28                 {
29                         if (!reader.MoveToFirstAttribute ())
30                                 return;
31                         do {
32                                 if (reader.NamespaceURI == "")
33                                         continue;
34                                 XmlAttribute a = doc.CreateAttribute (
35                                                 reader.Prefix,
36                                                 reader.LocalName,
37                                                 reader.NamespaceURI);
38                                 a.Value = reader.Value;
39                                 el.Foreign.Add (a);
40                         } while (reader.MoveToNextAttribute ());
41                         reader.MoveToElement ();
42                 }
43
44                 private void FillNonXmlAttributes (NvdlMessage el)
45                 {
46                         if (!reader.MoveToFirstAttribute ())
47                                 return;
48                         do {
49                                 if (reader.NamespaceURI == Nvdl.XmlNamespaceUri)
50                                         continue;
51                                 XmlAttribute a = doc.CreateAttribute (
52                                                 reader.Prefix,
53                                                 reader.LocalName,
54                                                 reader.NamespaceURI);
55                                 a.Value = reader.Value;
56                                 el.ForeignAttributes.Add (a);
57                         } while (reader.MoveToNextAttribute ());
58                         reader.MoveToElement ();
59                 }
60
61                 private void FillLocation (NvdlElementBase el)
62                 {
63                         el.SourceUri = reader.BaseURI;
64                         if (lineInfo != null) {
65                                 el.LineNumber = lineInfo.LineNumber;
66                                 el.LinePosition = lineInfo.LinePosition;
67                         }
68                 }
69
70                 private NvdlRuleTarget ParseMatch (string s)
71                 {
72                         if (s == null)
73                                 return NvdlRuleTarget.None;
74                         if (s.IndexOf ("elements") >= 0)
75                                 return (s.IndexOf ("attributes") >= 0) ?
76                                         NvdlRuleTarget.Both :
77                                         NvdlRuleTarget.Elements;
78                         else
79                                 return (s.IndexOf ("attributes") >= 0) ?
80                                         NvdlRuleTarget.Attributes :
81                                         NvdlRuleTarget.None;
82                 }
83
84                 private NvdlRules ReadRules ()
85                 {
86                         NvdlRules el = new NvdlRules ();
87                         FillLocation (el);
88                         el.SchemaType = reader.GetAttribute ("schemaType");
89                         el.StartMode = reader.GetAttribute ("startMode");
90                         FillForeignAttribute (el);
91                         if (reader.IsEmptyElement) {
92                                 reader.Skip ();
93                                 return el;
94                         }
95                         reader.Read ();
96                         do {
97                                 reader.MoveToContent ();
98                                 if (reader.NodeType == XmlNodeType.EndElement)
99                                         break;
100                                 if (reader.NamespaceURI != Nvdl.Namespace) {
101                                         el.Foreign.Add (doc.ReadNode (reader));
102                                         continue;
103                                 }
104                                 switch (reader.LocalName) {
105                                 case "mode":
106                                         el.Modes.Add (ReadMode ());
107                                         break;
108                                 case "namespace":
109                                         el.Rules.Add (ReadNamespace ());
110                                         break;
111                                 case "anyNamespace":
112                                         el.Rules.Add (ReadAnyNamespace ());
113                                         break;
114                                 case "trigger":
115                                         el.Triggers.Add (ReadTrigger ());
116                                         break;
117                                 }
118                         } while (!reader.EOF);
119                         if (!reader.EOF)
120                                 reader.Read ();
121                         return el;
122                 }
123
124                 private NvdlTrigger ReadTrigger ()
125                 {
126                         NvdlTrigger el = new NvdlTrigger ();
127                         FillLocation (el);
128                         el.NS = reader.GetAttribute ("ns");
129                         el.Name = reader.GetAttribute ("name");
130                         FillForeignAttribute (el);
131                         if (reader.IsEmptyElement) {
132                                 reader.Skip ();
133                                 return el;
134                         }
135                         reader.Read ();
136                         do {
137                                 reader.MoveToContent ();
138                                 if (reader.NodeType == XmlNodeType.EndElement)
139                                         break;
140                                 if (reader.NamespaceURI != Nvdl.Namespace) {
141                                         el.Foreign.Add (doc.ReadNode (reader));
142                                         continue;
143                                 }
144                         } while (!reader.EOF);
145                         if (!reader.EOF)
146                                 reader.Read ();
147                         return el;
148                 }
149
150                 private NvdlMode ReadMode ()
151                 {
152                         NvdlMode el = new NvdlMode ();
153                         FillLocation (el);
154                         el.Name = reader.GetAttribute ("name");
155                         ReadModeCommon (el);
156                         return el;
157                 }
158
159                 private NvdlIncludedMode ReadIncludedMode ()
160                 {
161                         NvdlIncludedMode el = new NvdlIncludedMode ();
162                         FillLocation (el);
163                         el.Name = reader.GetAttribute ("name");
164                         ReadModeCommon (el);
165                         return el;
166                 }
167
168                 private NvdlNestedMode ReadNestedMode ()
169                 {
170                         NvdlNestedMode el = new NvdlNestedMode ();
171                         FillLocation (el);
172                         ReadModeCommon (el);
173                         return el;
174                 }
175
176                 private void ReadModeCommon (NvdlModeBase el)
177                 {
178                         FillForeignAttribute (el);
179                         if (reader.IsEmptyElement) {
180                                 reader.Skip ();
181                                 return;
182                         }
183                         reader.Read ();
184                         do {
185                                 reader.MoveToContent ();
186                                 if (reader.NodeType == XmlNodeType.EndElement)
187                                         break;
188                                 if (reader.NamespaceURI != Nvdl.Namespace) {
189                                         el.Foreign.Add (doc.ReadNode (reader));
190                                         continue;
191                                 }
192                                 switch (reader.LocalName) {
193                                 case "mode":
194                                         el.IncludedModes.Add (ReadIncludedMode ());
195                                         break;
196                                 case "namespace":
197                                         el.Rules.Add (ReadNamespace ());
198                                         break;
199                                 case "anyNamespace":
200                                         el.Rules.Add (ReadAnyNamespace ());
201                                         break;
202                                 }
203                         } while (!reader.EOF);
204                         if (!reader.EOF)
205                                 reader.Read ();
206                         return;
207                 }
208
209                 private NvdlAnyNamespace ReadAnyNamespace ()
210                 {
211                         NvdlAnyNamespace el = new NvdlAnyNamespace ();
212                         FillLocation (el);
213                         el.Match = ParseMatch (reader.GetAttribute ("match"));
214                         FillForeignAttribute (el);
215                         if (reader.IsEmptyElement) {
216                                 reader.Skip ();
217                                 return el;
218                         }
219                         reader.Read ();
220                         do {
221                                 reader.MoveToContent ();
222                                 if (reader.NodeType == XmlNodeType.EndElement)
223                                         break;
224                                 if (reader.NamespaceURI != Nvdl.Namespace) {
225                                         el.Foreign.Add (doc.ReadNode (reader));
226                                         continue;
227                                 }
228                                 ReadAction (el);
229                         } while (!reader.EOF);
230                         if (!reader.EOF)
231                                 reader.Read ();
232                         return el;
233                 }
234
235                 private NvdlNamespace ReadNamespace ()
236                 {
237                         NvdlNamespace el = new NvdlNamespace ();
238                         FillLocation (el);
239                         el.NS = reader.GetAttribute ("ns");
240                         el.Wildcard = reader.GetAttribute ("wildcard");
241                         el.Match = ParseMatch (reader.GetAttribute ("match"));
242                         FillForeignAttribute (el);
243                         if (reader.IsEmptyElement) {
244                                 reader.Skip ();
245                                 return el;
246                         }
247                         reader.Read ();
248                         do {
249                                 reader.MoveToContent ();
250                                 if (reader.NodeType == XmlNodeType.EndElement)
251                                         break;
252                                 if (reader.NamespaceURI != Nvdl.Namespace) {
253                                         el.Foreign.Add (doc.ReadNode (reader));
254                                         continue;
255                                 }
256                                 ReadAction (el);
257                         } while (!reader.EOF);
258                         if (!reader.EOF)
259                                 reader.Read ();
260                         return el;
261                 }
262
263                 private void ReadAction (NvdlRule el)
264                 {
265                         switch (reader.LocalName) {
266                         case "cancelNestedActions":
267                                 el.Actions.Add (ReadCancelAction ());
268                                 break;
269                         case "validate":
270                                 el.Actions.Add (ReadValidate ());
271                                 break;
272                         case "allow":
273                                 el.Actions.Add (ReadAllow ());
274                                 break;
275                         case "reject":
276                                 el.Actions.Add (ReadReject ());
277                                 break;
278                         case "attach":
279                                 el.Actions.Add (ReadAttach ());
280                                 break;
281                         case "attachPlaceHolder":
282                                 el.Actions.Add (ReadAttachPlaceHolder ());
283                                 break;
284                         case "unwrap":
285                                 el.Actions.Add (ReadUnwrap ());
286                                 break;
287                         }
288                 }
289
290                 private NvdlCancelAction ReadCancelAction ()
291                 {
292                         NvdlCancelAction el = new NvdlCancelAction ();
293                         FillLocation (el);
294                         FillForeignAttribute (el);
295                         if (reader.IsEmptyElement) {
296                                 reader.Skip ();
297                                 return el;
298                         }
299                         reader.Read ();
300                         do {
301                                 reader.MoveToContent ();
302                                 if (reader.NodeType == XmlNodeType.EndElement)
303                                         break;
304                                 if (reader.NamespaceURI != Nvdl.Namespace) {
305                                         el.Foreign.Add (doc.ReadNode (reader));
306                                         continue;
307                                 }
308                         } while (!reader.EOF);
309                         if (!reader.EOF)
310                                 reader.Read ();
311                         return el;
312                 }
313
314                 private NvdlValidate ReadValidate ()
315                 {
316                         NvdlValidate el = new NvdlValidate ();
317                         NvdlModeUsage mu = new NvdlModeUsage ();
318                         el.ModeUsage = mu;
319                         FillLocation (el);
320                         el.SchemaType = reader.GetAttribute ("schemaType");
321                         el.SimpleMessage = reader.GetAttribute ("message");
322                         el.SchemaUri = reader.GetAttribute ("schema");
323                         mu.UseMode = reader.GetAttribute ("useMode");
324                         FillForeignAttribute (el);
325                         if (reader.IsEmptyElement) {
326                                 reader.Skip ();
327                                 return el;
328                         }
329                         reader.Read ();
330                         do {
331                                 reader.MoveToContent ();
332                                 if (reader.NodeType == XmlNodeType.EndElement)
333                                         break;
334                                 if (reader.NamespaceURI != Nvdl.Namespace) {
335                                         el.Foreign.Add (doc.ReadNode (reader));
336                                         continue;
337                                 }
338                                 switch (reader.LocalName) {
339                                 case "message":
340                                         el.Messages.Add (ReadMessage ());
341                                         break;
342                                 case "option":
343                                         el.Options.Add (ReadOption ());
344                                         break;
345                                 case "schema":
346                                         el.SchemaBody = (XmlElement) doc.ReadNode (reader);
347                                         break;
348                                 case "mode":
349                                         mu.NestedMode = ReadNestedMode ();
350                                         break;
351                                 case "context":
352                                         mu.Contexts.Add (ReadContext ());
353                                         break;
354                                 }
355                         } while (!reader.EOF);
356                         if (!reader.EOF)
357                                 reader.Read ();
358                         return el;
359                 }
360
361                 private NvdlAllow ReadAllow ()
362                 {
363                         NvdlAllow el = new NvdlAllow ();
364                         ReadCommonActionContent (el);
365                         return el;
366                 }
367
368                 private NvdlReject ReadReject ()
369                 {
370                         NvdlReject el = new NvdlReject ();
371                         ReadCommonActionContent (el);
372                         return el;
373                 }
374
375                 private NvdlAttach ReadAttach ()
376                 {
377                         NvdlAttach el = new NvdlAttach ();
378                         ReadCommonActionContent (el);
379                         return el;
380                 }
381
382                 private NvdlAttachPlaceHolder ReadAttachPlaceHolder ()
383                 {
384                         NvdlAttachPlaceHolder el = new NvdlAttachPlaceHolder ();
385                         ReadCommonActionContent (el);
386                         return el;
387                 }
388
389                 private NvdlUnwrap ReadUnwrap ()
390                 {
391                         NvdlUnwrap el = new NvdlUnwrap ();
392                         ReadCommonActionContent (el);
393                         return el;
394                 }
395
396                 private void ReadCommonActionContent (NvdlNoCancelAction el)
397                 {
398                         FillLocation (el);
399                         NvdlModeUsage mu = new NvdlModeUsage ();
400                         el.ModeUsage = mu;
401                         FillLocation (el);
402                         el.SimpleMessage = reader.GetAttribute ("message");
403                         mu.UseMode = reader.GetAttribute ("useMode");
404                         FillForeignAttribute (el);
405                         if (reader.IsEmptyElement) {
406                                 reader.Skip ();
407                                 return;
408                         }
409                         reader.Read ();
410                         do {
411                                 reader.MoveToContent ();
412                                 if (reader.NodeType == XmlNodeType.EndElement)
413                                         break;
414                                 if (reader.NamespaceURI != Nvdl.Namespace) {
415                                         el.Foreign.Add (doc.ReadNode (reader));
416                                         continue;
417                                 }
418                                 switch (reader.LocalName) {
419                                 case "mode":
420                                         mu.NestedMode = ReadNestedMode ();
421                                         break;
422                                 case "message":
423                                         el.Messages.Add (ReadMessage ());
424                                         break;
425                                 case "context":
426                                         mu.Contexts.Add (ReadContext ());
427                                         break;
428                                 }
429                         } while (!reader.EOF);
430                         if (!reader.EOF)
431                                 reader.Read ();
432                 }
433
434                 private NvdlMessage ReadMessage ()
435                 {
436                         NvdlMessage el = new NvdlMessage ();
437                         FillLocation (el);
438                         el.XmlLang = reader.GetAttribute ("lang", Nvdl.XmlNamespaceUri);
439                         FillNonXmlAttributes (el);
440                         if (reader.IsEmptyElement) {
441                                 reader.Skip ();
442                                 el.Text = "";
443                         }
444                         else
445                                 el.Text = reader.ReadElementString ();
446                         return el;
447                 }
448
449                 private NvdlOption ReadOption ()
450                 {
451                         NvdlOption el = new NvdlOption ();
452                         FillLocation (el);
453                         el.Name = reader.GetAttribute ("name");
454                         el.Arg = reader.GetAttribute ("arg");
455                         el.MustSupport = reader.GetAttribute ("mustSupport");
456                         FillForeignAttribute (el);
457                         if (reader.IsEmptyElement) {
458                                 reader.Skip ();
459                                 return el;
460                         }
461                         reader.Read ();
462                         do {
463                                 reader.MoveToContent ();
464                                 if (reader.NodeType == XmlNodeType.EndElement)
465                                         break;
466                                 if (reader.NamespaceURI != Nvdl.Namespace) {
467                                         el.Foreign.Add (doc.ReadNode (reader));
468                                         continue;
469                                 }
470                         } while (!reader.EOF);
471                         if (!reader.EOF)
472                                 reader.Read ();
473                         return el;
474                 }
475
476                 private NvdlContext ReadContext ()
477                 {
478                         NvdlContext el = new NvdlContext ();
479                         FillLocation (el);
480                         el.Path = reader.GetAttribute ("path");
481                         el.UseMode = reader.GetAttribute ("useMode");
482                         FillForeignAttribute (el);
483                         if (reader.IsEmptyElement) {
484                                 reader.Skip ();
485                                 return el;
486                         }
487                         reader.Read ();
488                         do {
489                                 reader.MoveToContent ();
490                                 if (reader.NodeType == XmlNodeType.EndElement)
491                                         break;
492                                 if (reader.NamespaceURI != Nvdl.Namespace) {
493                                         el.Foreign.Add (doc.ReadNode (reader));
494                                         continue;
495                                 }
496                                 switch (reader.LocalName) {
497                                 case "mode":
498                                         el.NestedMode = ReadNestedMode ();
499                                         break;
500                                 }
501                         } while (!reader.EOF);
502                         if (!reader.EOF)
503                                 reader.Read ();
504                         return el;
505                 }
506         }
507 }
508