com.crabshue.commons.args.CommandLineArgumentsParser Maven / Gradle / Ivy
package com.crabshue.commons.args;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.MissingOptionException;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import com.crabshue.commons.args.exceptions.ArgumentsErrorContext;
import com.crabshue.commons.args.exceptions.ArgumentsErrorType;
import com.crabshue.commons.args.option.OptionsBuilder;
import com.crabshue.commons.args.parser.TolerantGnuParser;
import com.crabshue.commons.exceptions.ApplicationException;
import com.crabshue.commons.exceptions.SystemException;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
/**
 * Command line arguments parser.
 */
@Slf4j
public class CommandLineArgumentsParser {
    private final CommandLineArgumentsUsagePrinter usagePrinter;
    public CommandLineArgumentsParser() {
        usagePrinter = new CommandLineArgumentsUsagePrinter();
    }
    /**
     * Parse command line arguments wrt a list of {@link Argument argument definitions}
     *
     * @param args      the command line arguments
     * @param arguments the argument definitions.
     * @return the map of parsed arguments.
     */
    public  Map parseArguments(@NonNull final String[] args,
                                                              @NonNull T... arguments) {
        final Options options = OptionsBuilder.buildOptions(arguments);
        final CommandLine commandLine = parseCommandLine(args, options);
        final Map ret = new HashMap<>();
        Arrays.stream(arguments)
            .forEach(
                argument -> ret.put(argument, this.resolveArgumentValue(commandLine, argument))
            );
        logger.info("Parsed arguments [{}] : [{}]", args, ret);
        return ret;
    }
    private CommandLine parseCommandLine(@NonNull final String[] args,
                                         @NonNull final Options options) {
        final CommandLineParser commandLineParser = new TolerantGnuParser(true);
        try {
            return commandLineParser.parse(options, args);
        } catch (MissingOptionException e) {
            System.out.println(e.getMessage());
            this.usagePrinter.printUsageMessage("script", options);
            throw new ApplicationException(ArgumentsErrorType.MISSING_REQUIRED_ARGUMENT, e)
                .addContextValue(ArgumentsErrorContext.REQUIRED, options.getRequiredOptions());
        } catch (ParseException e) {
            throw new SystemException(ArgumentsErrorType.ERROR_PARSING_COMMAND_LINE_ARGUMENTS, e);
        }
    }
    private  Object resolveArgumentValue(@NonNull final CommandLine commandLine,
                                                             @NonNull final T argument) {
        final Object ret;
        // if argument value is expected
        if (argument.isArgumentExpected()) {
            // repeatable argument
            if (argument.isRepeatable()) {
                final String[] res = commandLine.getOptionValues(argument.getOptionName());
                ret =
                    // if argument is present, use value
                    Objects.nonNull(res) ? Arrays.asList(res) :
                        // if no argument passed, use default value, if exists, empty list otherwise
                        Objects.nonNull(argument.getDefaultValue()) ? Collections.singletonList(argument.getDefaultValue()) : Collections.emptyList();
            } else {
                ret = commandLine.getOptionValue(argument.getOptionName(), argument.getDefaultValue());
            }
        }
        // if argument is a flag, i.e. no argument value is expected
        else {
            ret = commandLine.hasOption(argument.getOptionName());
        }
        return ret;
    }
}
        © 2015 - 2025 Weber Informatics LLC | Privacy Policy