uio--WebPageMain-Module

Overview

ExampleData | overview

Eine Vielzahl unserer Beispiele benötigt Daten, um auf deren Grundlage diese Daten umformen, filtern, sortieren oder zu einem Ergebnis auswerten zu können.

Ein Teil dieser Daten werden in dieser Sektion veröffentlicht.

Person Daten

Für die Erstellung von Collection erzeugt diese Klasse die zugehörigen Datensätze.

Da die Klasse von Zeit zu Zeit überarbeitet wird, kann es sein, dass die als Beispiel-Output in Programmen angebenen Ausgaben verändern können.



package com.stuelken.java.b2.exampledata;

import java.util.List;
import java.util.ArrayList;
import java.time.chrono.IsoChronology;
import java.time.LocalDate;

/**
 * Diese Klasse ist eine
 * 
 * @author t2m
 * @version 1.0.3.1
 */
public class Person {

	public enum Sex {
		MALE, FEMALE, UNDEFINED
	}

	int num;
	String name;
	LocalDate birthday;
	Sex gender;
	String emailAddress;

	Person(int num, String nameArg, LocalDate birthdayArg, Sex genderArg, String emailArg) {
		num = num;
		name = nameArg;
		birthday = birthdayArg;
		gender = genderArg;
		emailAddress = emailArg;
	}

	/**
	 * Entspricht der Nummer der Reihenfolge, mit welcher das Objekt definiert
	 * wurde.
	 * 
	 * @return
	 */
	public int getNum() {
		return this.num;
	}

	public int getAge() {
		return birthday.until(IsoChronology.INSTANCE.dateNow()).getYears();
	}

	public void printPerson() {
		System.out.println(name + ", " + this.getAge());
	}

	public Sex getGender() {
		return gender;
	}

	public String getName() {
		return name;
	}

	public String getEmailAddress() {
		return emailAddress;
	}

	public LocalDate getBirthday() {
		return birthday;
	}

	public static int compareByAge(Person a, Person b) {
		return a.birthday.compareTo(b.birthday);
	}

	public String toString() {
		String text = "";
		text += "\nPerson-Objekt (" //
				+ "name:" + this.getName() //
				+ ", num:" + this.getNum() //
				+ ", geschlecht:" + this.getGender() //
				+ ", geb.:" + this.getBirthday() //
				+ ", age:" + this.getAge()//
				+ ", email:" + this.getEmailAddress();
		return text;
	}

	public static List<Person> createGruppe() {
		//@formatter:off
	 List<Person> m = new ArrayList<>();
	 
	 m.add(new Person(1, "Anton", geboren(1980, 6, 20), Person.Sex.MALE, "anton@example.com"));
	 m.add(new Person(2, "Berta", geboren(1990, 7, 15), Person.Sex.FEMALE, "berta@example.com"));
	 m.add(new Person(3, "Cesar", geboren(1991, 8, 13), Person.Sex.MALE, "cesar@example.com"));
	 m.add(new Person(4, "Dora", geboren(2000, 9, 12), Person.Sex.MALE, "dora@example.com"));
	 m.add(new Person(5, "Ephigene", geboren(2015, 1, 4), Person.Sex.FEMALE, ""));
	 m.add(new Person(6, "Excelsius", geboren(2000, 9, 12), Person.Sex.MALE, "emil@example.com"));
	 m.add(new Person(7, "Hakaan", geboren(1964, 12, 10), Person.Sex.MALE, "emil@example.com"));
	 m.add(new Person(8, "Neutrum", geboren(2000, 9, 12), Person.Sex.UNDEFINED, "neutrum@example.com"));
	 m.add(new Person(9, "Torben", geboren(1969, 9, 10), Person.Sex.MALE, "torben@example.com"));
	 //@formatter:on

		return m;
	}

	private static LocalDate geboren(int jahr, int monat, int tag) {
		return IsoChronology.INSTANCE.date(jahr, monat, tag);
	}

}

