JD2022-TU1/main/tools/framework/JD.TeaBoxAddinSystem/Bootstrap/AbstractCommandLineHandler.cs

233 lines
6 KiB
C#

using System.Collections.Generic;
using System.Text;
using JD.Kernel.StaticHelpers;
namespace JD.TeaBoxAddinSystem.Bootstrap
{
/// <summary>
/// Abstract implementation of the <see cref="ICommandLineHandler"/>
/// </summary>
/// <remarks>
/// By default, this implementation will start the app in command line mode and will quit after it's executed
/// if its main <see cref="ArgumentSwitch"/> is present.
/// </remarks>
public abstract class AbstractCommandLineHandler : ICommandLineHandler
{
#region Constants
/// <summary>
/// Default width when writing columns in the console.
/// </summary>
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
/// <summary>
/// Arguments (do not use Runtime.Arguments when you want to test your class).
/// </summary>
protected Arguments Arguments
{
get { return m_arguments; }
}
/// <summary>
/// Gets whether the handler will be executed even if no argument from <see cref="ArgumentNames"/> are present.
/// </summary>
public virtual bool ExecuteEvenWhenNoArgumentNamesPresent
{
get
{
return false;
}
}
/// <summary>
/// Name of the main arguments of this handler.
/// </summary>
public abstract IEnumerable<string> ArgumentNames { get; }
IEnumerable<string> ICommandLineHelpTopic.Names
{
get
{
return ArgumentNames;
}
}
/// <summary>
/// Main argument switches.
/// </summary>
protected IEnumerable<ArgumentSwitch> ArgumentSwitches
{
get
{
foreach (string argumentName in ArgumentNames)
{
foreach (ArgumentSwitch argSwitch in Arguments[argumentName])
{
yield return argSwitch;
}
}
}
}
/// <summary>
/// Returns true if at least one of the main arguments is present.
/// </summary>
protected bool AtLeastOneArgumentExists
{
get
{
foreach (ArgumentSwitch argSwitch in ArgumentSwitches)
{
if (argSwitch != null)
{
return true;
}
}
return false;
}
}
/// <summary>
/// Whether to allow more than one of the switches in <see cref="ArgumentSwitches"/>.
/// </summary>
protected virtual bool AllowMoreThanOneSwitch
{
get
{
return false;
}
}
/// <summary>
/// Whether the application should quit after this handler has been executed.
/// </summary>
public virtual bool QuitAfterExecuted
{
get
{
return false;
}
}
/// <summary>
/// Overriden.
/// </summary>
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();
}
}
/// <summary>
/// Short Help Description.
/// </summary>
public abstract string ShortHelpDescription { get; }
/// <summary>
/// Long Help Description.
/// </summary>
public virtual string LongHelpDescription
{
get
{
return ShortHelpDescription;
}
}
#endregion
#region Methods
/// <summary>
/// Overriden.
/// </summary>
/// <returns></returns>
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;
}
/// <summary>
/// Overriden.
/// </summary>
public void Execute()
{
if (AtLeastOneArgumentExists || ExecuteEvenWhenNoArgumentNamesPresent)
{
ExecuteImpl();
}
}
/// <summary>
/// Abstract implemention of the command line handling.
/// </summary>
/// <remarks>
/// In this method, you are assured that at least one of the main arguments is present.
/// </remarks>
protected abstract void ExecuteImpl();
#endregion
}
}