1 using System;
2 using System.Collections;
3 using System.Collections.Specialized;
4 using System.IO;
5 using System.Xml;
6 using Commons.Xml.Relaxng;
7 using Commons.Xml.Relaxng.Rnc;
8 
9 namespace Commons.Xml.Nvdl
10 {
11 	public class NvdlRelaxngValidatorProvider : NvdlValidationProvider
12 	{
13 		public const string RncMimeType = "application/vnd.oasis-open.relax-ng.rnc";
14 
CreateGenerator( NvdlValidate validate, string schemaType, NvdlConfig config)15 		public override NvdlValidatorGenerator CreateGenerator (
16 			NvdlValidate validate, string schemaType, NvdlConfig config)
17 		{
18 			if (schemaType == RncMimeType)
19 				return CreateRncGenerator (validate, config);
20 			return base.CreateGenerator (validate, schemaType, config);
21 		}
22 
CreateRncGenerator(NvdlValidate validate, NvdlConfig config)23 		private NvdlValidatorGenerator CreateRncGenerator (NvdlValidate validate, NvdlConfig config)
24 		{
25 			XmlResolver resolver = config.XmlResolverInternal;
26 			string schemaUri = GetSchemaUri (validate);
27 			if (schemaUri == null)
28 				return null;
29 			Uri baseUri = resolver.ResolveUri (null, validate.SourceUri);
30 			Uri absUri = resolver.ResolveUri (baseUri, schemaUri);
31 			RelaxngPattern p = RncParser.ParseRnc (
32 				new StreamReader ((Stream) resolver.GetEntity (
33 					absUri,
34 					null,
35 					typeof (Stream))), null, absUri.ToString ());
36 			return new NvdlRelaxngValidatorGenerator (p, config);
37 		}
38 
CreateGenerator( XmlReader reader, NvdlConfig config)39 		public override NvdlValidatorGenerator CreateGenerator (
40 			XmlReader reader, NvdlConfig config)
41 		{
42 			if (reader.NamespaceURI != RelaxngGrammar.NamespaceURI)
43 				return null;
44 
45 			return new NvdlRelaxngValidatorGenerator (RelaxngPattern.Read (reader), config);
46 		}
47 	}
48 
49 	internal class NvdlRelaxngValidatorGenerator : NvdlValidatorGenerator
50 	{
51 		RelaxngPattern pattern;
52 
NvdlRelaxngValidatorGenerator(RelaxngPattern p, NvdlConfig config)53 		public NvdlRelaxngValidatorGenerator (RelaxngPattern p,
54 			NvdlConfig config)
55 		{
56 			// FIXME: use XmlResolver
57 			pattern = p;
58 		}
59 
CreateValidator(XmlReader reader, XmlResolver resolver)60 		public override XmlReader CreateValidator (XmlReader reader,
61 			XmlResolver resolver)
62 		{
63 			// XmlResolver is never used.
64 			RelaxngValidatingReader rvr =
65 				new RelaxngValidatingReader (
66 					reader, pattern);
67 			rvr.ReportDetails = true;
68 			return rvr;
69 		}
70 
CreateAttributeValidator( XmlReader reader, XmlResolver resolver)71 		public override XmlReader CreateAttributeValidator (
72 			XmlReader reader,
73 			XmlResolver resolver)
74 		{
75 			// XmlResolver is never used.
76 			RelaxngValidatingReader rvr =
77 				new RelaxngValidatingReader (
78 					reader, pattern);
79 			rvr.ReportDetails = true;
80 			return rvr;
81 		}
82 
AddOption(string name, string arg)83 		public override bool AddOption (string name, string arg)
84 		{
85 			return false;
86 		}
87 
HandleError(Exception ex, XmlReader reader, string nvdlLocation)88 		public override bool HandleError (Exception ex, XmlReader reader, string nvdlLocation)
89 		{
90 			if (ex is RelaxngException)
91 				throw new NvdlInstanceValidationException (String.Format ("RELAX NG validation error occured as a part of NVDL validation: " + ex.Message), ex, this, nvdlLocation);
92 			return false;
93 		}
94 	}
95 }
96