# HG changeset patch
# User František Kučera <franta-hg@frantovo.cz>
# Date 1404339515 -7200
# Node ID 3d5cc308e268fbcced2c7ac5c7b0ed873793d0e9
# Parent  6bcb20e856fe8cb91f14bb8af8a45265619b2050
CLIOptions, CLIParser – basics

diff -r 6bcb20e856fe -r 3d5cc308e268 analýza/alt2xml.txt
--- a/analýza/alt2xml.txt	Tue Jun 17 18:19:01 2014 +0200
+++ b/analýza/alt2xml.txt	Thu Jul 03 00:18:35 2014 +0200
@@ -51,6 +51,9 @@
 	TXT:
 		co řádek, to element
 		číslování řádků (atribut)
+	ESC:
+		převod escapovacích sekvencí na XHTML
+		barvy, tučné písmo
 	ASN.1:
 		DER, BER…
 	YAML:
@@ -66,6 +69,13 @@
 		volitelně počítat hashe
 		zpracovat celý podstrom nebo volitelně jen soubory/adresáře vyhovující regulárnímu výrazu
 		vhodné pro konfiguraci programů
+	XML.dir
+		taky souborový systém
+		ale ne obecný – specifická struktura
+		umožňuje popsat prakticky libovolné XML
+		adresář = element
+		soubor = atribut nebo textový uzel
+		číslování souborů/adresářů → pořadí uzlů
 	Jednoduché XML
 		definované odsazením
 
