src/main/java/cz/frantovo/rozsireneatributy/CLIParser.java
author František Kučera <franta-hg@frantovo.cz>
Sat, 16 Dec 2023 20:13:13 +0100
branchv_0
changeset 39 ec0e970e0830
parent 31 java/rozsirene-atributy/src/cz/frantovo/rozsireneatributy/CLIParser.java@1ab5ce94a146
child 42 d2414701ce09
permissions -rw-r--r--
Make, Ant, Maven a Netbeans - různé způsoby sestavení aplikace
franta-hg@31
     1
/**
franta-hg@31
     2
 * Rozšířené atributy – program na správu rozšířených atributů souborů
franta-hg@31
     3
 * Copyright © 2023 František Kučera (frantovo.cz)
franta-hg@31
     4
 *
franta-hg@31
     5
 * This program is free software: you can redistribute it and/or modify
franta-hg@31
     6
 * it under the terms of the GNU General Public License as published by
franta-hg@31
     7
 * the Free Software Foundation, either version 3 of the License.
franta-hg@31
     8
 *
franta-hg@31
     9
 * This program is distributed in the hope that it will be useful,
franta-hg@31
    10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
franta-hg@31
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
franta-hg@31
    12
 * GNU General Public License for more details.
franta-hg@31
    13
 *
franta-hg@31
    14
 * You should have received a copy of the GNU General Public License
franta-hg@31
    15
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
franta-hg@31
    16
 */
franta-hg@31
    17
package cz.frantovo.rozsireneatributy;
franta-hg@31
    18
franta-hg@31
    19
import cz.frantovo.rozsireneatributy.Konfigurace.DefiniceAtributu;
franta-hg@31
    20
import cz.frantovo.rozsireneatributy.Konfigurace.DefiniceHodnoty;
franta-hg@31
    21
import java.io.File;
franta-hg@31
    22
import java.util.Arrays;
franta-hg@31
    23
import java.util.Collection;
franta-hg@31
    24
import java.util.ResourceBundle;
franta-hg@31
    25
franta-hg@31
    26
/**
franta-hg@31
    27
 * Converts command line arguments from String array to object. Checks basic
franta-hg@31
    28
 * constraints (if only supported options are used and if they have correct
franta-hg@31
    29
 * number of parameters)
franta-hg@31
    30
 *
franta-hg@31
    31
 * @author Ing. František Kučera (frantovo.cz)
franta-hg@31
    32
 */
franta-hg@31
    33
public class CLIParser {
franta-hg@31
    34
franta-hg@31
    35
	private static final ResourceBundle překlady = ResourceBundle
franta-hg@31
    36
		.getBundle(Atribut.class.getPackageName() + ".Překlady");
franta-hg@31
    37
franta-hg@31
    38
	public Konfigurace parsujParametry(String[] parametry)
franta-hg@31
    39
		throws CLIParserException {
franta-hg@31
    40
		Konfigurace k = new Konfigurace();
franta-hg@31
    41
franta-hg@31
    42
		for (int i = 0; i < parametry.length; i++) {
franta-hg@31
    43
			String parametr = parametry[i];
franta-hg@31
    44
franta-hg@31
    45
			boolean odpovídá = false;
franta-hg@31
    46
franta-hg@31
    47
			for (Token t : Token.values()) {
franta-hg@31
    48
				if (t.odpovídá(parametr)) {
franta-hg@31
    49
					int parsedArgs = t.parsuj(parametry, i, k);
franta-hg@31
    50
					i = i + parsedArgs;
franta-hg@31
    51
					odpovídá = true;
franta-hg@31
    52
				}
franta-hg@31
    53
			}
franta-hg@31
    54
franta-hg@31
    55
			if (!odpovídá) {
franta-hg@31
    56
				throw new CLIParserException(
franta-hg@31
    57
					překlady.getString("chyba.cli.neznámýParametr") + parametr);
franta-hg@31
    58
			}
franta-hg@31
    59
		}
franta-hg@31
    60
franta-hg@31
    61
		if (k.getSoubor() == null)
franta-hg@31
    62
			throw new CLIParserException(
franta-hg@31
    63
					překlady.getString("chyba.cli.chybíSoubor"));
franta-hg@31
    64
		
franta-hg@31
    65
		return k;
franta-hg@31
    66
	}
franta-hg@31
    67
franta-hg@31
    68
	private static String načtiDalší(String[] parametry, int index)
franta-hg@31
    69
		throws CLIParserException {
franta-hg@31
    70
		if (index < parametry.length) {
franta-hg@31
    71
			return parametry[index];
franta-hg@31
    72
		} else {
franta-hg@31
    73
			throw new CLIParserException("Expecting value for option: "
franta-hg@31
    74
				+ parametry[index - 1]);
franta-hg@31
    75
		}
franta-hg@31
    76
	}
franta-hg@31
    77
franta-hg@31
    78
	private static boolean načtiDalšíBoolean(String[] parametry, int index)
franta-hg@31
    79
		throws CLIParserException {
franta-hg@31
    80
		String s = načtiDalší(parametry, index);
franta-hg@31
    81
		switch (s) {
franta-hg@31
    82
			case "true":
franta-hg@31
    83
			case "ano":
franta-hg@31
    84
				return true;
franta-hg@31
    85
			case "false":
franta-hg@31
    86
			case "ne":
franta-hg@31
    87
				return false;
franta-hg@31
    88
			default:
franta-hg@31
    89
				throw new CLIParserException("Neplatná logická hodnota: " + s);
franta-hg@31
    90
		}
franta-hg@31
    91
	}
franta-hg@31
    92
franta-hg@31
    93
	private static enum Token {
franta-hg@31
    94
franta-hg@31
    95
		SOUBOR("--soubor", "--file") {
franta-hg@31
    96
			@Override
franta-hg@31
    97
			public int parsuj(String[] parametry, int index, Konfigurace k)
franta-hg@31
    98
				throws CLIParserException {
franta-hg@31
    99
				int originalIndex = index;
franta-hg@31
   100
				k.setSoubor(new File(načtiDalší(parametry, ++index)));
franta-hg@31
   101
				return index - originalIndex;
franta-hg@31
   102
			}
franta-hg@31
   103
		},
franta-hg@31
   104
		POVINNÉ_ZAMYKÁNÍ("--povinné-zamykání", "--mandatory-locking") {
franta-hg@31
   105
			@Override
franta-hg@31
   106
			public int parsuj(String[] parametry, int index, Konfigurace k)
franta-hg@31
   107
				throws CLIParserException {
franta-hg@31
   108
				int originalIndex = index;
franta-hg@31
   109
				k.setPovinnéZamykání(načtiDalšíBoolean(parametry, ++index));
franta-hg@31
   110
				return index - originalIndex;
franta-hg@31
   111
			}
franta-hg@31
   112
		},
franta-hg@31
   113
		DEFINICE_ATRIBUTU("--definice-atributu", "--attribute-definition") {
franta-hg@31
   114
			@Override
franta-hg@31
   115
			public int parsuj(String[] parametry, int index, Konfigurace k)
franta-hg@31
   116
				throws CLIParserException {
franta-hg@31
   117
				int originalIndex = index;
franta-hg@31
   118
				String název = načtiDalší(parametry, ++index);
franta-hg@31
   119
				String popis = načtiDalší(parametry, ++index);
franta-hg@31
   120
				k.addAtribut(new DefiniceAtributu(název, popis));
franta-hg@31
   121
				return index - originalIndex;
franta-hg@31
   122
			}
franta-hg@31
   123
		},
franta-hg@31
   124
		HODNOTA_ATRIBUTU("--hodnota", "--value") {
franta-hg@31
   125
			@Override
franta-hg@31
   126
			public int parsuj(String[] parametry, int index, Konfigurace k)
franta-hg@31
   127
				throws CLIParserException {
franta-hg@31
   128
				int originalIndex = index;
franta-hg@31
   129
				String hodnota = načtiDalší(parametry, ++index);
franta-hg@31
   130
				String popis = načtiDalší(parametry, ++index);
franta-hg@31
   131
franta-hg@31
   132
				if (k.getAtributy().isEmpty())
franta-hg@31
   133
					throw new CLIParserException(
franta-hg@31
   134
						překlady.getString("chyba.cli.chybíDefiniceAtributu"));
franta-hg@31
   135
franta-hg@31
   136
				k.getAtributy()
franta-hg@31
   137
					.get(k.getAtributy().size() - 1)
franta-hg@31
   138
					.addHodnota(new DefiniceHodnoty(hodnota, popis));
franta-hg@31
   139
franta-hg@31
   140
				return index - originalIndex;
franta-hg@31
   141
			}
franta-hg@31
   142
		};
franta-hg@31
   143
franta-hg@31
   144
		private final Collection<String> parametry;
franta-hg@31
   145
franta-hg@31
   146
		private Token(String... parametry) {
franta-hg@31
   147
			this.parametry = Arrays.asList(parametry);
franta-hg@31
   148
		}
franta-hg@31
   149
franta-hg@31
   150
		/**
franta-hg@31
   151
		 * @param parametr e.g. „--input-file“
franta-hg@31
   152
		 * @return whether option is this token
franta-hg@31
   153
		 */
franta-hg@31
   154
		public boolean odpovídá(String parametr) {
franta-hg@31
   155
			return parametry.contains(parametr);
franta-hg@31
   156
		}
franta-hg@31
   157
franta-hg@31
   158
		/**
franta-hg@31
   159
		 * Parse String arguments and fill values into the options object.
franta-hg@31
   160
		 *
franta-hg@31
   161
		 * @param parametry CLI arguments
franta-hg@31
   162
		 * @param index index of the option matched by this token, like
franta-hg@31
   163
		 * „--input-file“
franta-hg@31
   164
		 * @param k object to be filled
franta-hg@31
   165
		 * @return number of parsed arguments – if option has no arguments (just
franta-hg@31
   166
		 * boolean flag), return 0, otherwise return positive integer: number of
franta-hg@31
   167
		 * eaten arguments.
franta-hg@31
   168
		 * @throws CLIParserException
franta-hg@31
   169
		 */
franta-hg@31
   170
		public abstract int parsuj(String[] parametry, int index, Konfigurace k)
franta-hg@31
   171
			throws CLIParserException;
franta-hg@31
   172
	}
franta-hg@31
   173
}