diff -r e417b37e6c08 -r f3b4caf1d05d java/copy-image-resizer/src/cz/frantovo/copyImageResizer/cli/CLIParser.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/java/copy-image-resizer/src/cz/frantovo/copyImageResizer/cli/CLIParser.java Sun Nov 16 21:59:13 2014 +0100 @@ -0,0 +1,139 @@ +/** + * copy-image-resizer + * Copyright © 2014 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, or + * (at your option) any later version. + * + * 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.copyImageResizer.cli; + +import java.io.File; +import java.util.Arrays; +import java.util.Collection; + +/** + * + * @author Ing. František Kučera (frantovo.cz) + */ +public class CLIParser { + + public CLIOptions parseOptions(String[] args) throws CLIParserException { + CLIOptions options = new CLIOptions(); + + for (int i = 0; i < args.length; i++) { + String arg = args[i]; + + boolean matches = false; + + for (Token t : Token.values()) { + if (t.matches(arg)) { + int parsedArgs = t.parse(args, i, options); + i = i + parsedArgs; + matches = true; + } + } + + if (!matches) { + throw new CLIParserException("Unknown option: " + arg); + } + } + + return options; + } + + private static String fetchNext(String[] args, int index) throws CLIParserException { + if (index < args.length) { + return args[index]; + } else { + throw new CLIParserException("Expecting value for option: " + args[index - 1]); + } + } + + private static enum Token { + + INPUT_DIR("--input-dir") { // bash-completion: option + @Override + public int parse(String[] args, int index, CLIOptions options) throws CLIParserException { + int originalIndex = index; + String name = fetchNext(args, ++index); + options.setInput(new File(name)); + return index - originalIndex; + } + }, + OUTPUT_DIR("--output-dir") { // bash-completion: option + @Override + public int parse(String[] args, int index, CLIOptions options) throws CLIParserException { + int originalIndex = index; + String name = fetchNext(args, ++index); + options.setOutput(new File(name)); + return index - originalIndex; + } + }, + SIZE("--size") { // bash-completion: option + @Override + public int parse(String[] args, int index, CLIOptions options) throws CLIParserException { + int originalIndex = index; + int width = parseInt(fetchNext(args, ++index)); + int height = parseInt(fetchNext(args, ++index)); + String directory = width + "x" + height; + options.addSize(new CLIOptions.SizeSpecification(width, height, directory)); + return index - originalIndex; + } + }, + SIZE_NAMED("--size-named") { // bash-completion: option + @Override + public int parse(String[] args, int index, CLIOptions options) throws CLIParserException { + int originalIndex = index; + int width = parseInt(fetchNext(args, ++index)); + int height = parseInt(fetchNext(args, ++index)); + String directory = fetchNext(args, ++index); + options.addSize(new CLIOptions.SizeSpecification(width, height, directory)); + return index - originalIndex; + } + }; + + private final Collection options; + + private Token(String... options) { + this.options = Arrays.asList(options); + } + + /** + * @param option e.g. „--input-file“ + * @return whether option is this token + */ + public boolean matches(String option) { + return options.contains(option); + } + + private static int parseInt(String number) throws CLIParserException { + try { + return Integer.parseInt(number); + } catch (Exception e) { + throw new CLIParserException("Unable to parse integer: " + number, e); + } + } + + /** + * Parse String arguments and fill values into the options object. + * + * @param args CLI arguments + * @param index index of the option matched by this token, like „--input-file“ + * @param options 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 parse(String[] args, int index, CLIOptions options) throws CLIParserException; + } +}