Может ли анализатор параметров командной строки Apache Commons игнорировать неизвестные параметры командной строки?
Я пишу Java-приложение, которое принимает аргументы командной строки, которые обрабатываются с помощью Apache Commons CLI с GnuParser. По причинам, которые не интересны, я хотел бы, чтобы он тихо игнорировал неизвестные параметры командной строки вместо того, чтобы выдавать исключение ParseException, но я не вижу способа сделать это. Я вижу, что в GnuParser.parse() есть логическая опция stopAtNonOption, но я хочу больше походить на ignoreAtNonOption, где он продолжит обработку параметров после обнаружения неизвестного токена.
Я мог бы реализовать свой собственный синтаксический анализатор, чтобы выполнить это, но я удивлен, что эта функциональность не встроена, поэтому я решил проверить, прежде чем идти по этому пути.
Пример кода для того, о чем я говорю:
try {
CommandLine commandLine = parser.parse(options, args);
// stopAtNonOption set to true (below) is also not what I want
// CommandLine commandLine = parser.parse(options, args, true);
} catch (ParseException e) {
LOG.error("error parsing arguments", e);
throw new RuntimeException(e);
}
4 ответа
Это работает для меня (другие парсеры тоже могут быть получены):
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);
}
}
}
Как уже упоминалось в комментарии, принятое решение больше не подходит, потому что processOption
метод устарел и удален.
Вот мое решение:
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()]));
}
}
По сравнению с решением, предложенным Паскалем, он также проверяет параметры с аргументами и сохраняет непарсированные аргументы в отдельном списке.
Это невозможно с Commons CLI. Но может быть и другой способ достичь ожидаемого результата, если вы предоставите более подробную информацию о вашем сценарии использования.
Я очень плохой разработчик, и я делаю это, чтобы сломать код:
public class EasyPosixParser extends PosixParser {
@Override
protected void processOption(String arg, ListIterator iter) throws ParseException
{
try {
super.processOption(arg, iter);
} catch (ParseException e) {
// do nothing
}
}
}
в вашем основном коде вы делаете:
CommandLineParser commandlineParser = new EasyPosixParser();