diff -r 6bcb20e856fe -r 3d5cc308e268 java/alt2xml-cli/src/cz/frantovo/alt2xml/cli/CLIOptions.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/java/alt2xml-cli/src/cz/frantovo/alt2xml/cli/CLIOptions.java	Thu Jul 03 00:18:35 2014 +0200
@@ -0,0 +1,94 @@
+/**
+ * Alt2XML
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package cz.frantovo.alt2xml.cli;
+
+import java.io.File;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * Holds options from command line, validates them, combines with configuration and provides derived
+ * objects.
+ *
+ * @author Ing. František Kučera (frantovo.cz)
+ */
+public class CLIOptions {
+
+	private File inputFile;
+	private InputStream inputStream;
+	private String inputUrl;
+
+	private String systemId;
+	private final Properties readerProperties = new Properties();
+
+	private OutputStream outputStream;
+	private String action;
+	private final Properties actionProperties = new Properties();
+	private final List<String> actionData = new ArrayList<>();
+
+	public void validate() throws InvalidOptionsException {
+		InvalidOptionsException e = new InvalidOptionsException();
+
+		/**
+		 * TODO: validace
+		 */
+		if (e.hasProblems()) {
+			throw e;
+		}
+	}
+
+	public void setInputFile(File inputFile) {
+		this.inputFile = inputFile;
+	}
+
+	public void setInputStream(InputStream inputStream) {
+		this.inputStream = inputStream;
+	}
+
+	public void setInputUrl(String inputUrl) {
+		this.inputUrl = inputUrl;
+	}
+
+	public void setSystemId(String systemId) {
+		this.systemId = systemId;
+	}
+ 
+	public void setOutputStream(OutputStream outputStream) {
+		this.outputStream = outputStream;
+	}
+	
+	public void setAction(String action) {
+		this.action = action;
+	}
+
+	public void addReaderProperty(String name, String value) {
+		readerProperties.put(name, value);
+	}
+
+	public void addActionProperty(String name, String value) {
+		actionProperties.put(name, value);
+	}
+
+	public void addActionData(String value) {
+		actionData.add(value);
+	}
+
+}
diff -r 6bcb20e856fe -r 3d5cc308e268 java/alt2xml-cli/src/cz/frantovo/alt2xml/cli/CLIParser.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/java/alt2xml-cli/src/cz/frantovo/alt2xml/cli/CLIParser.java	Thu Jul 03 00:18:35 2014 +0200
@@ -0,0 +1,159 @@
+/**
+ * Alt2XML
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package cz.frantovo.alt2xml.cli;
+
+import java.io.File;
+import java.io.InputStream;
+
+/**
+ * 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 CLIOptions parseOptions(String[] args, InputStream in) throws CLIParserException {
+		CLIOptions options = new CLIOptions();
+
+		for (int i = 0; i < args.length; i++) {
+			String arg = args[i];
+
+			for (Token t : Token.values()) {
+				if (t.matches(arg)) {
+					t.parse(args, i, options);
+				}
+			}
+
+			throw new CLIParserException("Unknown option: " + arg);
+		}
+
+		// Default output: STDOUT
+		options.setOutputStream(System.out);
+
+		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_FILE("--input-file") {
+					@Override
+					public int parse(String[] args, int index, CLIOptions options) throws CLIParserException {
+						int originalIndex = index;
+						options.setInputFile(new File(fetchNext(args, ++index)));
+						return index - originalIndex;
+					}
+				},
+		INPUT_STDIN("--input-stdin") {
+					@Override
+					public int parse(String[] args, int index, CLIOptions options) throws CLIParserException {
+						options.setInputStream(System.in);
+						return 0;
+					}
+				},
+		INPUT_URL("--input-url") {
+					@Override
+					public int parse(String[] args, int index, CLIOptions options) throws CLIParserException {
+						int originalIndex = index;
+						options.setInputUrl(fetchNext(args, ++index));
+						return index - originalIndex;
+					}
+				},
+		SYSTEM_ID("--system-id") {
+					@Override
+					public int parse(String[] args, int index, CLIOptions options) throws CLIParserException {
+						int originalIndex = index;
+						options.setSystemId(fetchNext(args, ++index));
+						return index - originalIndex;
+					}
+				},
+		READER_PROPERTY("--reader-property") {
+					@Override
+					public int parse(String[] args, int index, CLIOptions options) throws CLIParserException {
+						int originalIndex = index;
+						String name = fetchNext(args, ++index);
+						String value = fetchNext(args, ++index);
+						options.addReaderProperty(name, value);
+						return index - originalIndex;
+					}
+				},
+		ACTION("--action") {
+					@Override
+					public int parse(String[] args, int index, CLIOptions options) throws CLIParserException {
+						int originalIndex = index;
+						options.setAction(fetchNext(args, ++index));
+						return index - originalIndex;
+					}
+				},
+		ACTION_PROPERTY("--action-property") {
+					@Override
+					public int parse(String[] args, int index, CLIOptions options) throws CLIParserException {
+						int originalIndex = index;
+						String name = fetchNext(args, ++index);
+						String value = fetchNext(args, ++index);
+						options.addActionProperty(name, value);
+						return index - originalIndex;
+					}
+				},
+		ACTION_DATA("--") {
+					@Override
+					public int parse(String[] args, int index, CLIOptions options) throws CLIParserException {
+						int originalIndex = index;
+						for (index++; index < args.length; index++) {
+							options.addActionData(args[index]);
+						}
+						return index - originalIndex;
+					}
+				};
+
+		private final String option;
+
+		private Token(String option) {
+			this.option = option;
+		}
+
+		/**
+		 * @param option e.g. „--input-file“
+		 * @return whether option is this token
+		 */
+		public boolean matches(String option) {
+			return this.option.equals(option);
+		}
+
+		/**
+		 * 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;
+	}
+}
diff -r 6bcb20e856fe -r 3d5cc308e268 java/alt2xml-cli/src/cz/frantovo/alt2xml/cli/CLIParserException.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/java/alt2xml-cli/src/cz/frantovo/alt2xml/cli/CLIParserException.java	Thu Jul 03 00:18:35 2014 +0200
@@ -0,0 +1,40 @@
+/**
+ * Alt2XML
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package cz.frantovo.alt2xml.cli;
+
+/**
+ *
+ * @author Ing. František Kučera (frantovo.cz)
+ */
+public class CLIParserException extends Exception {
+
+	public CLIParserException() {
+	}
+
+	public CLIParserException(String message) {
+		super(message);
+	}
+
+	public CLIParserException(Throwable cause) {
+		super(cause);
+	}
+
+	public CLIParserException(String message, Throwable cause) {
+		super(message, cause);
+	}
+}
diff -r 6bcb20e856fe -r 3d5cc308e268 java/alt2xml-cli/src/cz/frantovo/alt2xml/cli/InvalidOptionsException.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/java/alt2xml-cli/src/cz/frantovo/alt2xml/cli/InvalidOptionsException.java	Thu Jul 03 00:18:35 2014 +0200
@@ -0,0 +1,66 @@
+/**
+ * Alt2XML
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package cz.frantovo.alt2xml.cli;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+
+/**
+ *
+ * @author Ing. František Kučera (frantovo.cz)
+ */
+public class InvalidOptionsException extends Exception {
+
+	private final Collection<OptionProblem> problems = new ArrayList<>();
+
+	public Collection<OptionProblem> getProblems() {
+		return Collections.unmodifiableCollection(problems);
+	}
+
+	public void addProblem(OptionProblem p) {
+		problems.add(p);
+	}
+
+	public boolean hasProblems() {
+		return !problems.isEmpty();
+	}
+
+	public static class OptionProblem {
+
+		private String description;
+		private Throwable exception;
+
+		public OptionProblem(String description) {
+			this.description = description;
+		}
+
+		public OptionProblem(String description, Throwable exception) {
+			this.description = description;
+			this.exception = exception;
+		}
+
+		public String getDescription() {
+			return description;
+		}
+
+		public Throwable getException() {
+			return exception;
+		}
+	}
+}
diff -r 6bcb20e856fe -r 3d5cc308e268 scripts/alt2xml.sh
--- a/scripts/alt2xml.sh	Tue Jun 17 18:19:01 2014 +0200
+++ b/scripts/alt2xml.sh	Thu Jul 03 00:18:35 2014 +0200
@@ -25,7 +25,7 @@
 	CLASS_PATH="$CLASS_PATH:$e";
 done
 
-MAIN_CLASS="cz.frantovo.alt2xml.cli.CLI";
+MAIN_CLASS="cz.frantovo.alt2xml.cli.CLIStarter";
 
 SAX_PARSER_FACTORY_ALT="cz.frantovo.alt2xml.ParserFactory";                             # our alternative ParserFactory as default
 SAX_PARSER_FACTORY_XML="com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl";  # former default factory as fallback