Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 49 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ It removes complex exception handling by providing automatic checks on common co
The tool supports a wide range of parameter types including Strings, Integers, Doubles, Booleans, and Characters,
catering to diverse application needs.

## Key features:
## Key features

- **Definition Of Parameters:** Define parameters with flag names and shorthands,
mandatory/optional status, as well as optional default values and descriptions.
Expand All @@ -33,7 +33,7 @@ catering to diverse application needs.
- **Extensible:** Extend the library with custom parameter classes tailored to your application’s needs.


## Example Code:
## Example Code

```java
import ArgsParser.*;
Expand Down Expand Up @@ -125,7 +125,7 @@ You can specify several fields for each parameter:
- **defaultValue**: A default value that the parameter returns if no argument was provided but accessed in the program.
- **isMandatory**: Determines whether the flag must be provided in the arguments. If set to true and the flag is missing, an ArgsException will be thrown.

#### The PthParameter
#### The PthParameter:
The Parameter handling Paths provides has one additional field in each of the two constructors:
`pathCheck`.
If this is set true, the parser will check if the provided path does exist, if not it will raise an ArgsException!
Expand Down Expand Up @@ -228,7 +228,7 @@ or like the following example for manually handling the ArgsExceptions:

### 4. Access the Arguments

#### direct access to arguments via its parameter
#### direct access to arguments via its parameter:
Access the console arguments given by the user by calling the `getArgument()` method on the parameter variable.
The return type matches the type defined when adding the parameter.
The **arguments can be used directly in your code**!
Expand All @@ -240,15 +240,15 @@ The **arguments can be used directly in your code**!
//...
```

#### check provision of a command or Parameter
#### check provision of a command or Parameter:
For the commands, a simple call of `isProvided` on the Command instance will return if the command was provided in args:
```java
//...
if (command.isProvided()) System.out.println("command provided");
//...
```

#### access arguments indirectly via the ArgsParser instance they were defined on
#### access arguments indirectly via the ArgsParser instance they were defined on:
With version 3.0.0 the `getArgumentOf(String fullFlag)` method ia available, thus arguments provided to a specific
parameter flag can be accessed by the parameter flugFlag name.
But this comes with some restrictions:
Expand All @@ -273,43 +273,45 @@ The same is possible with commands:
}
```

## Integrated --help function:
## Integrated --help function
The ArgsParser tool has an integrated help function. If the user provides the flag `--help` or `-h` the tool will print
a help message with all the defined parameters. The help message will contain the full flag, the short flag, the
description, and if the parameter is mandatory or not. The help message will be printed either for all parameters or only for the
parameter that was placed before the `--help` flag.

### Help example:
### Help example
Calling `--help` or `-h` without anything else on the programm will print all available parameters **in the order
they were added** on the ArgsParser Instance:

`> exampleProgramm --help`
```

############################################### HELP ###############################################
# [s]/[s+]=String | [i]/[i+]=Integer | [c]/[c+]=Character | [b]/[b+]=Boolean | [d]/[d+]=Double
# ('+' marks a flag that takes several arguments of the same type whitespace separated)
# (!)=mandatory | (?)=optional | (/)=command
# [s]=String | [i]=Integer | [d]=Double | [b+]=Boolean | [i+]=Integer
# ('+' marks a flag that takes several arguments of the same type whitespace separated)
# (!)=mandatory | ( )=optional | (/)=command
#
# Available Parameters:
# Available Parameters:
#
### --parameterFlag -pf [s] (!) short Description
### --parameterFlag -pf [s] (!) short Description
#
### --parameterFlag2 -pf2 [i] (?) No description available!
### --parameterFlag2 -pf2 [i] ( ) No description available!
#
### --parameterFlag3 -pf3 [d] (?) description
# default: 5.6
### --parameterFlag3 -pf3 [d] ( ) description
# default: 5.6
#
### --boolArray -bArr [b+] (?) Array of several boolean values
### --boolArray -bArr [b+] ( ) Array of several boolean values
# default: [true, false, false]
#
### --intArray -iArr [i+] (?) Array of several integer values
# default: [1, 2, 3]
### --intArray -iArr [i+] ( ) Array of several integer values
# default: [1, 2, 3]
#
# Available Commands:
# Available Commands:
#
### commandName cN (/) this is a description for the command
### commandName cN (/) this is a description for the command
#
####################################################################################################

```

while calling `--help` or `-h` with a specific parameter will only print the help message for that parameter:
Expand All @@ -318,14 +320,14 @@ while calling `--help` or `-h` with a specific parameter will only print the hel
```