ArgumentInterpreter

Diese Klasse ermöglicht das Auswerten von Argumenten, welche beim Start einer Konsolen-Anwendung in Java übertragen wurden.

Diese Klasse wird verwendet für einige Beispiele in welchen Webservices über Sockets und HTTP mit Subcommands und Commands erstellt werden, um beispielsweise -p 8080 oder --port 8080 auswerten zu können und über -h oder --help eine Hilfe zu Parametern angezeigt zu bekommen.



package com.stuelken.commons.utility.cli;

import java.io.PrintStream;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.stuelken.commons.DocDemo;
import com.stuelken.commons.DocDemos;
import com.stuelken.commons.documentation.DocState;
import com.stuelken.commons.documentation.DocStateEnum;

/**
 * Die {@link ArgumentInterpreter} ermöglicht das Auslesen von Kommandozeilenparametern wie
 * {@code "java progr start"} und Subparametern wie {@code "java progr start --port 8080"},
 * Hilfsfunktionen und mehr.
 * 
 * Die {@link ArgumentInterpreter} Klasse bietet die Funktionalität, um Argumente, welche beim
 * Aufruf eines Java-Programms mit {@code public static void main(string[] args) } mit
 * Schlüssel-Wert-Paaren wie beispielsweise -port 8080 oder -p 8080 übergeben wurden, interpretieren
 * und mit Standwerten basierend auf zusätzlich als {@link ArgumentOption} deklartierten
 * Standardwerten füllen zu können.
 * 
 * Der {@link ArgumentInterpreter} ist in der Lage, auch Werte von Strings in doppelten
 * Anführungstrichen sowie auch mit darin über {@code \"...\"} maskierten Anführungsstrichen
 * auswerten zu können. Zahlenwerte eines Schlüsselwertpaars können ebenso ausgewertet werden.
 * 
 * <ul>
 * <li>--help / -h: Default-Option zum Abfragen einer Hilfe, welche über
 * {@link #printUsage(PrintStream)} ausgegeben wird.</li>
 * <li>Subcommand(s) können registriert und dispatcht werden.</li>
 * <li></li>
 * </ul>
 * 
 * @see ArgumentInterpreterDemo
 * 
 * @author t2m
 * @version 1.5.3.82
 */
@DocDemo(content = "Objekte dieser Klassen dienen zur Auswertung von Kommandozeilen-Parametern.")
@DocState(DocStateEnum.A)
public class ArgumentInterpreter {

	/**
	 * Liste aller Subcommands.
	 */
	private final Map<String, ArgumentInterpreter> subcommands = new LinkedHashMap<>();

	/**
	 * Eine {@link ArgumentOption} beschreibt eine CLI-Option mit Defaultwerten welche immer dann
	 * gelten, wenn in den Argumenten, welcher beim Programmaufruf angegeben wurde, das
	 * Schlüssel-Wert-Paar beispielsweise für -p oder --port mit 8080 als Wert fehlen würde oder der
	 * zugehörige Wert nicht korrekt interpretiert werden kann.
	 * 
	 * Eine {@link ArgumentOption} beinhaltet Informationen zum {@link #key} als eigentlichem Schlüssel
	 * wie "port", "-p" als Kurzname in {@link #shortName} sowie "--pport" als Langname in
	 * {@link #longName}.
	 * 
	 * Darüber hinaus speichert eine {@link ArgumentOption} eine Liste von Strings für alle
	 * Defaultvalues in {@link #defaultValues}.
	 * 
	 * Mit {@link #getKey()}, {@link #getShortName()}, {@link #getLongName()} und
	 * {@link #getDefaultValues()} können die privaten Eigenschaften abgefragt werden.
	 * 
	 * @author t2m
	 */
	public static class ArgumentOption {

		/*
		 * === STATIC MEMBER
		 */

