package io.vivarium.scripts;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
public abstract class CommonsScript
{
public CommonsScript(String[] args)
{
run(args);
}
public CommonsScript()
{
}
/**
* Runs the script taking in an array of String objects. These strings can represent the arguments passed in as
* command line options.
*
* @param args
* Arguments to be parsed as options and values.
*/
public void run(String[] args)
{
CommandLine commandLine = parseArgs(args);
if (commandLine != null)
{
run(commandLine);
}
}
protected CommandLine parseArgs(String[] args)
{
DefaultParser parser = new DefaultParser();
try
{
CommandLine commandLine = parser.parse(this.getOptions(), args);
if (commandLine.hasOption("help"))
{
printUsageAndExit();
}
else
{
return commandLine;
}
}
catch (ParseException e)
{
printUsageAndExit();
}
return null;
}
protected Map<String, Object> extraArgsAsMap(CommandLine commandLine)
{
String[] args = commandLine.getArgs();
HashMap<String, Object> map = new HashMap<>();
for (int i = 0; i + 1 < args.length; i += 2)
{
map.put(args[i], args[i + 1]);
}
return map;
}
protected Options getOptions()
{
Options options = new Options();
for (Option option : this.getCommonOptions())
{
options.addOption(option);
}
for (Option option : this.getScriptSpecificOptions())
{
options.addOption(option);
}
return options;
}
protected Options getRequiredOptions()
{
Options requiredOptions = new Options();
for (Option option : this.getCommonOptions())
{
if (option.isRequired())
{
requiredOptions.addOption(option);
}
}
for (Option option : this.getScriptSpecificOptions())
{
if (option.isRequired())
{
requiredOptions.addOption(option);
}
}
return requiredOptions;
}
protected abstract List<Option> getScriptSpecificOptions();
protected List<Option> getCommonOptions()
{
LinkedList<Option> commonOptions = new LinkedList<>();
commonOptions.add(Option
.builder("h")
.required(false)
.longOpt("help")
.hasArg(false)
.desc("display this help and exit")
.build());
return commonOptions;
}
protected abstract String getExtraArgString();
protected abstract String getUsageHeader();
protected String getUsageFooter()
{
return "";
}
protected abstract void run(CommandLine commandLine);
protected void printUsageAndExit()
{
// Pull out just the required options
Options requiredOptions = this.getRequiredOptions();
StringWriter requiredOptionsSyntax = new StringWriter();
PrintWriter requiredOptionPrinter = new PrintWriter(requiredOptionsSyntax);
HelpFormatter syntaxFormatter = new HelpFormatter();
syntaxFormatter.printUsage(requiredOptionPrinter, 120, "", requiredOptions);
String requiredOptionsString = requiredOptionsSyntax.toString().trim();
// Do the rest of the stuff
Options fullOptions = this.getOptions();
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp(100,
this.getClass().getSimpleName() + requiredOptionsString + " [additional options]" + getExtraArgString(),
this.getUsageHeader(), fullOptions, this.getUsageFooter());
}
}