############################################### HELP ###############################################
# [s]/[s+]=String | [i]/[i+]=Integer | [c]/[c+]=Character | [b]/[b+]=Boolean | [d]/[d+]=Double
# ('+' marks a flag that takes several arguments of the same type whitespace separated)
# (!)=mandatory | (?)=optional | (/)=command
# [d]=Double
# (!)=mandatory | ( )=optional | (/)=command
#
### --parameterFlag3 -pf3 [d] (?) description
### --parameterFlag3 -pf3 [d] ( ) description
# default: 5.6
#
####################################################################################################

```

## ArgsException printout examples
Expand Down Expand Up @@ -364,22 +366,22 @@ for misspelled flags, the Parser will even do a suggestion:

```

## Create your own Parameters:
## Create your own Parameters
By creating a class extending Parameter<T> with T of the Type that your Parameter should handle, you can implement
your own Parameters that are compatible with this ArgsParser!

### To create a custom parameter, follow these steps:
#### 1. Define the Parameter Type:
#### 1. Define the Parameter Type
Determine the type T that the parameter will handle (e.g., Integer, String, etc.).
(We use Integer as T for this example!)
#### 2. Create the Subclass:
#### 2. Create the Subclass
Extend the Parameter<T> class, specifying the appropriate type.
```java
public class IntegerParameter extends Parameter<Integer> {
// Implementation details
}
```
#### 3. Implement Constructors:
#### 3. Implement Constructors
Provide constructors that call the superclass constructors, passing necessary parameters such as flags, description,
mandatory status, and default values if applicable.
```java
Expand All @@ -391,21 +393,27 @@ public IntegerParameter(Integer defaultValue, String fullFlag, String shortFlag,
super(defaultValue, fullFlag, shortFlag, description, Integer.class);
}
```
#### 4. Override castArgument:
Implement the castArgument method to convert the input string to the desired type T. Handle any
necessary validation and exception throwing within this method.
#### 4. Override castArgument & castDefaultToString
Implement the castArgument method to convert the input string to the desired type T.
A try-catch phrase is not needed as the castArgument is internally only used in such a statement ands makes sure to raise
InvalidArgTypeArgsException if the type is not correct.
```java
@Override
protected Integer castArgument(String argument) throws InvalidArgTypeArgsException {
try {
return Integer.parseInt(argument);
} catch (NumberFormatException e) {
throw new InvalidArgTypeArgsException(getFullFlag(), "Integer", "Invalid integer value: " + argument);
}
protected Integer castArgument(String argument) {
return Integer.parseInt(argument);
}

@Override
protected String castDefaultToString(Integer defaultValue) {
return defaultValue.toString();
}
```

## List of methods:
### Custom Parameters in Help
Custom parameters are automatically detected and included in the help message.
The correct parameter type is annotated and displayed accurately in the help output!

## List of methods

#### add a parameter to a parser instance:
- `parser.addParameter()`
Expand All @@ -419,7 +427,7 @@ protected Integer castArgument(String argument) throws InvalidArgTypeArgsExcepti
#### check provision of a specific command:
- `command.isProvided()`

#### check provision of a specific Parameter or if it has a value
#### check provision of a specific Parameter or if it has a value:
- `parameter.isProvided()`
- `parameter.hasArgument()`

Expand All @@ -430,7 +438,7 @@ protected Integer castArgument(String argument) throws InvalidArgTypeArgsExcepti
- `getArgumentOf(String fullFlag)`
- `checkIfCommandIsProvided(String fullCommandName)`

