package io.vertx.core.cli.impl;
import io.vertx.core.cli.*;
import io.vertx.core.cli.converters.Converters;
import java.util.*;
import java.util.stream.Collectors;
public class DefaultCommandLine implements CommandLine {
protected final CLI cli;
protected List<String> allArgs = new ArrayList<>();
protected Map<Option, List<String>> optionValues = new HashMap<>();
protected List<Option> optionsSeenInCommandLine = new ArrayList<>();
protected Map<Argument, List<String>> argumentValues = new HashMap<>();
protected boolean valid;
public DefaultCommandLine(CLI cli) {
this.cli = cli;
}
@Override
public CLI cli() {
return cli;
}
@Override
public List<String> allArguments() {
return allArgs;
}
public CommandLine addArgumentValue(String argument) {
allArgs.add(argument);
return this;
}
@Override
@SuppressWarnings("unchecked")
public <T> T getOptionValue(String name) {
Option option = cli.getOption(name);
if (option == null) {
return null;
}
if (option instanceof TypedOption) {
return getValue((TypedOption<T>) option);
} else {
return (T) getRawValueForOption(option);
}
}
@Override
public boolean isFlagEnabled(String name) {
Option option = cli.getOption(name);
if (option == null) {
throw new IllegalArgumentException("Cannot find the option '" + name + "'");
}
if (option.isFlag()) {
return optionsSeenInCommandLine.contains(option);
} else {
throw new IllegalStateException("Cannot retrieve the flag value on a non-flag option (" + name + ")");
}
}
@Override
@SuppressWarnings("unchecked")
public <T> List<T> getOptionValues(String name) {
Option option = cli.getOption(name);
if (option == null) {
return null;
}
if (option instanceof TypedOption) {
TypedOption<T> typed = (TypedOption<T>) option;
if (typed.isParsedAsList()) {
return createFromList(getRawValueForOption(option), typed);
} else {
return getRawValuesForOption(option).stream().map(s -> create(s, typed))
.collect(Collectors.toList());
}
} else {
return (List<T>) getRawValuesForOption(option);
}
}
@Override
@SuppressWarnings("unchecked")
public <T> List<T> getArgumentValues(int index) {
Argument argument = cli.getArgument(index);
if (argument == null) {
return null;
}
if (argument instanceof TypedArgument) {
TypedArgument<T> typed = (TypedArgument<T>) argument;
return getRawValuesForArgument(typed).stream().map(s -> create(s, typed))
.collect(Collectors.toList());
} else {
return (List<T>) getRawValuesForArgument(argument);
}
}
@Override
public <T> T getArgumentValue(String name) {
Argument arg = cli.getArgument(name);
if (arg == null) {
return null;
}
return getArgumentValue(arg.getIndex());
}
@Override
@SuppressWarnings("unchecked")
public <T> T getArgumentValue(int index) {
Argument arg = cli.getArgument(index);
if (arg == null) {
return null;
}
if (arg instanceof TypedArgument) {
return create(getRawValueForArgument(arg), (TypedArgument<T>) arg);
} else {
return (T) getRawValueForArgument(arg);
}
}
@Override
public boolean isOptionAssigned(Option option) {
return !getRawValuesForOption(option).isEmpty();
}
@Override
public List<String> getRawValuesForOption(Option option) {
List<?> list = optionValues.get(option);
if (list != null) {
return list.stream().map(Object::toString).collect(Collectors.toList());
}
return Collections.emptyList();
}
@Override
public List<String> getRawValuesForArgument(Argument argument) {
List<?> list = argumentValues.get(argument);
if (list != null) {
return list.stream().map(Object::toString).collect(Collectors.toList());
}
return Collections.emptyList();
}
public DefaultCommandLine addRawValue(Option option, String value) {
if (!acceptMoreValues(option) && !option.isFlag()) {
throw new CLIException("The option " + option.getName() + " does not accept value or has " +
"already been set");
}
if (! option.getChoices().isEmpty() && ! option.getChoices().contains(value)) {
throw new InvalidValueException(option, value);
}
List<String> list = optionValues.get(option);
if (list == null) {
list = new ArrayList<>();
optionValues.put(option, list);
}
list.add(value);
return this;
}
@Override
public String getRawValueForOption(Option option) {
if (isOptionAssigned(option)) {
return getRawValuesForOption(option).get(0);
}
return option.getDefaultValue();
}
@Override
public boolean acceptMoreValues(Option option) {
return option.isMultiValued() || option.isSingleValued() && !isOptionAssigned(option);
}
@Override
public String getRawValueForArgument(Argument arg) {
List values = argumentValues.get(arg);
if (values == null || values.isEmpty()) {
return arg.getDefaultValue();
}
return values.get(0).toString();
}
public DefaultCommandLine setRawValue(Argument arg, String rawValue) {
List<String> list = argumentValues.get(arg);
if (list == null) {
list = new ArrayList<>();
argumentValues.put(arg, list);
}
list.add(rawValue);
return this;
}
@Override
public boolean isArgumentAssigned(Argument arg) {
return argumentValues.get(arg) != null;
}
public DefaultCommandLine setSeenInCommandLine(Option option) {
optionsSeenInCommandLine.add(option);
return this;
}
@Override
public boolean isSeenInCommandLine(Option option) {
return optionsSeenInCommandLine.contains(option);
}
private <T> T getValue(TypedOption<T> option) {
if (isOptionAssigned(option)) {
return create(getRawValueForOption(option), option);
} else {
if (option.getDefaultValue() != null) {
return create(getRawValueForOption(option), option);
}
if (option.isFlag() || isBoolean(option)) {
try {
if (isSeenInCommandLine(option)) {
return (T) Boolean.TRUE;
} else {
return (T) Boolean.FALSE;
}
} catch (InvalidValueException e) {
throw new IllegalArgumentException(e);
}
}
}
return null;
}
private boolean isBoolean(TypedOption option) {
Class type = option.getType();
return type == Boolean.TYPE || type == Boolean.class;
}
public static <T> T create(String value, TypedArgument<T> argument) {
Objects.requireNonNull(argument);
if (value == null) {
value = argument.getDefaultValue();
}
if (value == null) {
return null;
}
try {
if (argument.getConverter() != null) {
return Converters.create(value, argument.getConverter());
} else {
return Converters.create(argument.getType(), value);
}
} catch (Exception e) {
throw new InvalidValueException(argument, value, e);
}
}
public static <T> T create(String value, TypedOption<T> option) {
Objects.requireNonNull(option);
if (value == null) {
value = option.getDefaultValue();
}
if (value == null) {
return null;
}
try {
if (option.getConverter() != null) {
return Converters.create(value, option.getConverter());
} else {
return Converters.create(option.getType(), value);
}
} catch (Exception e) {
throw new InvalidValueException(option, value, e);
}
}
public static <T> List<T> createFromList(String raw, TypedOption<T> option) {
if (raw == null) {
return Collections.emptyList();
}
final String[] segments = raw.split(option.getListSeparator());
return Arrays.stream(segments).map(s -> create(s.trim(), option)).collect(Collectors.toList());
}
@Override
public boolean isValid() {
return valid;
}
void setValidity(boolean validity) {
this.valid = validity;
}
@Override
public boolean isAskingForHelp() {
for (Option option : cli.getOptions()) {
if (option.isHelp() && isSeenInCommandLine(option)) {
return true;
}
}
return false;
}
}