I'd like to add this here as an answer to @Zangdak and to add my findings on the same problem.
If you do not call #setArgs(int) then a RuntimeException will occur. When you know the exact maximum amount of arguments to this option, then set this specific value. When this value is not known, the class Option has a constant for it: Option.UNLIMITED_VALUES
This would change gerrytans answer to the following:
Options options = new Options();
Option option = new Option("c", "c desc");
// Set option c to take 1 to oo arguments
option.setArgs(Option.UNLIMITED_VALUES);
options.addOption(option);
Answer from VeikkoW on Stack OverflowVideos
I'd like to add this here as an answer to @Zangdak and to add my findings on the same problem.
If you do not call #setArgs(int) then a RuntimeException will occur. When you know the exact maximum amount of arguments to this option, then set this specific value. When this value is not known, the class Option has a constant for it: Option.UNLIMITED_VALUES
This would change gerrytans answer to the following:
Options options = new Options();
Option option = new Option("c", "c desc");
// Set option c to take 1 to oo arguments
option.setArgs(Option.UNLIMITED_VALUES);
options.addOption(option);
You have to set maximum the number of argument values the option can take, otherwise it assumes the option only has 1 argument value
Options options = new Options();
Option option = new Option("c", "c desc");
// Set option c to take maximum of 10 arguments
option.setArgs(10);
options.addOption(option);
This works for me (other parsers can be derived, too):
public class ExtendedGnuParser extends GnuParser {
private boolean ignoreUnrecognizedOption;
public ExtendedGnuParser(final boolean ignoreUnrecognizedOption) {
this.ignoreUnrecognizedOption = ignoreUnrecognizedOption;
}
@Override
protected void processOption(final String arg, final ListIterator iter) throws ParseException {
boolean hasOption = getOptions().hasOption(arg);
if (hasOption || !ignoreUnrecognizedOption) {
super.processOption(arg, iter);
}
}
}
As mentioned in a comment, the accepted solution is no more suitable because the processOption method has been deprecated and removed.
Here's my solution:
public class ExtendedParser extends DefaultParser {
private final ArrayList<String> notParsedArgs = new ArrayList<>();
public String[] getNotParsedArgs() {
return notParsedArgs.toArray(new String[notParsedArgs.size()]);
}
@Override
public CommandLine parse(Options options, String[] arguments, boolean stopAtNonOption) throws ParseException {
if(stopAtNonOption) {
return parse(options, arguments);
}
List<String> knownArguments = new ArrayList<>();
notParsedArgs.clear();
boolean nextArgument = false;
for (String arg : arguments) {
if (options.hasOption(arg) || nextArgument) {
knownArguments.add(arg);
} else {
notParsedArgs.add(arg);
}
nextArgument = options.hasOption(arg) && options.getOption(arg).hasArg();
}
return super.parse(options, knownArguments.toArray(new String[knownArguments.size()]));
}
}
Compared with the solution proposed by Pascal, it also checks for options with arguments and it keeps not parsed args in a separate list.