		/**
		 * OptionBuilder für Konfiguration einer Option erzeugen
		 */
		private static final ArgumentOption HELP_OPTION = new ArgumentOptionBuilder("help")

		 .shortName("-h") // Kurzname
		 .longName("--help") // Langname
		 .description("Diese Hilfe anzeigen") // Beschreibung
		 .build(); // Eigentliche Option erzeugen

		/*
		 * === OBJECT MEMBER
		 */

		/**
		 * Der Key/Schlüssel für eine {@link ArgumentOption} wie beispielsweise "port".
		 */
		private final String key;

		/**
		 * Die Kurzbezeichnung des Parameters wie -p statt --port
		 */
		private final String shortName;

		/**
		 * Die Langbezeichnung wie --port statt -p für den Port
		 */
		private final String longName;

		/**
		 * Eine Liste von String-Werten für den Fall, dass ein Schlüssel-Wert-Paar nicht nur einen Wert
		 * sondern mehrere Werte haben kann wie beispielsweise eine Angabe von --coordinates mit Latitude
		 * und Longitude.
		 */
		private final List<String> defaultValues;

		/*
		 * === CONSTRUCTOR + BUILDER
		 */

		/**
		 * Eine Beschreibung des Parameters und seiner Werte wie beispielsweise für "port" die Info, dass es
		 * sich um den Anfangs- und Endpunkt einer Verbindung handelt und ein üblicher Port für
		 * Webanwendungen bei Port 80 liegt, sofern der Zugriff nicht innerhalb des Servers über einen Proxy
		 * geroutet wird.
		 */
		private String description;

		/**
		 * Konstruktor
		 * 
		 * @param b
		 */
		// @formatter:off	
 private ArgumentOption(ArgumentOptionBuilder b) {
 this.key = b.key;
 this.shortName = b.shortName;
 this.longName = b.longName;
 this.defaultValues = b.defaultValues != null
 ? Collections.unmodifiableList(b.defaultValues)
 : Collections.emptyList();
 
 this.description = b.description;
 }
 // @formatter:on

		/**
		 * Getter für die Beschreibung der Option, siehe {@link #description}.
		 * 
		 * @return
		 */
		public String getDescription() {
			return this.description;
		}

		/**
		 * Getter für den Key oder Schlüssel wie "port", siehe {@link #key}
		 * 
		 * @return
		 */
		public String getKey() {
			return key;
		}

		/**
		 * Getter für die Kurzbezeichnung wie -p statt --port, siehe {@link #shortName}
		 * 
		 * @return
		 */
		public String getShortName() {
			return shortName;
		}

		/**
		 * Getter für die Langbezeichnung der Option wie --port statt -port, vergleiche {@link #longName}
		 * 
		 * @return
		 */
		public String getLongName() {
			return longName;
		}

		/**
		 * Liefert eine Liste von 0, 1 oder n Werten die als Standardwerte gelten; {@link ArgumentOption}
		 * Instanzen wie beispielsweise für Koordinaten führen dazu, dass der Wert --coordinates zwei Werte
		 * hat, nicht einen.
		 * 
		 * @return
		 */
		public List<String> getDefaultValues() {
			return defaultValues;
		}

		/**
		 * Builder für die Erzeugung von Option
		 * 
		 * @author t2m
		 */
		public static class ArgumentOptionBuilder {
			private final String key;
			private String shortName, longName;
			private List<String> defaultValues;
			private String description;

			public ArgumentOptionBuilder(String key) {
				this.key = key;
			}

			public ArgumentOptionBuilder shortName(String sn) {
				this.shortName = sn;
				return this;
			}

			public ArgumentOptionBuilder longName(String ln) {
				this.longName = ln;
				return this;
			}

			/**
			 * {@index "Example Arrays.asList"}
			 * 
			 * @param vals
			 * @return
			 */
			public ArgumentOptionBuilder defaultValues(String... vals) {
				this.defaultValues = Arrays.asList(vals);
				return this;
			}

