From a8c507dc29fcafe9f96a9b1122792c52b27f0edb Mon Sep 17 00:00:00 2001
From: Andrey Ruzhanskiy <andrey.ruzhanskiy@tu-dresden.de>
Date: Thu, 18 Jul 2019 20:02:28 +0200
Subject: [PATCH] Code cleanup, added Javadoc, added new parsecheck for mode
 and added new message when violated.

---
 .../de/tudresden/inf/mci/brailleplot/App.java |  18 +---
 .../JavaPropertiesConfigurationValidator.java |  34 +++++-
 .../brailleplot/exporter/PrintDirector.java   | 102 +++++++-----------
 ...figuration.java => PrinterCapability.java} |   1 +
 4 files changed, 75 insertions(+), 80 deletions(-)
 rename src/main/java/de/tudresden/inf/mci/brailleplot/exporter/{PrinterConfiguration.java => PrinterCapability.java} (96%)

diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/App.java b/src/main/java/de/tudresden/inf/mci/brailleplot/App.java
index 8ba38b2c..1d401169 100644
--- a/src/main/java/de/tudresden/inf/mci/brailleplot/App.java
+++ b/src/main/java/de/tudresden/inf/mci/brailleplot/App.java
@@ -3,7 +3,7 @@ package de.tudresden.inf.mci.brailleplot;
 
 import de.tudresden.inf.mci.brailleplot.configparser.*;
 import de.tudresden.inf.mci.brailleplot.exporter.PrintDirector;
-import de.tudresden.inf.mci.brailleplot.exporter.PrinterConfiguration;
+import de.tudresden.inf.mci.brailleplot.exporter.PrinterCapability;
 
 import de.tudresden.inf.mci.brailleplot.printabledata.MatrixData;
 import de.tudresden.inf.mci.brailleplot.printabledata.SimpleMatrixDataImpl;
