Skip to content
This repository has been archived by the owner on May 16, 2022. It is now read-only.

StevenCyb/Java_ArgParser

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

About This Project

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.

Table Of Contents

Scope Of Functions

  • 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

How To Use It

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.

Create The Main Object

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);

Definition Simple Arguments

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);

Definition Arguments With Rules

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.

Add Autogenerated Help Argument

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

Parse The Arguments

Now the arguments from the main (String[] args) can be passed to the parser.

argumentParser.parse(args);

Get Argument Values

To get the value after parsing, simply read the value from the respective definition object as follows.

System.out.println(iad.getValue());

Put All Together

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
		}
	}
}

Further Examples

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