using System.Collections.Generic; using System.Text; using JD.Kernel.StaticHelpers; namespace JD.TeaBoxAddinSystem.Bootstrap { /// /// Abstract implementation of the /// /// /// By default, this implementation will start the app in command line mode and will quit after it's executed /// if its main is present. /// public abstract class AbstractCommandLineHandler : ICommandLineHandler { #region Constants /// /// Default width when writing columns in the console. /// public const int ColumnWidth = 40; #endregion #region Variables private readonly Arguments m_arguments; #endregion #region Constructor protected AbstractCommandLineHandler() : this(Runtime.Arguments) { } protected AbstractCommandLineHandler(Arguments arguments) { Throw.IfNull(arguments, "arguments"); m_arguments = arguments; } #endregion #region Properties /// /// Arguments (do not use Runtime.Arguments when you want to test your class). /// protected Arguments Arguments { get { return m_arguments; } } /// /// Gets whether the handler will be executed even if no argument from are present. /// public virtual bool ExecuteEvenWhenNoArgumentNamesPresent { get { return false; } } /// /// Name of the main arguments of this handler. /// public abstract IEnumerable ArgumentNames { get; } IEnumerable ICommandLineHelpTopic.Names { get { return ArgumentNames; } } /// /// Main argument switches. /// protected IEnumerable ArgumentSwitches { get { foreach (string argumentName in ArgumentNames) { foreach (ArgumentSwitch argSwitch in Arguments[argumentName]) { yield return argSwitch; } } } } /// /// Returns true if at least one of the main arguments is present. /// protected bool AtLeastOneArgumentExists { get { foreach (ArgumentSwitch argSwitch in ArgumentSwitches) { if (argSwitch != null) { return true; } } return false; } } /// /// Whether to allow more than one of the switches in . /// protected virtual bool AllowMoreThanOneSwitch { get { return false; } } /// /// Whether the application should quit after this handler has been executed. /// public virtual bool QuitAfterExecuted { get { return false; } } /// /// Overriden. /// public virtual string HelpSyntax { get { StringBuilder builder = new StringBuilder(); bool first = true; foreach (string mainArgument in ArgumentNames) { if (!first) { builder.Append(", "); } else { first = false; } builder.Append(Arguments.MainSwitchChar); builder.Append(mainArgument); } return builder.ToString(); } } /// /// Short Help Description. /// public abstract string ShortHelpDescription { get; } /// /// Long Help Description. /// public virtual string LongHelpDescription { get { return ShortHelpDescription; } } #endregion #region Methods /// /// Overriden. /// /// public virtual bool Initialize() { // Check for the multiple switches if (!AllowMoreThanOneSwitch) { bool gotOne = false; foreach (ArgumentSwitch mySwitch in ArgumentSwitches) { if (gotOne) { throw new CommandLineArgumentException($"Cannot have more than one \"{mySwitch.Name}\" switch at the same time."); } gotOne = true; } } return AtLeastOneArgumentExists; } /// /// Overriden. /// public void Execute() { if (AtLeastOneArgumentExists || ExecuteEvenWhenNoArgumentNamesPresent) { ExecuteImpl(); } } /// /// Abstract implemention of the command line handling. /// /// /// In this method, you are assured that at least one of the main arguments is present. /// protected abstract void ExecuteImpl(); #endregion } }