1 using System; 2 using System.Collections.Generic; 3 using System.Diagnostics; 4 using System.IO; 5 using System.Reflection; 6 using System.Xml; 7 using System.Xml.Schema; 8 9 using Mono.Options; 10 11 namespace Mono.Documentation 12 { 13 public class MDocValidator : MDocCommand 14 { 15 XmlReaderSettings settings; 16 long errors = 0; 17 Run(IEnumerable<string> args)18 public override void Run (IEnumerable<string> args) 19 { 20 string[] validFormats = { 21 "ecma", 22 }; 23 string format = "ecma"; 24 var p = new OptionSet () { 25 { "f|format=", 26 "The documentation {0:FORMAT} used within PATHS. " + 27 "Valid formats include:\n " + 28 string.Join ("\n ", validFormats) + "\n" + 29 "If no format provided, `ecma' is used.", 30 v => format = v }, 31 }; 32 List<string> files = Parse (p, args, "validate", 33 "[OPTIONS]+ PATHS", 34 "Validate PATHS against the specified format schema."); 35 if (files == null) 36 return; 37 if (Array.IndexOf (validFormats, format) < 0) 38 Error ("Invalid documentation format: {0}.", format); 39 Run (format, files); 40 } 41 Run(string format, IEnumerable<string> files)42 public void Run (string format, IEnumerable<string> files) 43 { 44 Stream s = null; 45 46 switch (format) { 47 case "ecma": 48 s = Assembly.GetExecutingAssembly ().GetManifestResourceStream ("monodoc-ecma.xsd"); 49 break; 50 51 default: 52 throw new NotSupportedException (string.Format ("The format `{0}' is not suppoted.", format)); 53 } 54 55 if (s == null) 56 throw new NotSupportedException (string.Format ("The schema for `{0}' was not found.", format)); 57 58 settings = new XmlReaderSettings (); 59 settings.Schemas.Add (XmlSchema.Read (s, null)); 60 settings.Schemas.Compile (); 61 settings.ValidationType = ValidationType.Schema; 62 settings.ValidationEventHandler += OnValidationEvent; 63 64 // skip args[0] because it is the provider name 65 foreach (string arg in files) { 66 if (IsMonodocFile (arg)) 67 ValidateFile (arg); 68 69 if (Directory.Exists (arg)) 70 { 71 RecurseDirectory (arg); 72 } 73 } 74 75 Message (errors == 0 ? TraceLevel.Info : TraceLevel.Error, 76 "Total validation errors: {0}", errors); 77 } 78 ValidateFile(string file)79 void ValidateFile (string file) 80 { 81 try { 82 using (var reader = XmlReader.Create (new XmlTextReader (file), settings)) { 83 while (reader.Read ()) { 84 // do nothing 85 } 86 } 87 } 88 catch (Exception e) { 89 Message (TraceLevel.Error, "mdoc: {0}", e.ToString ()); 90 } 91 } 92 RecurseDirectory(string dir)93 void RecurseDirectory (string dir) 94 { 95 string[] files = Directory.GetFiles (dir, "*.xml"); 96 foreach (string f in files) 97 { 98 if (IsMonodocFile (f)) 99 ValidateFile (f); 100 } 101 102 string[] dirs = Directory.GetDirectories (dir); 103 foreach (string d in dirs) 104 RecurseDirectory (d); 105 } 106 OnValidationEvent(object sender, ValidationEventArgs a)107 void OnValidationEvent (object sender, ValidationEventArgs a) 108 { 109 errors ++; 110 Message (TraceLevel.Error, "mdoc: {0}", a.Message); 111 } 112 IsMonodocFile(string file)113 static bool IsMonodocFile (string file) 114 { 115 if (File.Exists (file) && Path.GetExtension (file).ToLower () == ".xml") 116 return true; 117 else 118 return false; 119 120 } 121 } 122 } 123 124