@@ -149,22 +149,10 @@ public final class App {
 
             // Last Step: Printing
 
-
-            if (PrintDirector.printerExists("Index Everest-D V4")) {
-                System.out.println("Ja");
-            } else {
-                System.out.println("Nein");
-            }
-
             MatrixData<Boolean> data = new SimpleMatrixDataImpl<>(printer, formatA4, 18, 20, true);
             String printerConfigUpperCase = printer.getProperty("mode").toString().toUpperCase();
-            PrintDirector printD = new PrintDirector(PrinterConfiguration.valueOf(printerConfigUpperCase));
-            printD.print(printer.getProperty("name").toString(), data);
-
-            /*
-            byte[] data = lt.buildDemo(1);
-            lt.printString(data);
-            */
+            PrintDirector printD = new PrintDirector(PrinterCapability.valueOf(printerConfigUpperCase), printer);
+            printD.print(data);
 
         } catch (final Exception e) {
             terminateWithException(e);
diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/configparser/JavaPropertiesConfigurationValidator.java b/src/main/java/de/tudresden/inf/mci/brailleplot/configparser/JavaPropertiesConfigurationValidator.java
index 328eec40..d495bac1 100644
--- a/src/main/java/de/tudresden/inf/mci/brailleplot/configparser/JavaPropertiesConfigurationValidator.java
+++ b/src/main/java/de/tudresden/inf/mci/brailleplot/configparser/JavaPropertiesConfigurationValidator.java
@@ -1,7 +1,9 @@
 package de.tudresden.inf.mci.brailleplot.configparser;
 
-import de.tudresden.inf.mci.brailleplot.exporter.PrinterConfiguration;
+import de.tudresden.inf.mci.brailleplot.exporter.PrinterCapability;
 
+import javax.print.PrintService;
+import javax.print.PrintServiceLookup;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.util.HashMap;
@@ -31,10 +33,11 @@ class JavaPropertiesConfigurationValidator implements ConfigurationValidator {
         Predicate<String> requirePositive = JavaPropertiesConfigurationValidator::checkIfPositive;
         Predicate<String> requireFileExists = JavaPropertiesConfigurationValidator::checkIfFileExists;
         Predicate<String> requireEnum = JavaPropertiesConfigurationValidator::checkIfEnum;
+        Predicate<String> requirePrinterExists = JavaPropertiesConfigurationValidator::checkIfPrinterExists;
 
         // Definition of valid printer properties
         Map<String, Predicate<String>> p = new HashMap<>();
-        p.put("name", requireNotEmpty);
+        p.put("name", requireNotEmpty.and(requirePrinterExists));
         p.put("min.charsPerLine", requireInteger.and(requirePositive));
         p.put("max.charsPerLine", requireInteger.and(requirePositive));
         p.put("min.linesPerPage", requireInteger.and(requirePositive));
@@ -166,11 +169,36 @@ class JavaPropertiesConfigurationValidator implements ConfigurationValidator {
 
 
     private static boolean checkIfEnum(final String name) {
-        for (PrinterConfiguration p : PrinterConfiguration.values()) {
+        for (PrinterCapability p : PrinterCapability.values()) {
             if (p.toString().toLowerCase().equals(name)) {
                 return true;
             }
         }
+        PrinterCapability[] possibleValues = PrinterCapability.values();
+        StringBuilder sBuilder = new StringBuilder();
+        for (int i = 0; i < possibleValues.length; i++) {
+            sBuilder.append(possibleValues[i]).append(",");
+        }
+        String result =  sBuilder.deleteCharAt(sBuilder.length() - 1).toString();
+        throw new RuntimeException("The given mode for the printer "
+                + name + "is currently not supported/not found in"
+                + "the system. Currently, the possible values are: " + result);
+    }
+
+    /**
+     * Static method for checking if the printer, which was given, exists in the Printer System Dialog.
+     * @param printerName The name of the printer to check.
+     * @return True if printer exists. False if not.
+     */
+
+    private static boolean checkIfPrinterExists(final String printerName) {
+        PrintService[] services = PrintServiceLookup.lookupPrintServices(null, null);
+        for (PrintService service: services) {
+            if (service.getName().equals(printerName)) {
+                return true;
+            }
+        }
         return false;
     }
+
 }
diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/exporter/PrintDirector.java b/src/main/java/de/tudresden/inf/mci/brailleplot/exporter/PrintDirector.java
index 54076527..76eb086b 100644
--- a/src/main/java/de/tudresden/inf/mci/brailleplot/exporter/PrintDirector.java
+++ b/src/main/java/de/tudresden/inf/mci/brailleplot/exporter/PrintDirector.java
@@ -1,21 +1,24 @@
 package de.tudresden.inf.mci.brailleplot.exporter;
 
 
+import de.tudresden.inf.mci.brailleplot.configparser.Printer;
 import de.tudresden.inf.mci.brailleplot.printabledata.MatrixData;
 
 import javax.print.*;
 import javax.print.attribute.HashPrintRequestAttributeSet;
 import javax.print.attribute.PrintRequestAttributeSet;
+import java.util.Objects;
 
 /**
  * Implements a variation of the GoF Design pattern Builder. This class is used for setting the printerconfiguration and
  * for printing.
  * @author Andrey Ruzhanskiy
+ * @version 17.07.2019
  */
 public class PrintDirector {
 
     private AbstractDocumentBuilder mBuilder;
-    private final PrinterConfiguration mPrinter;
+    private final PrinterCapability mPrinter;
     private PrintService mService;
     private String mPrinterName;
     private DocFlavor mDocflavor;
@@ -24,13 +27,16 @@ public class PrintDirector {
     /**
      * Constructor for the PrintDirector. Main Class for printing. The class takes care of the complex Protocol to build
      * the document for the given configuration.
-     * @param printer Which printerconfiguration should be used. Normalprinter assumes that no special Features like
+     * @param printerCap Which printerconfiguration should be used. Normalprinter assumes that no special Features like
      *                GraphicMode or FloatindDotArea will be used.
+     * @param printerConfig The Printer object, used for extracting the name of the printer.
      */
 
-    public PrintDirector(final PrinterConfiguration printer) {
-        this.mPrinter = printer;
-
+    public PrintDirector(final PrinterCapability printerCap, final Printer printerConfig) {
+        Objects.requireNonNull(printerCap);
+        Objects.requireNonNull(printerConfig);
+        this.mPrinter = printerCap;
+        mPrinterName = printerConfig.getProperty("name").toString();
         switch (mPrinter) {
             case NORMALPRINTER: mBuilder = new NormalBuilder(); break;
             case INDEX_EVEREST_D_V4_GRAPHIC_PRINTER:
@@ -41,84 +47,56 @@ public class PrintDirector {
                 break;
             default: throw new IllegalArgumentException();
         }
+
     }
 
     /**
-     * Static method for checking if the printer, which was given, exists in the Printer System Dialog.
-     * @param printerName The name of the printer to check.
-     * @return
+     * Public method for printing the given Document with the given data.
+     * @param data Data to be printed.
      */
 
-    public static boolean printerExists(final String printerName) {
-        PrintService[] services = PrintServiceLookup.lookupPrintServices(null, null);
-        for (PrintService service: services) {
-            if (service.getName().equals(printerName)) {
-                return true;
-            }
-        }
-        return false;
+    public <T> void print(final MatrixData<T> data)  {
+        Objects.requireNonNull(data);
+        setUpDoc();
+        setUpService();
+        byte[] result = mBuilder.assemble(data);
+        print(result);
     }
 
-
     /**
-     * Method for setting the Printer.
-     * @param printerName
-     * @throws IllegalArgumentException if the printer is not found.
+     * Method for setting up the DocFlavor for printing. Currently, not parameterised because the printer can
+     * (hopefully) understand raw bytes with an octet stream.
      */
-    private void setPrinter(final String printerName) {
-        if (printerExists(printerName)) {
-            mPrinterName = printerName;
-            PrintService[] services = PrintServiceLookup.lookupPrintServices(null, null);
-            for (PrintService service: services) {
-                if (service.getName().equals(mPrinterName)) {
-                    mService = service;
-                }
-            }
-        } else {
-            throw new IllegalArgumentException("The given Printer " + printerName + " was not found in the System.");
-        }
+    private void setUpDoc() {
+        mDocflavor = new DocFlavor("application/octet-stream", "[B");
     }
 
+
     /**
-     * Stub.
-     * @param printerName
+     * Method for setting the correct printer Service for the Printername.
+     * @throws RuntimeException if the System cant find the service.
      */
 
-    @SuppressWarnings("checkstyle:MagicNumber")
-    public <T> void print(final String printerName, final MatrixData<T> data)  {
-        if (printerName == null || data == null) {
-            throw new NullPointerException();
-        }
-        String printerNameFromConfig = data.getPrinterConfig().getProperty("name").toString();
-        if (printerName.equals(printerNameFromConfig)) {
-            setUpDoc();
-            setPrinter(printerName);
-            byte[] result = mBuilder.assemble(data);
-            print(result);
-        } else {
-            throw new IllegalArgumentException("The given Printername does not correspond with the Printername "
-                    + "in the printerConfig. Printerconfig: " + printerNameFromConfig + " Printer " + printerName);
+    private void setUpService() {
+        PrintService[] services = PrintServiceLookup.lookupPrintServices(null, null);
+        for (PrintService service: services) {
+            if (service.getName().equals(mPrinterName)) {
+                mService = service;
+                return;
+            }
         }
-
-    }
-
-    /**
-     * Method for setting up the DocFlavor fir printing. Currently, not parameterised because the printer can (hopefully
-     * understand raw bytes with an octet stream.
-     */
-    private void setUpDoc() {
-        mDocflavor = new DocFlavor("application/octet-stream", "[B");
+        throw new RuntimeException("Cant register Printerservice for the printername : " + mPrinterName);
     }
 
     /**
-     * Private Method for sendind the data to the printer.
-     * @param data
+     * Private Method for sending the data to the printer. Separated from the public method so that the assemble process
+     * and the printing process are separated logically, but from outside it looks like it all happens in one method.
+     * @param data to be printed.
+     * @throws PrintException If the printingjob could not be completed.
      */
 
     private void print(final byte[] data) {
-        if (data == null) {
-            throw new NullPointerException();
-        }
+        Objects.requireNonNull(data);
         Doc doc = new SimpleDoc(data, mDocflavor, null);
         PrintRequestAttributeSet asset = new HashPrintRequestAttributeSet();
         DocPrintJob job = mService.createPrintJob();
diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/exporter/PrinterConfiguration.java b/src/main/java/de/tudresden/inf/mci/brailleplot/exporter/PrinterCapability.java
similarity index 96%
rename from src/main/java/de/tudresden/inf/mci/brailleplot/exporter/PrinterConfiguration.java
rename to src/main/java/de/tudresden/inf/mci/brailleplot/exporter/PrinterCapability.java
index 6b5ca91d..cb74aa62 100644
--- a/src/main/java/de/tudresden/inf/mci/brailleplot/exporter/PrinterConfiguration.java
+++ b/src/main/java/de/tudresden/inf/mci/brailleplot/exporter/PrinterCapability.java
@@ -8,6 +8,7 @@ package de.tudresden.inf.mci.brailleplot.exporter;
  * Softwaredeveloper must
  * Currently used in PrintDirector.
  * @author Andrey Ruzhanskiy
+ * @version 17.07.2019
  */
 
 public enum PrinterConfiguration {
-- 
GitLab