/Ntreev.Library.Commands/CommandMemberUsagePrinter.cs

https://github.com/NtreevSoft/CommandLineParser · C# · 316 lines · 262 code · 38 blank · 16 comment · 45 complexity · 7d60101a000ffc344375d716f8f4ea8b MD5 · raw file

  1. //Released under the MIT License.
  2. //
  3. //Copyright (c) 2018 Ntreev Soft co., Ltd.
  4. //
  5. //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
  6. //documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
  7. //rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
  8. //persons to whom the Software is furnished to do so, subject to the following conditions:
  9. //
  10. //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
  11. //Software.
  12. //
  13. //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  14. //WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  15. //COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  16. //OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  17. using System;
  18. using System.Collections.Generic;
  19. using System.Linq;
  20. using System.Text;
  21. using System.IO;
  22. using System.Reflection;
  23. using Ntreev.Library.Commands.Properties;
  24. using System.CodeDom.Compiler;
  25. namespace Ntreev.Library.Commands
  26. {
  27. public class CommandMemberUsagePrinter
  28. {
  29. private readonly string name;
  30. private readonly object instance;
  31. private readonly string summary;
  32. private readonly string description;
  33. public CommandMemberUsagePrinter(string name, object instance)
  34. {
  35. var provider = CommandDescriptor.GetUsageDescriptionProvider(instance.GetType());
  36. this.name = name;
  37. this.instance = instance;
  38. this.summary = provider.GetSummary(instance);
  39. this.description = provider.GetDescription(instance);
  40. }
  41. public virtual void Print(TextWriter writer, CommandMemberDescriptor[] descriptors)
  42. {
  43. using (var tw = new CommandTextWriter(writer))
  44. {
  45. this.Print(tw, descriptors);
  46. }
  47. }
  48. public virtual void Print(TextWriter writer, CommandMemberDescriptor descriptor)
  49. {
  50. using (var tw = new CommandTextWriter(writer))
  51. {
  52. this.Print(tw, descriptor);
  53. }
  54. }
  55. public string Name
  56. {
  57. get { return this.name; }
  58. }
  59. public object Instance
  60. {
  61. get { return this.instance; }
  62. }
  63. public string Summary
  64. {
  65. get { return this.summary; }
  66. }
  67. public string Description
  68. {
  69. get { return this.description; }
  70. }
  71. private void Print(CommandTextWriter writer, CommandMemberDescriptor[] descriptors)
  72. {
  73. this.PrintSummary(writer, descriptors);
  74. this.PrintDescription(writer, descriptors);
  75. this.PrintUsage(writer, descriptors);
  76. this.PrintRequirements(writer, descriptors);
  77. this.PrintVariables(writer, descriptors);
  78. this.PrintOptions(writer, descriptors);
  79. }
  80. private void PrintSummary(CommandTextWriter writer, CommandMemberDescriptor[] descriptors)
  81. {
  82. if (this.Summary == string.Empty)
  83. return;
  84. writer.WriteLine(Resources.Summary);
  85. writer.Indent++;
  86. writer.WriteLine(this.Summary);
  87. writer.Indent--;
  88. writer.WriteLine();
  89. }
  90. private void PrintUsage(CommandTextWriter writer, CommandMemberDescriptor[] descriptors)
  91. {
  92. var query = from item in descriptors
  93. orderby item.IsRequired descending
  94. select this.GetString(item);
  95. var maxWidth = writer.Width - (writer.TabString.Length * writer.Indent);
  96. var line = this.Name;
  97. writer.WriteLine(Resources.Usage);
  98. writer.Indent++;
  99. foreach (var item in query)
  100. {
  101. if (line != string.Empty)
  102. line += " ";
  103. if (line.Length + item.Length >= maxWidth)
  104. {
  105. writer.WriteLine(line);
  106. line = string.Empty.PadLeft(this.Name.Length + 1);
  107. }
  108. line += item;
  109. }
  110. writer.WriteLine(line);
  111. writer.Indent--;
  112. writer.WriteLine();
  113. }
  114. private void PrintDescription(CommandTextWriter writer, CommandMemberDescriptor[] descriptors)
  115. {
  116. if (this.Description == string.Empty)
  117. return;
  118. writer.WriteLine(Resources.Description);
  119. writer.Indent++;
  120. writer.WriteMultiline(this.Description);
  121. writer.Indent--;
  122. writer.WriteLine();
  123. }
  124. private void PrintRequirements(CommandTextWriter writer, CommandMemberDescriptor[] descriptors)
  125. {
  126. var items = descriptors.Where(item => item.GetType() == typeof(CommandPropertyDescriptor))
  127. .Where(item => item.IsRequired == true)
  128. .ToArray();
  129. if (items.Any() == false)
  130. return;
  131. writer.WriteLine(Resources.Requirements);
  132. writer.Indent++;
  133. foreach (var item in items)
  134. {
  135. this.PrintRequirement(writer, item);
  136. }
  137. writer.Indent--;
  138. writer.WriteLine();
  139. }
  140. private void PrintVariables(CommandTextWriter writer, CommandMemberDescriptor[] descriptors)
  141. {
  142. var descriptor = descriptors.FirstOrDefault(item => item is CommandMemberArrayDescriptor);
  143. if (descriptor == null)
  144. return;
  145. writer.WriteLine(Resources.Variables);
  146. writer.Indent++;
  147. this.PrintVariables(writer, descriptor);
  148. writer.Indent--;
  149. writer.WriteLine();
  150. }
  151. private void PrintOptions(CommandTextWriter writer, CommandMemberDescriptor[] descriptors)
  152. {
  153. var items = descriptors.Where(item => item.GetType() == typeof(CommandPropertyDescriptor))
  154. .Where(item => item.IsRequired == false)
  155. .ToArray();
  156. if (items.Any() == false)
  157. return;
  158. writer.WriteLine(Resources.Options);
  159. writer.Indent++;
  160. foreach (var item in items)
  161. {
  162. this.PrintOption(writer, item);
  163. }
  164. writer.Indent--;
  165. writer.WriteLine();
  166. }
  167. private void Print(CommandTextWriter writer, CommandMemberDescriptor descriptor)
  168. {
  169. this.PrintSummary(writer, descriptor);
  170. this.PrintUsage(writer, descriptor);
  171. this.PrintDescription(writer, descriptor);
  172. }
  173. private void PrintSummary(CommandTextWriter writer, CommandMemberDescriptor descriptor)
  174. {
  175. writer.WriteLine(Resources.Summary);
  176. writer.Indent++;
  177. writer.WriteLine(descriptor.Summary);
  178. writer.Indent--;
  179. writer.WriteLine();
  180. }
  181. private void PrintUsage(CommandTextWriter writer, CommandMemberDescriptor descriptor)
  182. {
  183. writer.WriteLine(Resources.Usage);
  184. writer.Indent++;
  185. writer.WriteLine(this.GetString(descriptor));
  186. writer.Indent--;
  187. writer.WriteLine();
  188. }
  189. private void PrintDescription(CommandTextWriter writer, CommandMemberDescriptor descriptor)
  190. {
  191. writer.WriteLine(Resources.Description);
  192. writer.Indent++;
  193. writer.WriteLine(descriptor.Description);
  194. writer.Indent--;
  195. writer.WriteLine();
  196. }
  197. private void PrintRequirement(CommandTextWriter writer, CommandMemberDescriptor descriptor)
  198. {
  199. if (descriptor.IsExplicit == true)
  200. {
  201. writer.WriteLine(descriptor.DisplayPattern);
  202. }
  203. else
  204. {
  205. if (descriptor.Name != string.Empty)
  206. writer.WriteLine(descriptor.Name);
  207. else
  208. writer.WriteLine(CommandSettings.NameGenerator(descriptor.DescriptorName));
  209. }
  210. var description = descriptor.Summary != string.Empty ? descriptor.Summary : descriptor.Description;
  211. if (description != string.Empty)
  212. {
  213. writer.Indent++;
  214. writer.WriteMultiline(description);
  215. writer.Indent--;
  216. }
  217. writer.WriteLine();
  218. }
  219. private void PrintVariables(CommandTextWriter writer, CommandMemberDescriptor descriptor)
  220. {
  221. writer.WriteLine(descriptor.Name + " ...");
  222. writer.Indent++;
  223. writer.WriteMultiline(descriptor.Description);
  224. writer.Indent--;
  225. writer.WriteLine();
  226. }
  227. private void PrintOption(CommandTextWriter writer, CommandMemberDescriptor descriptor)
  228. {
  229. if (descriptor.ShortNamePattern != string.Empty)
  230. writer.WriteLine(descriptor.ShortNamePattern);
  231. if (descriptor.NamePattern != string.Empty)
  232. writer.WriteLine(descriptor.NamePattern);
  233. var description = descriptor.Summary != string.Empty ? descriptor.Summary : descriptor.Description;
  234. if (description != string.Empty)
  235. {
  236. writer.Indent++;
  237. writer.WriteMultiline(description);
  238. writer.Indent--;
  239. }
  240. writer.WriteLine();
  241. }
  242. private string GetString(CommandMemberDescriptor descriptor)
  243. {
  244. if (descriptor.IsRequired == true)
  245. {
  246. var descriptorName = descriptor.Name;
  247. if (descriptorName == string.Empty)
  248. descriptorName = CommandSettings.NameGenerator(descriptor.DescriptorName);
  249. var patternItems = new string[] { descriptor.ShortNamePattern, descriptor.NamePattern };
  250. var patternText = string.Join(" | ", patternItems.Where(item => item != string.Empty).ToArray());
  251. if (descriptor.DefaultValue == DBNull.Value)
  252. {
  253. if (descriptor.IsExplicit == true)
  254. return string.Format("<{0} {1}>", patternText, descriptorName);
  255. else
  256. return string.Format("<{0}>", descriptorName);
  257. }
  258. else
  259. {
  260. if (descriptor.IsExplicit == true)
  261. return string.Format("<{0} {1}='{2}'>", patternText, descriptorName, descriptor.DefaultValue ?? "null");
  262. else
  263. return string.Format("<{0}='{1}'>", descriptorName, descriptor.DefaultValue ?? "null");
  264. }
  265. }
  266. else if (descriptor is CommandMemberArrayDescriptor)
  267. {
  268. return string.Format("[{0} ...]", descriptor.Name);
  269. }
  270. else
  271. {
  272. var patternItems = new string[] { descriptor.ShortNamePattern, descriptor.NamePattern };
  273. var patternText = string.Join(" | ", patternItems.Where(item => item != string.Empty).ToArray());
  274. return string.Format("[{0}]", patternText);
  275. }
  276. }
  277. }
  278. }