			/**
			 * Erfassen einer Erläuterung (englisch description) welche über die Hilfe ausgegeben werden kann.
			 * 
			 * @param desc Ein String mit einer Erläuterung dieses Parameters und möglicher Werte.
			 * @return
			 */
			public ArgumentOptionBuilder description(String desc) { // neu
				this.description = desc;
				return this;
			}

			/**
			 * Erzeugen der eigentlich {@link ArgumentOption} Instanz.
			 * 
			 * @return
			 */
			public ArgumentOption build() {
				return new ArgumentOption(this);
			}

		}
	}

	/*
	 * === Builder zum Registrieren aller Optionen
	 */

	/**
	 * Eine Map welche für einen Kurznamen die zugehörigen {@link ArgumentOption} Definitionen
	 * speichert.
	 */
	private final Map<String, ArgumentOption> nameToOpt = new HashMap<>();

	/**
	 * Ein Map mit deren Hilfe von einem Schlüssel wie -p oder --port auf eine mögliche
	 * {@link ArgumentOption} Definition geschlossen werden kann.
	 */
	private final LinkedHashMap<String, ArgumentOption> keyToOpt = new LinkedHashMap<>();

	/**
	 * Privater Konstruktor. Objekte können nur über die statische {@link #builder()} Methode erzeugt
	 * werden.
	 */
	private ArgumentInterpreter() {
	}

	/**
	 * Statische Factory baut den Builder und fügt HELP_OPTION automatisch ein, liefert einen
	 * {@link ArgumentInterpreterBuilder} mit welchem eine {@link ArgumentInterpreter} Instanz erzeugt
	 * werden kann.
	 * 
	 * @return
	 */
	public static ArgumentInterpreterBuilder builder() {
		ArgumentInterpreterBuilder b = new ArgumentInterpreterBuilder();
		// HELP global registrieren
		b.inst.keyToOpt.put(ArgumentOption.HELP_OPTION.getKey(), ArgumentOption.HELP_OPTION);
		b.inst.nameToOpt.put(ArgumentOption.HELP_OPTION.getShortName(), ArgumentOption.HELP_OPTION);
		b.inst.nameToOpt.put(ArgumentOption.HELP_OPTION.getLongName(), ArgumentOption.HELP_OPTION);
		return b;
	}

	/**
	 * Builder für {@link ArgumentInterpreter} Instanzen.
	 * 
	 * @author t2m
	 */
	public static class ArgumentInterpreterBuilder {

		/**
		 * Referenz auf die einzige Instanz des {@link ArgumentInterpreter}.
		 */
		private final ArgumentInterpreter inst = new ArgumentInterpreter();

		/**
		 * Map aller Subcommand(s)
		 */
		private final Map<String, ArgumentInterpreter> subcommands = new LinkedHashMap<>();

		/*
		 * === BUILDER
		 */

		/**
		 * 
		 * @author t2m
		 */
		public static class Builder {

			/**
			 * Referenz auf die einzige Instanz des {@link ArgumentInterpreter}.
			 */
			private final ArgumentInterpreter inst = new ArgumentInterpreter();

			/**
			 * Eine Map mit {@link ArgumentInterpreter} Varianten speichert, damit man mit einem Programm auch
			 * weitere Befehle verarbeitet werden können, die alle ihre eigenen Parameter,
			 * {@link ArgumentOption} Definitionen und Standardwerte haben.
			 */
			private final Map<String, ArgumentInterpreter> subcommands = new HashMap<>();

			public Builder defineSubcommand(String name, ArgumentInterpreter sub) {
				subcommands.put(name, sub);
				return this;
			}

			public ParsedArgs parse(String[] args) {
				if (args.length > 0 && subcommands.containsKey(args[0])) {
					return subcommands.get(args[0]).parse(Arrays.copyOfRange(args, 1, args.length));
				}
				return inst.parse(args);
			}
		}