## Full Code Example:
## Full Code Example
```java
public static void main(String[] args) {
// initialize ArgsParser instance
Expand Down
44 changes: 32 additions & 12 deletions src/ArgsParser/ArgsParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
*
* <ol>
* <li>Define as many Parameters on a ArgsParser instance as needed by using {@link ArgsParser#addParameter(Parameter)}.
* This method takes a instance of any Parameter<?> type. There are several usage-ready child classes for the most
* This method takes a instance of any Parameter type. There are several usage-ready child classes for the most
* common types used. There are also Array type Parameters for each equivalent:
*
* <ul>
Expand Down Expand Up @@ -69,8 +69,8 @@ public class ArgsParser {
private final LinkedList<String> commandsInDefinitionOrder = new LinkedList<>();
private final LinkedList<String> flagsInDefinitionOrder = new LinkedList<>();
protected boolean parseArgsWasCalled = false;
private int longestFlagSize = 0;
private int longestShortFlag = 0;
private int longestFullFlagSize = 0;
private int longestShortFlagSize = 0;

/**
* Constructor
Expand Down Expand Up @@ -99,7 +99,7 @@ protected boolean parseArgsWasCalled() {
* If the input flag is already correctly formatted, it will be returned unchanged.
* </p>
*
* <h3>Examples:</h3>
* <p>Examples:</p>
* <pre>
* makeFlag("example", false) → "--example"
* makeFlag("--example", false) → "--example"
Expand Down Expand Up @@ -130,7 +130,7 @@ protected static String makeFlag(String flag, boolean isShortName) {
* If any of these conditions are violated, an {@link IllegalArgumentException} will be thrown.
* </p>
*
* <h3>Examples:</h3>
* <p>Examples:</p>
* <pre>
* checkReservedFlags("--example", "-e"); // Valid
* checkReservedFlags("--help", "-h"); // Throws IllegalArgumentException
Expand Down Expand Up @@ -169,7 +169,7 @@ protected void checkReservedFlags(String fullVersion, String shortVersion) {
* are longer. This ensures proper alignment when displaying flags in help messages or documentation.
* </p>
*
* <h3>Behavior:</h3>
* <p>Behavior:</p>
* <ul>
* <li>Compares the length of the provided full flag name with the current maximum length (`longestFlagSize`).</li>
* <li>Updates `longestFlagSize` if the new full flag is longer.</li>
Expand All @@ -182,10 +182,10 @@ protected void checkReservedFlags(String fullVersion, String shortVersion) {
*/
protected void setNameSizes(String fullVersion, String shortVersion) {
int nameSize = fullVersion.length();
if (longestFlagSize < nameSize) longestFlagSize = nameSize;
if (longestFullFlagSize < nameSize) longestFullFlagSize = nameSize;

int shortSize = shortVersion.length();
if (longestShortFlag < shortSize) longestShortFlag = shortSize;
if (longestShortFlagSize < shortSize) longestShortFlagSize = shortSize;
}


Expand All @@ -196,7 +196,7 @@ protected void setNameSizes(String fullVersion, String shortVersion) {
* and doesn't conflict with reserved flags such as `--help` or `-h`.
* </p>
*
* <h2>Behavior:</h2>
* <p>Behavior:</p>
* <ul>
* <li>Validates that the parameter's full and short flags are non-empty and unique.</li>
* <li>Ensures reserved flags (`--help`, `-h`) are not being reused.</li>
Expand Down Expand Up @@ -277,7 +277,26 @@ public Command addCommand(Command command) {
* @param commands commands that cannot be combined
*/
public void toggle(Command... commands) {
if (commands.length <= 1) throw new IllegalArgumentException("Must specify at least two commands in one toggle!");
if (!hasUniqueElements(commands)) throw new IllegalArgumentException("Commands have to be unique, no duplications allowed!");
toggleList.add(commands);
for (Command command : commands) {
command.setToggle(commands);
}
}

/**
* Checks whether an array has only unique elements or not.
*
* @param array the array to be checked
* @return true if all elements are unique, false else wise.
*/
private static boolean hasUniqueElements(Command[] array) {
Set<Command> uniqueElements = new HashSet<>();
for (Command command : array) {
if (!uniqueElements.add(command)) return false;
}
return true;
}


Expand Down Expand Up @@ -318,6 +337,7 @@ public void parse(String[] args) throws IllegalArgumentException {
* detected during the parsing process, specific exceptions are thrown
* to indicate what went wrong.
*
* @param args The main-methods String[] args array that holds the Strings coming from the command-line.
* @throws NoArgumentsProvidedArgsException if no command-line arguments are provided.
* @throws UnknownFlagArgsException if an unknown flag is encountered in the arguments.
* @throws TooManyArgumentsArgsException if too many arguments are provided.
Expand Down Expand Up @@ -378,18 +398,18 @@ private void checkForHelpCall(String[] args) throws UnknownFlagArgsException, Ca
if (oneArgProvided && (args[0].equals("--help") || args[0].equals("-h"))) { // if --help or -h was called, the help is printed
throw new CalledForHelpNotification(parameterMap, flagsInDefinitionOrder,
commandMap, commandsInDefinitionOrder,
longestFlagSize, longestShortFlag);
longestFullFlagSize, longestShortFlagSize);

} else if (twoArgsProvided && (args[1].equals("--help") || args[1].equals("-h"))) {
if (firstArgumentIsParameter) { // if the first argument is a parameter and --help follows,
throw new CalledForHelpNotification(parameterMap, Collections.singletonList(args[0]),
commandMap, new LinkedList<>(),
longestFlagSize, longestShortFlag);
longestFullFlagSize, longestShortFlagSize);

} else if (firstArgumentIsCommand) { // if the first argument is a command and --help follows
throw new CalledForHelpNotification(parameterMap, new LinkedList<>(),
commandMap, Collections.singletonList(args[0]),
longestFlagSize, longestShortFlag);
longestFullFlagSize, longestShortFlagSize);

} else { // if the first argument is not a parameter but --help was called,
// the program notifies the user of an unknown parameter input
Expand Down
Loading