Refreshed the CSProj files to use the new output build directory
[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.NameList = reader.GetAttribute ("nameList");
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                         default:
288                                 throw new NotSupportedException ();
289                         }
290                 }
291
292                 private NvdlCancelAction ReadCancelAction ()
293                 {
294                         NvdlCancelAction el = new NvdlCancelAction ();
295                         FillLocation (el);
296                         FillForeignAttribute (el);
297                         if (reader.IsEmptyElement) {
298                                 reader.Skip ();
299                                 return el;
300                         }
301                         reader.Read ();
302                         do {
303                                 reader.MoveToContent ();
304                                 if (reader.NodeType == XmlNodeType.EndElement)
305                                         break;
306                                 if (reader.NamespaceURI != Nvdl.Namespace) {
307                                         el.Foreign.Add (doc.ReadNode (reader));
308                                         continue;
309                                 }
310                         } while (!reader.EOF);
311                         if (!reader.EOF)
312                                 reader.Read ();
313                         return el;
314                 }
315
316                 private NvdlValidate ReadValidate ()
317                 {
318                         NvdlValidate el = new NvdlValidate ();
319                         NvdlModeUsage mu = new NvdlModeUsage ();
320                         el.ModeUsage = mu;
321                         FillLocation (el);
322                         el.SchemaType = reader.GetAttribute ("schemaType");
323                         el.SimpleMessage = reader.GetAttribute ("message");
324                         el.SchemaUri = reader.GetAttribute ("schema");
325                         mu.UseMode = reader.GetAttribute ("useMode");
326                         FillForeignAttribute (el);
327                         if (reader.IsEmptyElement) {
328                                 reader.Skip ();
329                                 return el;
330                         }
331                         reader.Read ();
332                         do {
333                                 reader.MoveToContent ();
334                                 if (reader.NodeType == XmlNodeType.EndElement)
335                                         break;
336                                 if (reader.NamespaceURI != Nvdl.Namespace) {
337                                         el.Foreign.Add (doc.ReadNode (reader));
338                                         continue;
339                                 }
340                                 switch (reader.LocalName) {
341                                 case "message":
342                                         el.Messages.Add (ReadMessage ());
343                                         break;
344                                 case "option":
345                                         el.Options.Add (ReadOption ());
346                                         break;
347                                 case "schema":
348                                         el.SchemaBody = (XmlElement) doc.ReadNode (reader);
349                                         break;
350                                 case "mode":
351                                         mu.NestedMode = ReadNestedMode ();
352                                         break;
353                                 case "context":
354                                         mu.Contexts.Add (ReadContext ());
355                                         break;
356                                 default:
357                                         throw new NotSupportedException ();
358                                 }
359                         } while (!reader.EOF);
360                         if (!reader.EOF)
361                                 reader.Read ();
362                         return el;
363                 }
364
365                 private NvdlAllow ReadAllow ()
366                 {
367                         NvdlAllow el = new NvdlAllow ();
368                         ReadCommonActionContent (el);
369                         return el;
370                 }
371
372                 private NvdlReject ReadReject ()
373                 {
374                         NvdlReject el = new NvdlReject ();
375                         ReadCommonActionContent (el);
376                         return el;
377                 }
378
379                 private NvdlAttach ReadAttach ()
380                 {
381                         NvdlAttach el = new NvdlAttach ();
382                         ReadCommonActionContent (el);
383                         return el;
384                 }
385
386                 private NvdlAttachPlaceholder ReadAttachPlaceholder ()
387                 {
388                         NvdlAttachPlaceholder el = new NvdlAttachPlaceholder ();
389                         ReadCommonActionContent (el);
390                         return el;
391                 }
392
393                 private NvdlUnwrap ReadUnwrap ()
394                 {
395                         NvdlUnwrap el = new NvdlUnwrap ();
396                         ReadCommonActionContent (el);
397                         return el;
398                 }
399
400                 private void ReadCommonActionContent (NvdlNoCancelAction el)
401                 {
402                         FillLocation (el);
403                         NvdlModeUsage mu = new NvdlModeUsage ();
404                         el.ModeUsage = mu;
405                         FillLocation (el);
406                         el.SimpleMessage = reader.GetAttribute ("message");
407                         mu.UseMode = reader.GetAttribute ("useMode");
408                         FillForeignAttribute (el);
409                         if (reader.IsEmptyElement) {
410                                 reader.Skip ();
411                                 return;
412                         }
413                         reader.Read ();
414                         do {
415                                 reader.MoveToContent ();
416                                 if (reader.NodeType == XmlNodeType.EndElement)
417                                         break;
418                                 if (reader.NamespaceURI != Nvdl.Namespace) {
419                                         el.Foreign.Add (doc.ReadNode (reader));
420                                         continue;
421                                 }
422                                 switch (reader.LocalName) {
423                                 case "mode":
424                                         mu.NestedMode = ReadNestedMode ();
425                                         break;
426                                 case "message":
427                                         el.Messages.Add (ReadMessage ());
428                                         break;
429                                 case "context":
430                                         mu.Contexts.Add (ReadContext ());
431                                         break;
432                                 default:
433                                         throw new NotSupportedException ();
434                                 }
435                         } while (!reader.EOF);
436                         if (!reader.EOF)
437                                 reader.Read ();
438                 }
439
440                 private NvdlMessage ReadMessage ()
441                 {
442                         NvdlMessage el = new NvdlMessage ();
443                         FillLocation (el);
444                         el.XmlLang = reader.GetAttribute ("lang", Nvdl.XmlNamespaceUri);
445                         FillNonXmlAttributes (el);
446                         if (reader.IsEmptyElement) {
447                                 reader.Skip ();
448                                 el.Text = "";
449                         }
450                         else
451                                 el.Text = reader.ReadElementString ();
452                         return el;
453                 }
454
455                 private NvdlOption ReadOption ()
456                 {
457                         NvdlOption el = new NvdlOption ();
458                         FillLocation (el);
459                         el.Name = reader.GetAttribute ("name");
460                         el.Arg = reader.GetAttribute ("arg");
461                         el.MustSupport = reader.GetAttribute ("mustSupport");
462                         FillForeignAttribute (el);
463                         if (reader.IsEmptyElement) {
464                                 reader.Skip ();
465                                 return el;
466                         }
467                         reader.Read ();
468                         do {
469                                 reader.MoveToContent ();
470                                 if (reader.NodeType == XmlNodeType.EndElement)
471                                         break;
472                                 if (reader.NamespaceURI != Nvdl.Namespace) {
473                                         el.Foreign.Add (doc.ReadNode (reader));
474                                         continue;
475                                 }
476                         } while (!reader.EOF);
477                         if (!reader.EOF)
478                                 reader.Read ();
479                         return el;
480                 }
481
482                 private NvdlContext ReadContext ()
483                 {
484                         NvdlContext el = new NvdlContext ();
485                         FillLocation (el);
486                         el.Path = reader.GetAttribute ("path");
487                         el.UseMode = reader.GetAttribute ("useMode");
488                         FillForeignAttribute (el);
489                         if (reader.IsEmptyElement) {
490                                 reader.Skip ();
491                                 return el;
492                         }
493                         reader.Read ();
494                         do {
495                                 reader.MoveToContent ();
496                                 if (reader.NodeType == XmlNodeType.EndElement)
497                                         break;
498                                 if (reader.NamespaceURI != Nvdl.Namespace) {
499                                         el.Foreign.Add (doc.ReadNode (reader));
500                                         continue;
501                                 }
502                                 switch (reader.LocalName) {
503                                 case "mode":
504                                         el.NestedMode = ReadNestedMode ();
505                                         break;
506                                 default:
507                                         throw new NotSupportedException ();
508                                 }
509                         } while (!reader.EOF);
510                         if (!reader.EOF)
511                                 reader.Read ();
512                         return el;
513                 }
514         }
515 }
516