		/**
		 * Definieren einer {@link ArgumentOption} als Information für den {@link ArgumentInterpreter},
		 * damit dieser weiß, welche Schlüssel wie -p oder --port verwendet werden und welche Standardwerte
		 * oder auch welchen Kurz- und Langnamen diese haben.
		 * 
		 * @param opt
		 * @return
		 */
		public ArgumentInterpreterBuilder define(ArgumentOption opt) {
			inst.keyToOpt.put(opt.getKey(), opt);
			// @formatter:off	
	 if (opt.getShortName() != null) inst.nameToOpt.put(opt.getShortName(), opt);
	 if (opt.getLongName() != null) inst.nameToOpt.put(opt.getLongName(), opt);
	 return this;
	 // @formatter:on
		}

		/**
		 * Subcommand registrieren
		 * 
		 * @param name
		 * @param interpreter
		 * @return
		 */
		public ArgumentInterpreterBuilder defineSubcommand(String name, ArgumentInterpreter interpreter) {
			inst.subcommands.put(name, interpreter);
			return this;
		}

		/**
		 * Parst über eine interne private Methode die als Schlüssel-Wert-Paare wie beispielsweise -p oder
		 * --port mit 8080 angegebenen Werte.
		 * 
		 * @param args
		 * @return
		 */
		public ParsedArgs parse(String[] args) {
			return inst.parse(args);
		}

		/** Usage ausgeben */
		public void printUsage(PrintStream out) {
			inst.printUsage(out);
		}

		/**
		 * Fügt alle erfassten Subcommands der Instanz des {@link ArgumentInterpreter} hinzu und liefert
		 * abschließend die Referenz auf das erzeugte {@link ArgumentInterpreter} Objekt.
		 */
		public ArgumentInterpreter build() {
			// Subcommands in das Ziel-Objekt einfügen
			inst.subcommands.putAll(this.subcommands);
			return inst;
		}

	}

	/*
	 * === Parser-Logik
	 */

	/**
	 * Subcommand--Displatching und Parsen der als String-Array übergebenen Schlüssel-Wert-Parameter
	 * bestehend aus jeweils einem Key wie beispielsweise -p und --port und dem zugehörigen Wert wie
	 * beispielsweise 8080.
	 * 
	 * Wenn für einen Key bereits ein Eintrag in den {@link ArgumentOption} Werten angegeben wurde, wird
	 * zu Beginn intern erst einmal der Defaultwert genutzt, damit für den Fall, dass für den gelesenen
	 * Key wie -p oder --port kein Wert geparst werden konnte, dann dieser Standardwert gilt.
	 * 
	 * @param argv Ein Array mit Strings wie man es von {@code public static void main(String[] args)}
	 * kennt.
	 * @return Liefert eine {@link ParsedArgs} Instanz als Container der geparsten Schlüssel-Wert-Paare
	 * unter Berücksichting möglicherweise Standardwerte.
	 */
	public ParsedArgs parse(String[] argv) {
		// Subcommand-Erkennung
		if (argv.length > 0 && subcommands.containsKey(argv[0])) {
			String sub = argv[0];
			ArgumentInterpreter subInt = subcommands.get(sub);
			String[] rest = Arrays.copyOfRange(argv, 1, argv.length);
			ParsedArgs pa = subInt.parse(rest);
			pa.setSubcommand(sub);
			return pa;
		}
		// --- bisheriger Parser-Loop ---
		LinkedHashMap<String, List<String>> parsed = new LinkedHashMap<>();
		ArgumentOption current = null;
		for (String token : argv) {
			if (nameToOpt.containsKey(token)) {
				current = nameToOpt.get(token);
				parsed.putIfAbsent(current.getKey(), new ArrayList<>());
			} else if (current != null) {
				parsed.get(current.getKey()).add(unquote(token));
			}
		}
		return new ParsedArgs(parsed, keyToOpt);
	}

