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