franta-hg@31: /**
franta-hg@31: * Rozšířené atributy – program na správu rozšířených atributů souborů
franta-hg@31: * Copyright © 2023 František Kučera (frantovo.cz)
franta-hg@31: *
franta-hg@31: * This program is free software: you can redistribute it and/or modify
franta-hg@31: * it under the terms of the GNU General Public License as published by
franta-hg@31: * the Free Software Foundation, either version 3 of the License.
franta-hg@31: *
franta-hg@31: * This program is distributed in the hope that it will be useful,
franta-hg@31: * but WITHOUT ANY WARRANTY; without even the implied warranty of
franta-hg@31: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
franta-hg@31: * GNU General Public License for more details.
franta-hg@31: *
franta-hg@31: * You should have received a copy of the GNU General Public License
franta-hg@31: * along with this program. If not, see .
franta-hg@31: */
franta-hg@31: package cz.frantovo.rozsireneatributy;
franta-hg@31:
franta-hg@31: import cz.frantovo.rozsireneatributy.Konfigurace.DefiniceAtributu;
franta-hg@31: import cz.frantovo.rozsireneatributy.Konfigurace.DefiniceHodnoty;
franta-hg@31: import java.io.File;
franta-hg@31: import java.util.Arrays;
franta-hg@31: import java.util.Collection;
franta-hg@31: import java.util.ResourceBundle;
franta-hg@31:
franta-hg@31: /**
franta-hg@31: * Converts command line arguments from String array to object. Checks basic
franta-hg@31: * constraints (if only supported options are used and if they have correct
franta-hg@31: * number of parameters)
franta-hg@31: *
franta-hg@31: * @author Ing. František Kučera (frantovo.cz)
franta-hg@31: */
franta-hg@31: public class CLIParser {
franta-hg@31:
franta-hg@31: private static final ResourceBundle překlady = ResourceBundle
franta-hg@31: .getBundle(Atribut.class.getPackageName() + ".Překlady");
franta-hg@31:
franta-hg@31: public Konfigurace parsujParametry(String[] parametry)
franta-hg@31: throws CLIParserException {
franta-hg@31: Konfigurace k = new Konfigurace();
franta-hg@31:
franta-hg@31: for (int i = 0; i < parametry.length; i++) {
franta-hg@31: String parametr = parametry[i];
franta-hg@31:
franta-hg@31: boolean odpovídá = false;
franta-hg@31:
franta-hg@31: for (Token t : Token.values()) {
franta-hg@31: if (t.odpovídá(parametr)) {
franta-hg@31: int parsedArgs = t.parsuj(parametry, i, k);
franta-hg@31: i = i + parsedArgs;
franta-hg@31: odpovídá = true;
franta-hg@31: }
franta-hg@31: }
franta-hg@31:
franta-hg@31: if (!odpovídá) {
franta-hg@31: throw new CLIParserException(
franta-hg@31: překlady.getString("chyba.cli.neznámýParametr") + parametr);
franta-hg@31: }
franta-hg@31: }
franta-hg@31:
franta-hg@31: if (k.getSoubor() == null)
franta-hg@31: throw new CLIParserException(
franta-hg@31: překlady.getString("chyba.cli.chybíSoubor"));
franta-hg@31:
franta-hg@31: return k;
franta-hg@31: }
franta-hg@31:
franta-hg@31: private static String načtiDalší(String[] parametry, int index)
franta-hg@31: throws CLIParserException {
franta-hg@31: if (index < parametry.length) {
franta-hg@31: return parametry[index];
franta-hg@31: } else {
franta-hg@31: throw new CLIParserException("Expecting value for option: "
franta-hg@31: + parametry[index - 1]);
franta-hg@31: }
franta-hg@31: }
franta-hg@31:
franta-hg@31: private static boolean načtiDalšíBoolean(String[] parametry, int index)
franta-hg@31: throws CLIParserException {
franta-hg@31: String s = načtiDalší(parametry, index);
franta-hg@31: switch (s) {
franta-hg@31: case "true":
franta-hg@31: case "ano":
franta-hg@31: return true;
franta-hg@31: case "false":
franta-hg@31: case "ne":
franta-hg@31: return false;
franta-hg@31: default:
franta-hg@31: throw new CLIParserException("Neplatná logická hodnota: " + s);
franta-hg@31: }
franta-hg@31: }
franta-hg@31:
franta-hg@31: private static enum Token {
franta-hg@31:
franta-hg@31: SOUBOR("--soubor", "--file") {
franta-hg@31: @Override
franta-hg@31: public int parsuj(String[] parametry, int index, Konfigurace k)
franta-hg@31: throws CLIParserException {
franta-hg@31: int originalIndex = index;
franta-hg@31: k.setSoubor(new File(načtiDalší(parametry, ++index)));
franta-hg@31: return index - originalIndex;
franta-hg@31: }
franta-hg@31: },
franta-hg@31: POVINNÉ_ZAMYKÁNÍ("--povinné-zamykání", "--mandatory-locking") {
franta-hg@31: @Override
franta-hg@31: public int parsuj(String[] parametry, int index, Konfigurace k)
franta-hg@31: throws CLIParserException {
franta-hg@31: int originalIndex = index;
franta-hg@31: k.setPovinnéZamykání(načtiDalšíBoolean(parametry, ++index));
franta-hg@31: return index - originalIndex;
franta-hg@31: }
franta-hg@31: },
franta-hg@31: DEFINICE_ATRIBUTU("--definice-atributu", "--attribute-definition") {
franta-hg@31: @Override
franta-hg@31: public int parsuj(String[] parametry, int index, Konfigurace k)
franta-hg@31: throws CLIParserException {
franta-hg@31: int originalIndex = index;
franta-hg@31: String název = načtiDalší(parametry, ++index);
franta-hg@31: String popis = načtiDalší(parametry, ++index);
franta-hg@31: k.addAtribut(new DefiniceAtributu(název, popis));
franta-hg@31: return index - originalIndex;
franta-hg@31: }
franta-hg@31: },
franta-hg@31: HODNOTA_ATRIBUTU("--hodnota", "--value") {
franta-hg@31: @Override
franta-hg@31: public int parsuj(String[] parametry, int index, Konfigurace k)
franta-hg@31: throws CLIParserException {
franta-hg@31: int originalIndex = index;
franta-hg@31: String hodnota = načtiDalší(parametry, ++index);
franta-hg@31: String popis = načtiDalší(parametry, ++index);
franta-hg@31:
franta-hg@31: if (k.getAtributy().isEmpty())
franta-hg@31: throw new CLIParserException(
franta-hg@31: překlady.getString("chyba.cli.chybíDefiniceAtributu"));
franta-hg@31:
franta-hg@31: k.getAtributy()
franta-hg@31: .get(k.getAtributy().size() - 1)
franta-hg@31: .addHodnota(new DefiniceHodnoty(hodnota, popis));
franta-hg@31:
franta-hg@31: return index - originalIndex;
franta-hg@31: }
franta-hg@31: };
franta-hg@31:
franta-hg@31: private final Collection parametry;
franta-hg@31:
franta-hg@31: private Token(String... parametry) {
franta-hg@31: this.parametry = Arrays.asList(parametry);
franta-hg@31: }
franta-hg@31:
franta-hg@31: /**
franta-hg@31: * @param parametr e.g. „--input-file“
franta-hg@31: * @return whether option is this token
franta-hg@31: */
franta-hg@31: public boolean odpovídá(String parametr) {
franta-hg@31: return parametry.contains(parametr);
franta-hg@31: }
franta-hg@31:
franta-hg@31: /**
franta-hg@31: * Parse String arguments and fill values into the options object.
franta-hg@31: *
franta-hg@31: * @param parametry CLI arguments
franta-hg@31: * @param index index of the option matched by this token, like
franta-hg@31: * „--input-file“
franta-hg@31: * @param k object to be filled
franta-hg@31: * @return number of parsed arguments – if option has no arguments (just
franta-hg@31: * boolean flag), return 0, otherwise return positive integer: number of
franta-hg@31: * eaten arguments.
franta-hg@31: * @throws CLIParserException
franta-hg@31: */
franta-hg@31: public abstract int parsuj(String[] parametry, int index, Konfigurace k)
franta-hg@31: throws CLIParserException;
franta-hg@31: }
franta-hg@31: }