diff --git a/pom.xml b/pom.xml
index fd7a6c9..029d0b5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -14,7 +14,9 @@
0.0.2-SNAPSHOT
+ 1.2.10
2.0.25
+ 1.7.35
@@ -35,10 +37,19 @@
pdfbox
${pdfbox.version}
+
+ org.slf4j
+ slf4j-api
+ ${slf4j.version}
+
+
+ ch.qos.logback
+ logback-classic
+ ${logback.version}
+
org.junit.jupiter
junit-jupiter-api
- test
diff --git a/src/main/java/ch/fritteli/labyrinth/generator/Main.java b/src/main/java/ch/fritteli/labyrinth/generator/Main.java
index 1acf787..df3ebef 100644
--- a/src/main/java/ch/fritteli/labyrinth/generator/Main.java
+++ b/src/main/java/ch/fritteli/labyrinth/generator/Main.java
@@ -7,10 +7,12 @@ import ch.fritteli.labyrinth.generator.renderer.pdffile.PDFFileRenderer;
import ch.fritteli.labyrinth.generator.renderer.text.TextRenderer;
import ch.fritteli.labyrinth.generator.renderer.textfile.TextFileRenderer;
import lombok.NonNull;
+import lombok.extern.slf4j.Slf4j;
import java.nio.file.Path;
import java.nio.file.Paths;
+@Slf4j
public class Main {
public static void main(@NonNull final String[] args) {
int width = 100;
@@ -28,19 +30,19 @@ public class Main {
final PDFFileRenderer pdfFileRenderer = PDFFileRenderer.newInstance()
.setTargetFile(userHome.resolve(baseFilename + ".pdf"));
- System.out.println("Labyrinth-ID: " + labyrinth.getRandomSeed());
+ log.info("Labyrinth-ID: {}", labyrinth.getRandomSeed());
// Render Labyrinth to stdout
- System.out.println(textRenderer.render(labyrinth));
+ log.info("Text rendering:\n{}", textRenderer.render(labyrinth));
// Render Labyrinth solution to stdout
- System.out.println(textRenderer.setRenderSolution(true).render(labyrinth));
+ log.info("Text rendering with solution:\n{}", textRenderer.setRenderSolution(true).render(labyrinth));
// Render HTML to stdout
- System.out.println(htmlRenderer.render(labyrinth));
+ log.info("HTML rendering:\n{}", htmlRenderer.render(labyrinth));
// Render Labyrinth and solution to (separate) files
- System.out.println(textFileRenderer.render(labyrinth));
+ log.info("Text rendering to file:\n{}", textFileRenderer.render(labyrinth));
// Render HTML to file
- System.out.println(htmlFileRenderer.render(labyrinth));
+ log.info("HTML rendering to file:\n{}", htmlFileRenderer.render(labyrinth));
// Render PDF to file
- System.out.println(pdfFileRenderer.render(labyrinth));
+ log.info("PDF rendering to file:\n{}", pdfFileRenderer.render(labyrinth));
}
private static String getBaseFilename(@NonNull final Labyrinth labyrinth) {
diff --git a/src/main/java/ch/fritteli/labyrinth/generator/renderer/html/HTMLRenderer.java b/src/main/java/ch/fritteli/labyrinth/generator/renderer/html/HTMLRenderer.java
index 03666a7..fc03f38 100644
--- a/src/main/java/ch/fritteli/labyrinth/generator/renderer/html/HTMLRenderer.java
+++ b/src/main/java/ch/fritteli/labyrinth/generator/renderer/html/HTMLRenderer.java
@@ -16,6 +16,7 @@ public class HTMLRenderer implements Renderer {
}
@NonNull
+ @Override
public String render(@NonNull final Labyrinth labyrinth) {
if (labyrinth.getWidth() == 0 || labyrinth.getHeight() == 0) {
return this.getPreamble(labyrinth) + POSTAMBLE;
diff --git a/src/main/java/ch/fritteli/labyrinth/generator/renderer/htmlfile/HTMLFileRenderer.java b/src/main/java/ch/fritteli/labyrinth/generator/renderer/htmlfile/HTMLFileRenderer.java
index 3407537..db829bc 100644
--- a/src/main/java/ch/fritteli/labyrinth/generator/renderer/htmlfile/HTMLFileRenderer.java
+++ b/src/main/java/ch/fritteli/labyrinth/generator/renderer/htmlfile/HTMLFileRenderer.java
@@ -3,25 +3,30 @@ package ch.fritteli.labyrinth.generator.renderer.htmlfile;
import ch.fritteli.labyrinth.generator.model.Labyrinth;
import ch.fritteli.labyrinth.generator.renderer.Renderer;
import ch.fritteli.labyrinth.generator.renderer.html.HTMLRenderer;
+import io.vavr.control.Option;
+import io.vavr.control.Try;
import lombok.NonNull;
+import lombok.extern.slf4j.Slf4j;
+import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.util.NoSuchElementException;
+@Slf4j
public class HTMLFileRenderer implements Renderer {
@NonNull
private static final HTMLRenderer HTML_RENDERER = HTMLRenderer.newInstance();
- private Path targetFile;
+ @NonNull
+ private Option targetFile;
private HTMLFileRenderer() {
- try {
- this.targetFile = Files.createTempFile("labyrinth_", ".html");
- } catch (IOException e) {
- System.err.println("Unable to set default target file.");
- e.printStackTrace();
- }
+ this.targetFile = Try
+ .of(() -> Files.createTempFile("labyrinth_", ".html"))
+ .onFailure(ex -> log.error("Unable to set default target file.", ex))
+ .toOption();
}
@NonNull
@@ -30,30 +35,33 @@ public class HTMLFileRenderer implements Renderer {
}
public boolean isTargetFileDefinedAndWritable() {
- return this.targetFile != null && this.targetFile.toFile().canWrite();
+ return this.targetFile
+ .map(Path::toFile)
+ .exists(File::canWrite);
}
@NonNull
public HTMLFileRenderer setTargetFile(@NonNull final Path targetFile) {
- this.targetFile = targetFile;
+ this.targetFile = Option.of(targetFile);
return this;
}
+ @NonNull
@Override
public Path render(@NonNull final Labyrinth labyrinth) {
if (!this.isTargetFileDefinedAndWritable()) {
try {
- Files.createFile(this.targetFile);
- } catch (IOException e) {
+ Files.createFile(this.targetFile.get());
+ } catch (IOException | NoSuchElementException e) {
throw new IllegalArgumentException("Cannot write to target file.", e);
}
}
final String html = HTML_RENDERER.render(labyrinth);
+ final Path targetFile = this.targetFile.get();
try {
- Files.writeString(this.targetFile, html, StandardCharsets.UTF_8);
+ Files.writeString(targetFile, html, StandardCharsets.UTF_8);
} catch (IOException e) {
- System.err.println("Failed writing to file " + this.targetFile.normalize().toString());
- e.printStackTrace();
+ log.error("Failed writing to file " + targetFile.normalize(), e);
}
return targetFile;
}
diff --git a/src/main/java/ch/fritteli/labyrinth/generator/renderer/pdf/Generator.java b/src/main/java/ch/fritteli/labyrinth/generator/renderer/pdf/Generator.java
index 7f15ba1..971fed2 100644
--- a/src/main/java/ch/fritteli/labyrinth/generator/renderer/pdf/Generator.java
+++ b/src/main/java/ch/fritteli/labyrinth/generator/renderer/pdf/Generator.java
@@ -8,6 +8,7 @@ import io.vavr.control.Option;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.Value;
+import lombok.extern.slf4j.Slf4j;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentInformation;
import org.apache.pdfbox.pdmodel.PDPage;
@@ -20,14 +21,12 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
@RequiredArgsConstructor
+@Slf4j
class Generator {
@NonNull
private final Labyrinth labyrinth;
- private static boolean isValid(@NonNull final Position position) {
- return position.getX() >= 0 && position.getY() >= 0;
- }
-
+ @NonNull
public byte[] generate() {
final float pageWidth = this.labyrinth.getWidth() * PDFRenderer.SCALE + 2 * PDFRenderer.MARGIN;
final float pageHeight = this.labyrinth.getHeight() * PDFRenderer.SCALE + 2 * PDFRenderer.MARGIN;
@@ -48,14 +47,14 @@ class Generator {
this.drawVerticalLines(puzzlePageContentStream, solutionPageContentStream);
this.drawSolution(solutionPageContentStream);
} catch (IOException e) {
- e.printStackTrace();
+ log.error("Error while rendering PDF document", e);
}
final ByteArrayOutputStream output = new ByteArrayOutputStream();
try {
pdDocument.save(output);
pdDocument.close();
} catch (IOException e) {
- e.printStackTrace();
+ log.error("Error while writing PDF data", e);
}
return output.toByteArray();
}
diff --git a/src/main/java/ch/fritteli/labyrinth/generator/renderer/pdf/PDFRenderer.java b/src/main/java/ch/fritteli/labyrinth/generator/renderer/pdf/PDFRenderer.java
index dd4183c..c9ff88a 100644
--- a/src/main/java/ch/fritteli/labyrinth/generator/renderer/pdf/PDFRenderer.java
+++ b/src/main/java/ch/fritteli/labyrinth/generator/renderer/pdf/PDFRenderer.java
@@ -16,8 +16,8 @@ public class PDFRenderer implements Renderer {
return new PDFRenderer();
}
- @Override
@NonNull
+ @Override
public byte[] render(@NonNull final Labyrinth labyrinth) {
final Generator generator = new Generator(labyrinth);
return generator.generate();
diff --git a/src/main/java/ch/fritteli/labyrinth/generator/renderer/pdffile/PDFFileRenderer.java b/src/main/java/ch/fritteli/labyrinth/generator/renderer/pdffile/PDFFileRenderer.java
index 781d33f..a6753e0 100644
--- a/src/main/java/ch/fritteli/labyrinth/generator/renderer/pdffile/PDFFileRenderer.java
+++ b/src/main/java/ch/fritteli/labyrinth/generator/renderer/pdffile/PDFFileRenderer.java
@@ -6,6 +6,7 @@ import ch.fritteli.labyrinth.generator.renderer.pdf.PDFRenderer;
import io.vavr.control.Option;
import io.vavr.control.Try;
import lombok.NonNull;
+import lombok.extern.slf4j.Slf4j;
import java.io.File;
import java.io.IOException;
@@ -13,6 +14,7 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.util.NoSuchElementException;
+@Slf4j
public class PDFFileRenderer implements Renderer {
@NonNull
private static final PDFRenderer PDF_RENDERER = PDFRenderer.newInstance();
@@ -22,10 +24,7 @@ public class PDFFileRenderer implements Renderer {
private PDFFileRenderer() {
this.targetFile = Try
.of(() -> Files.createTempFile("labyrinth_", ".pdf"))
- .onFailure(ex -> {
- System.err.println("Unable to set default target file.");
- ex.printStackTrace();
- })
+ .onFailure(ex -> log.error("Unable to set default target file.", ex))
.toOption();
}
@@ -37,8 +36,7 @@ public class PDFFileRenderer implements Renderer {
public boolean isTargetFileDefinedAndWritable() {
return this.targetFile
.map(Path::toFile)
- .map(File::canWrite)
- .getOrElse(false);
+ .exists(File::canWrite);
}
@NonNull
@@ -47,6 +45,7 @@ public class PDFFileRenderer implements Renderer {
return this;
}
+ @NonNull
@Override
public Path render(@NonNull final Labyrinth labyrinth) {
if (!this.isTargetFileDefinedAndWritable()) {
@@ -61,8 +60,7 @@ public class PDFFileRenderer implements Renderer {
try {
Files.write(targetFile, bytes);
} catch (IOException e) {
- System.err.println("Failed writing to file " + targetFile.normalize().toString());
- e.printStackTrace();
+ log.error("Failed writing to file " + targetFile.normalize(), e);
}
return targetFile;
}
diff --git a/src/main/java/ch/fritteli/labyrinth/generator/renderer/text/TextRenderer.java b/src/main/java/ch/fritteli/labyrinth/generator/renderer/text/TextRenderer.java
index ecb605f..b7ce398 100644
--- a/src/main/java/ch/fritteli/labyrinth/generator/renderer/text/TextRenderer.java
+++ b/src/main/java/ch/fritteli/labyrinth/generator/renderer/text/TextRenderer.java
@@ -23,6 +23,7 @@ public class TextRenderer implements Renderer {
}
@NonNull
+ @Override
public String render(@NonNull final Labyrinth labyrinth) {
if (labyrinth.getWidth() == 0 || labyrinth.getHeight() == 0) {
return "";
diff --git a/src/main/java/ch/fritteli/labyrinth/generator/renderer/textfile/TextFileRenderer.java b/src/main/java/ch/fritteli/labyrinth/generator/renderer/textfile/TextFileRenderer.java
index 9f0d959..d274f37 100644
--- a/src/main/java/ch/fritteli/labyrinth/generator/renderer/textfile/TextFileRenderer.java
+++ b/src/main/java/ch/fritteli/labyrinth/generator/renderer/textfile/TextFileRenderer.java
@@ -4,29 +4,42 @@ import ch.fritteli.labyrinth.generator.model.Labyrinth;
import ch.fritteli.labyrinth.generator.renderer.Renderer;
import ch.fritteli.labyrinth.generator.renderer.text.TextRenderer;
import io.vavr.collection.List;
+import io.vavr.control.Option;
+import io.vavr.control.Try;
import lombok.NonNull;
+import lombok.extern.slf4j.Slf4j;
+import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.util.NoSuchElementException;
+@Slf4j
public class TextFileRenderer implements Renderer> {
@NonNull
private static final TextRenderer TEXT_RENDERER = TextRenderer.newInstance();
- private Path targetLabyrinthFile;
- private Path targetSolutionFile;
+ @NonNull
+ private Option targetLabyrinthFile;
+ @NonNull
+ private Option targetSolutionFile;
private TextFileRenderer() {
- try {
- this.targetLabyrinthFile = Files.createTempFile("labyrinth_", ".txt");
- this.targetSolutionFile = this.targetLabyrinthFile.getParent().resolve(
- this.targetLabyrinthFile.getFileName().toString().replace(".txt", "-solution.txt")
- );
- } catch (IOException e) {
- System.err.println("Unable to set default target file.");
- e.printStackTrace();
- }
+ this.targetLabyrinthFile = Try
+ .of(() -> Files.createTempFile("labyrinth_", ".txt"))
+ .onFailure(ex -> log.error("Unable to set default target file", ex))
+ .toOption();
+
+ this.targetSolutionFile = this.targetLabyrinthFile.toTry()
+ .map(Path::getParent)
+ .flatMap(parent -> this.targetLabyrinthFile.toTry()
+ .map(Path::getFileName)
+ .map(Path::toString)
+ .map(a -> a.replace(".txt", "-solution.txt"))
+ .map(parent::resolve))
+ .onFailure(ex -> log.error("Unable to set default solution target file", ex))
+ .toOption();
}
@NonNull
@@ -35,38 +48,44 @@ public class TextFileRenderer implements Renderer> {
}
public boolean isTargetLabyrinthFileDefinedAndWritable() {
- return this.targetLabyrinthFile != null && this.targetLabyrinthFile.toFile().canWrite();
+ return this.targetLabyrinthFile
+ .map(Path::toFile)
+ .exists(File::canWrite);
}
public boolean isTargetSolutionFileDefinedAndWritable() {
- return this.targetSolutionFile != null && this.targetSolutionFile.toFile().canWrite();
+ return this.targetSolutionFile
+ .map(Path::toFile)
+ .exists(File::canWrite);
}
@NonNull
public TextFileRenderer setTargetLabyrinthFile(@NonNull final Path targetLabyrinthFile) {
- this.targetLabyrinthFile = targetLabyrinthFile;
+ this.targetLabyrinthFile = Option.of(targetLabyrinthFile);
return this;
}
@NonNull
public TextFileRenderer setTargetSolutionFile(@NonNull final Path targetSolutionFile) {
- this.targetSolutionFile = targetSolutionFile;
+ this.targetSolutionFile = Option.of(targetSolutionFile);
return this;
}
+ @NonNull
@Override
public List render(@NonNull final Labyrinth labyrinth) {
if (!this.isTargetLabyrinthFileDefinedAndWritable()) {
try {
- Files.createFile(this.targetLabyrinthFile);
- } catch (IOException e) {
+ Files.createFile(this.targetLabyrinthFile.get());
+ } catch (IOException | NoSuchElementException e) {
+ log.error("Cannot write to target labyrinth file.", e);
throw new IllegalArgumentException("Cannot write to target labyrinth file.", e);
}
}
if (!this.isTargetSolutionFileDefinedAndWritable()) {
try {
- Files.createFile(this.targetSolutionFile);
- } catch (IOException e) {
+ Files.createFile(this.targetSolutionFile.get());
+ } catch (IOException | NoSuchElementException e) {
throw new IllegalArgumentException("Cannot write to target solution file.", e);
}
}
@@ -76,13 +95,18 @@ public class TextFileRenderer implements Renderer> {
text = TEXT_RENDERER.setRenderSolution(false).render(labyrinth).strip();
solution = TEXT_RENDERER.setRenderSolution(true).render(labyrinth).strip();
}
+ final Path targetLabyrinthFile = this.targetLabyrinthFile.get();
+ final Path targetSolutionFile = this.targetSolutionFile.get();
try {
- Files.write(this.targetLabyrinthFile, text.getBytes(StandardCharsets.UTF_8));
- Files.write(this.targetSolutionFile, solution.getBytes(StandardCharsets.UTF_8));
+ Files.write(targetLabyrinthFile, text.getBytes(StandardCharsets.UTF_8));
} catch (IOException e) {
- System.err.println("Failed writing to file " + this.targetLabyrinthFile.normalize().toString());
- e.printStackTrace();
+ log.error("Failed writing to file " + targetLabyrinthFile.normalize(), e);
}
- return List.of(this.targetLabyrinthFile, this.targetSolutionFile);
+ try {
+ Files.write(targetSolutionFile, solution.getBytes(StandardCharsets.UTF_8));
+ } catch (IOException e) {
+ log.error("Failed writing to file " + targetSolutionFile.normalize());
+ }
+ return List.of(targetLabyrinthFile, targetSolutionFile);
}
}
diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml
new file mode 100644
index 0000000..fd7cd55
--- /dev/null
+++ b/src/main/resources/logback.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+