Skip to content
Snippets Groups Projects
Commit adb673a9 authored by Leonard Kupper's avatar Leonard Kupper
Browse files

Make ready for automatic merge.

parents 5ae1910f 11bf86c7
No related branches found
No related tags found
1 merge request!7Feat/configuration parser 5
Showing
with 393 additions and 2 deletions
......@@ -28,6 +28,7 @@ repositories {
dependencies {
// Use JUnit test framework
compile group: 'commons-cli', name: 'commons-cli', version: '1.4'
testImplementation('org.junit.jupiter:junit-jupiter:5.4.2')
// Logging
......
package de.tudresden.inf.mci.brailleplot;
import de.tudresden.inf.mci.brailleplot.configparser.PrinterProperty;
import de.tudresden.inf.mci.brailleplot.commandline.CommandLineParser;
import de.tudresden.inf.mci.brailleplot.commandline.SettingType;
import de.tudresden.inf.mci.brailleplot.commandline.SettingsReader;
import de.tudresden.inf.mci.brailleplot.commandline.SettingsWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Optional;
import java.util.concurrent.ConcurrentLinkedDeque;
/**
......@@ -107,10 +113,17 @@ public final class App {
mLogger.info("Application started");
// Parse command line parameters
CommandLineParser cliParser = new CommandLineParser();
SettingsWriter settings = cliParser.parse(args);
SettingsReader settingsReader = settings;
// If requested, print help and exit
Optional<Boolean> printHelp = settingsReader.isTrue(SettingType.DISPLAY_HELP);
if (printHelp.isPresent() && printHelp.get()) {
cliParser.printHelp();
return EXIT_SUCCESS;
}
// Parse csv data
......
package de.tudresden.inf.mci.brailleplot.commandline;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
/**
* Performs command line parsing and creates a {@link Settings} object.
* @author Georg Graßnick
* @version 2019.05.31
*/
public class CommandLineParser {
private Options mOptions;
public CommandLineParser() {
setupOptions();
}
private void setupOptions() {
mOptions = new Options();
mOptions.addOption("h", SettingType.DISPLAY_HELP.toString(), false, "Print help and exit")
.addOption("c", SettingType.CSV_LOCATION.toString(), true, "Path to CSV")
.addOption("s", SettingType.SEMANTIC_MAPPING.toString(), true, "Literal for semantic mapping")
.addOption("p", SettingType.PRINTER_CONFIG_PATH.toString(), true, "path to printer configuration file");
}
/**
* Parse command line parameters.
* @param args The arguments from the commandline.
* @return A {@link Settings} object that represents the values from the command line parameters.
* @throws ParsingException On any underlying error.
*/
public final Settings parse(final String[] args) throws ParsingException {
org.apache.commons.cli.CommandLineParser parser = new DefaultParser();
CommandLine cmdLine;
try {
cmdLine = parser.parse(mOptions, args);
} catch (ParseException pe) {
throw new ParsingException("Could not parse command line", pe);
}
return new Settings(cmdLine);
}
/**
* Print usage information to the command line.
*/
public final void printHelp() {
HelpFormatter formatter = new HelpFormatter();
String headerForOptions = "Convert csv into braille";
String footerForOptions = "Report Issues to Leonard Kupper";
formatter.printHelp("braillegraphics", headerForOptions, mOptions, footerForOptions, true);
}
}
package de.tudresden.inf.mci.brailleplot.commandline;
/**
* Exception class.
* Indicates, some error has occurred while parsing the command line parameters.
* Most likely created by malformed user input.
* @author Georg Graßnick
* @version 2019.05.31
*/
public class ParsingException extends Exception {
public ParsingException() { }
public ParsingException(final String message) {
super(message);
}
public ParsingException(final Throwable cause) {
super(cause);
}
public ParsingException(final String message, final Throwable cause) {
super(message, cause);
}
}
package de.tudresden.inf.mci.brailleplot.commandline;
/**
* Represents all possible parsed options parsed from the command line.
* @author Georg Graßnick
* @version 2019.05.31
*/
public enum SettingType {
DISPLAY_HELP("help"),
CSV_LOCATION("csv-path"),
PRINTER_CONFIG_PATH("printer-config-path"),
SEMANTIC_MAPPING("semantic-mapping");
private final String mName;
SettingType(final String name) {
this.mName = name;
}
static SettingType fromString(final String s) {
switch (s) {
case "help":
return DISPLAY_HELP;
case "csv-path":
return CSV_LOCATION;
case "printer-config-path":
return PRINTER_CONFIG_PATH;
case "semantic-mapping":
return SEMANTIC_MAPPING;
default:
throw new IllegalArgumentException("Setting not available");
}
}
public String toString() {
return mName;
}
}
package de.tudresden.inf.mci.brailleplot.commandline;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Optional;
/**
* Encapsulates Settings for the Application from the command line.
* @author Georg Graßnick
* @version 2019.05.31
*/
public final class Settings implements SettingsReader, SettingsWriter {
private Map<SettingType, String> mSettings;
private final Logger mLogger = LoggerFactory.getLogger(this.getClass());
private static final String BOOL_TRUE = Boolean.toString(true);
private static final String BOOL_FALSE = Boolean.toString(false);
/**
* Constructor.
* @param cmdLine CommandLine object to take information from.
*/
Settings(final CommandLine cmdLine) {
mSettings = new HashMap<>();
setup(cmdLine);
}
/**
* Populates the Settings class with arguments from the command line.
* @param cmdLine {@link CommandLine} object to take take settings from.
*/
private void setup(final CommandLine cmdLine) {
for (Iterator<Option> it = cmdLine.iterator(); it.hasNext();) {
Option o = it.next();
if (o.hasArg()) {
SettingType type = SettingType.fromString(o.getLongOpt());
mSettings.put(type, o.getValue());
mLogger.trace("Added string \"{}\" with value \"{}\"", type, o.getValue());
} else {
mSettings.put(SettingType.fromString(o.getLongOpt()), BOOL_TRUE);
mLogger.trace("Added flag \"{}\" set to \"{}\"", SettingType.fromString(o.getLongOpt()), BOOL_TRUE);
}
}
}
/**
* Check if a specific setting is set.
* @param setting The requested setting.
* @return true if the parameter is set, else false.
*/
public boolean isPresent(final SettingType setting) {
return mSettings.containsKey(setting);
}
/**
* Get the value of a setting, if set.
* @param setting The requested Setting to request the value for.
* @return {@link Optional}{@literal <String>} if setting is set, or {@link Optional#empty()} if the requested setting
* was not specified by the user.
* Use {@link Settings#isPresent(SettingType)} to check the value of a boolean parameter.
*/
public Optional<String> getSetting(final SettingType setting) {
if (!mSettings.containsKey(setting)) {
return Optional.empty();
}
return Optional.of(mSettings.get(setting));
}
/**
* Get the boolean value of a setting, if set.
* @param setting The requested Setting to request the value for.
* @return {@link Optional}{@literal <Boolean>} if setting is set, or {@link Optional#empty()} if the requested setting
* was not specified by the user.
*/
public Optional<Boolean> isTrue(final SettingType setting) {
if (!mSettings.containsKey(setting)) {
return Optional.empty();
}
if (mSettings.get(setting).equals(BOOL_TRUE)) {
return Optional.of(true);
} else {
return Optional.of(false);
}
}
/**
* Set the value of a setting.
* @param setting {@link SettingType} the setting to be changed.
* @param value {@link String} The value to set.
*/
public void setSetting(final SettingType setting, final String value) {
mSettings.replace(setting, value);
}
/**
* Set the value of a setting to a specific {@link Boolean}.
* @param setting {@link SettingType} the setting to be changed.
* @param isTrue {@link String} The value to set.
*/
public void setSetting(final SettingType setting, final Boolean isTrue) {
if (isTrue) {
mSettings.replace(setting, BOOL_TRUE);
} else {
mSettings.replace(setting, BOOL_FALSE);
}
}
/**
* Delete the set value of a setting, if it is set.
* @param setting {@link SettingType} the setting to be removed.
*/
public void deleteSettingValue(final SettingType setting) {
mSettings.remove(setting);
}
}
package de.tudresden.inf.mci.brailleplot.commandline;
import java.util.Optional;
/**
* Supplies an interface for reading settings.
* @author Georg Graßnick
* @version 2019.06.01
*/
public interface SettingsReader {
Optional<String> getSetting(SettingType setting);
boolean isPresent(SettingType setting);
Optional<Boolean> isTrue(SettingType setting);
}
package de.tudresden.inf.mci.brailleplot.commandline;
/**
* Implementing classes are guaranteed to support manipulating settings.
* Currently, the implementation is not thread safe!
* @author Georg Graßnick
* @version 2019.06.01
*/
public interface SettingsWriter extends SettingsReader {
void setSetting(SettingType setting, String value);
void setSetting(SettingType setting, Boolean isTrue);
void deleteSettingValue(SettingType setting);
}
/**
* Responsible for command line parsing and the creation of an {@link de.tudresden.inf.mci.brailleplot.commandline.Settings} object
* which can be queried by {@link de.tudresden.inf.mci.brailleplot.commandline.SettingsReader}
* and manipulated by {@link de.tudresden.inf.mci.brailleplot.commandline.SettingsWriter}.
*/
package de.tudresden.inf.mci.brailleplot.commandline;
package de.tudresden.inf.mci.brailleplot.commandline;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.fail;
/**
* Tests the CommandlineParser and the querying of parameters of the Settings object.
*/
class CommandLineParserTest {
private CommandLineParser commandLineParser = new CommandLineParser();
@Test
void testParseLegalArgs() {
String[] args = {"-h", "--csv-path", "foobar"};
Assertions.assertDoesNotThrow(() -> {commandLineParser.parse(args);});
}
@Test
void testIllegalArgs() {
String[] args = {"-h --foobar"};
Assertions.assertThrows(ParsingException.class, () -> {commandLineParser.parse(args);});
}
@Test
void testEmptyArgs() {
String[] args = {""};
Assertions.assertDoesNotThrow(() -> {commandLineParser.parse(args);});
}
@Test
void testBoolFlagRecognized() {
String[] args = {"-h"};
SettingsReader settings;
try {
settings = commandLineParser.parse(args);
} catch (ParsingException pe) {
fail();
return; // Never executed, satisfy compiler
}
Optional<Boolean> flag = settings.isTrue(SettingType.DISPLAY_HELP);
Assertions.assertTrue(flag.isPresent());
Assertions.assertTrue(flag.get());
}
@Test
void testBoolFlagCorrectlyNotRecognized() {
String[] args = {""};
SettingsReader settings;
try {
settings = commandLineParser.parse(args);
} catch (ParsingException pe) {
fail();
return; // Never executed, satisfy compiler
}
Optional<Boolean> flag = settings.isTrue(SettingType.DISPLAY_HELP);
Assertions.assertFalse(flag.isPresent());
}
@Test
void testParameterRecognized() {
final String param = "xyz";
String[] args = {"--csv-path", param};
SettingsReader settings;
try {
settings = commandLineParser.parse(args);
} catch (ParsingException pe) {
fail();
return; // Never executed, satisfy compiler
}
Optional<String> flag = settings.getSetting(SettingType.CSV_LOCATION);
Assertions.assertTrue(flag.isPresent());
Assertions.assertTrue(flag.get().equals(param));
}
@Test
void testParameterCorrectlyNotRecognized() {
String[] args = {""};
SettingsReader settings;
try {
settings = commandLineParser.parse(args);
} catch (ParsingException pe) {
fail();
return; // Never executed, satisfy compiler
}
Optional<String> flag = settings.getSetting(SettingType.CSV_LOCATION);
Assertions.assertFalse(flag.isPresent());
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment