diff -r 41e91ea94acb -r ec0e970e0830 src/main/java/cz/frantovo/rozsireneatributy/CLIParser.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/cz/frantovo/rozsireneatributy/CLIParser.java Sat Dec 16 20:13:13 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;
+ }
+}