I have needed an argument parser for some java projects. There are some libraries available, but I wanted something tailor-made. Maybe it could be useful for others, too, so I decided to publish it. The documentation is a bit lean, if you need more detailed descriptions, let me know.
- Define arguments needed for your console applications
- Integer Arguments
- Double Arguments
- String Arguments
- Flag Arguments
- Define whether an argument is required
- Define a default value
- Define different rules for this argument
It's that simple: Import the JAR file (from 'release/ArgParser_X.X'
) or the packages and classes into your project. Now you can create an ArgumentParser
object and define your arguments. Finally, you call the parse method and pass the arguments and get the result. A more detailed description of how to use ArgParser can be found in the following sections.
Before the arguments are defined, a ArgumentParser
object is required. Here bool1
defines whether the program should be terminated if the user uses a help argument. bool2
defines whether an exception should be thrown if a required argument is not given. bool3
defines whether an exception should be thrown if the user enters an undefined argument.
ArgumentParser argumentParser = new ArgumentParser(bool1, bool2, bool3);
The arguments are then defined. In the following example a StringArgumentDefinition
is created. It could also be an IntegerArgumentDefinition
, DoubleArgumentDefinition
or FlagArgumentDefinition
. The parameters are the same for all four. The respective argument is assigned one or more prefixes in the first parameter, e.g. new String[]{"-s", "-src", "-source"}
. In argumentDescription
a string can be set which describes the argument e.g. "The image source."
. isRequired
specifies whether this argument must be set by the user or is optional. In defaultValue
is deposited which value is valid for this argument by default.
StringArgumentDefinition sad = new StringArgumentDefinition(prefixes, argumentDescription, isRequired, defaultValue)
Then the argument definition can be added to the argument parser.
argumentParser.add(sad);
Let's assume that we want to add rules to the previously created argument definition. In this example we want an argument for a PNG image. Then we could change the instantiation as follows. As an additional parameter we set an array with the type StringArgumentRule
. The first added rule checks if the image has the extension .png | .PNG
. The second rule checks if the file exists and is really a file.
StringArgumentDefinition sad = new StringArgumentDefinition(
new String[]{"-s", "-src", "-source"}, // With prefixes implied the argument
"Image source", // What is the argument for
true, // This Argument is required
"", // Set nothing as default, since this argument is tagged as required
new StringArgumentRule[] {
new StringArgumentRegularExpressionRule("^.*(.png|.PNG){1}$", "File is PNG"), // Is it a PNG image
new StringArgumentFileExistsRule() // Does this file exists
}
);
For the IntegerArgumentDefinition
use IntegerArgumentRule
and for DoubleArgumentDefinition
DoubleArgumentRule
. There are no rules for FlagArgumentDefinition
because it is a bit assignment (true, false
) without variance.
Now an automatically generated help argument can be created. As with the previous argument definitions, a prefix is defined for this. In addition, a title is defined for the output. The following example shows an instantiation of this help argument.
argumentParser.addHelpArgument(new String[] {"-h", "-help"}, "This arguments are available:");
The output would look like this once the user enters -h
or -help
:
This arguments are available:
{-s,-src,-source} Required: yes Image source
Now the arguments from the main (String[] args)
can be passed to the parser.
argumentParser.parse(args);
To get the value after parsing, simply read the value from the respective definition object as follows.
System.out.println(iad.getValue());
Now everything together and with an error handling.
public class Main {
public static void main(String[] args) {
ArgumentParser argumentParser = new ArgumentParser(true, true, true); // Create first and ArgumentParser object
try { // Catch the exceptions
StringArgumentDefinition sad = new StringArgumentDefinition( // Create a argument definition for an image source
new String[]{"-s", "-src", "-source"}, // This argument can be addressed with the following prefixes
"Image source", // What is the argument for
true, // This Argument is required
"", // Set nothing as default, since this argument is tagged as required
new StringArgumentRule[] { // Add some rules
new StringArgumentRegularExpressionRule("^.*(.png|.PNG){1}$", "File is PNG"), // Is it a PNG image
new StringArgumentFileExistsRule() // Does this file exists
}
);
argumentParser.addHelpArgument(new String[] {"-h", "-help"}, "This arguments are available:");
argumentParser.add(sad); // Add this argument definition to the parser
argumentParser.parse(args); // Parse the users input
System.out.println("Load image from " + sad.getValue()); // Get the users input for image source
// Do something with the image path like loading and displaying
} catch (NonUniquePrefixException | NotSupportedInThisVersionException e) { // If that happens, you have a bug in the code
e.printStackTrace();
}
catch (UnknownArgumentException | MissingArgumentException | ValueParseException | RuleNotObservedException e) { // This eception can be provoke by the users input
System.err.println(e.getMessage()); // Print the exception for the user
}
}
}
In the following example, a temperature is written to the database. As argument we want the username, the password and the table name of the database. Additionally we need the IP and a port. We also offer the user the option to disable encrypted communication. Last but not least we want a valid temperature. We assume that we have tempreatures in the range of -40 to 120 degrees.
public class Main2 {
public static void main(String[] args) {
ArgumentParser argumentParser = new ArgumentParser(true, true, true); // Create first and ArgumentParser object
try { // Catch the exceptions
StringArgumentDefinition mysqlUser = new StringArgumentDefinition(new String[] {"-u", "-user"}, "MySql username", true, "", new StringArgumentRule[] {
new StringArgumentRegularExpressionRule("^[a-zA-Z0-9]{4,}$")
});
StringArgumentDefinition mysqlPassword = new StringArgumentDefinition(new String[] {"-p", "-pw"}, "MySql password", true, "", new StringArgumentRule[] {
new StringArgumentRegularExpressionRule("^[a-zA-Z0-9]{4,}$")
});
StringArgumentDefinition mysqlTable = new StringArgumentDefinition(new String[] {"-t", "-table"}, "MySql table", false, "temperature_log", new StringArgumentRule[] {
new StringArgumentRegularExpressionRule("^[a-zA-Z0-9_]{4,}$")
});
StringArgumentDefinition mysqlIp = new StringArgumentDefinition(new String[] {"-ip"}, "MySql server IP", true, "temperature_log", new StringArgumentRule[] {
new StringArgumentRegularExpressionRule(RegularExpressionCollection.IP_FORMAT(), "Valid IP address"), // Check if the IP is in the correct format. Uses a template from the Regular expression collection.
new StringArgumentIpAddressReachableRule(2500) // Check if the give IP is reachable
});
IntegerArgumentDefinition mysqlPort = new IntegerArgumentDefinition(new String[] {"-port"}, "MySql server port", false, 3306, new IntegerArgumentRule[] {
new IntegerArgumentRegularExpressionRule("^(3306|33060|389|){1}$", "Port out of {3306|33060|389}") // Just example ports for illustration
});
FlagArgumentDefinition encryptedCommunication = new FlagArgumentDefinition(new String[] {"-c", "-crypt"}, "Encrypted communication", false, true); // A flag can be triggered by the prefix like 'aplication -c'
DoubleArgumentDefinition temperature = new DoubleArgumentDefinition(new String[] {"-temp", "-temperature"}, "Temperature to log", true, 0.0, new DoubleArgumentRule[] {
new DoubleArgumentProportionRule(NumberProportionRuleType.GREATER_EQUAL, -40.0),
new DoubleArgumentProportionRule(NumberProportionRuleType.LESS_EQUAL, 120.0)
});
argumentParser.addHelpArgument(new String[] {"-h", "-help"}, "This arguments are available:");
argumentParser.add(mysqlUser);
argumentParser.add(mysqlPassword);
argumentParser.add(mysqlTable);
argumentParser.add(mysqlIp);
argumentParser.add(mysqlPort);
argumentParser.add(encryptedCommunication);
argumentParser.add(temperature);
argumentParser.parse(args);
System.out.println("Connect to " + mysqlIp.getValue() + ":" + mysqlPort.getValue() + (encryptedCommunication.getValue()?" with a secure connection":" with an unsafe connection"));
System.out.println("Use credentials Username:[" + mysqlUser.getValue() + "] Password:[" + mysqlPassword.getValue() + "]");
System.out.println("Insert [" + temperature.getValue() + "]°C into table [" + mysqlTable.getValue() + "]");
} catch (NonUniquePrefixException e) { // If that happens, you have a bug in the code
e.printStackTrace();
}
catch (UnknownArgumentException | MissingArgumentException | ValueParseException | RuleNotObservedException e) { // This eception can be provoke by the users input
System.err.println(e.getMessage()); // Print the exception for the user
}
}
}
If the application is executed with help argument (-h
), the following is output:
This arguments are available:
{-u,-user} Required: yes MySql username
{-p,-pw} Required: yes MySql password
{-t,-table} Required: no MySql table (default 'temperature_log')
{-ip} Required: yes MySql server IP
{-port} Required: no MySql server port (default '3306')
{-c,-crypt} Required: no Encrypted communication (default 'yes')
{-temp,-temperature} Required: yes Temperature to log
If the arguments are given -u root -p Tutorial19 -ip 127.0.0.1 -c -temp 22.3
. Then the output is as follows:
Connect to 127.0.0.1:3306 with an unsafe connection
Use credentials Username:[root] Password:[Tutorial19]
Insert [22.3]°C into table [temperature_log]
If an unallowed port is specified -u root -p Tutorial19 -ip 127.0.0.1 -port 42 -c -temp 22.3
, then the output is:
The rule 'Port out of {3306|33060|389}' for argument {-port} is not observed with the argument '42'.
If the temperature argument is not given, the output is:
Missing argument:
{-temp,-temperature} Temperature to log