diff -r 7e08730da258 -r 4a1864c3e867 java/sql-dk/src/main/java/info/globalcode/sql/dk/CLIParser.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/java/sql-dk/src/main/java/info/globalcode/sql/dk/CLIParser.java Mon Mar 04 20:15:24 2019 +0100 @@ -0,0 +1,216 @@ +/** + * SQL-DK + * Copyright © 2013 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 info.globalcode.sql.dk; + +import static info.globalcode.sql.dk.Functions.readString; +import info.globalcode.sql.dk.InfoLister.InfoType; +import info.globalcode.sql.dk.configuration.Property; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 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 { + + public static final String TYPE_NAME_SEPARATOR = ":"; + + public CLIOptions parseOptions(String[] args, InputStream in) throws CLIParserException { + CLIOptions options = new CLIOptions(); + + List numberedTypes = new ArrayList<>(); + Map namedTypes = new HashMap<>(); + + for (int i = 0; i < args.length; i++) { + String arg = args[i]; + switch (arg) { + case Tokens.TYPES: + String typesString = fetchNext(args, ++i); + + for (String oneType : typesString.split(",")) { + int sepatratorIndex = oneType.indexOf(TYPE_NAME_SEPARATOR); + if (sepatratorIndex == -1) { + numberedTypes.add(getType(oneType.toUpperCase())); + } else { + String namePart = oneType.substring(0, sepatratorIndex).trim(); + String typePart = oneType.substring(sepatratorIndex + TYPE_NAME_SEPARATOR.length(), oneType.length()); + namedTypes.put(namePart, getType(typePart.toUpperCase())); + } + } + break; + case Tokens.NAME_PREFIX: + options.setNamePrefix(fetchNext(args, ++i)); + break; + case Tokens.NAME_SUFFIX: + options.setNameSuffix(fetchNext(args, ++i)); + break; + case Tokens.DB: + options.setDatabaseName(fetchNext(args, ++i)); + break; + case Tokens.SQL: + options.setSql(fetchNext(args, ++i)); + break; + case Tokens.SQL_IN: + try { + options.setSql(readString(in)); + } catch (IOException e) { + throw new CLIParserException("Unable to read SQL from the input stream", e); + } + break; + case Tokens.BATCH: + options.setBatch(true); + break; + case Tokens.DATA: // --data is the last option + for (i++; i < args.length; i++) { + arg = args[i]; + Parameter parameter; + if (numberedTypes.isEmpty()) { + parameter = new Parameter(arg, null); + } else { + int paramIndex = options.getNumberedParameters().size(); + SQLType paramType; + try { + paramType = numberedTypes.get(paramIndex); + } catch (IndexOutOfBoundsException e) { + throw new CLIParserException("Missing type for parameter #" + paramIndex, e); + } catch (NullPointerException e) { + throw new CLIParserException("Invalid type definition for parameter #" + paramIndex, e); + } + parameter = new Parameter(arg, paramType); + } + options.addNumberedParameter(parameter); + } + break; + case Tokens.DATA_NAMED: + for (i++; i < args.length; i++) { + String paramName = args[i]; + String paramValue = fetchNext(args, ++i); + options.addNamedParameter(new NamedParameter(paramName, paramValue, namedTypes.get(paramName))); + } + break; + case Tokens.FORMATTER: + options.setFormatterName(fetchNext(args, ++i)); + break; + case Tokens.DB_PROPERTY: + options.addDatabaseProperty(new Property(fetchNext(args, ++i), fetchNext(args, ++i))); + break; + case Tokens.FORMATTER_PROPERTY: + options.addFormatterProperty(new Property(fetchNext(args, ++i), fetchNext(args, ++i))); + break; + case Tokens.INFO_HELP: + options.addShowInfo(InfoType.HELP); + break; + case Tokens.INFO_FORMATTERS: + options.addShowInfo(InfoType.FORMATTERS); + break; + case Tokens.INFO_FORMATTER_PROPERTIES: + options.addShowInfo(InfoType.FORMATTER_PROPERTIES); + options.addFormatterNameToListProperties(fetchNext(args, ++i)); + break; + case Tokens.INFO_LICENSE: + options.addShowInfo(InfoType.LICENSE); + break; + case Tokens.INFO_JAVA_PROPERTIES: + options.addShowInfo(InfoType.JAVA_PROPERTIES); + break; + case Tokens.INFO_ENVIRONMENT_VARIABLES: + options.addShowInfo(InfoType.ENVIRONMENT_VARIABLES); + break; + case Tokens.INFO_TYPES: + options.addShowInfo(InfoType.TYPES); + break; + case Tokens.INFO_VERSION: + options.addShowInfo(InfoType.VERSION); + break; + case Tokens.INFO_JDBC_DRIVERS: + options.addShowInfo(InfoType.JDBC_DRIVERS); + break; + case Tokens.INFO_JDBC_PROPERTIES: + options.addShowInfo(InfoType.JDBC_PROPERTIES); + options.addDatabaseNameToListProperties(fetchNext(args, ++i)); + break; + case Tokens.INFO_DATABASES: + options.addShowInfo(InfoType.DATABASES); + break; + case Tokens.INFO_CONNECTION: + options.addShowInfo(InfoType.CONNECTION); + options.addDatabaseNameToTest(fetchNext(args, ++i)); + break; + default: + throw new CLIParserException("Unknown option: " + arg); + } + } + return options; + } + + private 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]); + } + } + + public static class Tokens { + + // bash-completion:options: + public static final String DB = "--db"; // bash-completion:option // help: database name + public static final String DB_PROPERTY = "--db-property"; // bash-completion:option // help: name and value + public static final String SQL = "--sql"; // bash-completion:option // help: SQL query/command + public static final String SQL_IN = "--sql-in"; // bash-completion:option // help: SQL query/command + public static final String BATCH = "--batch"; // bash-completion:option // help: batch mode (no argument) + public static final String DATA = "--data"; // bash-completion:option // help: list of ordinal parameters + public static final String DATA_NAMED = "--data-named"; // bash-completion:option // help: list of named parameters + public static final String NAME_PREFIX = "--name-prefix"; // bash-completion:option // help: parameter name prefix – regular expression + public static final String NAME_SUFFIX = "--name-suffix"; // bash-completion:option // help: parameter name suffix – regular expression + public static final String TYPES = "--types"; // bash-completion:option // help: comma separated list of parameter types + public static final String FORMATTER = "--formatter"; // bash-completion:option // help: name of the output formatter + public static final String FORMATTER_PROPERTY = "--formatter-property"; // bash-completion:option // help: name and value + public static final String INFO_HELP = "--help"; // bash-completion:option // help: print this help + public static final String INFO_VERSION = "--version"; // bash-completion:option // help: print version info + public static final String INFO_LICENSE = "--license"; // bash-completion:option // help: print license + public static final String INFO_JAVA_PROPERTIES = "--list-java-properties"; // bash-completion:option // help: list of Java system properties + public static final String INFO_ENVIRONMENT_VARIABLES = "--list-environment-variables"; // bash-completion:option // help: list of environment variables + public static final String INFO_FORMATTERS = "--list-formatters"; // bash-completion:option // help: print list of available formatters + public static final String INFO_FORMATTER_PROPERTIES = "--list-formatter-properties"; // bash-completion:option // help: print list of available properties for given formatter + public static final String INFO_TYPES = "--list-types"; // bash-completion:option // help: print list of available data types + public static final String INFO_JDBC_DRIVERS = "--list-jdbc-drivers"; // bash-completion:option // help: list of available JDBC drivers + public static final String INFO_JDBC_PROPERTIES = "--list-jdbc-properties"; // bash-completion:option // help: list of available JDBC properties for given database + public static final String INFO_DATABASES = "--list-databases"; // bash-completion:option // help: print list of configured databases + public static final String INFO_CONNECTION = "--test-connection"; // bash-completion:option // help: test connection to particular database + + private Tokens() { + } + } + + private SQLType getType(String typeString) throws CLIParserException { + try { + return SQLType.valueOf(typeString.trim()); + } catch (IllegalArgumentException e) { + throw new CLIParserException("Unsupported type: " + typeString, e); + } + } +}