	/**
	 * Ersetzen der mit {@code \"} bei der Texteingabe maskierten Anführungstriche innerhalb von
	 * Zeichenfolgen, welche wiederum in doppelten Anführungstrichen stehen.
	 * 
	 * @param s
	 * @return
	 */
	private String unquote(String s) {
		if (s.startsWith("\"") && s.endsWith("\"") && s.length() > 1) {
			s = s.substring(1, s.length() - 1);
		}
		return s.replace("\\\"", "\"");
	}

	/**
	 * Kapselt die bereits geparsten Kommandozeilenargumente
	 * 
	 * @author t2m
	 */
	public static class ParsedArgs {

		/**
		 * Der Bezeichner des Subcommand(s)
		 */
		private String subcommand;

		/**
		 * Eine {@link Map} aller interpretierten Schlüssel-Wert-Paare, wobei ein jeder Schlüssel je nach
		 * Konfiguration 0, 1 oder n Werte haben kann.
		 */
		private final Map<String, List<String>> parsed;

		/**
		 * Eine {@link Map} aller {@link ArgumentOption} Definitionen für di verschiedenen Parameter welche
		 * als Schlüsselwertpaare beispielsweise für den Key -p oder --port haben angegeben werden können.
		 */
		private final Map<String, ArgumentOption> opts;

		/** Intern vom Parser gesetzt */
		void setSubcommand(String sub) {
			this.subcommand = sub;
		}

		/** Gewähltes Subcommand auslesen */
		public String getSubcommand() {
			return subcommand;
		}

		/**
		 * Konstruktor für {@link ParsedArgs} Objekte welche als Container für sowohl die geparsten und
		 * damit interpretierten Argumente und Parameter als auch der Erfassung von Optionen für diese
		 * Parameter dienen, damit auch Standardwerte bekann sind.
		 * 
		 * @param parsed
		 * @param opts
		 */
		public ParsedArgs(Map<String, List<String>> parsed, Map<String, ArgumentOption> opts) {
			this.parsed = parsed;
			this.opts = opts;
		}

		/**
		 * Prüft, ob in den geparsten Parametern ein Schlüsselwertpaar für diesen Key wie beispielsweise für
		 * -p oder -port angegeben wurde.
		 * 
		 * @param key Ein Parameterschlüssel wie beispielsweise -p oder --port
		 * @return Liefert true wenn der Parameter dieses Keys angegeben wurde
		 */
		public boolean has(String key) {
			return parsed.containsKey(key) || !opts.get(key).getDefaultValues().isEmpty();
		}

		/**
		 * Liefert für einen Key wie -p oder --port einen String der Werts.
		 * 
		 * @param key Ein Schlüssel wie -p oder -port
		 * @return
		 */
		// @formatter:off	
 public String get(String key) {
 List<String> vals = parsed.containsKey(key) 
 ? parsed.get(key)
 : opts.get(key).getDefaultValues();
 return vals.isEmpty() ? null : vals.get(0);
 }
 // @formatter:on	

		/**
		 * Liefert eine Liste aller String-Werte für einen Schlüssel.
		 * 
		 * Wenn der Key in der Liste vorhanden ist, wird eine nicht mehr modifizierbare Liste als Collection
		 * geliefert welche die Werte für diesen Key beinhaltet.
		 * 
		 * Wenn der Key allerdings nicht vorhanden ist in den geparsten Parametern, dann wird versucht, über
		 * die erfassten {@link ArgumentOption} Werte der Standardwert gesucht.
		 * 
		 * @param key Ein Schlüssel wie -p oder -port
		 * @return
		 */
		// @formatter:off	
 public List<String> getAll(String key) {
 return parsed.containsKey(key) 
 ? Collections.unmodifiableList(parsed.get(key))
 : opts.get(key).getDefaultValues();
 }
 // @formatter:on	

		/**
		 * Ermitteln eines int-Wertes aus einem String.
		 * 
		 * @param key Schlüssel für den Parameter wie z. B. -p oder --port
		 * @param fallback Standardwert für den Fall, dass der eigentliche Wert nicht gelesen werden konnte.
		 * @return
		 */
		public int getInt(String key, int fallback) {
			String v = get(key);
			if (v == null)
				return fallback;
			try {
				return Integer.parseInt(v);
			} catch (NumberFormatException e) {
				return fallback;
			}
		}

	}

	/**
	 * Druckt eine Übersicht aller definierten Optionen mit Kurz- und Langnamen, Beschreibung und
	 * Defaultwert(en).
	 * 
	 * TODO: Wie gibt man die HIlfe eigentlich aus?
	 * 
	 * // Hilfe anzeigen. if (pa.has("help")) { pa.printUsage(System.out); return; }
	 */
	public void printUsage(PrintStream out) {
		out.println("Usage:");

		// @formatter:off
	 keyToOpt.values().forEach(
	 opt -> {
			 String names = Stream
			 .of(opt.getShortName(), opt.getLongName())
			 	.filter(Objects::nonNull)
			 .collect(Collectors.joining(", "));
			 
			 String defs = opt.getDefaultValues()
			 		 .isEmpty() ? "" : " (default: " + String.join("|", opt.getDefaultValues()) + ")";
			 
			 out.printf(" %-20s %s%s%n", names, opt.getDescription(), defs);
	 }
		);
		
 	// @formatter:on
		if (!subcommands.isEmpty()) {
			out.println("\nSubcommands:");
			subcommands.keySet().forEach(sc -> out.println(" " + sc));
		}
	}

	/**
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		System.out.println("Objekte dieser Klassen dienen zur Auswertung von Kommandozeilen-Parametern. ");
		System.out.println("Für ein Beispiel siehe: ArgumentInterpreterDemo ");
	}

}



package com.stuelken.commons.utility.cli;

import java.util.List;

import com.stuelken.commons.documentation.DocState;
import com.stuelken.commons.documentation.DocStateEnum;
import com.stuelken.commons.utility.cli.ArgumentInterpreter.ArgumentInterpreterBuilder;
import com.stuelken.commons.utility.cli.ArgumentInterpreter.ArgumentOption;
import com.stuelken.commons.utility.cli.ArgumentInterpreter.ParsedArgs;
import com.stuelken.commons.utility.cli.ArgumentInterpreter.ArgumentOption.ArgumentOptionBuilder;

/**
 * Diese Klasse dient der Demonstration, wie man die {@link ArgumentInterpreter}
 * 
 * @author t2m
 */
@DocState(DocStateEnum.A)
public class ArgumentInterpreterDemo {

	public static void main(String[] args) {

		// --- Globale Optionen ---
		ArgumentOption portOpt = new ArgumentOptionBuilder("port").shortName("-p") // Kurzname
		 .longName("--port") // Langname
		 .defaultValues("8080") // Hier nur 1 Wert
		 .description("Port auf welchem das Programm laufen wird wie z. B. 8080.") // Info für Hilfe
		 .build();

		ArgumentOption descOpt = new ArgumentOptionBuilder("description").shortName("-d") // Kurzname
		 .longName("--description") // Langname
		 .defaultValues("Sie können über die Description eine \"ganz tolle\" Kurzbeschreibung ergänzen.") //
		 .description("Freitext-Beschreibung").build();

		ArgumentOption coordOpt = new ArgumentOptionBuilder("coordinates") // Parameter mit 2 Werten
		 .longName("--coordinates") // Langname
		 .defaultValues("50.0713685076578", "8.243344189019252") // zwei Werte
		 .description("Koordinaten als zwei Werte (Lat,Long)") // Beschreibung
		 .build();

		// --- Subcommand "init" ---
		ArgumentInterpreter initInt = ArgumentInterpreter.builder() //
		 .define(new ArgumentOptionBuilder("config") //
		 .longName("--config") //
		 .description("Pfad zur Init-Konfig") //
		 .defaultValues("init.cfg") //
		 .build() //
				) //
		 .build(); //

		/*
		 * === Deklaration von Subcommand für "start"
		 */
		ArgumentInterpreter startInt = ArgumentInterpreter //
		 .builder() // (1) ArgumentInterpreterBuilder
		 .define( // (2) Definition einer neuen Option 
		 		new ArgumentOptionBuilder("port") // (3) Builder für die Option beschaffen
		 .shortName("-p") // (4) Kurzen Konsolenparameter angeben
		 .longName("--port") // (5) Langen Konsolenparameter angeben
		 .defaultValues("8080") // (6) Standardwert für den Fall fehlender Angaben setzen.
		 .description("Port für Service-Start") // (7) Kurzbeschreibung für die Hilfefunktion
		 .build() // (8) Option erzeugen.
				) //
		 .build(); //

		// --- Haupt-Builder mit globalen Optionen und Subcommands ---
		ArgumentInterpreterBuilder builder = ArgumentInterpreter.builder() //
		 .define(portOpt) //
		 .define(descOpt) //
		 .define(coordOpt) //
		 .defineSubcommand("init", initInt) //
		 .defineSubcommand("start", startInt); //
		
		/*
		 * === Parsen der Argumente von der Kommandozeile
		 */		

		ParsedArgs pa = builder.parse(args);

		/*
		 * === Hilfe auf der Konsole anzeigen, wenn "--help" erkannt wurde.
		 */
		
		if (pa.has("help")) {
			builder.printUsage(System.out);
			return;
		}
		
		/*
		 * === Reagieren auf Subcommand Befehle
		 */		

		// --- Subcommand dispatch ---
		String sub = pa.getSubcommand();
		
		if (sub != null) {
			System.out.println("Info: Selected Subcommand: " + sub);
			switch (sub) {
				// Subcommand "init": java programm init --config
				case "init":
					String cfg = pa.get("config");
					System.out.println("Info: Init mit Konfig: " + cfg);
					break;
					// Subcommand "start": java programm start --port 8080 
				case "start":
					int sp = pa.getInt("port", 8080);
					System.out.println("Info: Start auf Port: " + sp);
					break;
				default:
					System.out.println("Info: Unbekanntes Subcommand: " + sub);
			}
			return;
		}

		// --- Kein Subcommand: globale Werte ausgeben ---
		int port = pa.getInt("port", 80);
		String desc = pa.get("description");
		List<String> coords = pa.getAll("coordinates");

		System.out.println("Port = " + port);
		System.out.println("Description = " + desc);
		System.out.println("Coordinates = " + coords);
	}
}

//@formatter:off
/*
=== (1) Aufrufen ohne Parameter == 

java ArgumentInterpreterDemo
 
=== (2) Aufrufen mit Hilfe == 

java ArgumentInterpreterDemo --help 

Usage:
 -h, --help Diese Hilfe anzeigen
 -p, --port Port auf welchem das Programm laufen wird wie z. B. 8080. (default: 8080)
 -d, --description Freitext-Beschreibung (default: Sie k�nnen �ber die Description eine "ganz tolle" Kurzbeschreibung erg�nzen.)
 --coordinates Koordinaten als zwei Werte (Lat,Long) (default: 50.0713685076578|8.243344189019252)

Subcommands:
 init
 start
 
=== (3) Aufrufen mit Subcommand init ==

java ArgumentInterpreterDemo init 

Wähle Subcommand: init
Init mit Konfig: init.cfg
 
=== (4) Aufrufen mit Subcommand start ==

java ArgumentInterpreterDemo start 
 
Wähle Subcommand: start
Start auf Port: 8080
 
*/
//@formatter:on

Links

FootNotes


    UI ORGANIZED.

    UIO3 Es ist einfacher als Du denkst.

    Stelle noch heute Deine Anfrage.

    uio--WebPageFooter-Module