1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/main/java/cz/frantovo/rozsireneatributy/CLIParser.java Sat Dec 16 20:13:13 2023 +0100
1.3 @@ -0,0 +1,173 @@
1.4 +/**
1.5 + * Rozšířené atributy – program na správu rozšířených atributů souborů
1.6 + * Copyright © 2023 František Kučera (frantovo.cz)
1.7 + *
1.8 + * This program is free software: you can redistribute it and/or modify
1.9 + * it under the terms of the GNU General Public License as published by
1.10 + * the Free Software Foundation, either version 3 of the License.
1.11 + *
1.12 + * This program is distributed in the hope that it will be useful,
1.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.15 + * GNU General Public License for more details.
1.16 + *
1.17 + * You should have received a copy of the GNU General Public License
1.18 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
1.19 + */
1.20 +package cz.frantovo.rozsireneatributy;
1.21 +
1.22 +import cz.frantovo.rozsireneatributy.Konfigurace.DefiniceAtributu;
1.23 +import cz.frantovo.rozsireneatributy.Konfigurace.DefiniceHodnoty;
1.24 +import java.io.File;
1.25 +import java.util.Arrays;
1.26 +import java.util.Collection;
1.27 +import java.util.ResourceBundle;
1.28 +
1.29 +/**
1.30 + * Converts command line arguments from String array to object. Checks basic
1.31 + * constraints (if only supported options are used and if they have correct
1.32 + * number of parameters)
1.33 + *
1.34 + * @author Ing. František Kučera (frantovo.cz)
1.35 + */
1.36 +public class CLIParser {
1.37 +
1.38 + private static final ResourceBundle překlady = ResourceBundle
1.39 + .getBundle(Atribut.class.getPackageName() + ".Překlady");
1.40 +
1.41 + public Konfigurace parsujParametry(String[] parametry)
1.42 + throws CLIParserException {
1.43 + Konfigurace k = new Konfigurace();
1.44 +
1.45 + for (int i = 0; i < parametry.length; i++) {
1.46 + String parametr = parametry[i];
1.47 +
1.48 + boolean odpovídá = false;
1.49 +
1.50 + for (Token t : Token.values()) {
1.51 + if (t.odpovídá(parametr)) {
1.52 + int parsedArgs = t.parsuj(parametry, i, k);
1.53 + i = i + parsedArgs;
1.54 + odpovídá = true;
1.55 + }
1.56 + }
1.57 +
1.58 + if (!odpovídá) {
1.59 + throw new CLIParserException(
1.60 + překlady.getString("chyba.cli.neznámýParametr") + parametr);
1.61 + }
1.62 + }
1.63 +
1.64 + if (k.getSoubor() == null)
1.65 + throw new CLIParserException(
1.66 + překlady.getString("chyba.cli.chybíSoubor"));
1.67 +
1.68 + return k;
1.69 + }
1.70 +
1.71 + private static String načtiDalší(String[] parametry, int index)
1.72 + throws CLIParserException {
1.73 + if (index < parametry.length) {
1.74 + return parametry[index];
1.75 + } else {
1.76 + throw new CLIParserException("Expecting value for option: "
1.77 + + parametry[index - 1]);
1.78 + }
1.79 + }
1.80 +
1.81 + private static boolean načtiDalšíBoolean(String[] parametry, int index)
1.82 + throws CLIParserException {
1.83 + String s = načtiDalší(parametry, index);
1.84 + switch (s) {
1.85 + case "true":
1.86 + case "ano":
1.87 + return true;
1.88 + case "false":
1.89 + case "ne":
1.90 + return false;
1.91 + default:
1.92 + throw new CLIParserException("Neplatná logická hodnota: " + s);
1.93 + }
1.94 + }
1.95 +
1.96 + private static enum Token {
1.97 +
1.98 + SOUBOR("--soubor", "--file") {
1.99 + @Override
1.100 + public int parsuj(String[] parametry, int index, Konfigurace k)
1.101 + throws CLIParserException {
1.102 + int originalIndex = index;
1.103 + k.setSoubor(new File(načtiDalší(parametry, ++index)));
1.104 + return index - originalIndex;
1.105 + }
1.106 + },
1.107 + POVINNÉ_ZAMYKÁNÍ("--povinné-zamykání", "--mandatory-locking") {
1.108 + @Override
1.109 + public int parsuj(String[] parametry, int index, Konfigurace k)
1.110 + throws CLIParserException {
1.111 + int originalIndex = index;
1.112 + k.setPovinnéZamykání(načtiDalšíBoolean(parametry, ++index));
1.113 + return index - originalIndex;
1.114 + }
1.115 + },
1.116 + DEFINICE_ATRIBUTU("--definice-atributu", "--attribute-definition") {
1.117 + @Override
1.118 + public int parsuj(String[] parametry, int index, Konfigurace k)
1.119 + throws CLIParserException {
1.120 + int originalIndex = index;
1.121 + String název = načtiDalší(parametry, ++index);
1.122 + String popis = načtiDalší(parametry, ++index);
1.123 + k.addAtribut(new DefiniceAtributu(název, popis));
1.124 + return index - originalIndex;
1.125 + }
1.126 + },
1.127 + HODNOTA_ATRIBUTU("--hodnota", "--value") {
1.128 + @Override
1.129 + public int parsuj(String[] parametry, int index, Konfigurace k)
1.130 + throws CLIParserException {
1.131 + int originalIndex = index;
1.132 + String hodnota = načtiDalší(parametry, ++index);
1.133 + String popis = načtiDalší(parametry, ++index);
1.134 +
1.135 + if (k.getAtributy().isEmpty())
1.136 + throw new CLIParserException(
1.137 + překlady.getString("chyba.cli.chybíDefiniceAtributu"));
1.138 +
1.139 + k.getAtributy()
1.140 + .get(k.getAtributy().size() - 1)
1.141 + .addHodnota(new DefiniceHodnoty(hodnota, popis));
1.142 +
1.143 + return index - originalIndex;
1.144 + }
1.145 + };
1.146 +
1.147 + private final Collection<String> parametry;
1.148 +
1.149 + private Token(String... parametry) {
1.150 + this.parametry = Arrays.asList(parametry);
1.151 + }
1.152 +
1.153 + /**
1.154 + * @param parametr e.g. „--input-file“
1.155 + * @return whether option is this token
1.156 + */
1.157 + public boolean odpovídá(String parametr) {
1.158 + return parametry.contains(parametr);
1.159 + }
1.160 +
1.161 + /**
1.162 + * Parse String arguments and fill values into the options object.
1.163 + *
1.164 + * @param parametry CLI arguments
1.165 + * @param index index of the option matched by this token, like
1.166 + * „--input-file“
1.167 + * @param k object to be filled
1.168 + * @return number of parsed arguments – if option has no arguments (just
1.169 + * boolean flag), return 0, otherwise return positive integer: number of
1.170 + * eaten arguments.
1.171 + * @throws CLIParserException
1.172 + */
1.173 + public abstract int parsuj(String[] parametry, int index, Konfigurace k)
1.174 + throws CLIParserException;
1.175 + }
1.176 +}