CLIOptions, CLIParser – basics
authorFrantišek Kučera <franta-hg@frantovo.cz>
Thu, 03 Jul 2014 00:18:35 +0200
changeset 543d5cc308e268
parent 53 6bcb20e856fe
child 55 c703fb7f088f
CLIOptions, CLIParser – basics
analýza/alt2xml.txt
java/alt2xml-cli/src/cz/frantovo/alt2xml/cli/CLIOptions.java
java/alt2xml-cli/src/cz/frantovo/alt2xml/cli/CLIParser.java
java/alt2xml-cli/src/cz/frantovo/alt2xml/cli/CLIParserException.java
java/alt2xml-cli/src/cz/frantovo/alt2xml/cli/InvalidOptionsException.java
scripts/alt2xml.sh
     1.1 --- a/analýza/alt2xml.txt	Tue Jun 17 18:19:01 2014 +0200
     1.2 +++ b/analýza/alt2xml.txt	Thu Jul 03 00:18:35 2014 +0200
     1.3 @@ -51,6 +51,9 @@
     1.4  	TXT:
     1.5  		co řádek, to element
     1.6  		číslování řádků (atribut)
     1.7 +	ESC:
     1.8 +		převod escapovacích sekvencí na XHTML
     1.9 +		barvy, tučné písmo
    1.10  	ASN.1:
    1.11  		DER, BER…
    1.12  	YAML:
    1.13 @@ -66,6 +69,13 @@
    1.14  		volitelně počítat hashe
    1.15  		zpracovat celý podstrom nebo volitelně jen soubory/adresáře vyhovující regulárnímu výrazu
    1.16  		vhodné pro konfiguraci programů
    1.17 +	XML.dir
    1.18 +		taky souborový systém
    1.19 +		ale ne obecný – specifická struktura
    1.20 +		umožňuje popsat prakticky libovolné XML
    1.21 +		adresář = element
    1.22 +		soubor = atribut nebo textový uzel
    1.23 +		číslování souborů/adresářů → pořadí uzlů
    1.24  	Jednoduché XML
    1.25  		definované odsazením
    1.26  
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/java/alt2xml-cli/src/cz/frantovo/alt2xml/cli/CLIOptions.java	Thu Jul 03 00:18:35 2014 +0200
     2.3 @@ -0,0 +1,94 @@
     2.4 +/**
     2.5 + * Alt2XML
     2.6 + * Copyright © 2014 František Kučera (frantovo.cz)
     2.7 + *
     2.8 + * This program is free software: you can redistribute it and/or modify
     2.9 + * it under the terms of the GNU General Public License as published by
    2.10 + * the Free Software Foundation, either version 3 of the License, or
    2.11 + * (at your option) any later version.
    2.12 + *
    2.13 + * This program is distributed in the hope that it will be useful,
    2.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    2.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    2.16 + * GNU General Public License for more details.
    2.17 + *
    2.18 + * You should have received a copy of the GNU General Public License
    2.19 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
    2.20 + */
    2.21 +package cz.frantovo.alt2xml.cli;
    2.22 +
    2.23 +import java.io.File;
    2.24 +import java.io.InputStream;
    2.25 +import java.io.OutputStream;
    2.26 +import java.util.ArrayList;
    2.27 +import java.util.List;
    2.28 +import java.util.Properties;
    2.29 +
    2.30 +/**
    2.31 + * Holds options from command line, validates them, combines with configuration and provides derived
    2.32 + * objects.
    2.33 + *
    2.34 + * @author Ing. František Kučera (frantovo.cz)
    2.35 + */
    2.36 +public class CLIOptions {
    2.37 +
    2.38 +	private File inputFile;
    2.39 +	private InputStream inputStream;
    2.40 +	private String inputUrl;
    2.41 +
    2.42 +	private String systemId;
    2.43 +	private final Properties readerProperties = new Properties();
    2.44 +
    2.45 +	private OutputStream outputStream;
    2.46 +	private String action;
    2.47 +	private final Properties actionProperties = new Properties();
    2.48 +	private final List<String> actionData = new ArrayList<>();
    2.49 +
    2.50 +	public void validate() throws InvalidOptionsException {
    2.51 +		InvalidOptionsException e = new InvalidOptionsException();
    2.52 +
    2.53 +		/**
    2.54 +		 * TODO: validace
    2.55 +		 */
    2.56 +		if (e.hasProblems()) {
    2.57 +			throw e;
    2.58 +		}
    2.59 +	}
    2.60 +
    2.61 +	public void setInputFile(File inputFile) {
    2.62 +		this.inputFile = inputFile;
    2.63 +	}
    2.64 +
    2.65 +	public void setInputStream(InputStream inputStream) {
    2.66 +		this.inputStream = inputStream;
    2.67 +	}
    2.68 +
    2.69 +	public void setInputUrl(String inputUrl) {
    2.70 +		this.inputUrl = inputUrl;
    2.71 +	}
    2.72 +
    2.73 +	public void setSystemId(String systemId) {
    2.74 +		this.systemId = systemId;
    2.75 +	}
    2.76 + 
    2.77 +	public void setOutputStream(OutputStream outputStream) {
    2.78 +		this.outputStream = outputStream;
    2.79 +	}
    2.80 +	
    2.81 +	public void setAction(String action) {
    2.82 +		this.action = action;
    2.83 +	}
    2.84 +
    2.85 +	public void addReaderProperty(String name, String value) {
    2.86 +		readerProperties.put(name, value);
    2.87 +	}
    2.88 +
    2.89 +	public void addActionProperty(String name, String value) {
    2.90 +		actionProperties.put(name, value);
    2.91 +	}
    2.92 +
    2.93 +	public void addActionData(String value) {
    2.94 +		actionData.add(value);
    2.95 +	}
    2.96 +
    2.97 +}
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/java/alt2xml-cli/src/cz/frantovo/alt2xml/cli/CLIParser.java	Thu Jul 03 00:18:35 2014 +0200
     3.3 @@ -0,0 +1,159 @@
     3.4 +/**
     3.5 + * Alt2XML
     3.6 + * Copyright © 2014 František Kučera (frantovo.cz)
     3.7 + *
     3.8 + * This program is free software: you can redistribute it and/or modify
     3.9 + * it under the terms of the GNU General Public License as published by
    3.10 + * the Free Software Foundation, either version 3 of the License, or
    3.11 + * (at your option) any later version.
    3.12 + *
    3.13 + * This program is distributed in the hope that it will be useful,
    3.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    3.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    3.16 + * GNU General Public License for more details.
    3.17 + *
    3.18 + * You should have received a copy of the GNU General Public License
    3.19 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
    3.20 + */
    3.21 +package cz.frantovo.alt2xml.cli;
    3.22 +
    3.23 +import java.io.File;
    3.24 +import java.io.InputStream;
    3.25 +
    3.26 +/**
    3.27 + * Converts command line arguments from String array to object.
    3.28 + * Checks basic constraints (if only supported options are used and if they have correct number of
    3.29 + * parameters)
    3.30 + *
    3.31 + * @author Ing. František Kučera (frantovo.cz)
    3.32 + */
    3.33 +public class CLIParser {
    3.34 +
    3.35 +	public CLIOptions parseOptions(String[] args, InputStream in) throws CLIParserException {
    3.36 +		CLIOptions options = new CLIOptions();
    3.37 +
    3.38 +		for (int i = 0; i < args.length; i++) {
    3.39 +			String arg = args[i];
    3.40 +
    3.41 +			for (Token t : Token.values()) {
    3.42 +				if (t.matches(arg)) {
    3.43 +					t.parse(args, i, options);
    3.44 +				}
    3.45 +			}
    3.46 +
    3.47 +			throw new CLIParserException("Unknown option: " + arg);
    3.48 +		}
    3.49 +
    3.50 +		// Default output: STDOUT
    3.51 +		options.setOutputStream(System.out);
    3.52 +
    3.53 +		return options;
    3.54 +	}
    3.55 +
    3.56 +	private static String fetchNext(String[] args, int index) throws CLIParserException {
    3.57 +		if (index < args.length) {
    3.58 +			return args[index];
    3.59 +		} else {
    3.60 +			throw new CLIParserException("Expecting value for option: " + args[index - 1]);
    3.61 +		}
    3.62 +	}
    3.63 +
    3.64 +	private static enum Token {
    3.65 +
    3.66 +		INPUT_FILE("--input-file") {
    3.67 +					@Override
    3.68 +					public int parse(String[] args, int index, CLIOptions options) throws CLIParserException {
    3.69 +						int originalIndex = index;
    3.70 +						options.setInputFile(new File(fetchNext(args, ++index)));
    3.71 +						return index - originalIndex;
    3.72 +					}
    3.73 +				},
    3.74 +		INPUT_STDIN("--input-stdin") {
    3.75 +					@Override
    3.76 +					public int parse(String[] args, int index, CLIOptions options) throws CLIParserException {
    3.77 +						options.setInputStream(System.in);
    3.78 +						return 0;
    3.79 +					}
    3.80 +				},
    3.81 +		INPUT_URL("--input-url") {
    3.82 +					@Override
    3.83 +					public int parse(String[] args, int index, CLIOptions options) throws CLIParserException {
    3.84 +						int originalIndex = index;
    3.85 +						options.setInputUrl(fetchNext(args, ++index));
    3.86 +						return index - originalIndex;
    3.87 +					}
    3.88 +				},
    3.89 +		SYSTEM_ID("--system-id") {
    3.90 +					@Override
    3.91 +					public int parse(String[] args, int index, CLIOptions options) throws CLIParserException {
    3.92 +						int originalIndex = index;
    3.93 +						options.setSystemId(fetchNext(args, ++index));
    3.94 +						return index - originalIndex;
    3.95 +					}
    3.96 +				},
    3.97 +		READER_PROPERTY("--reader-property") {
    3.98 +					@Override
    3.99 +					public int parse(String[] args, int index, CLIOptions options) throws CLIParserException {
   3.100 +						int originalIndex = index;
   3.101 +						String name = fetchNext(args, ++index);
   3.102 +						String value = fetchNext(args, ++index);
   3.103 +						options.addReaderProperty(name, value);
   3.104 +						return index - originalIndex;
   3.105 +					}
   3.106 +				},
   3.107 +		ACTION("--action") {
   3.108 +					@Override
   3.109 +					public int parse(String[] args, int index, CLIOptions options) throws CLIParserException {
   3.110 +						int originalIndex = index;
   3.111 +						options.setAction(fetchNext(args, ++index));
   3.112 +						return index - originalIndex;
   3.113 +					}
   3.114 +				},
   3.115 +		ACTION_PROPERTY("--action-property") {
   3.116 +					@Override
   3.117 +					public int parse(String[] args, int index, CLIOptions options) throws CLIParserException {
   3.118 +						int originalIndex = index;
   3.119 +						String name = fetchNext(args, ++index);
   3.120 +						String value = fetchNext(args, ++index);
   3.121 +						options.addActionProperty(name, value);
   3.122 +						return index - originalIndex;
   3.123 +					}
   3.124 +				},
   3.125 +		ACTION_DATA("--") {
   3.126 +					@Override
   3.127 +					public int parse(String[] args, int index, CLIOptions options) throws CLIParserException {
   3.128 +						int originalIndex = index;
   3.129 +						for (index++; index < args.length; index++) {
   3.130 +							options.addActionData(args[index]);
   3.131 +						}
   3.132 +						return index - originalIndex;
   3.133 +					}
   3.134 +				};
   3.135 +
   3.136 +		private final String option;
   3.137 +
   3.138 +		private Token(String option) {
   3.139 +			this.option = option;
   3.140 +		}
   3.141 +
   3.142 +		/**
   3.143 +		 * @param option e.g. „--input-file“
   3.144 +		 * @return whether option is this token
   3.145 +		 */
   3.146 +		public boolean matches(String option) {
   3.147 +			return this.option.equals(option);
   3.148 +		}
   3.149 +
   3.150 +		/**
   3.151 +		 * Parse String arguments and fill values into the options object.
   3.152 +		 *
   3.153 +		 * @param args CLI arguments
   3.154 +		 * @param index index of the option matched by this token, like „--input-file“
   3.155 +		 * @param options object to be filled
   3.156 +		 * @return number of parsed arguments – if option has no arguments (just boolean flag),
   3.157 +		 * return 0, otherwise return positive integer: number of eaten arguments.
   3.158 +		 * @throws CLIParserException
   3.159 +		 */
   3.160 +		public abstract int parse(String[] args, int index, CLIOptions options) throws CLIParserException;
   3.161 +	}
   3.162 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/java/alt2xml-cli/src/cz/frantovo/alt2xml/cli/CLIParserException.java	Thu Jul 03 00:18:35 2014 +0200
     4.3 @@ -0,0 +1,40 @@
     4.4 +/**
     4.5 + * Alt2XML
     4.6 + * Copyright © 2014 František Kučera (frantovo.cz)
     4.7 + *
     4.8 + * This program is free software: you can redistribute it and/or modify
     4.9 + * it under the terms of the GNU General Public License as published by
    4.10 + * the Free Software Foundation, either version 3 of the License, or
    4.11 + * (at your option) any later version.
    4.12 + *
    4.13 + * This program is distributed in the hope that it will be useful,
    4.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    4.16 + * GNU General Public License for more details.
    4.17 + *
    4.18 + * You should have received a copy of the GNU General Public License
    4.19 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
    4.20 + */
    4.21 +package cz.frantovo.alt2xml.cli;
    4.22 +
    4.23 +/**
    4.24 + *
    4.25 + * @author Ing. František Kučera (frantovo.cz)
    4.26 + */
    4.27 +public class CLIParserException extends Exception {
    4.28 +
    4.29 +	public CLIParserException() {
    4.30 +	}
    4.31 +
    4.32 +	public CLIParserException(String message) {
    4.33 +		super(message);
    4.34 +	}
    4.35 +
    4.36 +	public CLIParserException(Throwable cause) {
    4.37 +		super(cause);
    4.38 +	}
    4.39 +
    4.40 +	public CLIParserException(String message, Throwable cause) {
    4.41 +		super(message, cause);
    4.42 +	}
    4.43 +}
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/java/alt2xml-cli/src/cz/frantovo/alt2xml/cli/InvalidOptionsException.java	Thu Jul 03 00:18:35 2014 +0200
     5.3 @@ -0,0 +1,66 @@
     5.4 +/**
     5.5 + * Alt2XML
     5.6 + * Copyright © 2014 František Kučera (frantovo.cz)
     5.7 + *
     5.8 + * This program is free software: you can redistribute it and/or modify
     5.9 + * it under the terms of the GNU General Public License as published by
    5.10 + * the Free Software Foundation, either version 3 of the License, or
    5.11 + * (at your option) any later version.
    5.12 + *
    5.13 + * This program is distributed in the hope that it will be useful,
    5.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    5.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    5.16 + * GNU General Public License for more details.
    5.17 + *
    5.18 + * You should have received a copy of the GNU General Public License
    5.19 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
    5.20 + */
    5.21 +package cz.frantovo.alt2xml.cli;
    5.22 +
    5.23 +import java.util.ArrayList;
    5.24 +import java.util.Collection;
    5.25 +import java.util.Collections;
    5.26 +
    5.27 +/**
    5.28 + *
    5.29 + * @author Ing. František Kučera (frantovo.cz)
    5.30 + */
    5.31 +public class InvalidOptionsException extends Exception {
    5.32 +
    5.33 +	private final Collection<OptionProblem> problems = new ArrayList<>();
    5.34 +
    5.35 +	public Collection<OptionProblem> getProblems() {
    5.36 +		return Collections.unmodifiableCollection(problems);
    5.37 +	}
    5.38 +
    5.39 +	public void addProblem(OptionProblem p) {
    5.40 +		problems.add(p);
    5.41 +	}
    5.42 +
    5.43 +	public boolean hasProblems() {
    5.44 +		return !problems.isEmpty();
    5.45 +	}
    5.46 +
    5.47 +	public static class OptionProblem {
    5.48 +
    5.49 +		private String description;
    5.50 +		private Throwable exception;
    5.51 +
    5.52 +		public OptionProblem(String description) {
    5.53 +			this.description = description;
    5.54 +		}
    5.55 +
    5.56 +		public OptionProblem(String description, Throwable exception) {
    5.57 +			this.description = description;
    5.58 +			this.exception = exception;
    5.59 +		}
    5.60 +
    5.61 +		public String getDescription() {
    5.62 +			return description;
    5.63 +		}
    5.64 +
    5.65 +		public Throwable getException() {
    5.66 +			return exception;
    5.67 +		}
    5.68 +	}
    5.69 +}
     6.1 --- a/scripts/alt2xml.sh	Tue Jun 17 18:19:01 2014 +0200
     6.2 +++ b/scripts/alt2xml.sh	Thu Jul 03 00:18:35 2014 +0200
     6.3 @@ -25,7 +25,7 @@
     6.4  	CLASS_PATH="$CLASS_PATH:$e";
     6.5  done
     6.6  
     6.7 -MAIN_CLASS="cz.frantovo.alt2xml.cli.CLI";
     6.8 +MAIN_CLASS="cz.frantovo.alt2xml.cli.CLIStarter";
     6.9  
    6.10  SAX_PARSER_FACTORY_ALT="cz.frantovo.alt2xml.ParserFactory";                             # our alternative ParserFactory as default
    6.11  SAX_PARSER_FACTORY_XML="com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl";  # former default factory as fallback