All Downloads are FREE. Search and download functionalities are using the official Maven repository.

javax0.jamal.tools.CmdParser Maven / Gradle / Ivy

package javax0.jamal.tools;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

/**
 * A parameter parser that is to parse the command line and after that to query the command parameters.
 */
public class CmdParser {

    private final Map keys = new HashMap<>();
    private final List values = new ArrayList<>();

    /**
     * Parse a string and build up the parsed structures.
     * 

* A line can have the form *

* {@code * key1=value1 key2=value2 .... parameter ... key3=value3 ... parameter * } *

* The keys have to be unique, so no one key can be used twice. The parameters that stand alone on the line * without an associated key can be mixed between, before and after the keys. *

* The keys, in case they are defined in the argument {@code parameters} are case-insensitive. * * @param parts the line that contains the keys and also the arguments * @param parameters a set of parameter names that are allowed on the line. In case this parameter is null any * parameter is allowed. If this set is empty then no parameter is allowed. If the set contains * the parameter names then the line may use any non-ambiguous prefix of any parameter and the * parsed structure will contain the full parameter name even if the user typed a short prefix. * @return the parsed structure object that can later be queried * @throws IllegalArgumentException if the line is not properly formatted */ public static CmdParser parse(String[] parts, Set parameters) { final var it = new CmdParser(); for (var part : parts) { var partIsKey = false; while (part.startsWith("-")) { part = part.substring(1); partIsKey = true; } final var eq = part.indexOf("="); if (eq == -1) { if (part.length() > 0) { if (partIsKey) { it.keys.put(findIt(part, parameters), "true"); } else { it.values.add(part); } } } else { final var key = part.substring(0, eq); final var value = part.substring(eq + 1); final var realKey = findIt(key, parameters); if( it.keys.containsKey(realKey)) { throw new IllegalArgumentException("The key " + realKey + " is defined more than once"); } it.keys.put(realKey, value); } } return it; } /** * Find the key in the usable parameters' set. The key matches a parameter if it is a prefix of the parameter. * If there are more than one parameter that matches the key then it is an error. The user has to specify an * unambiguous prefix of the parameter. * * @param key the key the user entered * @param set the set of parameters that are allowed on the line * @return the full name of the parameter that was found */ private static String findIt(String key, Set set) { if (set == null) { return key; } final List commandsFound = new ArrayList<>(); for (final var s : set) { if (s.toLowerCase().startsWith(key.toLowerCase())) { commandsFound.add(s); } } if (commandsFound.size() == 1) { return commandsFound.get(0); } if (commandsFound.size() == 0) { throw new IllegalArgumentException(key + " is not an allowed parameter"); } throw new IllegalArgumentException("Parameter " + key + " is ambiguous. " + "It matches " + String.join(",", commandsFound) + "."); } /** * Get the value that was associated with the key on the parsed line. * * @param key the full key as it was defined in the possible keys set * @return the optional value as it was on the line or {@code Optional.empty()} * in case the key was not present on the line */ public Optional get(String key) { return Optional.ofNullable(keys.get(key)); } /** * Get the {@code i}-th parameter (starting with 0) from the parsed line. In case {@code i} is larger than * the index of the last parameter {@code Optional.empty()} is returned. * * @param i index of the parameter * @return the parameter from the line or {@code Optional.empty()} if {@code i} is too large */ public Optional get(int i) { if (i < values.size()) { return Optional.ofNullable(values.get(i)); } else { return Optional.empty(); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy