mirror of
https://github.com/itplr-kosit/validator.git
synced 2026-05-26 01:05:38 +00:00
support multiple configuration
This commit is contained in:
parent
730d7fefe9
commit
2e6efdd16f
59 changed files with 1136 additions and 608 deletions
|
|
@ -16,25 +16,19 @@
|
|||
|
||||
package de.kosit.validationtool.cmd;
|
||||
|
||||
import static de.kosit.validationtool.cmd.CommandLineOptions.HELP;
|
||||
import static de.kosit.validationtool.cmd.CommandLineOptions.createHelpOptions;
|
||||
import static de.kosit.validationtool.cmd.CommandLineOptions.createOptions;
|
||||
import static de.kosit.validationtool.cmd.CommandLineOptions.printHelp;
|
||||
import static de.kosit.validationtool.impl.Printer.writeErr;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import org.apache.commons.cli.CommandLineParser;
|
||||
import org.apache.commons.cli.DefaultParser;
|
||||
import org.apache.commons.cli.Options;
|
||||
import org.apache.commons.cli.ParseException;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.fusesource.jansi.AnsiConsole;
|
||||
import org.fusesource.jansi.AnsiConsole;
|
||||
import org.fusesource.jansi.AnsiRenderer.Code;
|
||||
|
||||
import de.kosit.validationtool.cmd.report.Line;
|
||||
import de.kosit.validationtool.impl.Printer;
|
||||
|
||||
import picocli.CommandLine;
|
||||
import picocli.CommandLine.ParseResult;
|
||||
|
||||
/**
|
||||
* Commandline interface of the validator. It parses the commandline args and hands over actual execution to
|
||||
* {@link Validator}.
|
||||
|
|
@ -59,7 +53,9 @@ public class CommandLineApplication {
|
|||
AnsiConsole.systemInstall();
|
||||
final ReturnValue resultStatus = mainProgram(args);
|
||||
if (!resultStatus.equals(ReturnValue.DAEMON_MODE)) {
|
||||
sayGoodby(resultStatus);
|
||||
if (!resultStatus.equals(ReturnValue.HELP_REQUEST) && resultStatus.getCode() >= 0) {
|
||||
sayGoodby(resultStatus);
|
||||
}
|
||||
System.exit(resultStatus.getCode());
|
||||
} else {
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(() -> Printer.writeOut("Shutting down daemon ...")));
|
||||
|
|
@ -79,60 +75,37 @@ public class CommandLineApplication {
|
|||
// for testing purposes. Unless jvm is terminated during tests. See above
|
||||
static ReturnValue mainProgram(final String[] args) {
|
||||
|
||||
final Options options = createOptions();
|
||||
ReturnValue resultStatus;
|
||||
final CommandLine commandLine = new CommandLine(new CommandLineOptions());
|
||||
try {
|
||||
if (isHelpRequested(args)) {
|
||||
printHelp(options);
|
||||
resultStatus = ReturnValue.SUCCESS;
|
||||
commandLine.setExecutionExceptionHandler(CommandLineApplication::logExecutionException);
|
||||
commandLine.execute(args);
|
||||
if (commandLine.isUsageHelpRequested()) {
|
||||
resultStatus = ReturnValue.HELP_REQUEST;
|
||||
} else {
|
||||
final CommandLineParser parser = new DefaultParser();
|
||||
final CommandLine cmd = parser.parse(options, args);
|
||||
configureLogging(cmd);
|
||||
resultStatus = Validator.mainProgram(cmd);
|
||||
resultStatus = ObjectUtils.defaultIfNull(commandLine.getExecutionResult(), ReturnValue.PARSING_ERROR);
|
||||
if (resultStatus.getCode() != ReturnValue.PARSING_ERROR.getCode()
|
||||
&& resultStatus.getCode() != ReturnValue.SUCCESS.getCode()) {
|
||||
commandLine.usage(System.out);
|
||||
}
|
||||
}
|
||||
} catch (final ParseException e) {
|
||||
|
||||
} catch (final Exception e) {
|
||||
writeErr("Error processing command line arguments: {0}", e.getMessage(), e);
|
||||
printHelp(options);
|
||||
resultStatus = ReturnValue.PARSING_ERROR;
|
||||
}
|
||||
return resultStatus;
|
||||
}
|
||||
|
||||
private static boolean isHelpRequested(final String[] args) {
|
||||
final Options helpOptions = createHelpOptions();
|
||||
try {
|
||||
final CommandLineParser parser = new DefaultParser();
|
||||
final CommandLine cmd = parser.parse(helpOptions, args, true);
|
||||
if (cmd.hasOption(HELP.getOpt()) || args.length == 0) {
|
||||
return true;
|
||||
}
|
||||
} catch (final ParseException e) {
|
||||
// we can ignore that, we just look for the help parameters
|
||||
}
|
||||
return false;
|
||||
private static int logExecutionException(final Exception ex, final CommandLine cli, final ParseResult parseResult) {
|
||||
Printer.writeErr(ex, ex.getMessage());
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static void configureLogging(final CommandLine cmd) throws ParseException {
|
||||
if (cmd.hasOption(CommandLineOptions.DEBUG_LOG.getOpt())) {
|
||||
System.setProperty(org.slf4j.impl.SimpleLogger.DEFAULT_LOG_LEVEL_KEY, "DEBUG");
|
||||
} else if (cmd.hasOption(CommandLineOptions.LOG_LEVEL.getOpt())) {
|
||||
|
||||
final String level = Level.resolve(cmd.getOptionValue(CommandLineOptions.LOG_LEVEL.getOpt()));
|
||||
System.setProperty(org.slf4j.impl.SimpleLogger.DEFAULT_LOG_LEVEL_KEY, level);
|
||||
} else {
|
||||
System.setProperty(org.slf4j.impl.SimpleLogger.DEFAULT_LOG_LEVEL_KEY, "OFF");
|
||||
}
|
||||
}
|
||||
|
||||
private enum Level {
|
||||
enum Level {
|
||||
|
||||
INFO, WARN, DEBUG, TRACE, ERROR, OFF;
|
||||
|
||||
static String resolve(final String optionValue) throws ParseException {
|
||||
return Arrays.stream(values()).filter(e -> e.name().equalsIgnoreCase(optionValue)).map(Enum::name).findFirst()
|
||||
.orElseThrow(() -> new ParseException("Either specify trace,debug,info,warn,error as log level"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,100 +16,176 @@
|
|||
|
||||
package de.kosit.validationtool.cmd;
|
||||
|
||||
import org.apache.commons.cli.HelpFormatter;
|
||||
import org.apache.commons.cli.Option;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
import de.kosit.validationtool.cmd.CommandLineApplication.Level;
|
||||
|
||||
import picocli.CommandLine.ArgGroup;
|
||||
import picocli.CommandLine.Command;
|
||||
import picocli.CommandLine.Help.Visibility;
|
||||
import picocli.CommandLine.Option;
|
||||
import picocli.CommandLine.Parameters;
|
||||
|
||||
/**
|
||||
* Commandline Interface definition.
|
||||
*
|
||||
* @author Andreas Penski
|
||||
*/
|
||||
public class CommandLineOptions {
|
||||
@Command(description = "Structural and semantic validation of xml files", name = "KoSIT Validator", mixinStandardHelpOptions = false,
|
||||
separator = " ")
|
||||
@Getter
|
||||
public class CommandLineOptions implements Callable<ReturnValue> {
|
||||
|
||||
static final Option HELP = Option.builder("?").longOpt("help").argName("Help").desc("Displays this help").build();
|
||||
/**
|
||||
* @author Andreas Penski
|
||||
*/
|
||||
@Getter
|
||||
@NoArgsConstructor
|
||||
static class DaemonOptions {
|
||||
|
||||
static final Option SCENARIOS = Option.builder("s").required().longOpt("scenarios").hasArg().desc("Location of scenarios.xml e.g.")
|
||||
.build();
|
||||
@Option(names = { "-D", "--daemon" }, description = "Starts a daemon listing for validation requests", defaultValue = "false",
|
||||
required = true)
|
||||
private boolean daemonMode;
|
||||
|
||||
static final Option REPOSITORY = Option.builder("r").longOpt("repository").hasArg().desc("Directory containing scenario content")
|
||||
.build();
|
||||
@Option(names = { "-H", "--host" }, description = "The hostname / IP address to bind the daemon.", defaultValue = "localhost",
|
||||
showDefaultValue = Visibility.ALWAYS)
|
||||
private String host;
|
||||
|
||||
static final Option PRINT = Option.builder("p").longOpt("print").desc("Prints the check result to stdout").build();
|
||||
@Option(names = { "-P", "--port" }, description = "The port to bind the daemon.", defaultValue = "8080",
|
||||
showDefaultValue = Visibility.ALWAYS)
|
||||
private int port;
|
||||
|
||||
static final Option OUTPUT = Option.builder("o").longOpt("output-directory")
|
||||
.desc("Defines the out directory for results. Defaults to cwd").hasArg().build();
|
||||
@Option(names = { "-T", "--threads" },
|
||||
description = "Number of threads processing validation requests. Default depends on processor count", defaultValue = "-1",
|
||||
showDefaultValue = Visibility.NEVER)
|
||||
private int workerCount;
|
||||
|
||||
static final Option EXTRACT_HTML = Option.builder("h").longOpt("html")
|
||||
.desc("Extract and save any html content within result as a separate file ").build();
|
||||
|
||||
static final Option DEBUG = Option.builder("d").longOpt("debug").desc("Prints some more debug information").build();
|
||||
|
||||
static final Option SERIALIZE_REPORT_INPUT = Option.builder("c").longOpt("serialize-report-input")
|
||||
.desc("Serializes the report input to the cwd").build();
|
||||
|
||||
static final Option CHECK_ASSERTIONS = Option.builder("c").longOpt("check-assertions").hasArg()
|
||||
.desc("Check the result using defined assertions").argName("assertions-file").build();
|
||||
|
||||
static final Option SERVER = Option.builder("D").longOpt("daemon").desc("Starts a daemon listing for validation requests").build();
|
||||
|
||||
static final Option HOST = Option.builder("H").longOpt("host").hasArg()
|
||||
.desc("The hostname / IP address to bind the daemon. Default is localhost").build();
|
||||
|
||||
static final Option PORT = Option.builder("P").longOpt("port").hasArg().desc("The port to bind the daemon. Default is 8080").build();
|
||||
|
||||
static final Option WORKER_COUNT = Option.builder("T").longOpt("threads").hasArg()
|
||||
.desc("Number of threads processing validation requests").build();
|
||||
|
||||
static final Option DISABLE_GUI = Option.builder("G").longOpt("disable-gui").desc("Disables the GUI of the daemon mode").build();
|
||||
|
||||
static final Option REPORT_POSTFIX = Option.builder(null).longOpt("report-postfix").hasArg()
|
||||
.desc("Postfix of the generated report name").build();
|
||||
|
||||
static final Option REPORT_PREFIX = Option.builder(null).longOpt("report-prefix").hasArg().desc("Prefix of the generated report name")
|
||||
.build();
|
||||
|
||||
static final Option DEBUG_LOG = Option.builder("X").longOpt("debug-logging").desc("Enables full debug log. Alias for -l debug").build();
|
||||
|
||||
static final Option LOG_LEVEL = Option.builder("l").longOpt("log-level").hasArg()
|
||||
.desc("Enables a certain log level for debugging " + "purposes").build();
|
||||
|
||||
static final Option PRINT_MEM_STATS = Option.builder("m").longOpt("memory-stats").desc("Prints some memory stats").build();
|
||||
|
||||
private CommandLineOptions() {
|
||||
// hide
|
||||
@Option(names = { "-G", "--disable-gui" }, description = "Disables the GUI of the daemon mode")
|
||||
private boolean disableGUI;
|
||||
}
|
||||
|
||||
static org.apache.commons.cli.Options createOptions() {
|
||||
final org.apache.commons.cli.Options options = new org.apache.commons.cli.Options();
|
||||
options.addOption(HELP);
|
||||
options.addOption(SERVER);
|
||||
options.addOption(HOST);
|
||||
options.addOption(PORT);
|
||||
options.addOption(SCENARIOS);
|
||||
options.addOption(REPOSITORY);
|
||||
options.addOption(PRINT);
|
||||
options.addOption(OUTPUT);
|
||||
options.addOption(EXTRACT_HTML);
|
||||
options.addOption(DEBUG);
|
||||
options.addOption(CHECK_ASSERTIONS);
|
||||
options.addOption(PRINT_MEM_STATS);
|
||||
options.addOption(WORKER_COUNT);
|
||||
options.addOption(DISABLE_GUI);
|
||||
options.addOption(REPORT_POSTFIX);
|
||||
options.addOption(REPORT_PREFIX);
|
||||
options.addOption(LOG_LEVEL);
|
||||
options.addOption(DEBUG_LOG);
|
||||
return options;
|
||||
/**
|
||||
* @author Andreas Penski
|
||||
*/
|
||||
@Getter
|
||||
@NoArgsConstructor
|
||||
static class CliOptions {
|
||||
|
||||
@Option(names = { "-o", "--output-directory" }, description = "Defines the out directory for results.", defaultValue = ".",
|
||||
required = true)
|
||||
private Path outputPath;
|
||||
|
||||
@Option(names = { "-h", "--html", "--extract-html" },
|
||||
description = "Extract and save any html content within result as a separate file")
|
||||
private boolean extractHtml;
|
||||
|
||||
@Option(names = { "--serialize-report-input" }, description = "Serializes the report input to the cwd", defaultValue = "false")
|
||||
private boolean serializeInput;
|
||||
|
||||
@Option(names = { "-c", "--check-assertions" }, paramLabel = "assertions-file",
|
||||
description = "Check the result using defined assertions")
|
||||
private Path assertions;
|
||||
|
||||
@Option(names = { "--report-postfix" }, description = "Postfix of the generated report name")
|
||||
private String reportPostfix;
|
||||
|
||||
@Option(names = { "--report-prefix" }, description = "Prefix of the generated report name")
|
||||
private String reportPrefix;
|
||||
|
||||
@Option(names = { "-m", "--memory-stats" }, description = "Prints some memory stats")
|
||||
private boolean printMemoryStats;
|
||||
|
||||
@Option(names = { "-p", "--print" }, description = "Prints the check result to stdout")
|
||||
private boolean printReport;
|
||||
|
||||
@Parameters(arity = "1..*", description = "Files to validate")
|
||||
private List<Path> files;
|
||||
|
||||
}
|
||||
|
||||
static void printHelp(final org.apache.commons.cli.Options options) {
|
||||
// automatically generate the help statement
|
||||
final HelpFormatter formatter = new HelpFormatter();
|
||||
formatter.printHelp("check-tool -s <scenario-config-file> [OPTIONS] [FILE]... ", options, false);
|
||||
/**
|
||||
* Definition of logical name and a path for a configuration artifact.
|
||||
*
|
||||
* @author Andreas Penski
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public abstract static class Definition {
|
||||
|
||||
String name;
|
||||
|
||||
Path path;
|
||||
}
|
||||
|
||||
static org.apache.commons.cli.Options createHelpOptions() {
|
||||
final org.apache.commons.cli.Options options = new org.apache.commons.cli.Options();
|
||||
options.addOption(HELP);
|
||||
return options;
|
||||
/**
|
||||
* Definition of logical name and a path for a repository.
|
||||
*
|
||||
* @author Andreas Penski
|
||||
*/
|
||||
public static class RepositoryDefinition extends Definition {
|
||||
// just for type safety
|
||||
}
|
||||
|
||||
/**
|
||||
* Definition of logical name and a path for a scenario configuration file.
|
||||
*
|
||||
* @author Andreas Penski
|
||||
*/
|
||||
public static class ScenarioDefinition extends Definition {
|
||||
// just for type safety
|
||||
}
|
||||
|
||||
@ArgGroup(exclusive = false, heading = "Daemon options\n")
|
||||
private DaemonOptions daemonOptions;
|
||||
|
||||
@ArgGroup(exclusive = false, heading = "CLI usage options\n")
|
||||
private CliOptions cliOptions;
|
||||
|
||||
@Option(names = { "-d", "--debug" }, description = "Prints some more debug information")
|
||||
private boolean debugOutput;
|
||||
|
||||
@Option(names = { "-?", "--help" }, usageHelp = true, description = "display this help message")
|
||||
boolean usageHelpRequested;
|
||||
|
||||
@Option(names = { "-X", "--debug-logging" }, description = "Enables full debug log. Alias for -l debug")
|
||||
private boolean debugLog;
|
||||
|
||||
@Option(names = { "-l", "--log-level" }, description = "Enables a certain log level for debugging purposes", defaultValue = "OFF")
|
||||
private Level logLevel;
|
||||
|
||||
@Option(names = { "-r", "--repository" }, paramLabel = "repository-path", description = "Directory containing scenario content",
|
||||
converter = TypeConverter.RepositoryConverter.class)
|
||||
private List<RepositoryDefinition> repositories;
|
||||
|
||||
@Option(names = { "-s", "--scenarios" }, description = "Location of scenarios.xml", paramLabel = "scenario.xml", required = true,
|
||||
converter = TypeConverter.ScenarioConverter.class)
|
||||
private List<ScenarioDefinition> scenarios;
|
||||
|
||||
@Override
|
||||
public ReturnValue call() throws Exception {
|
||||
configureLogging(this);
|
||||
return Validator.mainProgram(this);
|
||||
}
|
||||
|
||||
private static void configureLogging(final CommandLineOptions cmd) {
|
||||
if (cmd.isDebugLog()) {
|
||||
System.setProperty(org.slf4j.impl.SimpleLogger.DEFAULT_LOG_LEVEL_KEY, "DEBUG");
|
||||
} else {
|
||||
System.setProperty(org.slf4j.impl.SimpleLogger.DEFAULT_LOG_LEVEL_KEY, cmd.getLogLevel().name());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isDaemonModeEnabled() {
|
||||
return getDaemonOptions() != null;
|
||||
}
|
||||
|
||||
public boolean isCliModeEnabled() {
|
||||
return getCliOptions() != null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@ import de.kosit.validationtool.cmd.report.Line;
|
|||
import de.kosit.validationtool.impl.DefaultCheck;
|
||||
import de.kosit.validationtool.impl.tasks.CheckAction;
|
||||
|
||||
import net.sf.saxon.s9api.Processor;
|
||||
|
||||
/**
|
||||
* Simple Erweiterung der Klasse {@link DefaultCheck} um das Ergebnis der Assertion-Prüfung auszuwerten und auszugeben.
|
||||
* Diese Klasse stellt keine fachliche Erweiterung des eigentlichen Prüfvorganges dar!
|
||||
|
|
@ -55,8 +57,8 @@ class InternalCheck extends DefaultCheck {
|
|||
*
|
||||
* @param configuration die Konfiguration
|
||||
*/
|
||||
InternalCheck(final Configuration configuration) {
|
||||
super(configuration);
|
||||
InternalCheck(final Processor processor, final Configuration... configuration) {
|
||||
super(processor, configuration);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ public class ReturnValue {
|
|||
|
||||
public static final ReturnValue SUCCESS = new ReturnValue(0);
|
||||
|
||||
public static final ReturnValue HELP_REQUEST = new ReturnValue(0);
|
||||
|
||||
public static final ReturnValue CONFIGURATION_ERROR = new ReturnValue(-2);
|
||||
|
||||
public static final ReturnValue DAEMON_MODE = new ReturnValue(-100);
|
||||
|
|
@ -41,4 +43,5 @@ public class ReturnValue {
|
|||
public static ReturnValue createFailed(final int count) {
|
||||
return new ReturnValue(count);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
99
src/main/java/de/kosit/validationtool/cmd/TypeConverter.java
Normal file
99
src/main/java/de/kosit/validationtool/cmd/TypeConverter.java
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* Copyright 2017-2021 Koordinierungsstelle für IT-Standards (KoSIT)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package de.kosit.validationtool.cmd;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import de.kosit.validationtool.cmd.CommandLineOptions.Definition;
|
||||
import de.kosit.validationtool.cmd.CommandLineOptions.RepositoryDefinition;
|
||||
import de.kosit.validationtool.cmd.CommandLineOptions.ScenarioDefinition;
|
||||
import de.kosit.validationtool.impl.ScenarioRepository;
|
||||
|
||||
import picocli.CommandLine.ITypeConverter;
|
||||
|
||||
/**
|
||||
* Custom type converters for dealing with command line input.
|
||||
*
|
||||
* @author Andreas Penski
|
||||
*/
|
||||
class TypeConverter {
|
||||
|
||||
/**
|
||||
* Type converter for a repository definition specification e.g. '-r somelocation.xml OR -r myid=somelocation.xml'
|
||||
*
|
||||
* @author Andreas Penski
|
||||
*/
|
||||
public static class RepositoryConverter implements ITypeConverter<RepositoryDefinition> {
|
||||
|
||||
@Override
|
||||
public RepositoryDefinition convert(final String value) throws Exception {
|
||||
return TypeConverter.convert(RepositoryDefinition.class, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Type converter for a scenario definition specification e.g. '-s somelocation.xml OR -s myid=somelocation.xml'
|
||||
*
|
||||
* @author Andreas Penski
|
||||
*/
|
||||
public static class ScenarioConverter implements ITypeConverter<ScenarioDefinition> {
|
||||
|
||||
@Override
|
||||
public ScenarioDefinition convert(final String value) throws Exception {
|
||||
return TypeConverter.convert(ScenarioDefinition.class, value);
|
||||
}
|
||||
}
|
||||
|
||||
final static Map<Class<?>, AtomicInteger> counter = new HashMap<>();
|
||||
|
||||
private static String getDefaultName(final Class<?> type) {
|
||||
final AtomicInteger current = counter.computeIfAbsent(type, a -> new AtomicInteger(1));
|
||||
return ScenarioRepository.DEFAULT + "_" + current.getAndIncrement();
|
||||
}
|
||||
|
||||
private static <T extends Definition> T convert(final Class<T> type, final String value) {
|
||||
T def = null;
|
||||
if (isNotBlank(value)) {
|
||||
final String[] splitted = value.split("=");
|
||||
if (splitted.length == 1) {
|
||||
def = createNewInstance(type);
|
||||
def.setName(getDefaultName(type));
|
||||
def.setPath(Paths.get(splitted[0].trim()));
|
||||
} else if (splitted.length == 2) {
|
||||
def = createNewInstance(type);
|
||||
def.setName(splitted[0].trim());
|
||||
def.setPath(Paths.get(splitted[1].trim()));
|
||||
} else {
|
||||
throw new IllegalArgumentException("Not a valid repository specification " + value);
|
||||
}
|
||||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
private static <T extends Definition> T createNewInstance(final Class<T> type) {
|
||||
try {
|
||||
return type.getConstructor().newInstance();
|
||||
} catch (final ReflectiveOperationException e) {
|
||||
throw new IllegalStateException("Error creating instance of type " + type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -16,25 +16,9 @@
|
|||
|
||||
package de.kosit.validationtool.cmd;
|
||||
|
||||
import static de.kosit.validationtool.cmd.CommandLineOptions.CHECK_ASSERTIONS;
|
||||
import static de.kosit.validationtool.cmd.CommandLineOptions.DEBUG;
|
||||
import static de.kosit.validationtool.cmd.CommandLineOptions.DISABLE_GUI;
|
||||
import static de.kosit.validationtool.cmd.CommandLineOptions.EXTRACT_HTML;
|
||||
import static de.kosit.validationtool.cmd.CommandLineOptions.HELP;
|
||||
import static de.kosit.validationtool.cmd.CommandLineOptions.HOST;
|
||||
import static de.kosit.validationtool.cmd.CommandLineOptions.OUTPUT;
|
||||
import static de.kosit.validationtool.cmd.CommandLineOptions.PORT;
|
||||
import static de.kosit.validationtool.cmd.CommandLineOptions.PRINT;
|
||||
import static de.kosit.validationtool.cmd.CommandLineOptions.PRINT_MEM_STATS;
|
||||
import static de.kosit.validationtool.cmd.CommandLineOptions.REPORT_POSTFIX;
|
||||
import static de.kosit.validationtool.cmd.CommandLineOptions.REPORT_PREFIX;
|
||||
import static de.kosit.validationtool.cmd.CommandLineOptions.REPOSITORY;
|
||||
import static de.kosit.validationtool.cmd.CommandLineOptions.SCENARIOS;
|
||||
import static de.kosit.validationtool.cmd.CommandLineOptions.SERIALIZE_REPORT_INPUT;
|
||||
import static de.kosit.validationtool.cmd.CommandLineOptions.SERVER;
|
||||
import static de.kosit.validationtool.cmd.CommandLineOptions.WORKER_COUNT;
|
||||
import static de.kosit.validationtool.cmd.CommandLineOptions.createOptions;
|
||||
import static de.kosit.validationtool.cmd.CommandLineOptions.printHelp;
|
||||
import static org.apache.commons.lang3.ObjectUtils.defaultIfNull;
|
||||
import static org.apache.commons.lang3.StringUtils.EMPTY;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotEmpty;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
|
@ -42,18 +26,15 @@ import java.nio.file.Files;
|
|||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import org.apache.commons.cli.Option;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.fusesource.jansi.AnsiRenderer.Code;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
|
@ -62,18 +43,23 @@ import de.kosit.validationtool.api.Configuration;
|
|||
import de.kosit.validationtool.api.Input;
|
||||
import de.kosit.validationtool.api.InputFactory;
|
||||
import de.kosit.validationtool.api.Result;
|
||||
import de.kosit.validationtool.cmd.CommandLineOptions.CliOptions;
|
||||
import de.kosit.validationtool.cmd.CommandLineOptions.Definition;
|
||||
import de.kosit.validationtool.cmd.CommandLineOptions.RepositoryDefinition;
|
||||
import de.kosit.validationtool.cmd.CommandLineOptions.ScenarioDefinition;
|
||||
import de.kosit.validationtool.cmd.assertions.Assertions;
|
||||
import de.kosit.validationtool.cmd.report.Line;
|
||||
import de.kosit.validationtool.config.ConfigurationLoader;
|
||||
import de.kosit.validationtool.daemon.Daemon;
|
||||
import de.kosit.validationtool.impl.ConversionService;
|
||||
import de.kosit.validationtool.impl.EngineInformation;
|
||||
import de.kosit.validationtool.impl.Printer;
|
||||
import de.kosit.validationtool.impl.ScenarioRepository;
|
||||
import de.kosit.validationtool.impl.xml.ProcessorProvider;
|
||||
|
||||
import net.sf.saxon.s9api.Processor;
|
||||
|
||||
/**
|
||||
* Actual evaluation and processing of commandline argumtens.
|
||||
* Actual evaluation and processing of CommandLineOptions argumtens.
|
||||
*
|
||||
* @author Andreas Penski
|
||||
*/
|
||||
|
|
@ -90,23 +76,23 @@ public class Validator {
|
|||
*
|
||||
* @param cmd parsed commandline.
|
||||
*/
|
||||
static ReturnValue mainProgram(final CommandLine cmd) {
|
||||
static ReturnValue mainProgram(final CommandLineOptions cmd) {
|
||||
greeting();
|
||||
final org.apache.commons.cli.Options options = createOptions();
|
||||
final ReturnValue returnValue;
|
||||
try {
|
||||
if (cmd.hasOption(SERVER.getOpt())) {
|
||||
if (cmd.isDaemonModeEnabled()) {
|
||||
startDaemonMode(cmd);
|
||||
returnValue = ReturnValue.DAEMON_MODE;
|
||||
} else if (cmd.hasOption(HELP.getOpt()) || (cmd.getArgList().isEmpty() && !isPiped())) {
|
||||
printHelp(options);
|
||||
returnValue = ReturnValue.PARSING_ERROR;
|
||||
} else {
|
||||
} else if (cmd.isCliModeEnabled() || isPiped()) {
|
||||
returnValue = processActions(cmd);
|
||||
} else {
|
||||
Printer.writeErr("No test target found");
|
||||
returnValue = ReturnValue.CONFIGURATION_ERROR;
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
e.printStackTrace();
|
||||
Printer.writeErr(e.getMessage());
|
||||
if (cmd.hasOption(DEBUG.getOpt())) {
|
||||
if (cmd.isDebugOutput()) {
|
||||
log.error(e.getMessage(), e);
|
||||
} else {
|
||||
log.error(e.getMessage());
|
||||
|
|
@ -120,83 +106,55 @@ public class Validator {
|
|||
Printer.writeOut("{0} version {1}", EngineInformation.getName(), EngineInformation.getVersion());
|
||||
}
|
||||
|
||||
private static int determinePort(final CommandLine cmd) {
|
||||
int port = 8080;
|
||||
if (checkOptionWithValue(PORT, cmd)) {
|
||||
port = Integer.parseInt(cmd.getOptionValue(PORT.getOpt()));
|
||||
}
|
||||
return port;
|
||||
}
|
||||
|
||||
private static int determineThreads(final CommandLine cmd) {
|
||||
private static int determineThreads(final CommandLineOptions.DaemonOptions cmd) {
|
||||
int threads = Runtime.getRuntime().availableProcessors();
|
||||
if (checkOptionWithValue(WORKER_COUNT, cmd)) {
|
||||
threads = Integer.parseInt(cmd.getOptionValue(WORKER_COUNT.getOpt()));
|
||||
if (cmd.getWorkerCount() > 0) {
|
||||
threads = cmd.getWorkerCount();
|
||||
}
|
||||
return threads;
|
||||
}
|
||||
|
||||
private static String determineHost(final CommandLine cmd) {
|
||||
String host = "localhost";
|
||||
if (checkOptionWithValue(HOST, cmd)) {
|
||||
host = cmd.getOptionValue(HOST.getOpt());
|
||||
private static void startDaemonMode(final CommandLineOptions cmd) {
|
||||
if (cmd.isCliModeEnabled()) {
|
||||
Printer.writeErr("Mixed mode configuration detected. Use either daemon mode or cli mode commandline options. They are mutual "
|
||||
+ "exclusive. Will ignore cli mode options");
|
||||
}
|
||||
return host;
|
||||
}
|
||||
|
||||
private static void startDaemonMode(final CommandLine cmd) {
|
||||
final Option[] unavailable = new Option[] { PRINT, CHECK_ASSERTIONS, DEBUG, OUTPUT, EXTRACT_HTML, REPORT_POSTFIX, REPORT_PREFIX };
|
||||
warnUnusedOptions(cmd, unavailable, true);
|
||||
final ConfigurationLoader config = getConfiguration(cmd);
|
||||
final Daemon validDaemon = new Daemon(determineHost(cmd), determinePort(cmd), determineThreads(cmd));
|
||||
if (cmd.hasOption(DISABLE_GUI.getOpt())) {
|
||||
validDaemon.setGuiEnabled(false);
|
||||
}
|
||||
final Configuration configuration = config.build();
|
||||
printScenarios(configuration);
|
||||
final List<Configuration> configuration = getConfiguration(cmd);
|
||||
final CommandLineOptions.DaemonOptions daemonOptions = cmd.getDaemonOptions();
|
||||
final Daemon validDaemon = new Daemon(daemonOptions.getHost(), daemonOptions.getPort(), determineThreads(daemonOptions));
|
||||
validDaemon.setGuiEnabled(!daemonOptions.isDisableGUI());
|
||||
Printer.writeOut("\nStarting daemon mode ...");
|
||||
validDaemon.startServer(configuration);
|
||||
validDaemon.startServer(ProcessorProvider.getProcessor(), configuration.toArray(new Configuration[configuration.size()]));
|
||||
}
|
||||
|
||||
private static void warnUnusedOptions(final CommandLine cmd, final Option[] unavailable, final boolean daemon) {
|
||||
Arrays.stream(cmd.getOptions()).filter(o -> ArrayUtils.contains(unavailable, o))
|
||||
.map(o -> "The option " + o.getLongOpt() + " is not available in daemon mode").forEach(log::error);
|
||||
if (daemon && !cmd.getArgList().isEmpty()) {
|
||||
log.info("Ignoring test targets in daemon mode");
|
||||
}
|
||||
}
|
||||
|
||||
private static ReturnValue processActions(final CommandLine cmd) throws IOException {
|
||||
private static ReturnValue processActions(final CommandLineOptions cmd) throws IOException {
|
||||
long start = System.currentTimeMillis();
|
||||
final Option[] unavailable = new Option[] { HOST, PORT, WORKER_COUNT, DISABLE_GUI };
|
||||
warnUnusedOptions(cmd, unavailable, false);
|
||||
final Configuration config = getConfiguration(cmd).build();
|
||||
printScenarios(config);
|
||||
final InternalCheck check = new InternalCheck(config);
|
||||
final Path outputDirectory = determineOutputDirectory(cmd);
|
||||
|
||||
final Processor processor = config.getContentRepository().getProcessor();
|
||||
if (cmd.hasOption(EXTRACT_HTML.getOpt())) {
|
||||
final Processor processor = ProcessorProvider.getProcessor();
|
||||
final List<Configuration> config = getConfiguration(cmd);
|
||||
final InternalCheck check = new InternalCheck(processor, config.toArray(new Configuration[0]));
|
||||
final CommandLineOptions.CliOptions cliOptions = defaultIfNull(cmd.getCliOptions(), new CliOptions());
|
||||
final Path outputDirectory = determineOutputDirectory(cliOptions);
|
||||
if (cliOptions.isExtractHtml()) {
|
||||
check.getCheckSteps().add(new ExtractHtmlContentAction(processor, outputDirectory));
|
||||
}
|
||||
check.getCheckSteps().add(new SerializeReportAction(outputDirectory, processor, determineNamingStrategy(cmd)));
|
||||
if (cmd.hasOption(SERIALIZE_REPORT_INPUT.getOpt())) {
|
||||
check.getCheckSteps().add(new SerializeReportAction(outputDirectory, processor, determineNamingStrategy(cliOptions)));
|
||||
if (cliOptions.isSerializeInput()) {
|
||||
check.getCheckSteps().add(new SerializeReportInputAction(outputDirectory, check.getConversionService()));
|
||||
}
|
||||
if (cmd.hasOption(PRINT.getOpt())) {
|
||||
if (cliOptions.isPrintReport()) {
|
||||
check.getCheckSteps().add(new PrintReportAction(processor));
|
||||
}
|
||||
|
||||
if (cmd.hasOption(CHECK_ASSERTIONS.getOpt())) {
|
||||
final Assertions assertions = loadAssertions(cmd.getOptionValue(CHECK_ASSERTIONS.getOpt()));
|
||||
if (cliOptions.getAssertions() != null) {
|
||||
final Assertions assertions = loadAssertions(cliOptions.getAssertions());
|
||||
check.getCheckSteps().add(new CheckAssertionAction(assertions, processor));
|
||||
}
|
||||
if (cmd.hasOption(PRINT_MEM_STATS.getOpt())) {
|
||||
if (cliOptions.isPrintMemoryStats()) {
|
||||
check.getCheckSteps().add(new PrintMemoryStats());
|
||||
}
|
||||
log.info("Setup completed in {}ms\n", System.currentTimeMillis() - start);
|
||||
|
||||
final Collection<Input> targets = determineTestTargets(cmd);
|
||||
final Collection<Input> targets = determineTestTargets(cliOptions);
|
||||
start = System.currentTimeMillis();
|
||||
final Map<String, Result> results = new HashMap<>();
|
||||
Printer.writeOut("\nProcessing of {0} objects started", targets.size());
|
||||
|
|
@ -216,42 +174,79 @@ public class Validator {
|
|||
return check.isSuccessful(results) ? ReturnValue.SUCCESS : ReturnValue.createFailed(check.getNotAcceptableCount(results));
|
||||
}
|
||||
|
||||
private static ConfigurationLoader getConfiguration(final CommandLine cmd) {
|
||||
final URI scenarioLocation = determineDefinition(cmd);
|
||||
final URI repositoryLocation = determineRepository(cmd);
|
||||
reportConfiguration(scenarioLocation, repositoryLocation);
|
||||
return Configuration.load(scenarioLocation, repositoryLocation);
|
||||
/**
|
||||
* @param cmd the Command Line Options
|
||||
*
|
||||
* @return a list of configurations of the scenarios and repositories passed in cmd
|
||||
*/
|
||||
private static List<Configuration> getConfiguration(final CommandLineOptions cmd) {
|
||||
final List<ScenarioDefinition> scenarios = defaultIfNull(cmd.getScenarios(), Collections.emptyList());
|
||||
final Map<String, Path> mappedScenarios = scenarios.stream()
|
||||
.collect(Collectors.toMap(ScenarioDefinition::getName, ScenarioDefinition::getPath));
|
||||
final List<RepositoryDefinition> repos = defaultIfNull(cmd.getRepositories(), Collections.emptyList());
|
||||
final Map<String, Path> mappedRepos = repos.stream().collect(Collectors.toMap(Definition::getName, Definition::getPath));
|
||||
checkUnused(mappedScenarios, mappedRepos);
|
||||
|
||||
return mappedScenarios.entrySet().stream().map(e -> {
|
||||
assertFileExistance(e.getValue(), "scenario");
|
||||
final URI scenarioLocation = e.getValue().toUri();
|
||||
final URI repositoryLocation = findRepository(e.getKey(), mappedRepos);
|
||||
|
||||
reportLoading(scenarioLocation, repositoryLocation);
|
||||
final Configuration configuration = Configuration.load(scenarioLocation, repositoryLocation)
|
||||
.build(ProcessorProvider.getProcessor());
|
||||
reportConfiguration(configuration);
|
||||
return configuration;
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
}
|
||||
|
||||
private static void reportConfiguration(final URI scenarioLocation, final URI repositoryLocation) {
|
||||
private static void checkUnused(final Map<String, Path> scenarios, final Map<String, Path> repositories) {
|
||||
final List<Entry<String, Path>> unused = repositories.entrySet().stream().filter(e -> scenarios.get(e.getKey()) == null)
|
||||
.collect(Collectors.toList());
|
||||
unused.removeIf(e -> e.getKey().equals(ScenarioRepository.DEFAULT_ID));
|
||||
unused.forEach(e -> Printer.writeErr("Warning: repository definition \"{0}\" is not used", e.getKey()));
|
||||
}
|
||||
|
||||
private static URI findRepository(final String key, final Map<String, Path> repositories) {
|
||||
final Path path = repositories.getOrDefault(key, repositories.get(ScenarioRepository.DEFAULT_ID));
|
||||
if (path == null) {
|
||||
throw new IllegalArgumentException(String.format("No repository location for scenario definition '%s' specified", key));
|
||||
}
|
||||
return determineRepository(path);
|
||||
}
|
||||
|
||||
private static void reportLoading(final URI scenarioLocation, final URI repositoryLocation) {
|
||||
Printer.writeOut("Loading scenarios from {0}", scenarioLocation);
|
||||
Printer.writeOut("Using repository {0}", repositoryLocation);
|
||||
Printer.writeOut(EMPTY);
|
||||
}
|
||||
|
||||
private static void printScenarios(final Configuration configuration) {
|
||||
private static void reportConfiguration(final Configuration configuration) {
|
||||
Printer.writeOut("Loaded \"{0}\" by {1} from {2} ", configuration.getName(), configuration.getAuthor(), configuration.getDate());
|
||||
Printer.writeOut("\nThe following scenarios are available:");
|
||||
Printer.writeOut("The following scenarios are available:");
|
||||
configuration.getScenarios().forEach(e -> {
|
||||
final Line line = new Line(Code.GREEN);
|
||||
line.add(" * " + e.getName());
|
||||
Printer.writeOut(line.render(false, false));
|
||||
|
||||
});
|
||||
Printer.writeOut(EMPTY);
|
||||
|
||||
}
|
||||
|
||||
private static NamingStrategy determineNamingStrategy(final CommandLine cmd) {
|
||||
private static NamingStrategy determineNamingStrategy(final CommandLineOptions.CliOptions cmd) {
|
||||
final DefaultNamingStrategy namingStrategy = new DefaultNamingStrategy();
|
||||
if (cmd.hasOption(REPORT_PREFIX.getLongOpt())) {
|
||||
namingStrategy.setPrefix(cmd.getOptionValue(REPORT_PREFIX.getLongOpt()));
|
||||
if (isNotEmpty(cmd.getReportPrefix())) {
|
||||
namingStrategy.setPrefix(cmd.getReportPrefix());
|
||||
}
|
||||
if (cmd.hasOption(REPORT_POSTFIX.getLongOpt())) {
|
||||
namingStrategy.setPostfix(cmd.getOptionValue(REPORT_POSTFIX.getLongOpt()));
|
||||
if (isNotEmpty(cmd.getReportPostfix())) {
|
||||
namingStrategy.setPostfix(cmd.getReportPostfix());
|
||||
}
|
||||
|
||||
return namingStrategy;
|
||||
}
|
||||
|
||||
private static Assertions loadAssertions(final String optionValue) {
|
||||
final Path p = Paths.get(optionValue);
|
||||
private static Assertions loadAssertions(final Path p) {
|
||||
Assertions a = null;
|
||||
if (Files.exists(p)) {
|
||||
final ConversionService c = new ConversionService();
|
||||
|
|
@ -261,24 +256,23 @@ public class Validator {
|
|||
return a;
|
||||
}
|
||||
|
||||
private static Path determineOutputDirectory(final CommandLine cmd) {
|
||||
final String value = cmd.getOptionValue(OUTPUT.getOpt());
|
||||
final Path fir;
|
||||
if (StringUtils.isNotBlank(value)) {
|
||||
fir = Paths.get(value);
|
||||
if ((!Files.exists(fir) && !fir.toFile().mkdirs()) || !Files.isDirectory(fir)) {
|
||||
throw new IllegalStateException(String.format("Invalid target directory %s specified", value));
|
||||
private static Path determineOutputDirectory(final CommandLineOptions.CliOptions cmd) {
|
||||
final Path dir;
|
||||
if (cmd.getOutputPath() != null) {
|
||||
dir = cmd.getOutputPath();
|
||||
if ((!Files.exists(dir) && !dir.toFile().mkdirs()) || !Files.isDirectory(dir)) {
|
||||
throw new IllegalStateException(String.format("Invalid target directory %s specified", dir.toString()));
|
||||
}
|
||||
} else {
|
||||
fir = Paths.get(""/* cwd */);
|
||||
dir = Paths.get(""/* cwd */);
|
||||
}
|
||||
return fir;
|
||||
return dir;
|
||||
}
|
||||
|
||||
private static Collection<Input> determineTestTargets(final CommandLine cmd) throws IOException {
|
||||
private static Collection<Input> determineTestTargets(final CommandLineOptions.CliOptions cmd) throws IOException {
|
||||
final Collection<Input> targets = new ArrayList<>();
|
||||
if (!cmd.getArgList().isEmpty()) {
|
||||
cmd.getArgList().forEach(e -> targets.addAll(determineTestTarget(e)));
|
||||
if (cmd.getFiles() != null && !cmd.getFiles().isEmpty()) {
|
||||
cmd.getFiles().forEach(e -> targets.addAll(determineTestTarget(e)));
|
||||
}
|
||||
if (isPiped()) {
|
||||
targets.add(readFromPipe());
|
||||
|
|
@ -289,22 +283,23 @@ public class Validator {
|
|||
return targets;
|
||||
}
|
||||
|
||||
@SuppressWarnings("java:S4829") // sanitation is delegated to xml stack
|
||||
private static boolean isPiped() throws IOException {
|
||||
return System.in.available() > 0;
|
||||
}
|
||||
|
||||
@SuppressWarnings("java:S4829") // sanitation is delegated to xml stack
|
||||
private static Input readFromPipe() {
|
||||
return InputFactory.read(System.in, "stdin");
|
||||
}
|
||||
|
||||
private static Collection<Input> determineTestTarget(final String s) {
|
||||
final Path d = Paths.get(s);
|
||||
private static Collection<Input> determineTestTarget(final Path d) {
|
||||
if (Files.isDirectory(d)) {
|
||||
return listDirectoryTargets(d);
|
||||
} else if (Files.exists(d)) {
|
||||
return Collections.singleton(InputFactory.read(d));
|
||||
}
|
||||
log.warn("The specified test target {} does not exist. Will be ignored", s);
|
||||
log.warn("The specified test target {} does not exist. Will be ignored", d);
|
||||
return Collections.emptyList();
|
||||
|
||||
}
|
||||
|
|
@ -319,44 +314,21 @@ public class Validator {
|
|||
|
||||
}
|
||||
|
||||
private static URI determineRepository(final CommandLine cmd) {
|
||||
if (checkOptionWithValue(REPOSITORY, cmd)) {
|
||||
final Path d = Paths.get(cmd.getOptionValue(REPOSITORY.getOpt()));
|
||||
if (Files.isDirectory(d)) {
|
||||
return d.toUri();
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
String.format("Not a valid path for repository definition specified: '%s'", d.toAbsolutePath()));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static URI determineDefinition(final CommandLine cmd) {
|
||||
checkOptionWithValue(SCENARIOS, cmd);
|
||||
final Path f = Paths.get(cmd.getOptionValue(SCENARIOS.getOpt()));
|
||||
if (Files.isRegularFile(f)) {
|
||||
return f.toAbsolutePath().toUri();
|
||||
private static URI determineRepository(final Path d) {
|
||||
if (Files.isDirectory(d)) {
|
||||
return d.toUri();
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
String.format("Not a valid path for scenario definition specified: '%s'", f.toAbsolutePath()));
|
||||
String.format("Not a valid path for repository definition specified: '%s'", d.toAbsolutePath()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static boolean checkOptionWithValue(final Option option, final CommandLine cmd) {
|
||||
final String opt = option.getOpt();
|
||||
if (cmd.hasOption(opt)) {
|
||||
final String value = cmd.getOptionValue(opt);
|
||||
if (StringUtils.isNoneBlank(value)) {
|
||||
return true;
|
||||
} else {
|
||||
throw new IllegalArgumentException(String.format("Option value required for Option '%s'", option.getLongOpt()));
|
||||
}
|
||||
} else if (option.isRequired()) {
|
||||
|
||||
throw new IllegalArgumentException(String.format("Option '%s' required ", option.getLongOpt()));
|
||||
private static void assertFileExistance(final Path f, final String type) {
|
||||
if (!Files.isRegularFile(f)) {
|
||||
throw new IllegalArgumentException(
|
||||
String.format("Not a valid path for %s definition specified: '%s'", type, f.toAbsolutePath()));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue