franta-hg@3: /**
franta-hg@3: * copy-image-resizer
franta-hg@3: * Copyright © 2014 František Kučera (frantovo.cz)
franta-hg@3: *
franta-hg@3: * This program is free software: you can redistribute it and/or modify
franta-hg@3: * it under the terms of the GNU General Public License as published by
franta-hg@3: * the Free Software Foundation, either version 3 of the License, or
franta-hg@3: * (at your option) any later version.
franta-hg@3: *
franta-hg@3: * This program is distributed in the hope that it will be useful,
franta-hg@3: * but WITHOUT ANY WARRANTY; without even the implied warranty of
franta-hg@3: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
franta-hg@3: * GNU General Public License for more details.
franta-hg@3: *
franta-hg@3: * You should have received a copy of the GNU General Public License
franta-hg@3: * along with this program. If not, see .
franta-hg@3: */
franta-hg@4: package cz.frantovo.copyImageResizer.cli;
franta-hg@3:
franta-hg@5: import cz.frantovo.copyImageResizer.RecursiveOptions;
franta-hg@3: import java.io.File;
franta-hg@3: import java.util.Arrays;
franta-hg@3: import java.util.Collection;
franta-hg@3:
franta-hg@3: /**
franta-hg@3: *
franta-hg@3: * @author Ing. František Kučera (frantovo.cz)
franta-hg@3: */
franta-hg@3: public class CLIParser {
franta-hg@3:
franta-hg@5: public RecursiveOptions parseOptions(String[] args) throws CLIParserException {
franta-hg@5: RecursiveOptions options = new RecursiveOptions();
franta-hg@3:
franta-hg@3: for (int i = 0; i < args.length; i++) {
franta-hg@3: String arg = args[i];
franta-hg@3:
franta-hg@3: boolean matches = false;
franta-hg@3:
franta-hg@3: for (Token t : Token.values()) {
franta-hg@3: if (t.matches(arg)) {
franta-hg@3: int parsedArgs = t.parse(args, i, options);
franta-hg@3: i = i + parsedArgs;
franta-hg@3: matches = true;
franta-hg@3: }
franta-hg@3: }
franta-hg@3:
franta-hg@3: if (!matches) {
franta-hg@3: throw new CLIParserException("Unknown option: " + arg);
franta-hg@3: }
franta-hg@3: }
franta-hg@3:
franta-hg@3: return options;
franta-hg@3: }
franta-hg@3:
franta-hg@3: private static String fetchNext(String[] args, int index) throws CLIParserException {
franta-hg@3: if (index < args.length) {
franta-hg@3: return args[index];
franta-hg@3: } else {
franta-hg@3: throw new CLIParserException("Expecting value for option: " + args[index - 1]);
franta-hg@3: }
franta-hg@3: }
franta-hg@3:
franta-hg@3: private static enum Token {
franta-hg@3:
franta-hg@3: INPUT_DIR("--input-dir") { // bash-completion: option
franta-hg@3: @Override
franta-hg@5: public int parse(String[] args, int index, RecursiveOptions options) throws CLIParserException {
franta-hg@3: int originalIndex = index;
franta-hg@3: String name = fetchNext(args, ++index);
franta-hg@3: options.setInput(new File(name));
franta-hg@3: return index - originalIndex;
franta-hg@3: }
franta-hg@3: },
franta-hg@3: OUTPUT_DIR("--output-dir") { // bash-completion: option
franta-hg@3: @Override
franta-hg@5: public int parse(String[] args, int index, RecursiveOptions options) throws CLIParserException {
franta-hg@3: int originalIndex = index;
franta-hg@3: String name = fetchNext(args, ++index);
franta-hg@3: options.setOutput(new File(name));
franta-hg@3: return index - originalIndex;
franta-hg@3: }
franta-hg@3: },
franta-hg@3: SIZE("--size") { // bash-completion: option
franta-hg@3: @Override
franta-hg@5: public int parse(String[] args, int index, RecursiveOptions options) throws CLIParserException {
franta-hg@3: int originalIndex = index;
franta-hg@3: int width = parseInt(fetchNext(args, ++index));
franta-hg@3: int height = parseInt(fetchNext(args, ++index));
franta-hg@3: String directory = width + "x" + height;
franta-hg@5: options.addSize(new RecursiveOptions.SizeSpecification(width, height, directory));
franta-hg@3: return index - originalIndex;
franta-hg@3: }
franta-hg@3: },
franta-hg@3: SIZE_NAMED("--size-named") { // bash-completion: option
franta-hg@3: @Override
franta-hg@5: public int parse(String[] args, int index, RecursiveOptions options) throws CLIParserException {
franta-hg@3: int originalIndex = index;
franta-hg@3: int width = parseInt(fetchNext(args, ++index));
franta-hg@3: int height = parseInt(fetchNext(args, ++index));
franta-hg@3: String directory = fetchNext(args, ++index);
franta-hg@5: options.addSize(new RecursiveOptions.SizeSpecification(width, height, directory));
franta-hg@3: return index - originalIndex;
franta-hg@3: }
franta-hg@3: };
franta-hg@3:
franta-hg@3: private final Collection options;
franta-hg@3:
franta-hg@3: private Token(String... options) {
franta-hg@3: this.options = Arrays.asList(options);
franta-hg@3: }
franta-hg@3:
franta-hg@3: /**
franta-hg@3: * @param option e.g. „--input-file“
franta-hg@3: * @return whether option is this token
franta-hg@3: */
franta-hg@3: public boolean matches(String option) {
franta-hg@3: return options.contains(option);
franta-hg@3: }
franta-hg@3:
franta-hg@3: private static int parseInt(String number) throws CLIParserException {
franta-hg@3: try {
franta-hg@3: return Integer.parseInt(number);
franta-hg@3: } catch (Exception e) {
franta-hg@3: throw new CLIParserException("Unable to parse integer: " + number, e);
franta-hg@3: }
franta-hg@3: }
franta-hg@3:
franta-hg@3: /**
franta-hg@3: * Parse String arguments and fill values into the options object.
franta-hg@3: *
franta-hg@3: * @param args CLI arguments
franta-hg@3: * @param index index of the option matched by this token, like „--input-file“
franta-hg@3: * @param options object to be filled
franta-hg@3: * @return number of parsed arguments – if option has no arguments (just boolean flag),
franta-hg@3: * return 0, otherwise return positive integer: number of eaten arguments.
franta-hg@3: * @throws CLIParserException
franta-hg@3: */
franta-hg@5: public abstract int parse(String[] args, int index, RecursiveOptions options) throws CLIParserException;
franta-hg@3: }
franta-hg@3: }