From e265667f253e6a15e61b11ac31453fac76170165 Mon Sep 17 00:00:00 2001
From: Andreas Penski <18-andreas.penski@users.noreply.projekte.kosit.org>
Date: Mon, 10 Aug 2020 06:38:20 +0000
Subject: [PATCH] Resolve "Validator new feature: Pruefbericht Gesamtuebersicht
bei Batch Verarbeitung"
---
.idea/encodings.xml | 1 +
CHANGELOG.md | 8 +-
docs/api.md | 2 +-
pom.xml | 14 +-
.../api/CheckConfiguration.java | 2 +-
.../cmd/CommandLineApplication.java | 16 +-
.../cmd/DefaultNamingStrategy.java | 2 +-
.../validationtool/cmd/InternalCheck.java | 73 +++-
.../validationtool/cmd/PrintReportAction.java | 8 +-
.../validationtool/cmd/report/Format.java | 84 +++++
.../kosit/validationtool/cmd/report/Grid.java | 320 ++++++++++++++++++
.../validationtool/cmd/report/Justify.java | 35 ++
.../kosit/validationtool/cmd/report/Line.java | 106 ++++++
.../kosit/validationtool/cmd/report/Text.java | 63 ++++
.../validationtool/daemon/CheckHandler.java | 1 +
.../validationtool/daemon/GuiHandler.java | 19 +-
.../validationtool/daemon/HealthHandler.java | 8 +-
.../validationtool/daemon/RoutingHandler.java | 14 +-
.../impl/ClassPathResourceResolver.java | 3 +-
.../impl/CollectingErrorEventHandler.java | 11 +-
.../impl/ContentRepository.java | 2 +-
.../impl/ConversionService.java | 2 +-
.../impl/input/SourceInput.java | 12 +-
.../impl/input/StreamHelper.java | 4 +
.../validationtool/impl/model/BaseOutput.java | 6 +-
.../impl/model/BaseXMLSyntaxError.java | 24 --
.../impl/tasks/SchemaValidationAction.java | 2 +
.../xml/StrictRelativeResolvingStrategy.java | 11 +-
.../validationtool/daemon/CheckHandlerIT.java | 34 +-
.../validationtool/impl/DefaultCheckTest.java | 9 +-
.../impl/SimpleScenarioCheckTest.java | 5 +-
31 files changed, 791 insertions(+), 110 deletions(-)
create mode 100644 src/main/java/de/kosit/validationtool/cmd/report/Format.java
create mode 100644 src/main/java/de/kosit/validationtool/cmd/report/Grid.java
create mode 100644 src/main/java/de/kosit/validationtool/cmd/report/Justify.java
create mode 100644 src/main/java/de/kosit/validationtool/cmd/report/Line.java
create mode 100644 src/main/java/de/kosit/validationtool/cmd/report/Text.java
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
index 63fc954..893896a 100644
--- a/.idea/encodings.xml
+++ b/.idea/encodings.xml
@@ -5,6 +5,7 @@
+
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d5e7c79..0c80cb9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,12 +9,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
- `getFailedAsserts()` and `isSchematronValid()` in [DefaultResult.java](https://github.com/itplr-kosit/validator/blob/master/src/main/java/de/kosit/validationtool/impl/DefaultResult.java)
do not reflect actual schematron validation result
-- Processing aborts on schematron execution errors (e.g. errors within schematron logic). The validator now generates a report in such cases.
+- processing aborts on schematron execution errors (e.g. errors within schematron logic). The validator now generates a report in such cases.
- exception while resolving when using XSLT's `unparsed-text()` function within report generation
+### Added
+- [CLI] add summary report
+
### Changed
- engine info contains version number of the validator (configurations can output this in the report for maintainance puposes)
-- Options to customize serialized report file names (cmdline only) via `--report-prefix` and `--report-postfix`
+- options to customize serialized report file names (cmdline only) via `--report-prefix` and `--report-postfix`
+- remove unused dependency Apache Commons HTTP
## 1.3.0
diff --git a/docs/api.md b/docs/api.md
index e2bed19..7999743 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -41,7 +41,7 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import de.kosit.validationtool.api.Check;
-import de.kosit.validationtool.api.CheckConfiguration;
+import de.kosit.validationtool.api.Configuration;
import de.kosit.validationtool.api.Input;
import de.kosit.validationtool.api.InputFactory;
import de.kosit.validationtool.api.Result;
diff --git a/pom.xml b/pom.xml
index 0c7b6d3..e60b16a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,6 +1,6 @@
-
+
4.0.0
KoSIT XML Prüftool Implementierung
@@ -76,6 +76,12 @@
1.4
true
+
+ org.fusesource.jansi
+ jansi
+ 1.18
+ true
+
org.slf4j
slf4j-simple
@@ -129,12 +135,6 @@
1.0.0
test
-
-org.apache.httpcomponents
-httpclient
- 4.5.8
-
-
diff --git a/src/main/java/de/kosit/validationtool/api/CheckConfiguration.java b/src/main/java/de/kosit/validationtool/api/CheckConfiguration.java
index 10b3d56..dddf41a 100644
--- a/src/main/java/de/kosit/validationtool/api/CheckConfiguration.java
+++ b/src/main/java/de/kosit/validationtool/api/CheckConfiguration.java
@@ -36,7 +36,7 @@ import de.kosit.validationtool.impl.Scenario;
* Zentrale Konfigration einer Prüf-Instanz.
*
* @author Andreas Penski
- * @deprecated since 2.0 use {@link Configuration} instead
+ * @deprecated since 1.3.0 use {@link Configuration} instead
*/
@Getter
@Setter
diff --git a/src/main/java/de/kosit/validationtool/cmd/CommandLineApplication.java b/src/main/java/de/kosit/validationtool/cmd/CommandLineApplication.java
index 9705028..5421f71 100644
--- a/src/main/java/de/kosit/validationtool/cmd/CommandLineApplication.java
+++ b/src/main/java/de/kosit/validationtool/cmd/CommandLineApplication.java
@@ -28,7 +28,10 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
@@ -45,6 +48,7 @@ import lombok.extern.slf4j.Slf4j;
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.assertions.Assertions;
import de.kosit.validationtool.config.ConfigurationLoader;
import de.kosit.validationtool.daemon.Daemon;
@@ -58,6 +62,7 @@ import net.sf.saxon.s9api.Processor;
* @author Andreas Penski
*/
@Slf4j
+@SuppressWarnings("squid:S3725") // performance is not a problem here
public class CommandLineApplication {
private static final Option HELP = Option.builder("?").longOpt("help").argName("Help").desc("Displays this help").build();
@@ -247,16 +252,17 @@ public class CommandLineApplication {
final Collection targets = determineTestTargets(cmd);
start = System.currentTimeMillis();
+ final Map results = new HashMap<>();
for (final Path p : targets) {
final Input input = InputFactory.read(p);
- check.checkInput(input);
+ results.put(p, check.checkInput(input));
}
- final boolean result = check.printAndEvaluate();
+ final boolean result = check.printAndEvaluate(results);
log.info("Processing {} object(s) completed in {}ms", targets.size(), System.currentTimeMillis() - start);
return result ? 0 : 1;
} catch (final Exception e) {
- e.printStackTrace();
+ e.printStackTrace();// NOSONAR
if (cmd.hasOption(DEBUG.getOpt())) {
log.error(e.getMessage(), e);
} else {
@@ -327,8 +333,8 @@ public class CommandLineApplication {
}
private static Collection listDirectoryTargets(final Path d) {
- try {
- return Files.list(d).filter(path -> path.toString().endsWith(".xml")).collect(Collectors.toList());
+ try ( final Stream stream = Files.list(d) ) {
+ return stream.filter(path -> path.toString().endsWith(".xml")).collect(Collectors.toList());
} catch (final IOException e) {
throw new IllegalStateException("IOException while list directory content. Can not determine test targets.", e);
}
diff --git a/src/main/java/de/kosit/validationtool/cmd/DefaultNamingStrategy.java b/src/main/java/de/kosit/validationtool/cmd/DefaultNamingStrategy.java
index b4ceeba..0debe17 100644
--- a/src/main/java/de/kosit/validationtool/cmd/DefaultNamingStrategy.java
+++ b/src/main/java/de/kosit/validationtool/cmd/DefaultNamingStrategy.java
@@ -25,7 +25,7 @@ public class DefaultNamingStrategy implements NamingStrategy {
if (StringUtils.isEmpty(base)) {
throw new IllegalArgumentException("Can not generate name based on null input");
}
- final int index = base.lastIndexOf(".");
+ final int index = base.lastIndexOf('.');
final StringBuilder result = new StringBuilder();
if (isNotEmpty(this.prefix)) {
result.append(this.prefix).append("-");
diff --git a/src/main/java/de/kosit/validationtool/cmd/InternalCheck.java b/src/main/java/de/kosit/validationtool/cmd/InternalCheck.java
index 2a2c007..4933fdf 100644
--- a/src/main/java/de/kosit/validationtool/cmd/InternalCheck.java
+++ b/src/main/java/de/kosit/validationtool/cmd/InternalCheck.java
@@ -19,14 +19,28 @@
package de.kosit.validationtool.cmd;
+import java.io.PrintWriter;
+import java.nio.file.Path;
+import java.util.Comparator;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.fusesource.jansi.AnsiRenderer.Code;
+
import lombok.extern.slf4j.Slf4j;
import de.kosit.validationtool.api.Configuration;
import de.kosit.validationtool.api.Input;
import de.kosit.validationtool.api.Result;
+import de.kosit.validationtool.api.XmlError;
+import de.kosit.validationtool.cmd.report.Grid;
+import de.kosit.validationtool.cmd.report.Grid.ColumnDefinition;
+import de.kosit.validationtool.cmd.report.Justify;
+import de.kosit.validationtool.cmd.report.Line;
import de.kosit.validationtool.impl.DefaultCheck;
import de.kosit.validationtool.impl.tasks.CheckAction;
+
/**
* Simple Erweiterung der Klasse {@link DefaultCheck} um das Ergebnis der Assertion-Prüfung auszwerten und auszugeben.
* Diese Klasse stellt keine fachlicher Erweiterung des eigentlichen Prüfvorganges dar!
@@ -66,7 +80,11 @@ class InternalCheck extends DefaultCheck {
return result;
}
- boolean printAndEvaluate() {
+ boolean printAndEvaluate(final Map results) {
+ final PrintWriter writer = new PrintWriter(System.out);// NOSONAR
+ writer.write(createResultGrid(results).render());
+ writer.write(createStatusLine(results));
+ writer.flush();
if (this.failedAssertions > 0) {
log.error("Assertion check failed.\n\nAssertions run: {}, Assertions failed: {}\n", this.checkAssertions,
this.failedAssertions);
@@ -74,7 +92,58 @@ class InternalCheck extends DefaultCheck {
log.info("Assertion check successful.\n\nAssertions run: {}, Assertions failed: {}\n", this.checkAssertions,
this.failedAssertions);
}
- return this.failedAssertions == 0;
+ return this.failedAssertions == 0 && results.entrySet().stream().allMatch(e -> e.getValue().isAcceptable());
+ }
+
+ private static String createStatusLine(final Map results) {
+ final long acceptable = results.entrySet().stream().filter(e -> e.getValue().isAcceptable()).count();
+ final long rejected = results.entrySet().stream().filter(e -> !e.getValue().isAcceptable()).count();
+ final long errors = results.entrySet().stream().filter(e -> !e.getValue().isProcessingSuccessful()).count();
+ final Line line = new Line();
+ line.add(String.format("Validation of %s objects finished. ", results.size()));
+ line.add("Acceptable: ").add(acceptable, Code.GREEN);
+ line.add(" Rejected: ").add(rejected, Code.RED);
+ if (errors > 0) {
+ line.add(" Processing errors: ").add(errors, Code.RED);
+ }
+ return line.render();
+ }
+
+ private static Grid createResultGrid(final Map results) {
+ final Grid grid = new Grid(
+ //@formatter:off
+ new ColumnDefinition("filename", 60, 10, 1),
+ new ColumnDefinition("Schema", 7).justify(Justify.CENTER),
+ new ColumnDefinition("Schematron", 10).justify(Justify.CENTER),
+ new ColumnDefinition("Acceptance", 10, 5).justify(Justify.CENTER),
+ new ColumnDefinition("Error/Description", 60,20,3)
+ );
+ //@formatter:on
+ results.entrySet().stream().sorted(Comparator.comparing(e -> e.getKey().getFileName())).forEach(e -> {
+ final Result value = e.getValue();
+
+ final Code textcolor = value.isAcceptable() ? Code.GREEN : Code.RED;
+ grid.addCell(e.getKey().getFileName(), textcolor);
+ grid.addCell(value.isSchemaValid() ? "Y" : "N", textcolor);
+ grid.addCell(value.isSchematronValid() ? "Y" : "N", textcolor);
+ grid.addCell(value.getAcceptRecommendation(), textcolor);
+ grid.addCell(joinErrors(value));
+ });
+ return grid;
+ }
+
+ private static String joinErrors(final Result value) {
+ final StringBuilder b = new StringBuilder();
+ b.append(String.join(";", value.getProcessingErrors()));
+ if (value.getSchemaViolations() != null && !value.getSchemaViolations().isEmpty()) {
+ b.append(b.length() > 0 ? ";" : "");
+ b.append(value.getSchemaViolations().stream().map(XmlError::getMessage).collect(Collectors.joining(";")));
+ }
+ if (value.getSchematronResult() != null && !value.getSchematronResult().isEmpty()) {
+ b.append(b.length() > 0 ? ";" : "");
+ b.append(value.getSchematronResult().stream().flatMap(e -> e.getMessages().stream()).collect(Collectors.joining(";")));
+ }
+ return b.toString();
}
}
diff --git a/src/main/java/de/kosit/validationtool/cmd/PrintReportAction.java b/src/main/java/de/kosit/validationtool/cmd/PrintReportAction.java
index 0659397..ba7c25b 100644
--- a/src/main/java/de/kosit/validationtool/cmd/PrintReportAction.java
+++ b/src/main/java/de/kosit/validationtool/cmd/PrintReportAction.java
@@ -42,13 +42,13 @@ class PrintReportAction implements CheckAction {
private final Processor processor;
@Override
- public void check(Bag results) {
+ public void check(final Bag results) {
try {
final StringWriter writer = new StringWriter();
- final Serializer serializer = processor.newSerializer(writer);
+ final Serializer serializer = this.processor.newSerializer(writer);
serializer.serializeNode(results.getReport());
- System.out.print(writer.toString());
- } catch (SaxonApiException e) {
+ System.out.print(writer.toString()); // NOSONAR
+ } catch (final SaxonApiException e) {
log.error("Error while printing result to stdout", e);
}
}
diff --git a/src/main/java/de/kosit/validationtool/cmd/report/Format.java b/src/main/java/de/kosit/validationtool/cmd/report/Format.java
new file mode 100644
index 0000000..58b3dfa
--- /dev/null
+++ b/src/main/java/de/kosit/validationtool/cmd/report/Format.java
@@ -0,0 +1,84 @@
+package de.kosit.validationtool.cmd.report;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.fusesource.jansi.AnsiRenderer.Code;
+
+import lombok.Getter;
+
+/**
+ * Simple value holder for ansi formatting codes.
+ *
+ * @author Andreas Penski
+ */
+@Getter
+public class Format {
+
+ private Code textColor;
+
+ private Code background;
+
+ @Getter
+ private final Set codes = new HashSet<>();
+
+ public Code[] mergeCodes(final Collection newCodes) {
+ return mergeCodes(newCodes.toArray(new Code[newCodes.size()]));
+ }
+
+ public Code[] mergeCodes(final Code... newCodes) {
+ final Code[] allCodes = ArrayUtils.addAll(ArrayUtils.addAll(this.codes.toArray(new Code[0]), newCodes), this.textColor,
+ this.background);
+
+ final Optional color = Arrays.stream(allCodes).filter(Objects::nonNull).filter(Code::isColor).findFirst();
+ final Optional bg = Arrays.stream(allCodes).filter(Objects::nonNull).filter(Code::isBackground).findFirst();
+ final List attributes = Arrays.stream(allCodes).filter(Objects::nonNull).filter(Code::isBackground).filter(Code::isColor)
+ .collect(Collectors.toList());
+ attributes.add(color.orElse(this.textColor));
+ attributes.add(bg.orElse(this.background));
+ return attributes.stream().filter(Objects::nonNull).toArray(Code[]::new);
+ }
+
+ /**
+ * Sets explicit text color.
+ *
+ * @param textColor the color.
+ *
+ * @return this {@link Format}
+ */
+ public Format color(final Code textColor) {
+ this.textColor = textColor;
+ return this;
+ }
+
+ /**
+ * Sets explicit background color.
+ *
+ * @param color the color.
+ *
+ * @return this {@link Format}
+ */
+ public Format background(final Code color) {
+ this.background = color;
+ return this;
+ }
+
+ /**
+ * Fügt weitere Formatierungscodes hinzu.
+ *
+ * @param codes die Codes
+ *
+ * @return this {@link Format}
+ */
+ public Format addCodes(final Code... codes) {
+ this.codes.addAll(Arrays.asList(codes));
+ return this;
+ }
+}
diff --git a/src/main/java/de/kosit/validationtool/cmd/report/Grid.java b/src/main/java/de/kosit/validationtool/cmd/report/Grid.java
new file mode 100644
index 0000000..f96b7ef
--- /dev/null
+++ b/src/main/java/de/kosit/validationtool/cmd/report/Grid.java
@@ -0,0 +1,320 @@
+package de.kosit.validationtool.cmd.report;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
+
+import org.apache.commons.lang3.StringUtils;
+import org.fusesource.jansi.AnsiRenderer.Code;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+/**
+ * An text based grid for cli based programs.
+ *
+ * @author Andreas Penski
+ */
+public class Grid {
+
+ /**
+ * A definition / configuration for a column with a result table.
+ */
+ @Getter
+ public static class ColumnDefinition {
+
+ private static final int MAX_LENGTH = 80;
+
+ private final String name;
+
+ private int length = 0;
+
+ private final int maxLength;
+
+ private final int minLength;
+
+ private final int maxLines;
+
+ private Justify justify = Justify.LEFT;
+
+ /**
+ * Constructor.
+ *
+ * @param name the name of the column
+ */
+ public ColumnDefinition(final String name) {
+ this(name, -1, -1, 1);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param name the name of the column
+ * @param maxLength the max length of the column
+ */
+ public ColumnDefinition(final String name, final int maxLength) {
+ this(name, maxLength, -1, 1);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param name the name of the column
+ * @param maxLength the max length of the column
+ */
+ public ColumnDefinition(final String name, final int maxLength, final int minLength) {
+ this(name, maxLength, minLength, 1);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param name the name of the column
+ * @param minLength the max length of the column
+ * @param maxLines the max lines per cell
+ */
+ public ColumnDefinition(final String name, final int maxLength, final int minLength, final int maxLines) {
+ this.name = name;
+ this.maxLength = maxLength;
+ this.minLength = minLength;
+ this.maxLines = maxLines;
+ }
+
+ /**
+ * Returns the actual max length of the column
+ *
+ * @return max length
+ */
+ public int getLength() {
+ if (this.minLength > 0 && this.minLength > this.length) {
+ return this.minLength;
+ }
+ if (this.maxLength > 0 && this.length > this.maxLength) {
+ return this.maxLength;
+ }
+ return this.length;
+ }
+
+ /**
+ * Sets a calculated length for the column.
+ *
+ * @param length the length
+ */
+ public void setLength(final int length) {
+ if (length > this.length) {
+ this.length = length;
+ }
+ if (length > MAX_LENGTH) {
+ this.length = MAX_LENGTH;
+ }
+ }
+
+ public ColumnDefinition justify(final Justify justify) {
+ this.justify = justify;
+ return this;
+ }
+ }
+
+ @RequiredArgsConstructor
+ @Getter
+ private static class Cell {
+
+ private final Format format = DEFAULT_FORMAT;
+
+ private final List text;
+
+ public Cell(final Text txt) {
+ this.text = new ArrayList<>();
+ this.text.add(txt);
+ }
+
+ public Cell(final Object object, final Code... codes) {
+ this(new Text(object, codes));
+ }
+
+ protected Line getFormattedLine(final int lineNumber, final ColumnDefinition def) {
+ final Line line = new Line();
+ int startSubstring = lineNumber * def.getLength();
+ int currentVisibleLength = 0;
+ for (final Text t : this.text) {
+ final String part = t.getVisibleText(startSubstring, def.getLength());
+ currentVisibleLength += part.length();
+ if (StringUtils.isNotBlank(part)) {
+ line.add(part, t.getFormat());
+ if (currentVisibleLength >= def.getLength()) {
+ break;
+ }
+ startSubstring = 0;
+ } else {
+ startSubstring = startSubstring - t.getLength();
+ }
+ }
+ return line;
+ }
+
+ protected List getFormattedLines(final ColumnDefinition def) {
+ int count = 0;
+ Line line;
+ final List lines = new ArrayList<>();
+ while ((line = getFormattedLine(count++, def)).isNotEmpty()) {
+ lines.add(line);
+ }
+ return lines;
+ }
+
+ public String render(final int row, final ColumnDefinition def) {
+ final List test = getFormattedLines(def);
+ final Line line = test.size() > row ? test.get(row) : null;
+ if (line != null) {
+ return def.getJustify().apply(line.render(false, row == def.getMaxLines() - 1 && test.size() > def.getMaxLines()),
+ def.getLength() + (line.getLength() - line.getVisibleLength()));
+ }
+ return def.getJustify().apply("", def.getLength());
+
+ }
+
+ public Cell add(final Object object, final Code... codes) {
+ this.text.add(new Text(object, codes));
+ return this;
+ }
+
+
+
+ }
+
+ private static final Format DEFAULT_FORMAT = new Format();
+
+ /**
+ * A grid / table for printing results.
+ */
+
+ private final List definitions = new ArrayList<>();
+
+ private final List values = new ArrayList<>();
+
+ /**
+ * Constructor.
+ *
+ * @param def {@link ColumnDefinition}s
+ */
+ public Grid(final ColumnDefinition... def) {
+ Stream.of(def).forEach(this::addColumn);
+ }
+
+ private String generateGridStart() {
+ return IntStream.range(0, getLineLength() + this.definitions.size()).mapToObj(i -> "-").collect(Collectors.joining("")) + "\n";
+ }
+
+ private String generateGridEnd() {
+ return IntStream.range(0, getLineLength() + this.definitions.size()).mapToObj(i -> "-").collect(Collectors.joining("")) + "\n";
+ }
+
+ private String generateHeader() {
+ return "|" + this.definitions.stream().map(d -> StringUtils.rightPad(d.getName(), d.getLength())).collect(Collectors.joining("|"))
+ + "|\n";
+ }
+
+ /**
+ * Adds new a column definition.
+ *
+ * @param def definitions
+ * @return this grid
+ */
+ public Grid addColumn(final ColumnDefinition def) {
+ this.definitions.add(def);
+ return this;
+ }
+
+ private void calculateLength() {
+ IntStream.range(0, this.definitions.size()).forEach(i -> {
+ final ColumnDefinition def = this.definitions.get(i);
+ final List column = getColumn(i);
+ final int maxLength = column.stream().mapToInt(cell -> cell.getText().stream().mapToInt(Text::getLength).sum()).max().orElse(0);
+ def.setLength(Math.max(maxLength, def.getName().length()));
+
+ });
+ }
+
+ public List getColumn(final int index) {
+
+ return IntStream.range(0, this.values.size()).filter(n -> n % this.definitions.size() == index).mapToObj(this.values::get)
+ .collect(Collectors.toList());
+ }
+
+ public Grid addCell(final Cell cell) {
+ this.values.add(cell);
+ return this;
+ }
+
+ public Grid addCell(final Text... text) {
+ return addCell(new Cell(Arrays.asList(text)));
+ }
+
+ public Grid addCell(final Object cell, final Code... codes) {
+ final Format f = new Format();
+ f.addCodes(codes);
+ final Text t = new Text(cell, f);
+ return addCell(new Cell(t));
+ }
+
+ public Grid addCell(final Object cell) {
+ return addCell(cell, DEFAULT_FORMAT.getTextColor());
+ }
+
+ private Collection> prepareLines() {
+ final AtomicInteger counter = new AtomicInteger();
+ final int chunkSize = this.definitions.size();
+ return this.values.stream().collect(Collectors.groupingBy(it -> counter.getAndIncrement() / chunkSize)).values();
+ }
+
+ public String render() {
+ final StringBuilder b = new StringBuilder();
+ calculateLength();
+ b.append(generateGridStart());
+ b.append(generateHeader());
+ prepareLines().forEach(line -> b.append(printLine(line)));
+
+ b.append(generateGridEnd());
+ return b.toString();
+ }
+
+ private String printLine(final List| line) {
+ final StringBuilder b = new StringBuilder();
+ int virtualLine = 0;
+ while (true) {
+ final StringBuilder current = new StringBuilder();
+ final int bound = this.definitions.size();
+ for (int i = 0; i < bound; i++) {
+ final ColumnDefinition def = this.definitions.get(i);
+ current.append("|");
+ current.append(line.get(i).render(virtualLine, def));
+ }
+ current.append("|");
+ if (isEmpty(current) || virtualLine >= getMaxVirtualLine()) {
+ break;
+ }
+ b.append(current.toString());
+ virtualLine++;
+ b.append("\n");
+ }
+ return b.toString();
+
+ }
+
+ private static boolean isEmpty(final StringBuilder current) {
+ return current.toString().replaceAll("\\|", "").trim().length() == 0;
+ }
+
+ private int getMaxVirtualLine() {
+ return this.definitions.stream().mapToInt(ColumnDefinition::getMaxLines).max().orElseThrow(IllegalAccessError::new);
+ }
+
+ private int getLineLength() {
+ return this.definitions.stream().map(ColumnDefinition::getLength).reduce(0, Integer::sum);
+ }
+}
diff --git a/src/main/java/de/kosit/validationtool/cmd/report/Justify.java b/src/main/java/de/kosit/validationtool/cmd/report/Justify.java
new file mode 100644
index 0000000..8a238be
--- /dev/null
+++ b/src/main/java/de/kosit/validationtool/cmd/report/Justify.java
@@ -0,0 +1,35 @@
+package de.kosit.validationtool.cmd.report;
+
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * Justification modes for the text in grid columns.
+ *
+ * @author Andreas Penski
+ */
+public enum Justify {
+
+ LEFT {
+
+ @Override
+ public String apply(final String string, final int length) {
+ return StringUtils.rightPad(string, length);
+ }
+ },
+ CENTER {
+
+ @Override
+ public String apply(final String string, final int length) {
+ return StringUtils.center(string, length);
+ }
+ },
+ RIGHT {
+
+ @Override
+ public String apply(final String string, final int length) {
+ return StringUtils.leftPad(string, length);
+ }
+ };
+
+ public abstract String apply(String string, int length);
+}
diff --git a/src/main/java/de/kosit/validationtool/cmd/report/Line.java b/src/main/java/de/kosit/validationtool/cmd/report/Line.java
new file mode 100644
index 0000000..9cf0fa3
--- /dev/null
+++ b/src/main/java/de/kosit/validationtool/cmd/report/Line.java
@@ -0,0 +1,106 @@
+package de.kosit.validationtool.cmd.report;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+import org.fusesource.jansi.AnsiRenderer.Code;
+
+import lombok.NoArgsConstructor;
+
+/**
+ * Helper for printing a colored lines (with newline at the end) to the console.
+ */
+@NoArgsConstructor
+public class Line {
+
+ private final List texts = new ArrayList<>();
+
+ private Format baseFormat = new Format();
+
+ /**
+ * Constructor.
+ *
+ * @param format the configured base format
+ */
+ public Line(final Format format) {
+ this.baseFormat = format;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param codes Ansi escape codes for formatting
+ */
+ public Line(final Code... codes) {
+ this(new Format().addCodes(codes));
+ }
+
+ /**
+ * Add some text to the line.
+ *
+ * @param text the text
+ * @return this line
+ */
+ public Line add(final Text text) {
+ this.texts.add(text);
+ return this;
+ }
+
+ public Line add(final Object t) {
+ return add(new Text(t));
+ }
+
+ public Line add(final Object text, final Code... codes) {
+ return add(new Text(text, codes));
+ }
+
+ public Line add(final Object text, final Format format) {
+ return add(new Text(text, format));
+ }
+
+ public String render() {
+ return render(true, false);
+ }
+
+ String render(final boolean newLine, final boolean dotted) {
+ final List joins = new ArrayList<>();
+ final List reversed = new ArrayList<>(this.texts);
+ int replace = 0;
+ Collections.reverse(reversed);
+ if (dotted && getVisibleLength() > replace) {
+ replace = 3;
+ }
+ for (final Text t : reversed) {
+ if (replace > 0) {
+ final String render = t.render(t.getVisibleText(0, t.getVisibleLength() - replace), this.baseFormat);
+ if (StringUtils.isNotEmpty(render)) {
+ joins.add(render);
+ }
+ replace = replace - t.getVisibleLength();
+ } else {
+ joins.add(t.render(this.baseFormat));
+ }
+
+ }
+ Collections.reverse(joins);
+ return String.join(" ", joins) + (dotted ? "..." : "") + (newLine ? "\n" : "");
+ }
+
+ public int getLength() {
+ return this.texts.stream().mapToInt(Text::getLength).sum();
+ }
+
+ public static String render(final String text, final Code... codes) {
+ return new Line().add(text, codes).render();
+ }
+
+ public boolean isNotEmpty() {
+ return !this.texts.isEmpty();
+ }
+
+ public int getVisibleLength() {
+ return this.texts.stream().mapToInt(Text::getVisibleLength).sum();
+ }
+}
diff --git a/src/main/java/de/kosit/validationtool/cmd/report/Text.java b/src/main/java/de/kosit/validationtool/cmd/report/Text.java
new file mode 100644
index 0000000..4456c8d
--- /dev/null
+++ b/src/main/java/de/kosit/validationtool/cmd/report/Text.java
@@ -0,0 +1,63 @@
+package de.kosit.validationtool.cmd.report;
+
+import java.util.Arrays;
+
+import org.fusesource.jansi.AnsiRenderer;
+import org.fusesource.jansi.AnsiRenderer.Code;
+
+import lombok.Getter;
+
+/**
+ * Ansi formatted text for outputting to the console.
+ *
+ * @author Andreas Penski
+ */
+@Getter
+public class Text {
+
+ private final String value;
+
+ private Format format;
+
+ public Text(final Object value) {
+ this.value = value != null ? value.toString() : "";
+ this.format = new Format();
+ }
+
+ public Text(final Object value, final Format format) {
+ this(value);
+ this.format = format;
+ }
+
+ public Text(final Object value, final Code... codes) {
+ this(value, new Format().addCodes(codes));
+ }
+
+ public String getVisibleText(final int startIndex, final int length) {
+ if (startIndex < 0) {
+ return "Wrong cell text index";
+ }
+ if (startIndex > this.value.length()) {
+ return "";
+ }
+ final String substring = this.value.substring(startIndex);
+ return substring.length() > length ? substring.substring(0, length) : substring;
+ }
+
+ public String render(final String text, final Format baseformat) {
+ return AnsiRenderer.render(text,
+ Arrays.stream(this.format.mergeCodes(baseformat.getCodes())).map(Code::name).toArray(String[]::new));
+ }
+
+ public int getLength() {
+ return render(this.format).length();
+ }
+
+ public String render(final Format baseFormat) {
+ return render(getValue(), baseFormat);
+ }
+
+ public int getVisibleLength() {
+ return this.value.length();
+ }
+}
diff --git a/src/main/java/de/kosit/validationtool/daemon/CheckHandler.java b/src/main/java/de/kosit/validationtool/daemon/CheckHandler.java
index 1476d8c..29e0d62 100644
--- a/src/main/java/de/kosit/validationtool/daemon/CheckHandler.java
+++ b/src/main/java/de/kosit/validationtool/daemon/CheckHandler.java
@@ -44,6 +44,7 @@ class CheckHandler extends BaseHandler {
try {
log.debug("Incoming request");
final String requestMethod = httpExchange.getRequestMethod();
+ // check neccessary, since gui can be disabled
if (requestMethod.equals("POST")) {
final InputStream inputStream = httpExchange.getRequestBody();
if (inputStream.available() > 0) {
diff --git a/src/main/java/de/kosit/validationtool/daemon/GuiHandler.java b/src/main/java/de/kosit/validationtool/daemon/GuiHandler.java
index 972daf8..8dce9fe 100644
--- a/src/main/java/de/kosit/validationtool/daemon/GuiHandler.java
+++ b/src/main/java/de/kosit/validationtool/daemon/GuiHandler.java
@@ -1,15 +1,17 @@
package de.kosit.validationtool.daemon;
-import com.sun.net.httpserver.HttpExchange;
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
-import org.apache.commons.io.IOUtils;
-
import java.io.IOException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Arrays;
+import org.apache.commons.io.IOUtils;
+
+import com.sun.net.httpserver.HttpExchange;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
public class GuiHandler extends BaseHandler {
private static final URL INDEX_HTML = GuiHandler.class.getClassLoader().getResource("gui/index.html");
@@ -21,7 +23,7 @@ public class GuiHandler extends BaseHandler {
}
@Override
- public void handle(HttpExchange exchange) throws IOException {
+ public void handle(final HttpExchange exchange) throws IOException {
assert INDEX_HTML != null;
final String path = exchange.getRequestURI().toASCIIString();
if (path.equals("/")) {
@@ -29,7 +31,8 @@ public class GuiHandler extends BaseHandler {
} else{
final URL resource = GuiHandler.class.getClassLoader().getResource("gui" + path);
if (resource != null) {
- write(exchange,IOUtils.toString(resource, Charset.defaultCharset()).getBytes(), Mediatype.resolveBySuffix(resource.getPath()).getMimeType());;
+ write(exchange, IOUtils.toString(resource, Charset.defaultCharset()).getBytes(),
+ Mediatype.resolveBySuffix(resource.getPath()).getMimeType());
}else {
error(exchange,404,"not found");
}
@@ -45,7 +48,7 @@ public class GuiHandler extends BaseHandler {
CSS("text/css");
private final String mimeType;
- static Mediatype resolveBySuffix(String path){
+ static Mediatype resolveBySuffix(final String path) {
return Arrays.stream(values()).filter(e->path.toUpperCase().endsWith("."+e.name())).findFirst().orElse(Mediatype.MD);
}
}
diff --git a/src/main/java/de/kosit/validationtool/daemon/HealthHandler.java b/src/main/java/de/kosit/validationtool/daemon/HealthHandler.java
index de7e40f..3ca8ca6 100644
--- a/src/main/java/de/kosit/validationtool/daemon/HealthHandler.java
+++ b/src/main/java/de/kosit/validationtool/daemon/HealthHandler.java
@@ -4,13 +4,13 @@ import java.io.IOException;
import com.sun.net.httpserver.HttpExchange;
-import de.kosit.validationtool.impl.EngineInformation;
-import de.kosit.validationtool.model.daemon.ApplicationType;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import de.kosit.validationtool.api.Configuration;
import de.kosit.validationtool.impl.ConversionService;
+import de.kosit.validationtool.impl.EngineInformation;
+import de.kosit.validationtool.model.daemon.ApplicationType;
import de.kosit.validationtool.model.daemon.HealthType;
import de.kosit.validationtool.model.daemon.MemoryType;
@@ -39,7 +39,7 @@ class HealthHandler extends BaseHandler {
final HealthType h = new HealthType();
h.setMemory(createMemory());
h.setApplication(createApplication());
- h.setStatus(scenarios.getScenarios().size() > 0 ? "UP" : "DOWN");
+ h.setStatus(!this.scenarios.getScenarios().isEmpty() ? "UP" : "DOWN");
return h;
}
@@ -53,7 +53,7 @@ class HealthHandler extends BaseHandler {
}
private static ApplicationType createApplication() {
- ApplicationType a = new ApplicationType();
+ final ApplicationType a = new ApplicationType();
a.setBuild(EngineInformation.getBuild());
a.setName(EngineInformation.getName());
a.setVersion(EngineInformation.getVersion());
diff --git a/src/main/java/de/kosit/validationtool/daemon/RoutingHandler.java b/src/main/java/de/kosit/validationtool/daemon/RoutingHandler.java
index d15a39c..6a79457 100644
--- a/src/main/java/de/kosit/validationtool/daemon/RoutingHandler.java
+++ b/src/main/java/de/kosit/validationtool/daemon/RoutingHandler.java
@@ -1,11 +1,11 @@
package de.kosit.validationtool.daemon;
-import com.sun.net.httpserver.HttpExchange;
-import com.sun.net.httpserver.HttpHandler;
-import lombok.RequiredArgsConstructor;
-
import java.io.IOException;
+import com.sun.net.httpserver.HttpExchange;
+
+import lombok.RequiredArgsConstructor;
+
/**
* A simple handler which routes between the {@link CheckHandler} and the {@link GuiHandler} depending on the request.
*/
@@ -17,12 +17,12 @@ class RoutingHandler extends BaseHandler {
private final GuiHandler guiHandler;
@Override
- public void handle(HttpExchange exchange) throws IOException {
+ public void handle(final HttpExchange exchange) throws IOException {
final String requestMethod = exchange.getRequestMethod();
if (requestMethod.equals("POST")) {
- checkHandler.handle(exchange);
+ this.checkHandler.handle(exchange);
} else if (requestMethod.equals("GET")) {
- guiHandler.handle(exchange);
+ this.guiHandler.handle(exchange);
} else {
error(exchange, 405, String.format("Method % not supported", requestMethod));
}
diff --git a/src/main/java/de/kosit/validationtool/impl/ClassPathResourceResolver.java b/src/main/java/de/kosit/validationtool/impl/ClassPathResourceResolver.java
index 46ff31f..f97bbc8 100644
--- a/src/main/java/de/kosit/validationtool/impl/ClassPathResourceResolver.java
+++ b/src/main/java/de/kosit/validationtool/impl/ClassPathResourceResolver.java
@@ -114,8 +114,9 @@ class ClassPathResourceResolver implements LSResourceResolver {
try {
final URL resource = resolved.isAbsolute() ? resolved.toURL()
: ClassPathResourceResolver.class.getResource(resolved.toASCIIString());
- final InputStream in = resource.openStream();
final LSInputImpl input = new LSInputImpl(publicId, systemId, resolved.toASCIIString());
+ // intentionally not closed, since xml stack wants it open upon return
+ final InputStream in = resource.openStream();
input.setByteStream(in);
return input;
diff --git a/src/main/java/de/kosit/validationtool/impl/CollectingErrorEventHandler.java b/src/main/java/de/kosit/validationtool/impl/CollectingErrorEventHandler.java
index b1daca8..af02d6d 100644
--- a/src/main/java/de/kosit/validationtool/impl/CollectingErrorEventHandler.java
+++ b/src/main/java/de/kosit/validationtool/impl/CollectingErrorEventHandler.java
@@ -51,9 +51,9 @@ public class CollectingErrorEventHandler implements ValidationEventHandler, Erro
private static final int DEFAULT_ABORT_COUNT = 50;
- private final Collection errors = new ArrayList<>();
+ private static final int stopProcessCount = DEFAULT_ABORT_COUNT;
- private final int stopProcessCount = DEFAULT_ABORT_COUNT;
+ private final Collection errors = new ArrayList<>();
private static XMLSyntaxError createError(final XMLSyntaxErrorSeverity severity, final String message) {
final XMLSyntaxError e = new XMLSyntaxError();
@@ -97,7 +97,7 @@ public class CollectingErrorEventHandler implements ValidationEventHandler, Erro
e.setColumnNumber(event.getLocator().getColumnNumber());
e.setRowNumber(event.getLocator().getLineNumber());
this.errors.add(e);
- return this.stopProcessCount != this.errors.size();
+ return stopProcessCount != this.errors.size();
}
/**
@@ -161,9 +161,8 @@ public class CollectingErrorEventHandler implements ValidationEventHandler, Erro
public String getErrorDescription() {
final StringJoiner joiner = new StringJoiner("\n");
- this.errors.forEach(e -> joiner
- .add(e.getSeverityCode().value() + " " + e.getMessage() + " At row " + e.getRowNumber() + " at pos "
- + e.getColumnNumber()));
+ this.errors.forEach(e -> joiner.add(
+ e.getSeverityCode().value() + " " + e.getMessage() + " At row " + e.getRowNumber() + " at pos " + e.getColumnNumber()));
return joiner.toString();
}
}
\ No newline at end of file
diff --git a/src/main/java/de/kosit/validationtool/impl/ContentRepository.java b/src/main/java/de/kosit/validationtool/impl/ContentRepository.java
index 33a8388..84cd418 100644
--- a/src/main/java/de/kosit/validationtool/impl/ContentRepository.java
+++ b/src/main/java/de/kosit/validationtool/impl/ContentRepository.java
@@ -101,7 +101,7 @@ public class ContentRepository {
this.schemaFactory = this.resolvingConfigurationStrategy.createSchemaFactory();
}
- @SuppressWarnings("java:S2095")
+ @SuppressWarnings("squid:S2095")
private static Source resolve(final URL resource) {
try {
return new StreamSource(resource.openStream(), resource.toURI().getRawPath());
diff --git a/src/main/java/de/kosit/validationtool/impl/ConversionService.java b/src/main/java/de/kosit/validationtool/impl/ConversionService.java
index 0fc6cd0..5a362bf 100644
--- a/src/main/java/de/kosit/validationtool/impl/ConversionService.java
+++ b/src/main/java/de/kosit/validationtool/impl/ConversionService.java
@@ -131,7 +131,7 @@ public class ConversionService {
public void initialize(final Collection context) {
final String[] packages = context != null ? context.stream().map(Package::getName).toArray(String[]::new) : new String[0];
final StringJoiner joiner = new StringJoiner(":");
- Arrays.stream(packages).forEach(p -> joiner.add(p));
+ Arrays.stream(packages).forEach(joiner::add);
initialize(joiner.toString());
}
diff --git a/src/main/java/de/kosit/validationtool/impl/input/SourceInput.java b/src/main/java/de/kosit/validationtool/impl/input/SourceInput.java
index cb9f929..5cd7753 100644
--- a/src/main/java/de/kosit/validationtool/impl/input/SourceInput.java
+++ b/src/main/java/de/kosit/validationtool/impl/input/SourceInput.java
@@ -52,7 +52,7 @@ public class SourceInput extends AbstractInput {
}
private void validate() {
- if (!isHashcodeComputed() && !isSupported()) {
+ if (!isHashcodeComputed() && isNotSupported()) {
throw new IllegalStateException("Unsupported source. Only StreamSource supported yet");
}
if (!isHashcodeComputed() && ((StreamSource) this.source).getInputStream() == null) {
@@ -62,7 +62,7 @@ public class SourceInput extends AbstractInput {
@Override
public Source getSource() throws IOException {
- if (!isHashcodeComputed() && !isSupported()) {
+ if (!isHashcodeComputed() && isNotSupported()) {
throw new IllegalStateException("Unsupported source. Only InputStream-based StreamSource supported yet");
}
if (isConsumed()) {
@@ -71,8 +71,8 @@ public class SourceInput extends AbstractInput {
return isHashcodeComputed() ? this.source : wrappedSource();
}
- private boolean isSupported() {
- return isStreamSource();
+ private boolean isNotSupported() {
+ return !isStreamSource();
}
private boolean isConsumed() throws IOException {
@@ -107,9 +107,7 @@ public class SourceInput extends AbstractInput {
return result;
}
- private boolean isWrappingRequired() {
- return !isHashcodeComputed();
- }
+
@Override
public boolean supportsMultipleReads() {
diff --git a/src/main/java/de/kosit/validationtool/impl/input/StreamHelper.java b/src/main/java/de/kosit/validationtool/impl/input/StreamHelper.java
index bd8de8a..ad94155 100644
--- a/src/main/java/de/kosit/validationtool/impl/input/StreamHelper.java
+++ b/src/main/java/de/kosit/validationtool/impl/input/StreamHelper.java
@@ -24,6 +24,7 @@ public class StreamHelper {
* Helper class, which generates the hashcode while reading the stream e.g. for parsing the document. This allows
* generating the hashcode without an aditional reading step.
*/
+ @SuppressWarnings("squid:S4929") // efficient read is done by internally used stream
private static class DigestingInputStream extends FilterInputStream {
private final MessageDigest digest;
@@ -44,6 +45,7 @@ public class StreamHelper {
}
+ @SuppressWarnings("squid:S4929") // efficient read is done by internally used stream
private static class CountInputStream extends FilterInputStream {
private final LazyReadInput reference;
@@ -123,10 +125,12 @@ public class StreamHelper {
* @param input the input
* @throws IOException on I/O errors
*/
+ @SuppressWarnings("squid:S1854")
public static void drain(final InputStream input) throws IOException {
final byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int n;
+
while (EOF != (n = input.read(buffer))) {
// nothing
}
diff --git a/src/main/java/de/kosit/validationtool/impl/model/BaseOutput.java b/src/main/java/de/kosit/validationtool/impl/model/BaseOutput.java
index b6a670b..36c4179 100644
--- a/src/main/java/de/kosit/validationtool/impl/model/BaseOutput.java
+++ b/src/main/java/de/kosit/validationtool/impl/model/BaseOutput.java
@@ -43,7 +43,7 @@ public abstract class BaseOutput {
* @return true wenn mindestens ein {@link FailedAssert} vorhanden ist
*/
public boolean hasFailedAsserts() {
- return getFailedAsserts().size() > 0;
+ return !getFailedAsserts().isEmpty();
}
/**
@@ -69,4 +69,8 @@ public abstract class BaseOutput {
return getFailedAsserts().stream().filter(e -> e.getId().equals(name)).findAny();
}
+ public List getMessages() {
+ return getFailedAsserts().stream().map(FailedAssert::getText).flatMap(e -> e.getContent().stream()).map(Object::toString)
+ .collect(Collectors.toList());
+ }
}
diff --git a/src/main/java/de/kosit/validationtool/impl/model/BaseXMLSyntaxError.java b/src/main/java/de/kosit/validationtool/impl/model/BaseXMLSyntaxError.java
index ed4e188..957952c 100644
--- a/src/main/java/de/kosit/validationtool/impl/model/BaseXMLSyntaxError.java
+++ b/src/main/java/de/kosit/validationtool/impl/model/BaseXMLSyntaxError.java
@@ -53,30 +53,6 @@ public abstract class BaseXMLSyntaxError implements XmlError {
return String.format("%s At row %s at pos %s", getMessage(), getRowNumber(), getColumnNumber());
}
- /**
- * Getter aus dem schema
- *
- * @return Spalte des Fehlers
- */
- @Override
- public abstract Integer getColumnNumber();
-
- /**
- * Getter aus dem schema
- *
- * @return Zeile des Fehlers
- */
- @Override
- public abstract Integer getRowNumber();
-
- /**
- * Getter aus dem schema
- *
- * @return Fehlermeldung
- */
- @Override
- public abstract String getMessage();
-
/**
* Getter aus dem schema
*
diff --git a/src/main/java/de/kosit/validationtool/impl/tasks/SchemaValidationAction.java b/src/main/java/de/kosit/validationtool/impl/tasks/SchemaValidationAction.java
index a2396c8..22cca81 100644
--- a/src/main/java/de/kosit/validationtool/impl/tasks/SchemaValidationAction.java
+++ b/src/main/java/de/kosit/validationtool/impl/tasks/SchemaValidationAction.java
@@ -191,9 +191,11 @@ public class SchemaValidationAction implements CheckAction {
}
+ @SuppressWarnings("squid:S2095") // intentionally return open stream/autoclosable here
private SerializedDocument serialize(final Input input, final XdmNode object) throws IOException, SaxonApiException {
final SerializedDocument doc;
if (input instanceof AbstractInput && ((AbstractInput) input).getLength() < getInMemoryLimit()) {
+
doc = new ByteArraySerializedDocument(this.processor);
} else {
doc = new FileSerializedDocument(this.processor);
diff --git a/src/main/java/de/kosit/validationtool/impl/xml/StrictRelativeResolvingStrategy.java b/src/main/java/de/kosit/validationtool/impl/xml/StrictRelativeResolvingStrategy.java
index f88229a..3f5f375 100644
--- a/src/main/java/de/kosit/validationtool/impl/xml/StrictRelativeResolvingStrategy.java
+++ b/src/main/java/de/kosit/validationtool/impl/xml/StrictRelativeResolvingStrategy.java
@@ -70,6 +70,7 @@ public class StrictRelativeResolvingStrategy extends BaseResolvingStrategy {
@Override
public SchemaFactory createSchemaFactory() {
+ forceOpenJdkXmlImplementation();
final SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
disableExternalEntities(sf);
allowExternalSchema(sf, "file");
@@ -82,7 +83,7 @@ public class StrictRelativeResolvingStrategy extends BaseResolvingStrategy {
// verhindere global im Prinzip alle resolving strategien
final SecureUriResolver resolver = new SecureUriResolver();
processor.getUnderlyingConfiguration().setCollectionFinder(resolver);
- processor.getUnderlyingConfiguration().setOutputURIResolver(resolver);
+ processor.getUnderlyingConfiguration().setOutputURIResolver(resolver);// NOSONAR
processor.getUnderlyingConfiguration().setUnparsedTextURIResolver(resolver);
// grundsätzlich Feature-konfiguration:
@@ -92,10 +93,10 @@ public class StrictRelativeResolvingStrategy extends BaseResolvingStrategy {
processor.setConfigurationProperty(Feature.ALLOW_EXTERNAL_FUNCTIONS, false);
// Konfiguration des zu verwendenden Parsers, wenn Saxon selbst einen erzeugen muss, bspw. beim XSL parsen
- processor.setConfigurationProperty(FeatureKeys.XML_PARSER_FEATURE + encode(FEATURE_SECURE_PROCESSING), true);
- processor.setConfigurationProperty(FeatureKeys.XML_PARSER_FEATURE + encode(DISSALLOW_DOCTYPE_DECL_FEATURE), true);
- processor.setConfigurationProperty(FeatureKeys.XML_PARSER_FEATURE + encode(LOAD_EXTERNAL_DTD_FEATURE), false);
- processor.setConfigurationProperty(FeatureKeys.XML_PARSER_FEATURE + encode(XMLConstants.ACCESS_EXTERNAL_DTD), false);
+ processor.setConfigurationProperty(FeatureKeys.XML_PARSER_FEATURE + encode(FEATURE_SECURE_PROCESSING), true); // NOSONAR
+ processor.setConfigurationProperty(FeatureKeys.XML_PARSER_FEATURE + encode(DISSALLOW_DOCTYPE_DECL_FEATURE), true);// NOSONAR
+ processor.setConfigurationProperty(FeatureKeys.XML_PARSER_FEATURE + encode(LOAD_EXTERNAL_DTD_FEATURE), false);// NOSONAR
+ processor.setConfigurationProperty(FeatureKeys.XML_PARSER_FEATURE + encode(XMLConstants.ACCESS_EXTERNAL_DTD), false);// NOSONAR
return processor;
}
diff --git a/src/test/java/de/kosit/validationtool/daemon/CheckHandlerIT.java b/src/test/java/de/kosit/validationtool/daemon/CheckHandlerIT.java
index 0642137..4664422 100644
--- a/src/test/java/de/kosit/validationtool/daemon/CheckHandlerIT.java
+++ b/src/test/java/de/kosit/validationtool/daemon/CheckHandlerIT.java
@@ -1,17 +1,20 @@
package de.kosit.validationtool.daemon;
import static io.restassured.RestAssured.given;
+import static org.apache.http.HttpStatus.SC_OK;
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.io.IOUtils;
-import org.junit.Ignore;
+import org.apache.http.HttpStatus;
import org.junit.Test;
import de.kosit.validationtool.impl.Helper.Simple;
+import io.restassured.builder.MultiPartSpecBuilder;
import io.restassured.http.ContentType;
+import io.restassured.specification.MultiPartSpecification;
/**
* Testet the Daemon-Mode input , Methoden , Output Content-Type and the success case
@@ -24,22 +27,21 @@ public class CheckHandlerIT extends BaseIT {
private static final String APPLICATION_XML = "application/xml";
@Test
- public void makeSureThatSuccessTest() throws IOException {
+ public void simpleTest() throws IOException {
try ( final InputStream io = Simple.SIMPLE_VALID.toURL().openStream() ) {
- given().contentType(ContentType.XML).body(toContent(io)).when().post("/").then().statusCode(200);
+ given().contentType(ContentType.XML).body(toContent(io)).when().post("/").then().statusCode(SC_OK);
}
}
@Test
- public void NoInputTest() {
- given().body("").contentType(APPLICATION_XML).when().post("/").then().statusCode(400);
+ public void noInputTest() {
+ given().body("").contentType(APPLICATION_XML).when().post("/").then().statusCode(HttpStatus.SC_BAD_REQUEST);
}
@Test
- @Ignore // no default error report yet
- public void internalServerErrorTest() throws IOException {
- try ( final InputStream io = Simple.SCHEMA_INVALID.toURL().openStream() ) {
- given().contentType(APPLICATION_XML).body(toContent(io)).when().post("/").then().statusCode(200);
+ public void testUnknown() throws IOException {
+ try ( final InputStream io = Simple.UNKNOWN.toURL().openStream() ) {
+ given().contentType(APPLICATION_XML).body(toContent(io)).when().post("/").then().statusCode(SC_OK);
}
}
@@ -47,13 +49,19 @@ public class CheckHandlerIT extends BaseIT {
return IOUtils.toByteArray(io);
}
-
-
@Test
public void xmlResultTest() throws IOException {
-
try ( final InputStream io = Simple.SIMPLE_VALID.toURL().openStream() ) {
- given().body(toContent(io)).when().post("/").then().contentType(APPLICATION_XML).and().statusCode(200);
+ given().body(toContent(io)).when().post("/").then().contentType(APPLICATION_XML).and().statusCode(SC_OK);
}
}
+
+ @Test
+ public void testMultipart() throws IOException {
+ try ( final InputStream io = Simple.SIMPLE_VALID.toURL().openStream() ) {
+ final MultiPartSpecification spec = new MultiPartSpecBuilder(io).fileName("file").controlName("file").build();
+ given().multiPart(spec).when().post("/").then().statusCode(HttpStatus.SC_BAD_REQUEST);
+ }
+ }
+
}
diff --git a/src/test/java/de/kosit/validationtool/impl/DefaultCheckTest.java b/src/test/java/de/kosit/validationtool/impl/DefaultCheckTest.java
index d952e90..c3e5e1b 100644
--- a/src/test/java/de/kosit/validationtool/impl/DefaultCheckTest.java
+++ b/src/test/java/de/kosit/validationtool/impl/DefaultCheckTest.java
@@ -29,7 +29,6 @@ import static de.kosit.validationtool.impl.Helper.Simple.SIMPLE_VALID;
import static de.kosit.validationtool.impl.Helper.Simple.UNKNOWN;
import static org.assertj.core.api.Assertions.assertThat;
-import java.io.File;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@@ -39,7 +38,7 @@ import org.junit.Test;
import org.w3c.dom.Document;
import de.kosit.validationtool.api.AcceptRecommendation;
-import de.kosit.validationtool.api.CheckConfiguration;
+import de.kosit.validationtool.api.Configuration;
import de.kosit.validationtool.api.Input;
import de.kosit.validationtool.api.Result;
import de.kosit.validationtool.impl.Helper.Simple;
@@ -60,12 +59,10 @@ public class DefaultCheckTest {
@Before
public void setup() {
- final CheckConfiguration validConfig = new CheckConfiguration(Simple.SCENARIOS);
- validConfig.setScenarioRepository(new File(Simple.REPOSITORY_URI).toURI());
+ final Configuration validConfig = Configuration.load(Simple.SCENARIOS, Simple.REPOSITORY_URI).build();
this.validCheck = new DefaultCheck(validConfig);
- final CheckConfiguration errorConfig = new CheckConfiguration(Simple.ERROR_SCENARIOS);
- errorConfig.setScenarioRepository(new File(Simple.REPOSITORY_URI).toURI());
+ final Configuration errorConfig = Configuration.load(Simple.ERROR_SCENARIOS, Simple.REPOSITORY_URI).build();
this.errorCheck = new DefaultCheck(errorConfig);
}
diff --git a/src/test/java/de/kosit/validationtool/impl/SimpleScenarioCheckTest.java b/src/test/java/de/kosit/validationtool/impl/SimpleScenarioCheckTest.java
index b9b5de7..0ac2c9f 100644
--- a/src/test/java/de/kosit/validationtool/impl/SimpleScenarioCheckTest.java
+++ b/src/test/java/de/kosit/validationtool/impl/SimpleScenarioCheckTest.java
@@ -8,7 +8,7 @@ import org.junit.Before;
import org.junit.Test;
import de.kosit.validationtool.api.AcceptRecommendation;
-import de.kosit.validationtool.api.CheckConfiguration;
+import de.kosit.validationtool.api.Configuration;
import de.kosit.validationtool.api.InputFactory;
import de.kosit.validationtool.api.Result;
import de.kosit.validationtool.impl.Helper.Simple;
@@ -24,8 +24,7 @@ public class SimpleScenarioCheckTest {
@Before
public void setup() {
- final CheckConfiguration d = new CheckConfiguration(Simple.SCENARIOS);
- d.setScenarioRepository(Simple.REPOSITORY_URI);
+ final Configuration d = Configuration.load(Simple.SCENARIOS, Simple.REPOSITORY_URI).build();
this.implementation = new DefaultCheck(d);
}
| | | |