diff --git a/.gitignore b/.gitignore index f930235d667b3385e9c0d64eccd425e3f1dc0d7e..36111bc1a41b6dd6012549b0af28a2848ee83581 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ build out *gradle* !build.gradle +!integrationTest.gradle # IntelliJ .idea diff --git a/build.gradle b/build.gradle index 5cffa0a73a8ec20877b1463f91d426922f87f67a..acf86f9c71d2b05cf613b6f2f7ee237d47df3d78 100644 --- a/build.gradle +++ b/build.gradle @@ -30,7 +30,7 @@ dependencies { // Use JUnit test framework compile group: 'commons-cli', name: 'commons-cli', version: '1.4' testImplementation('org.junit.jupiter:junit-jupiter:5.4.2') - + // Logging compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.26' compile group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.3' @@ -38,9 +38,12 @@ dependencies { // Units compile group: 'javax.measure', name: 'unit-api', version: '2.0-PRD' compile group: 'tec.units', name: 'unit-ri', version: '1.0.3' + + // CSV parsing + compile "com.opencsv:opencsv:4.6" } -test { +tasks.withType(Test) { useJUnitPlatform() } @@ -57,7 +60,11 @@ jar { } } -checkstyleTest{ +checkstyleTest { showViolations = true checkstyleTest.enabled = false -} \ No newline at end of file +} + + // Needed for Integrationtests + +apply from: "$rootDir/integrationTest.gradle" \ No newline at end of file diff --git a/integrationTest.gradle b/integrationTest.gradle new file mode 100644 index 0000000000000000000000000000000000000000..a38fe5639576302fc3041ec0f312a7e7e822cbff --- /dev/null +++ b/integrationTest.gradle @@ -0,0 +1,17 @@ +sourceSets { + integrationTest { + java.srcDir 'src/integrationTest' + resources.srcDir 'src/test/resources' + compileClasspath += sourceSets.main.output + configurations.testRuntimeClasspath + runtimeClasspath += output + compileClasspath + } +} + +task integrationTest(type: Test) { + group = 'verification' + description = 'Runs Integrationtests.' + testClassesDirs = sourceSets.integrationTest.output.classesDirs + classpath = sourceSets.integrationTest.runtimeClasspath + mustRunAfter test + checkstyleIntegrationTest.enabled = false +} \ No newline at end of file diff --git a/src/integrationTest/java/PrintableDataExporterIntegTest.java b/src/integrationTest/java/PrintableDataExporterIntegTest.java new file mode 100644 index 0000000000000000000000000000000000000000..5d887597aed7972e852c97e3c6d3e2acfeac750e --- /dev/null +++ b/src/integrationTest/java/PrintableDataExporterIntegTest.java @@ -0,0 +1,206 @@ +import de.tudresden.inf.mci.brailleplot.commandline.CommandLineParser; +import de.tudresden.inf.mci.brailleplot.commandline.SettingsReader; +import de.tudresden.inf.mci.brailleplot.commandline.SettingsWriter; +import de.tudresden.inf.mci.brailleplot.configparser.Format; +import de.tudresden.inf.mci.brailleplot.configparser.JavaPropertiesConfigurationParser; +import de.tudresden.inf.mci.brailleplot.configparser.Printer; +import de.tudresden.inf.mci.brailleplot.printerbackend.PrintDirector; +import de.tudresden.inf.mci.brailleplot.printerbackend.PrinterCapability; +import de.tudresden.inf.mci.brailleplot.printabledata.MatrixData; +import de.tudresden.inf.mci.brailleplot.printabledata.SimpleMatrixDataImpl; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import javax.print.DocFlavor; +import java.io.File; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * Integrationtests for the components PrintableData and Exporter. + * Because most of the Exporter Unit tests depend heavily on the packages PrintableData and configParser, + * these are also located here. Most, if not all unittests for the exporter are tested via Reflection. It is + * contestable if these tests are really needed, but the with more LOC Coverage, there comes more possible stability. + * @author Andrey Ruzhanskiy + * @version 30.07.2019 + */ + +public class PrintableDataExporterIntegTest { + + private static String[] args; + private static CommandLineParser cliParser; + private static SettingsWriter settings; + private static SettingsReader settingsReader; + private static Printer printer; + private static Format format; + private static MatrixData<Boolean> data; + + + /** + * Setup Method for testing the exporter package. + */ + @BeforeAll + public static void setUp() { + Assertions.assertDoesNotThrow(() -> { + String correct = getResource("config/correct.properties").getAbsolutePath(); + String standard = getResource("config/default.properties").getAbsolutePath(); + JavaPropertiesConfigurationParser configParser = new JavaPropertiesConfigurationParser(correct, standard); + printer = configParser.getPrinter(); + printer.getProperty("brailletable").toString(); + format = configParser.getFormat("A4"); + data = new SimpleMatrixDataImpl<>(printer, format, 18, 20, true); + }); + } + + public static File getResource(String fileName) { + ClassLoader classLoader = ClassLoader.getSystemClassLoader(); + File resourceFile = new File(classLoader.getResource(fileName).getFile()); + return resourceFile; + } + /** + * Unittest/Integrationtest for the private Print method with a Null Servive. + * Expected: Nullpointerexception. + */ + @Test + public void testPrivatePrintWithNullService() { + Assertions.assertThrows(NullPointerException.class, () -> { + Method privatePrint = PrintDirector.class.getDeclaredMethod("print", byte[].class); + privatePrint.setAccessible(true); + try { + privatePrint.invoke(new PrintDirector(PrinterCapability.NORMALPRINTER,printer), new byte[] {0x55}); + } catch (InvocationTargetException e) { + throw e.getTargetException(); + } + }); + } + + /** + * Unittest/Integrationtest for private print method with a null byte. + * Expected: Nullpointerexception. + */ + @Test + public void testPrivatePrintWithNullByte() { + Assertions.assertThrows(NullPointerException.class, () -> { + Method privatePrint = PrintDirector.class.getDeclaredMethod("print", byte[].class); + privatePrint.setAccessible(true); + try { + privatePrint.invoke(new PrintDirector(PrinterCapability.NORMALPRINTER,printer), (Object) null); + } catch (InvocationTargetException e) { + throw e.getTargetException(); + } + }); + } + + /** + * Unittest/Integrationtest for private print method with non existing Docflavour. + * Expected: Nullpointerexception. + */ + @Test + public void testPrivatePrintWithNoDocFlavour() { + Assertions.assertThrows(NullPointerException.class, () -> { + Method privatePrint = PrintDirector.class.getDeclaredMethod("print", byte[].class); + privatePrint.setAccessible(true); + Method setUpService = PrintDirector.class.getDeclaredMethod("setUpService"); + setUpService.setAccessible(true); + try { + PrintDirector printD = new PrintDirector(PrinterCapability.NORMALPRINTER,printer); + setUpService.invoke(printD); + privatePrint.invoke(printD, new byte[] {0x55}); + } catch (InvocationTargetException e) { + throw e.getTargetException(); + } + }); + } + + /** + * Unittest/Integrationtest for private print Method with non existing Printer. + * Expected: RuntimeException + */ + + @Test + public void testPrivateSetUpServiceWithNotExistentPrinter() { + Assertions.assertThrows(RuntimeException.class, () -> { + Method setUpService = PrintDirector.class.getDeclaredMethod("setUpService"); + setUpService.setAccessible(true); + Field mPrinterName = PrintDirector.class.getDeclaredField("mPrinterName"); + mPrinterName.setAccessible(true); + try { + PrintDirector printD = new PrintDirector(PrinterCapability.NORMALPRINTER, printer); + mPrinterName.set(printD, "please dont exist, please please please"); + setUpService.invoke(printD); + } catch (InvocationTargetException e) { + throw e.getTargetException(); + } + }); + } + + /** + * Unittest/Integrationtest for Method SetUpService with NullPrinter. + * Expected: Nullpointerexception. + */ + @Test + public void testPrivateSetUpServiceWithNullPrinter() { + Assertions.assertThrows(NullPointerException.class, () -> { + Method setUpService = PrintDirector.class.getDeclaredMethod("setUpService"); + setUpService.setAccessible(true); + Field mPrinterName = PrintDirector.class.getDeclaredField("mPrinterName"); + mPrinterName.setAccessible(true); + try { + PrintDirector printD = new PrintDirector(PrinterCapability.NORMALPRINTER, printer); + mPrinterName.set(printD, (Object)null); + setUpService.invoke(printD); + } catch (InvocationTargetException e) { + throw e.getTargetException(); + } + }); + } + + + /** + * Unittest/Integrationtest for setting a Wrong Doc Flavor and trying to print with it. + * Expected: RuntimeException. + */ + @Test + public void testWrongDocFlavor() { + Assertions.assertThrows(RuntimeException.class, () -> { + Field mDocflavor = PrintDirector.class.getDeclaredField("mDocflavor"); + mDocflavor.setAccessible(true); + PrintDirector printD = new PrintDirector(PrinterCapability.NORMALPRINTER, printer); + mDocflavor.set(printD, new DocFlavor("text/html", "[B")); + Method setUpService = PrintDirector.class.getDeclaredMethod("setUpService"); + setUpService.setAccessible(true); + Method privatePrint = PrintDirector.class.getDeclaredMethod("print", byte[].class); + privatePrint.setAccessible(true); + try { + setUpService.invoke(printD); + privatePrint.invoke(printD, new byte[] {0x50}); + } catch (InvocationTargetException e){ + throw e.getTargetException(); + } + }); + } + + // Positve Testcases + + @Test + public void testFloatingDotCapability() { + Assertions.assertDoesNotThrow(() -> { + PrintDirector printD = new PrintDirector(PrinterCapability.INDEX_EVEREST_D_V4_FLOATINGDOT_PRINTER, printer); + }); + } + + @Test + public void testGraphicPrintCapability() { + Assertions.assertDoesNotThrow(() -> { + PrintDirector printD = new PrintDirector(PrinterCapability.INDEX_EVEREST_D_V4_GRAPHIC_PRINTER, printer); + }); + } + + @Test + public void testIsPrintServiceOn() { + Assertions.assertTrue(PrintDirector.isPrintServiceOn()); + } +} diff --git a/src/integrationTest/resources/config/correct.properties b/src/integrationTest/resources/config/correct.properties new file mode 100644 index 0000000000000000000000000000000000000000..37a86c5180c0f857e12dbd66ca502b76bd806523 --- /dev/null +++ b/src/integrationTest/resources/config/correct.properties @@ -0,0 +1,69 @@ +# JProperties Printer & Format Configuration +# +# Embosser: Index Everest-D V4 +# Version 1 Rev. 8 (19-07-19) +# +# Description: +# This is the main configuration file for use with the braille plot application +# when embossing with the 'Index Everest-D V4'. +# The configuration specifies the general printer abilities and defines +# pre-selectable formats for this embosser. +# +# https://gitlab.hrz.tu-chemnitz.de/s9444737--tu-dresden.de/brailleplot/wikis/Software%20Design#configuration-files +# ============================================================================= + +### General Printer Properties +### ========================== + +printer.name=Dummy Printer +printer.mode=normalprinter +printer.brailletable=src/integrationTest/resources/mapping/eurobraille.properties +printer.floatingDot.support=true +printer.floatingDot.resolution=0.05 + +# The following values represent the fixed indentation and maximum technical printing area of the embosser. +# If the outputs don't fit on the page you might want to tweak this values. (Check the format too.) +printer.constraint.top=5.0 +printer.constraint.left=0 +#printer.constraint.width=? TODO: Check out manual, Conduct printing tests with bigger formats +#printer.constraint.height=? +# The second constraint in the printer.raster namespace helps to limit the available printing area in steps of +# whole cells, for example if the printer enforces a maximum char per line limit or borders are activated. +printer.raster.constraint.top=0 +printer.raster.constraint.left=1 +printer.raster.constraint.width=35 +printer.raster.constraint.height=29 + +# The following properties define the exact grid spacing. +printer.raster.cellDistance.horizontal=3.6 +printer.raster.cellDistance.vertical=4.8 +printer.raster.dotDistance.horizontal=2.5 +printer.raster.dotDistance.vertical=2.5 +printer.raster.dotDiameter=1.5 + +### Format Definitions +### ================== + +# A4 Format +format.A4.page.width=210 +format.A4.page.height=297 +format.A4.margin.top=0 +format.A4.margin.left=0 +format.A4.margin.bottom=0 +format.A4.margin.right=0 + +# A5 Format +format.A5.page.width=148 +format.A5.page.height=210 +format.A5.margin.top=0 +format.A5.margin.left=0 +format.A5.margin.bottom=0 +format.A5.margin.right=0 + +# Wide Format +format.wide.page.width=272 +format.wide.page.height=210 +format.wide.margin.top=0 +format.wide.margin.left=0 +format.wide.margin.bottom=0 +format.wide.margin.right=0 \ No newline at end of file diff --git a/src/integrationTest/resources/config/default.properties b/src/integrationTest/resources/config/default.properties new file mode 100644 index 0000000000000000000000000000000000000000..f6405e0725ba3b349f015066b619f4ce41847f52 --- /dev/null +++ b/src/integrationTest/resources/config/default.properties @@ -0,0 +1,55 @@ +# JProperties Printer & Format Configuration +# +# Embosser: Dummy Default +# Test Revision (19-07-18) (DON'T USE FOR PRINTING) +# +# Description: +# This is the default configuration file for the braille plot application. +# The configuration specifies the default values of required properties. +# +# https://gitlab.hrz.tu-chemnitz.de/s9444737--tu-dresden.de/brailleplot/wikis/Software%20Design#configuration-files +# ============================================================================= + +# ATTENTION: Changes to this configuration will affect settings for ALL printer and format definitions which +# are not overriding the defaults. + +printer.mode=normalprinter +printer.brailletable=src/test/resources/mapping/eurobraille.properties +printer.floatingDot.support=false + +# The following values represent the fixed indentation and maximum technical printing area of the embosser. +# If the outputs don't fit on the page you might want to tweak this values. (Check the format too.) +printer.constraint.top=0 +printer.constraint.left=0 +# The second constraint in the printer.raster namespace helps to limit the available printing area in steps of +# whole cells, for example if the printer enforces a maximum char per line limit or borders are activated. +printer.raster.constraint.top=0 +printer.raster.constraint.left=0 +printer.raster.constraint.width=200 +printer.raster.constraint.height=300 + +# Overall grid layout / type +printer.raster.type=6-dot + +# The following properties define the exact grid spacing. Standard values based on the +# 'Marburg Medium' publication standard as described in the FFI braille technical guideline: +# https://www.ffi.de/assets/Uploads/Technische-Richtlinie-Blindenschrift.pdf +# See also: # https://codes.iccsafe.org/content/ICCA117_12003/chapter-7-communication-elements-and-features#ICCA117.1_2003_Ch07_Sec703 +printer.raster.cellDistance.horizontal=3.5 +printer.raster.cellDistance.vertical=5.0 +printer.raster.dotDistance.horizontal=2.5 +printer.raster.dotDistance.vertical=2.5 +printer.raster.dotDiameter=1.5 + + +### Format Definitions +### ================== + +# Default Format Definition +format.default.page.height=297 +format.default.margin.top=10 +format.default.margin.left=10 +format.default.margin.bottom=10 +format.default.margin.right=10 + +# This is a template. Do not define concrete formats in this file. Use the specific user config file for this purpose. \ No newline at end of file diff --git a/src/integrationTest/resources/config/false.properties b/src/integrationTest/resources/config/false.properties new file mode 100644 index 0000000000000000000000000000000000000000..4f0fc93c70d3dc2567a3a1eabaab26b299b5a313 --- /dev/null +++ b/src/integrationTest/resources/config/false.properties @@ -0,0 +1,69 @@ +# JProperties Printer & Format Configuration +# +# Embosser: Index Everest-D V4 +# Version 1 Rev. 8 (19-07-19) +# +# Description: +# This is the main configuration file for use with the braille plot application +# when embossing with the 'Index Everest-D V4'. +# The configuration specifies the general printer abilities and defines +# pre-selectable formats for this embosser. +# +# https://gitlab.hrz.tu-chemnitz.de/s9444737--tu-dresden.de/brailleplot/wikis/Software%20Design#configuration-files +# ============================================================================= + +### General Printer Properties +### ========================== + +printer.name=Index Everest-D V4 +printer.mode=normalKek +printer.brailletable=src/main/resources/mapping/eurobraille.propertiesKek +printer.floatingDot.support=true +printer.floatingDot.resolution=0.05 + +# The following values represent the fixed indentation and maximum technical printing area of the embosser. +# If the outputs don't fit on the page you might want to tweak this values. (Check the format too.) +printer.constraint.top=5.0 +printer.constraint.left=0 +#printer.constraint.width=? TODO: Check out manual, Conduct printing tests with bigger formats +#printer.constraint.height=? +# The second constraint in the printer.raster namespace helps to limit the available printing area in steps of +# whole cells, for example if the printer enforces a maximum char per line limit or borders are activated. +printer.raster.constraint.top=0 +printer.raster.constraint.left=1 +printer.raster.constraint.width=35 +printer.raster.constraint.height=29 + +# The following properties define the exact grid spacing. +printer.raster.cellDistance.horizontal=3.6 +printer.raster.cellDistance.vertical=4.8 +printer.raster.dotDistance.horizontal=2.5 +printer.raster.dotDistance.vertical=2.5 +printer.raster.dotDiameter=1.5 + +### Format Definitions +### ================== + +# A4 Format +format.A4.page.width=210 +format.A4.page.height=297 +format.A4.margin.top=0 +format.A4.margin.left=0 +format.A4.margin.bottom=0 +format.A4.margin.right=0 + +# A5 Format +format.A5.page.width=148 +format.A5.page.height=210 +format.A5.margin.top=0 +format.A5.margin.left=0 +format.A5.margin.bottom=0 +format.A5.margin.right=0 + +# Wide Format +format.wide.page.width=272 +format.wide.page.height=210 +format.wide.margin.top=0 +format.wide.margin.left=0 +format.wide.margin.bottom=0 +format.wide.margin.right=0 \ No newline at end of file diff --git a/src/integrationTest/resources/config/false2.properties b/src/integrationTest/resources/config/false2.properties new file mode 100644 index 0000000000000000000000000000000000000000..5287b37acf6a4868392b9c7ae713707a36a7db3b --- /dev/null +++ b/src/integrationTest/resources/config/false2.properties @@ -0,0 +1,69 @@ +# JProperties Printer & Format Configuration +# +# Embosser: Index Everest-D V4 +# Version 1 Rev. 8 (19-07-19) +# +# Description: +# This is the main configuration file for use with the braille plot application +# when embossing with the 'Index Everest-D V4'. +# The configuration specifies the general printer abilities and defines +# pre-selectable formats for this embosser. +# +# https://gitlab.hrz.tu-chemnitz.de/s9444737--tu-dresden.de/brailleplot/wikis/Software%20Design#configuration-files +# ============================================================================= + +### General Printer Properties +### ========================== + +printer.name=Index Everest-D V4 +printer.mode=normalKek +printer.brailletable=src/main/resources/mapping/eurobraille.properties +printer.floatingDot.support=true +printer.floatingDot.resolution=0.05 + +# The following values represent the fixed indentation and maximum technical printing area of the embosser. +# If the outputs don't fit on the page you might want to tweak this values. (Check the format too.) +printer.constraint.top=5.0 +printer.constraint.left=0 +#printer.constraint.width=? TODO: Check out manual, Conduct printing tests with bigger formats +#printer.constraint.height=? +# The second constraint in the printer.raster namespace helps to limit the available printing area in steps of +# whole cells, for example if the printer enforces a maximum char per line limit or borders are activated. +printer.raster.constraint.top=0 +printer.raster.constraint.left=1 +printer.raster.constraint.width=35 +printer.raster.constraint.height=29 + +# The following properties define the exact grid spacing. +printer.raster.cellDistance.horizontal=3.6 +printer.raster.cellDistance.vertical=4.8 +printer.raster.dotDistance.horizontal=2.5 +printer.raster.dotDistance.vertical=2.5 +printer.raster.dotDiameter=1.5 + +### Format Definitions +### ================== + +# A4 Format +format.A4.page.width=210 +format.A4.page.height=297 +format.A4.margin.top=0 +format.A4.margin.left=0 +format.A4.margin.bottom=0 +format.A4.margin.right=0 + +# A5 Format +format.A5.page.width=148 +format.A5.page.height=210 +format.A5.margin.top=0 +format.A5.margin.left=0 +format.A5.margin.bottom=0 +format.A5.margin.right=0 + +# Wide Format +format.wide.page.width=272 +format.wide.page.height=210 +format.wide.margin.top=0 +format.wide.margin.left=0 +format.wide.margin.bottom=0 +format.wide.margin.right=0 \ No newline at end of file diff --git a/src/integrationTest/resources/mapping/eurobraille.properties b/src/integrationTest/resources/mapping/eurobraille.properties new file mode 100644 index 0000000000000000000000000000000000000000..5a20a38bf440814956105a068e9f49d5234d9862 --- /dev/null +++ b/src/integrationTest/resources/mapping/eurobraille.properties @@ -0,0 +1,146 @@ +# JProperties Mapping BrailleTable +# +# Table: eurobraille +# Version 1 Rev. 3 (19-07-18) +# +# Description: +# This table contains a mapping from 6-bit-strings to decimal ascii byte values. +# It is used by the printer backend to encode data sent to the embosser. +# The pairs are ordered by ascending ascii byte value. +# +# ============================================================================= + +# 0-31:NUL-US (non visible characters) +# Space +000000=32 +# ! +000010=33 +# " +000100=34 +# # +001111=35 +# $ +000101=36 +# % +111111=37 +# & +111101=38 +# ' +000001=39 +# ( +011001=40 +# ) +001011=41 +# * +001010=42 +# + +011010=43 +# , +010000=44 +# - +001001=45 +# . +001000=46 +# / +010011=47 +# 0 +001101=48 +# 1 +100001=49 +# 2 +110001=50 +# 3 +100101=51 +# 4 +100111=52 +# 5 +100011=53 +# 6 +110101=54 +# 7 +110111=55 +# 8 +110011=56 +# 9 +010101=57 +# : +010010=58 +# ; +011000=59 +# < +000011=60 +# = +011011=61 +# > +000110=62 +# ? +010001=63 +# 64-90:@-Z +# [ +111011=91 +# 92:\ +# 93:] +# 94:^ +# _ +000111=95 +# ` +001110=96 +# a +100000=97 +# b +110000=98 +# c +100100=99 +# d +100110=100 +# e +100010=101 +# f +110100=102 +# g +110110=103 +# h +110010=104 +# i +010100=105 +# j +010110=106 +# k +101000=107 +# l +111000=108 +# m +101100=109 +# n +101110=110 +# o +101010=111 +# p +111100=112 +# q +111110=113 +# r +111010=114 +# s +011100=115 +# t +011110=116 +# u +101001=117 +# v +111001=118 +# w +010111=119 +# x +101101=120 +# y +101111=121 +# z +101011=122 +# { +011111=123 +# | +001100=124 +# ~ +011101=126 +# 127:DEL \ No newline at end of file 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 6b0a9f5c1ddaa5b4e5922abb1d935998bf0286ea..9d92f132440886e41f3350686c6e51ab7c37b534 100644 --- a/src/main/java/de/tudresden/inf/mci/brailleplot/App.java +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/App.java @@ -1,20 +1,41 @@ package de.tudresden.inf.mci.brailleplot; +import de.tudresden.inf.mci.brailleplot.configparser.Format; +import de.tudresden.inf.mci.brailleplot.configparser.JavaPropertiesConfigurationParser; +import de.tudresden.inf.mci.brailleplot.configparser.Printer; + +import de.tudresden.inf.mci.brailleplot.printerbackend.PrintDirector; +import de.tudresden.inf.mci.brailleplot.printerbackend.PrinterCapability; + +import de.tudresden.inf.mci.brailleplot.printabledata.SimpleMatrixDataImpl; + import de.tudresden.inf.mci.brailleplot.commandline.CommandLineParser; import de.tudresden.inf.mci.brailleplot.commandline.SettingType; import de.tudresden.inf.mci.brailleplot.commandline.SettingsReader; import de.tudresden.inf.mci.brailleplot.commandline.SettingsWriter; +import de.tudresden.inf.mci.brailleplot.csvparser.CsvOrientation; +import de.tudresden.inf.mci.brailleplot.csvparser.CsvParser; +import de.tudresden.inf.mci.brailleplot.csvparser.CsvType; +import de.tudresden.inf.mci.brailleplot.datacontainers.CategoricalPointListContainer; +import de.tudresden.inf.mci.brailleplot.datacontainers.PointList; +import de.tudresden.inf.mci.brailleplot.diagrams.BarChart; +import de.tudresden.inf.mci.brailleplot.rendering.MasterRenderer; +import de.tudresden.inf.mci.brailleplot.rendering.RasterCanvas; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; import java.util.Optional; import java.util.concurrent.ConcurrentLinkedDeque; /** * Main class. * Set up the application and run it. - * @author Georg Graßnick + * @author Georg Graßnick, Andrey Ruzhanskiy * @version 06.06.19 */ @@ -125,9 +146,52 @@ public final class App { return EXIT_SUCCESS; } + // Config Parsing + JavaPropertiesConfigurationParser configParser = new JavaPropertiesConfigurationParser( + getClass().getClassLoader().getResource("config/index_everest_d_v4.properties").getFile(), + getClass().getClassLoader().getResource("config/default.properties").getFile() + ); + Printer indexV4Printer = configParser.getPrinter(); + Format a4Format = configParser.getFormat("A4"); + // Parse csv data + ClassLoader classloader = Thread.currentThread().getContextClassLoader(); + InputStream csvStream = classloader.getResourceAsStream("examples/csv/0_bar_chart_categorical_vertical.csv"); + Reader csvReader = new BufferedReader(new InputStreamReader(csvStream)); + + CsvParser csvParser = new CsvParser(csvReader, ',', '\"'); + CategoricalPointListContainer<PointList> container = csvParser.parse(CsvType.X_ALIGNED_CATEGORIES, CsvOrientation.VERTICAL); + mLogger.debug("Internal data representation:\n {}", container.toString()); + BarChart barChart = new BarChart(container); + + // Render diagram + MasterRenderer renderer = new MasterRenderer(indexV4Printer, a4Format); + RasterCanvas canvas = renderer.rasterize(barChart); + SimpleMatrixDataImpl<Boolean> mat = (SimpleMatrixDataImpl<Boolean>) canvas.getCurrentPage(); + mLogger.debug("Render preview:\n" + mat.toBoolString()); + + // Config Parsing + + // Check if some SpoolerService/Printservice exists + if (!PrintDirector.isPrintServiceOn()) { + throw new Exception("Can't find any Printservices on this System."); + } - // ... + /* + We do not want to actually print on each run. + Until CLI parsing is fully integrated, you will have to disable this check by hand if you actually do + want to print. + Please do not commit changes to this. + */ + if (true) { + return EXIT_SUCCESS; + } + + // Last Step: Printing + @SuppressWarnings("checkstyle:MagicNumber") + String printerConfigUpperCase = indexV4Printer.getProperty("mode").toString().toUpperCase(); + PrintDirector printD = new PrintDirector(PrinterCapability.valueOf(printerConfigUpperCase), indexV4Printer); + printD.print(mat); } catch (final Exception e) { terminateWithException(e); @@ -137,5 +201,4 @@ public final class App { return EXIT_SUCCESS; } - } diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/brailleparser/AbstractBrailleTableParser.java b/src/main/java/de/tudresden/inf/mci/brailleplot/brailleparser/AbstractBrailleTableParser.java new file mode 100644 index 0000000000000000000000000000000000000000..f4496c627e261f7989b2222bdcd4ef2013543b4e --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/brailleparser/AbstractBrailleTableParser.java @@ -0,0 +1,15 @@ +package de.tudresden.inf.mci.brailleplot.brailleparser; + +/** + * Defines an interface which should be implemented in all parsers of braille tables. + */ +public interface AbstractBrailleTableParser { + + /** + * Common method for querying the braille table. + * @param key Braille cell, represented as string ("111000). + * @return Byte, represented as int, corresponding to the given braille cell. + */ + int getValue(String key); + +} diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/brailleparser/JsonParser.java b/src/main/java/de/tudresden/inf/mci/brailleplot/brailleparser/JsonParser.java new file mode 100644 index 0000000000000000000000000000000000000000..7f7c990528135262979e8f45627bb7d2b242ee8f --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/brailleparser/JsonParser.java @@ -0,0 +1,28 @@ +package de.tudresden.inf.mci.brailleplot.brailleparser; + +/** + * Class representing a Json parser entity. + * @author Andrey Ruzhanskiy + * @version 12.07.2019 + */ +public class JsonParser implements AbstractBrailleTableParser { + + /** + * Currently not supported. + * @param filePath File path to the braille table. + */ + public JsonParser(final String filePath) { + throw new UnsupportedOperationException(); + } + + + /** + * Currently not supported. + * @param key Braille cell, represented as string ("111000). + * @return The byte(int) representing the Braille cell specified in the braille table. + */ + @Override + public int getValue(final String key) { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/brailleparser/PropertiesParser.java b/src/main/java/de/tudresden/inf/mci/brailleplot/brailleparser/PropertiesParser.java new file mode 100644 index 0000000000000000000000000000000000000000..1b7e7db24c7ad8d703d1f949c34287b5f6e7d833 --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/brailleparser/PropertiesParser.java @@ -0,0 +1,45 @@ +package de.tudresden.inf.mci.brailleplot.brailleparser; + +import java.io.FileInputStream; +import java.util.Objects; +import java.util.Properties; + +/** + * Class representing a properties parser. + * @author Andrey Ruzhanskiy + * @version 12.07.2019 + */ + +public class PropertiesParser implements AbstractBrailleTableParser { + private Properties mProperties = new Properties(); + + /** + * Constructor for properties parser. Takes a filePath to the braille table file with the .properties file extension. + * @param filePath The path to the braille table. + * @throws RuntimeException If the file Path does not exists. + */ + public PropertiesParser(final String filePath) { + Objects.requireNonNull(filePath); + + FileInputStream stream; + try { + stream = new FileInputStream(filePath); + mProperties.load(stream); + stream.close(); + } catch (java.io.IOException e) { + throw new RuntimeException(e); + } + + } + + /** + * Method for querying the byte (represented via int) for a given cell from the braille table. + * @param key The braille cell, represented as a string (for example "111000" for 6 braille cell). + * @return The byte(int) representing the braille cell specified in the braille table, + */ + @Override + public int getValue(final String key) { + Objects.requireNonNull(key); + return Integer.parseInt(mProperties.getProperty(key)); + } +} diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/brailleparser/XmlParser.java b/src/main/java/de/tudresden/inf/mci/brailleplot/brailleparser/XmlParser.java new file mode 100644 index 0000000000000000000000000000000000000000..6a6109e7a677176f6ac37c688786a3dd88c37d82 --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/brailleparser/XmlParser.java @@ -0,0 +1,31 @@ +package de.tudresden.inf.mci.brailleplot.brailleparser; + + +/** + * Class representing a XML parser entity. + * @author Andrey Ruzhanskiy + * @version 12.07.2019 + */ +public class XmlParser implements AbstractBrailleTableParser { + + + /** + * Currently not supported. + * + * @param filePath Path to the braille table. + */ + public XmlParser(final String filePath) { + throw new UnsupportedOperationException(); + } + + + /** + * Currently not supported. + * @param key braille cell, represented as String ("111000). + * @return The byte(int) representing the braille cell specified in the braille table. + */ + @Override + public int getValue(final String key) { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/brailleparser/package-info.java b/src/main/java/de/tudresden/inf/mci/brailleplot/brailleparser/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..78d84e8809471555a34f28987c562b6388878f02 --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/brailleparser/package-info.java @@ -0,0 +1,4 @@ +/** + * This package contains all the required classes and interfaces for braille table parsing. + */ +package de.tudresden.inf.mci.brailleplot.brailleparser; \ No newline at end of file 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 19d61e8b8e4e6c3315eac6857ba8f4975123e1f8..1aa3d30673e6686ab5298559b6c6cebcb68d8393 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,5 +1,8 @@ package de.tudresden.inf.mci.brailleplot.configparser; + +import de.tudresden.inf.mci.brailleplot.printerbackend.PrinterCapability; + import java.io.FileInputStream; import java.io.FileNotFoundException; import java.util.ArrayList; @@ -11,8 +14,8 @@ import java.util.regex.Pattern; /** * Concrete validator for properties parsed from configuration files in Java Property File format. - * @author Leonard Kupper - * @version 2019.07.18 + * @author Leonard Kupper, Andrey Ruzhanskiy + * @version 2019.07.30 */ class JavaPropertiesConfigurationValidator implements ConfigurationValidator { @@ -240,4 +243,29 @@ class JavaPropertiesConfigurationValidator implements ConfigurationValidator { } return true; } + + + + private static boolean checkIfEnum(final String name) { + 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 '" + + 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. + */ } diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/csvparser/Constants.java b/src/main/java/de/tudresden/inf/mci/brailleplot/csvparser/Constants.java new file mode 100644 index 0000000000000000000000000000000000000000..68ab0f5f80c38de866218dda11a52d8d8bc8b344 --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/csvparser/Constants.java @@ -0,0 +1,17 @@ +package de.tudresden.inf.mci.brailleplot.csvparser; + +import java.text.NumberFormat; +import java.util.Locale; + +/** + * Class for constants representation. + * @author SVGPlott-Team + * @version 2019.07.29 + */ +public final class Constants { + public static final Locale LOCALE = new Locale("de"); + public static final NumberFormat NUMBER_FORMAT = NumberFormat.getInstance(LOCALE); + + private Constants() { + } +} diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/csvparser/CsvDotParser.java b/src/main/java/de/tudresden/inf/mci/brailleplot/csvparser/CsvDotParser.java new file mode 100644 index 0000000000000000000000000000000000000000..5cfbb98567271ecf3b2449cb8e314dfbc722624c --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/csvparser/CsvDotParser.java @@ -0,0 +1,154 @@ +package de.tudresden.inf.mci.brailleplot.csvparser; + +import de.tudresden.inf.mci.brailleplot.datacontainers.PointList; +import de.tudresden.inf.mci.brailleplot.datacontainers.PointListContainer; +import de.tudresden.inf.mci.brailleplot.datacontainers.SimplePointListContainerImpl; +import de.tudresden.inf.mci.brailleplot.datacontainers.SimplePointListImpl; +import de.tudresden.inf.mci.brailleplot.point.Point2DDouble; + +import java.text.ParseException; +import java.util.Iterator; +import java.util.List; +import java.util.Objects; + +/** + * Parser for CSV files that contain data for a scatter plot. + * @author SVGPlott-Team, Georg Graßnick + * @version 2019.07.29 + */ +public class CsvDotParser extends CsvParseAlgorithm<PointListContainer<PointList>> { + + /** + * Parses scattered point data in horizontal data sets, alternating mX and mY. The + * first column contains the row mName in the mX row. + * @param csvData The parsed input String. + * @return A {@link PointListContainer}{@literal <}{@link PointList}{@literal >} representing the data. + */ + public PointListContainer<PointList> parseAsHorizontalDataSets(final List<? extends List<String>> csvData) { + Objects.requireNonNull(csvData); + int row = 0; + + PointListContainer<PointList> container = new SimplePointListContainerImpl(); + + // Continue as long as there are at least two further rows left + while (csvData.size() >= row + 2) { + PointList rowPoints = new SimplePointListImpl(); + + Iterator<String> xRowIterator = csvData.get(row).iterator(); + Iterator<String> yRowIterator = csvData.get(row + 1).iterator(); + + row += 2; + + // Get the row mName + if (xRowIterator.hasNext() && yRowIterator.hasNext()) { + rowPoints.setName(xRowIterator.next()); + yRowIterator.next(); + } else { + continue; + } + + // Get the row values + while (xRowIterator.hasNext() && yRowIterator.hasNext()) { + Number xValue; + Number yValue; + try { + xValue = Constants.NUMBER_FORMAT.parse(xRowIterator.next()); + yValue = Constants.NUMBER_FORMAT.parse(yRowIterator.next()); + } catch (ParseException e) { + continue; + } + Point2DDouble newPoint = new Point2DDouble(xValue.doubleValue(), yValue.doubleValue()); + rowPoints.pushBack(newPoint); + } + + // If there were no points found, do not add the row to the list + if (rowPoints.getSize() > 0) { + container.pushBack(rowPoints); + } + } + + // TODO First add points to PointList, then add PointList to PointListContainer, so that there is no need for a calculateExtrema call + container.calculateExtrema(); + return container; + } + + /** + * Parses scattered point data in vertical data sets, alternating mX and mY. The + * first row contains the column mName in the mX column. + * @param csvData The parsed input String. + * @return A {@link PointListContainer}{@literal <}{@link PointList}{@literal >} representing the data. + */ + @Override + public PointListContainer<PointList> parseAsVerticalDataSets(final List<? extends List<String>> csvData) { + Objects.requireNonNull(csvData); + + if (true) { + throw new UnsupportedOperationException("Vertical parsing is currently not supported"); + } + + int row = 0; + + PointListContainer<PointList> container = new SimplePointListContainerImpl(); + + if (csvData.isEmpty()) { + return container; + } + + // Iterate over the first row in order to get the headers + int col = 0; + for (String header : csvData.get(0)) { + if (col % 2 == 0) { + PointList pointList = new SimplePointListImpl(); + pointList.setName(header); + container.pushBack(pointList); + } + col++; + } + + row++; + + // Continue as long as there is at least one further rows left + while (csvData.size() >= row + 1) { + List<String> fields = csvData.get(row); + Iterator<String> fieldIterator = fields.iterator(); + + col = -1; + + while (fieldIterator.hasNext()) { + String xRaw = fieldIterator.next(); + String yRaw; + + col++; + + if (!fieldIterator.hasNext()) { + break; + } + + yRaw = fieldIterator.next(); + + Number xValue; + Number yValue; + + try { + xValue = Constants.NUMBER_FORMAT.parse(xRaw); + yValue = Constants.NUMBER_FORMAT.parse(yRaw); + } catch (ParseException e) { + col++; + continue; + } + + Point2DDouble point = new Point2DDouble(xValue.doubleValue(), yValue.doubleValue()); + + addPointToPointListList(container, col / 2, point); + + col++; + } + + row++; + } + + // TODO First add points to PointList, then add PointList to PointListContainer, so that there is no need for a calculateExtrema call + container.calculateExtrema(); + return container; + } +} diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/csvparser/CsvOrientation.java b/src/main/java/de/tudresden/inf/mci/brailleplot/csvparser/CsvOrientation.java new file mode 100644 index 0000000000000000000000000000000000000000..a336515470dcff25898ca1b9db951e555f8e8b7a --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/csvparser/CsvOrientation.java @@ -0,0 +1,45 @@ +package de.tudresden.inf.mci.brailleplot.csvparser; + +/** + * Enumeration of the two possible CSV orientations. + * @author SVGPlott-Team + * @version 2019.07.29 + */ +public enum CsvOrientation { + + HORIZONTAL, VERTICAL; + + public static CsvOrientation fromString(final String code) { + if (code.equals("vertical") || code.equals("v")) { + return CsvOrientation.VERTICAL; + } else { + return CsvOrientation.HORIZONTAL; + } + } + + @Override + public String toString() { + return super.toString().toLowerCase(); + } + + /** + * Converter class that converts strings to CsvOrientation. + */ + public static class CsvOrientationConverter { + + public CsvOrientationConverter() { + super(); + } + + /** + * Converts a String value into the corresponding CsvOrientation. + * @param value String + * @return CsvOrientation + */ + public CsvOrientation convert(final String value) { + CsvOrientation convertedValue = CsvOrientation.fromString(value); + return convertedValue; + } + + } +} diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/csvparser/CsvParseAlgorithm.java b/src/main/java/de/tudresden/inf/mci/brailleplot/csvparser/CsvParseAlgorithm.java new file mode 100644 index 0000000000000000000000000000000000000000..1d6109dbdedb29cc1062e9e5fac53ab90c8b2a68 --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/csvparser/CsvParseAlgorithm.java @@ -0,0 +1,73 @@ +package de.tudresden.inf.mci.brailleplot.csvparser; + +import de.tudresden.inf.mci.brailleplot.datacontainers.PointList; +import de.tudresden.inf.mci.brailleplot.datacontainers.PointListContainer; +import de.tudresden.inf.mci.brailleplot.datacontainers.SimplePointListImpl; +import de.tudresden.inf.mci.brailleplot.point.Point2DDouble; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Iterator; +import java.util.List; +import java.util.Objects; + +/** + * An algorithm for parsing CSV data. Contains implementations for two + * orientations of the data in the file. + * @param <T> The type of PointContainer, that is parsed to. + * @author SVGPlott-Team, Georg Graßnick + * @version 2019.07.29 + */ +public abstract class CsvParseAlgorithm<T extends PointListContainer<PointList>> { + + protected final Logger mLogger = LoggerFactory.getLogger(getClass()); + + /** + * If the data sets are oriented horizontally, i.e. in rows, parse the rows into + * {@link PointListContainer}{@literal <}{@link PointList}{@literal >}. + * @param csvData The parsed input String. + * @return A {@link PointListContainer}{@literal <PointList>} representing the data. + */ + public abstract T parseAsHorizontalDataSets(List<? extends List<String>> csvData); + + /** + * If the data sets are oriented horizontally, i.e. in rows, parse the rows into + * {@link PointListContainer}{@literal <}{@link PointList}{@literal >}. + * @param csvData The parsed input String. + * @return A {@link PointListContainer}{@literal <}{@link PointList}{@literal >} representing the data. + */ + public abstract T parseAsVerticalDataSets(List<? extends List<String>> csvData); + + /** + * Adds a {@link Point2DDouble} to a {@link PointList} in a {@link PointListContainer}{@literal <}{@link PointList}{@literal >}, + * specified by {@code listIndex}. Adds more {@link PointList PointLists} if + * needed. + * @param container The {@link PointListContainer}{@literal <}{@link PointList}{@literal >} to which the point shall be added + * @param index The index of the list to which the point shall be added + * @param point The {@link Point2DDouble} which shall be added + */ + protected void addPointToPointListList(final PointListContainer<PointList> container, final int index, final Point2DDouble point) { + Objects.requireNonNull(container); + Objects.requireNonNull(point); + + // TODO: Check if this actually works + + int currentIdx = 0; + int listsToAddCount = index - container.getSize(); + + Iterator<PointList> it = container.iterator(); + + // Add extra intermediate lists if required + if (listsToAddCount > 0) { + for (int i = 0; i < listsToAddCount; i++) { + container.pushBack(new SimplePointListImpl()); + } + } + // Add the element itself + for (; currentIdx < index; currentIdx++) { + it.next(); + } + it.next().pushBack(point); + } + +} diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/csvparser/CsvParser.java b/src/main/java/de/tudresden/inf/mci/brailleplot/csvparser/CsvParser.java new file mode 100644 index 0000000000000000000000000000000000000000..cd1b3e14015fe8788eaaf63ba2b395dc41a53be6 --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/csvparser/CsvParser.java @@ -0,0 +1,92 @@ +package de.tudresden.inf.mci.brailleplot.csvparser; + +import com.opencsv.CSVParserBuilder; +import com.opencsv.CSVReader; +import com.opencsv.CSVReaderBuilder; +import de.tudresden.inf.mci.brailleplot.datacontainers.PointList; +import de.tudresden.inf.mci.brailleplot.datacontainers.PointListContainer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.io.Reader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Objects; + +/** + * Class to represent the main parser. This parser chooses the corresponding parsing algorithm for the data. + * @author SVGPlott-Team, Georg Graßnick + * @version 2019.07.29 + */ +public final class CsvParser { + + private final Logger mLogger = LoggerFactory.getLogger(CsvParser.class); + + private ArrayList<ArrayList<String>> mCsvData; + + /** + * Initiates the parser. The parser reads from the specified {@code reader} + * and populates the internal data structures. + * + * @param reader The {@link Reader} interfacing the actual csv file object. Must not be null. + * @param separator char The character which is used to separate the values in the csv file. + * @param quoteChar char The character which is used to quote text paragraphs. + * @throws IOException Is thrown, if an error occurs while performing read operations on the reader. + */ + public CsvParser(final Reader reader, final char separator, final char quoteChar) throws IOException { + Objects.requireNonNull(reader); + CSVReader csvReader = new CSVReaderBuilder(reader) + .withCSVParser(new CSVParserBuilder() + .withQuoteChar(quoteChar) + .withSeparator(separator) + .build()) + .build(); + + mCsvData = new ArrayList<>(); + + for (String[] line : csvReader) { + mCsvData.add(new ArrayList<>(Arrays.asList(line))); + mLogger.trace("Read line: {}", Arrays.toString(line)); + } + + csvReader.close(); + } + + /** + * Chooses the right parsing algorithm. + * Casting in this method is not guaranteed to be safe, use at your own risk. + * @param csvType CsvType + * @param csvOrientation CsvOrientation + * @return PointListList + */ + @SuppressWarnings("unchecked") + public <T extends PointListContainer<PointList>> T parse(final CsvType csvType, final CsvOrientation csvOrientation) { + CsvParseAlgorithm<T> csvParseAlgorithm; + + mLogger.debug("Parsing data as \"{}\", orientation \"{}\"", csvType, csvOrientation); + + switch (csvType) { + case DOTS: + csvParseAlgorithm = ((CsvParseAlgorithm<T>) new CsvDotParser()); + break; + case X_ALIGNED: + csvParseAlgorithm = ((CsvParseAlgorithm<T>) new CsvXAlignedParser()); + break; + case X_ALIGNED_CATEGORIES: + csvParseAlgorithm = ((CsvParseAlgorithm<T>) new CsvXAlignedCategoriesParser()); + break; + default: + throw new UnsupportedOperationException(); + } + + switch (csvOrientation) { + case HORIZONTAL: + return csvParseAlgorithm.parseAsHorizontalDataSets(mCsvData); + case VERTICAL: + return csvParseAlgorithm.parseAsVerticalDataSets(mCsvData); + default: + throw new UnsupportedOperationException(); + } + } +} diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/csvparser/CsvType.java b/src/main/java/de/tudresden/inf/mci/brailleplot/csvparser/CsvType.java new file mode 100644 index 0000000000000000000000000000000000000000..957699fc9d635d83b6be18272ecfd37478b39e67 --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/csvparser/CsvType.java @@ -0,0 +1,59 @@ +package de.tudresden.inf.mci.brailleplot.csvparser; + +/** + * Determines what data is represented how by the CSV file. The values are + * structural properties, whereas the {@link XType} held by every value + * determines whether the mX values are metric or categorial. + * @author SVGPlott-Team + * @version 2019.07.29 + */ +public enum CsvType { + DOTS(XType.METRIC), X_ALIGNED(XType.METRIC), X_ALIGNED_CATEGORIES(XType.CATEGORIAL); + + public final XType mXType; + + CsvType(final XType xType) { + this.mXType = xType; + } + + public static CsvType fromString(final String value) { + switch (value.toLowerCase()) { + case "x_aligned": + case "xa": + return CsvType.X_ALIGNED; + case "x_aligned_categories": + case "xac": + return CsvType.X_ALIGNED_CATEGORIES; + case "dots": + case "d": + default: + return DOTS; + } + } + + @Override + public String toString() { + return super.toString().toLowerCase(); + } + + /** + * Converter class that converts strings to CsvType. + */ + public static class CsvTypeConverter { + + public CsvTypeConverter() { + super(); + } + + /** + * Converts a String value into the corresponding CsvType. + * @param value String + * @return CsvType + */ + public CsvType convert(final String value) { + CsvType convertedValue = CsvType.fromString(value); + return convertedValue; + } + + } +} diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/csvparser/CsvXAlignedCategoriesParser.java b/src/main/java/de/tudresden/inf/mci/brailleplot/csvparser/CsvXAlignedCategoriesParser.java new file mode 100644 index 0000000000000000000000000000000000000000..51a85c1b62f906d6fa46ac0b890fd36aadaf5190 --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/csvparser/CsvXAlignedCategoriesParser.java @@ -0,0 +1,145 @@ +package de.tudresden.inf.mci.brailleplot.csvparser; + +import de.tudresden.inf.mci.brailleplot.datacontainers.CategoricalPointListContainer; +import de.tudresden.inf.mci.brailleplot.datacontainers.PointList; +import de.tudresden.inf.mci.brailleplot.datacontainers.SimpleCategoricalPointListContainerImpl; +import de.tudresden.inf.mci.brailleplot.datacontainers.SimplePointListImpl; +import de.tudresden.inf.mci.brailleplot.point.Point2DDouble; + +import java.text.ParseException; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Objects; + +/** + * Parser for CSV files with bar chart data. Inherits from CsvParseAlgorithm. + * @author SVGPlott-Team, Georg Graßnick + * @version 2019.07.29 + */ +public class CsvXAlignedCategoriesParser extends CsvParseAlgorithm<CategoricalPointListContainer<PointList>> { + + @Override + public CategoricalPointListContainer<PointList> parseAsHorizontalDataSets(final List<? extends List<String>> csvData) { + Objects.requireNonNull(csvData); + + if (true) { + throw new UnsupportedOperationException("Horizontal parsing is currently not supported"); + } + + CategoricalPointListContainer<PointList> container = new SimpleCategoricalPointListContainerImpl(); + + Iterator<? extends List<String>> rowIterator = csvData.iterator(); + + if (!rowIterator.hasNext()) { + return container; + } + + Iterator<String> lineIterator = rowIterator.next().iterator(); + + // Move the iterator to the first category name + if (!lineIterator.hasNext()) { + return container; + } + + lineIterator.next(); + + if (!lineIterator.hasNext()) { + return container; + } + + // Store all categories + List<String> categories = new LinkedList<>(); + while (lineIterator.hasNext()) { + categories.add(lineIterator.next()); + } + + Iterator<String> categoriesIt = categories.iterator(); + // Store each row's data set + while (rowIterator.hasNext()) { + lineIterator = rowIterator.next().iterator(); + + // Create a PointList with the title of the data set + if (!lineIterator.hasNext()) { + continue; + } + String category = categoriesIt.next(); + PointList pointList = new SimplePointListImpl(category); + container.pushBack(pointList); + + // Add all the points + int colPosition = 0; + while (lineIterator.hasNext()) { + if (colPosition >= container.getSize()) { + break; + } + + // Find out the mY value + Number yValue; + try { + yValue = Constants.NUMBER_FORMAT.parse(lineIterator.next()); + } catch (ParseException e) { + colPosition++; + continue; + } + + // Add the new point + Point2DDouble newPoint = new Point2DDouble(colPosition, yValue.doubleValue()); + pointList.pushBack(newPoint); + colPosition++; + } + } + // TODO First add points to PointList, then add PointList to PointListContainer, so that there is no need for a calculateExtrema call + container.calculateExtrema(); + return container; + } + + @Override + public CategoricalPointListContainer<PointList> parseAsVerticalDataSets(final List<? extends List<String>> csvData) { + Objects.requireNonNull(csvData); + + CategoricalPointListContainer<PointList> container = new SimpleCategoricalPointListContainerImpl(); + Iterator<? extends List<String>> rowIt = csvData.iterator(); + + int rowNum = 0; // Keep track of the row number, so that we can include the erroneous row number in the exception. + while (rowIt.hasNext()) { + Iterator<String> lineIt = rowIt.next().iterator(); + rowNum++; + + // Check if we are in the first line, were all the categories are defined ... + if (rowNum == 1) { + while (lineIt.hasNext()) { + container.pushBackCategory(lineIt.next()); + } + // ... or if we are in a row, were the actual data sets are defined + } else { + // Get the name for the values of a data set + if (!lineIt.hasNext()) { + throw new MalformedCsvException("Line: " + rowNum + ": Data set must contain a name"); + } + String name = lineIt.next().trim(); + PointList pl = new SimplePointListImpl(name); + + // Parse all values + // Set the x value of each Point to the index of the category, they belong to + int columnNum = 0; + while (lineIt.hasNext()) { + columnNum++; + String value = lineIt.next().trim(); + + Number val; + try { + val = Constants.NUMBER_FORMAT.parse(value); + } catch (final ParseException pe) { + throw new MalformedCsvException("Line: " + rowNum + ": Could not parse value", pe); + } + Point2DDouble p = new Point2DDouble(columnNum, val.doubleValue()); + pl.pushBack(p); + } + container.pushBack(pl); + } + } + return container; + } + +} diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/csvparser/CsvXAlignedParser.java b/src/main/java/de/tudresden/inf/mci/brailleplot/csvparser/CsvXAlignedParser.java new file mode 100644 index 0000000000000000000000000000000000000000..8f5a775e1766d1dd5ed7357d4d3aa3bf6f121ba1 --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/csvparser/CsvXAlignedParser.java @@ -0,0 +1,147 @@ +package de.tudresden.inf.mci.brailleplot.csvparser; + +import de.tudresden.inf.mci.brailleplot.datacontainers.PointList; +import de.tudresden.inf.mci.brailleplot.datacontainers.PointListContainer; +import de.tudresden.inf.mci.brailleplot.datacontainers.SimplePointListContainerImpl; +import de.tudresden.inf.mci.brailleplot.datacontainers.SimplePointListImpl; +import de.tudresden.inf.mci.brailleplot.point.Point2DDouble; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Objects; + +/** + * Parser for CSV files with aligned mX-values. Inherits from CsvParseAlgorithm. + * @author SVGPlott-Team, Georg Graßnick + * @version 2019.07.29 + */ +public class CsvXAlignedParser extends CsvParseAlgorithm<PointListContainer<PointList>> { + + @Override + public PointListContainer<PointList> parseAsHorizontalDataSets(final List<? extends List<String>> csvData) { + Objects.requireNonNull(csvData); + + if (true) { + throw new UnsupportedOperationException("Horizontal parsing is currently not supported"); + } + + PointListContainer<PointList> container = new SimplePointListContainerImpl(); + List<Number> xValues = new ArrayList<>(); + Iterator<? extends List<String>> rowIterator = csvData.iterator(); + + if (!rowIterator.hasNext()) { + return container; + } + + Iterator<String> lineIterator = rowIterator.next().iterator(); + + // Move the iterator to the mX value + if (!lineIterator.hasNext()) { + return container; + } + lineIterator.next(); + if (!lineIterator.hasNext()) { + return container; + } + + // Store all mX values, if one is not specified store NaN + while (lineIterator.hasNext()) { + Number xValue; + try { + xValue = Constants.NUMBER_FORMAT.parse(lineIterator.next()); + } catch (ParseException e) { + xValue = Double.NaN; + } + xValues.add(xValue); + } + + // Store each row's data set + while (rowIterator.hasNext()) { + lineIterator = rowIterator.next().iterator(); + + // Create a PointList with the title of the data set + if (!lineIterator.hasNext()) { + continue; + } + PointList pointList = new SimplePointListImpl(); + pointList.setName(lineIterator.next()); + container.pushBack(pointList); + + // Add all the points + int colPosition = 0; + while (lineIterator.hasNext()) { + if (colPosition >= xValues.size()) { + break; + } + Number xValue = xValues.get(colPosition); + if (xValue.equals(Double.NaN)) { + lineIterator.next(); + colPosition++; + continue; + } + + // Find out the mY value + Number yValue; + try { + yValue = Constants.NUMBER_FORMAT.parse(lineIterator.next()); + } catch (ParseException e) { + colPosition++; + continue; + } + + // Add the new point + Point2DDouble newPoint = new Point2DDouble(xValue.doubleValue(), yValue.doubleValue()); + pointList.pushBack(newPoint); + colPosition++; + } + } + + // TODO First add points to PointList, then add PointList to PointListContainer, so that there is no need for a calculateExtrema call + container.calculateExtrema(); + return container; + } + + @Override + /** + * This method has been implemented from scratch, as there is no documentation about the structure of the CSV files whatsoever. + */ + public PointListContainer<PointList> parseAsVerticalDataSets(final List<? extends List<String>> csvData) { + Objects.requireNonNull(csvData); + + PointListContainer<PointList> container = new SimplePointListContainerImpl(); + Iterator<? extends List<String>> rowIt = csvData.iterator(); + + int rowNum = 0; // Keep track of the row number, so that we can include the erroneous row number in the exception. + while (rowIt.hasNext()) { + Iterator<String> lineIt = rowIt.next().iterator(); + rowNum++; + if (!lineIt.hasNext()) { + throw new MalformedCsvException("Line: " + rowNum + ": Data set must contain a name for a value"); + } + String name = lineIt.next().trim(); + if (!lineIt.hasNext()) { + throw new MalformedCsvException("Line: " + rowNum + ": Data set must contain a name for a value"); + } + String value = lineIt.next().trim(); + + // Log if there are more inputs that are not parsed + if (lineIt.hasNext()) { + mLogger.debug("Skipping additional column in line {}", rowNum); + } + Number val; + try { + val = Constants.NUMBER_FORMAT.parse(value); + } catch (final ParseException pe) { + throw new MalformedCsvException("Line: " + rowNum + ": Could not parse value", pe); + } + Point2DDouble p = new Point2DDouble(0, val.doubleValue()); + PointList pl = new SimplePointListImpl(name); + pl.pushBack(p); + container.pushBack(pl); + } + return container; + } + +} diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/csvparser/MalformedCsvException.java b/src/main/java/de/tudresden/inf/mci/brailleplot/csvparser/MalformedCsvException.java new file mode 100644 index 0000000000000000000000000000000000000000..37e3a3bf54e11f09feb2972cff3568248b649613 --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/csvparser/MalformedCsvException.java @@ -0,0 +1,25 @@ +package de.tudresden.inf.mci.brailleplot.csvparser; + +/** + * Exception class. + * Indicates, that the parsed CSV file was malformed. + * Most likely created by malformed user input. + * @author Georg Graßnick + * @version 2019.08.08 + */ +public class MalformedCsvException extends RuntimeException { + + public MalformedCsvException() { } + + public MalformedCsvException(final String message) { + super(message); + } + + public MalformedCsvException(final Throwable cause) { + super(cause); + } + + public MalformedCsvException(final String message, final Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/csvparser/XType.java b/src/main/java/de/tudresden/inf/mci/brailleplot/csvparser/XType.java new file mode 100644 index 0000000000000000000000000000000000000000..bf68c8016420e75b303fa043fc8491cbb3e9e1dc --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/csvparser/XType.java @@ -0,0 +1,10 @@ +package de.tudresden.inf.mci.brailleplot.csvparser; + +/** + * Determines whether the mX values are metric or categorial. + * @author SVGPlott-Team + * @version 2019.07.29 + */ +public enum XType { + METRIC, CATEGORIAL +} diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/csvparser/package-info.java b/src/main/java/de/tudresden/inf/mci/brailleplot/csvparser/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..f07812eff003b24c5e61e690fd6bb5f69a02d4d2 --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/csvparser/package-info.java @@ -0,0 +1,5 @@ +/** + * Package for parsing algorithms for CSV files. + * TODO refactor parser ({@link de.tudresden.inf.mci.brailleplot.csvparser.CsvXAlignedParser}, {@link de.tudresden.inf.mci.brailleplot.csvparser.CsvXAlignedCategoriesParser}, {@link de.tudresden.inf.mci.brailleplot.csvparser.CsvDotParser}) classes. Lots of blocks are copied with small modifications. + */ +package de.tudresden.inf.mci.brailleplot.csvparser; diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/datacontainers/AbstractPointContainer.java b/src/main/java/de/tudresden/inf/mci/brailleplot/datacontainers/AbstractPointContainer.java new file mode 100644 index 0000000000000000000000000000000000000000..deae7da54de6371bf20ab3f56b1dca6218100c50 --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/datacontainers/AbstractPointContainer.java @@ -0,0 +1,124 @@ +package de.tudresden.inf.mci.brailleplot.datacontainers; + +import de.tudresden.inf.mci.brailleplot.point.MinMaxPos2D; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Objects; +import java.util.stream.Stream; + +/** + * Abstract parent class for {@link SimplePointListContainerImpl} and {@link SimplePointListImpl}. + * @param <T> The type of the elements stored in this container. + * @author Georg Graßnick + * @version 2019.08.02 + */ +public abstract class AbstractPointContainer<T extends MinMaxPos2D<Double>> implements PointContainer<T>, MinMaxPos2D<Double> { + + protected LinkedList<T> mElements; + protected Double mMaxX = Double.NEGATIVE_INFINITY; + protected Double mMaxY = Double.NEGATIVE_INFINITY; + protected Double mMinX = Double.POSITIVE_INFINITY; + protected Double mMinY = Double.POSITIVE_INFINITY; + + @Override + public final int getSize() { + return mElements.size(); + } + + @Override + public final void pushBack(final T element) { + Objects.requireNonNull(element); + mElements.add(element); + checkExtrema(element); + } + + @Override + public final Iterator<T> iterator() { + return mElements.iterator(); + } + + @Override + public final boolean removeFirstOccurrence(final T elementToRename) { + Objects.requireNonNull(elementToRename); + return mElements.removeFirstOccurrence(elementToRename); + } + + @Override + public Stream<T> stream() { + return mElements.stream(); + } + + @Override + public final Double getMinX() { + return mMinX; + } + + @Override + public final Double getMaxX() { + return mMaxX; + } + + @Override + public final Double getMinY() { + return mMinY; + } + + @Override + public final Double getMaxY() { + return mMaxY; + } + + @Override + public final void calculateExtrema() { + for (T e : mElements) { + checkExtrema(e); + } + } + + private void checkExtrema(final T element) { + mMaxX = Math.max(element.getMaxX(), mMaxX); + mMinX = Math.min(element.getMinX(), mMinX); + mMaxY = Math.max(element.getMaxY(), mMaxY); + mMinY = Math.min(element.getMinY(), mMinY); + } + + private String getRecursiveIndentation(final int depth) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < depth; i++) { + sb.append(" "); + } + return sb.toString(); + } + + /** + * Generates a String representing the data structure. + * This function is called recursively on the child elements of a container, so that in the end, + * the caller receives a visual overview of the contents of this container down to the leaf nodes (@link Point2DDouble). + * @param depth The recursion depth of the current call. + * @return A recursive String representation of the container. + */ + protected String toRecursiveString(final int depth) { + StringBuilder sb = new StringBuilder(); + + if (depth == 0) { + sb.append(this.getClass()).append(":\n"); + } + for (T e: mElements) { + sb.append(getRecursiveIndentation(depth + 1)).append(e.getClass()).append(":\n"); + if (e instanceof AbstractPointContainer) { + @SuppressWarnings("unchecked") + AbstractPointContainer<T> a = ((AbstractPointContainer<T>) e); + sb.append(a.toRecursiveString(depth + 1)); + } else { + sb.append(getRecursiveIndentation(depth + 2)).append(e.toString()).append("\n"); + } + } + return sb.toString(); + } + + @Override + public String toString() { + return toRecursiveString(0); + } +} diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/datacontainers/CategoricalPointListContainer.java b/src/main/java/de/tudresden/inf/mci/brailleplot/datacontainers/CategoricalPointListContainer.java new file mode 100644 index 0000000000000000000000000000000000000000..55fb3a6832fd4e62a5b470ee8c51871937397b05 --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/datacontainers/CategoricalPointListContainer.java @@ -0,0 +1,43 @@ +package de.tudresden.inf.mci.brailleplot.datacontainers; + +import java.util.Iterator; + +/** + * A PointListContainer containing information about different categories. + * This will e.g. be useful when dealing with stacked bar charts. + * @param <T> The specific type of the {@link PointList}. Currently, there is only one generic type, + * but later on, one might define additional specialized {@link PointList} implementations. + * @author Georg Graßnick + * @version 2019.08.02 + */ +public interface CategoricalPointListContainer<T extends PointList> extends PointListContainer<T> { + + /** + * Adds a new category. + * @param category The category to add. + * @return The index, the category is inserted at. + */ + int pushBackCategory(String category); + + /** + * Get an iterator over all categories. + * @return An {@link Iterator} that iterates all contained categories; + */ + Iterator<String> categoriesIterator(); + + /** + * Get the number of categories. + * @return The number of categories. + */ + int getNumberOfCategories(); + + /** + * Get a category at a specif index. + * Indices are ranged from 0 to {@link CategoricalPointListContainer#getNumberOfCategories()} (exclusive end). + * @param index The index of the requested category. + * @return The {@link String} representing the category at the requested index. + * @throws IndexOutOfBoundsException If the index is {@literal <} 0 or index is {@literal >=} the return value of + * {@link CategoricalPointListContainer#getNumberOfCategories()} + */ + String getCategory(int index) throws IndexOutOfBoundsException; +} diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/datacontainers/Named.java b/src/main/java/de/tudresden/inf/mci/brailleplot/datacontainers/Named.java new file mode 100644 index 0000000000000000000000000000000000000000..665bf5dce3e20d5dc77888a7eb3656cf7c489c7d --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/datacontainers/Named.java @@ -0,0 +1,12 @@ +package de.tudresden.inf.mci.brailleplot.datacontainers; + +/** + * Interface for objects, that are identified by a name. + * @author Georg Graßnick + * @version 2019.07.29 + */ +public interface Named { + + String getName(); + void setName(String newName); +} diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/datacontainers/PointContainer.java b/src/main/java/de/tudresden/inf/mci/brailleplot/datacontainers/PointContainer.java new file mode 100644 index 0000000000000000000000000000000000000000..83947a8bd79f9da85096177d469ab7d36404dc91 --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/datacontainers/PointContainer.java @@ -0,0 +1,38 @@ +package de.tudresden.inf.mci.brailleplot.datacontainers; + +import de.tudresden.inf.mci.brailleplot.point.MinMaxPos2D; + +import java.util.stream.Stream; + +/** + * Parent Interface of {@link PointListContainer} and {@link PointList}. + * @param <T> The type of the elements stored in this container. + * @author Georg Graßnick + * @version 2019.07.29 + */ +public interface PointContainer<T> extends Iterable<T>, MinMaxPos2D<Double> { + + /** + * Returns the current size of the List. + * @return The number of elements currently stored + */ + int getSize(); + + /** + * Adds a point to the list. + * Also updates min and max values if required. + * @param element The element to be inserted. + */ + void pushBack(T element); + + /** + * Removes the first occurrence of the specified Point from the list. + * This does not update the minimum and maximum values itself, you have to call + * {@link MinMaxPos2D#calculateExtrema()} manually after removing. + * @param elementToRemove The element to be removed from this list + * @return True if this list contained the specified element, else false + */ + boolean removeFirstOccurrence(T elementToRemove); + + Stream<T> stream(); +} diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/datacontainers/PointList.java b/src/main/java/de/tudresden/inf/mci/brailleplot/datacontainers/PointList.java new file mode 100644 index 0000000000000000000000000000000000000000..9d41811040a8de1dde43be7ac983d8af6517ab18 --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/datacontainers/PointList.java @@ -0,0 +1,22 @@ +package de.tudresden.inf.mci.brailleplot.datacontainers; + +import de.tudresden.inf.mci.brailleplot.point.Point2DDouble; + +import java.util.ListIterator; + +/** + * Interface for a list-like data structure that holds a set of {@link Point2DDouble}. + * Implementing classes can be instantiated by data parser classes and are used as a data representation + * for use of the rasterizer. + * @author Georg Graßnick + * @version 2019.07.29 + */ +public interface PointList extends PointContainer<Point2DDouble>, Named { + + /** + * Returns an list iterator over all elements. + * @return An {@link ListIterator} over all managed{ @link Point2DDouble}. + */ + ListIterator<Point2DDouble> getListIterator(); + +} diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/datacontainers/PointListContainer.java b/src/main/java/de/tudresden/inf/mci/brailleplot/datacontainers/PointListContainer.java new file mode 100644 index 0000000000000000000000000000000000000000..bfe390d637e430c26c68afebc834458c2d0f54bb --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/datacontainers/PointListContainer.java @@ -0,0 +1,13 @@ +package de.tudresden.inf.mci.brailleplot.datacontainers; + +/** + * Interface for a container managing {@link PointList} objects. + * Implementing classes can be instantiated by data parser classes and are used as a data representation + * for use of the rasterizer. + * @param <T> The specific type of the {@link PointList}. Currently, there is only one generic type, + * but later on, one might define additional specialized {@link PointList} implementations. + * @author Georg Graßnick + * @version 2019.07.29 + */ +public interface PointListContainer<T extends PointList> extends PointContainer<T> { +} diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/datacontainers/SimpleCategoricalPointListContainerImpl.java b/src/main/java/de/tudresden/inf/mci/brailleplot/datacontainers/SimpleCategoricalPointListContainerImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..834e3b3a86639041a684c6d1ae8f1aea82147dfc --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/datacontainers/SimpleCategoricalPointListContainerImpl.java @@ -0,0 +1,65 @@ +package de.tudresden.inf.mci.brailleplot.datacontainers; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Objects; + +/** + * Low effort implementation of {@link CategoricalPointListContainer}{@literal <}{@link PointList}{@literal >}. + * @author Georg Graßnick + * @version 2019.08.02 + */ +public class SimpleCategoricalPointListContainerImpl extends SimplePointListContainerImpl implements CategoricalPointListContainer<PointList> { + + private ArrayList<String> mCategories; + + public SimpleCategoricalPointListContainerImpl() { + this(new ArrayList<>(), new ArrayList<>()); + } + + public SimpleCategoricalPointListContainerImpl(final List<String> initialCategories) { + this(new ArrayList<>(), initialCategories); + } + + public SimpleCategoricalPointListContainerImpl(final List<PointList> initialElements, final List<String> initialCategories) { + super(initialElements); + mCategories = new ArrayList<>(Objects.requireNonNull(initialCategories)); + } + + @Override + public int pushBackCategory(final String category) { + Objects.requireNonNull(category); + mCategories.add(category); + return mCategories.size() - 1; + } + + @Override + public Iterator<String> categoriesIterator() { + return mCategories.iterator(); + } + + @Override + public int getNumberOfCategories() { + return mCategories.size(); + } + + @Override + public String getCategory(final int index) throws IndexOutOfBoundsException { + if (index < 0 || index >= mCategories.size()) { + throw new IndexOutOfBoundsException("Index " + index + " out of bounds. Current bounds: 0 and " + mCategories.size()); + } + return mCategories.get(index); + } + + @Override + protected String toRecursiveString(final int depth) { + StringBuilder sb = new StringBuilder(); + sb.append("Categories:\n"); + for (String s : mCategories) { + sb.append(s).append("\n"); + } + sb.append(super.toRecursiveString(depth)); + return sb.toString(); + } +} diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/datacontainers/SimplePointListContainerImpl.java b/src/main/java/de/tudresden/inf/mci/brailleplot/datacontainers/SimplePointListContainerImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..028c5c192ed5a4fa61914c7d7e17d14bdab26106 --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/datacontainers/SimplePointListContainerImpl.java @@ -0,0 +1,22 @@ +package de.tudresden.inf.mci.brailleplot.datacontainers; + +import java.util.LinkedList; +import java.util.List; +import java.util.Objects; + +/** + * A low effort implementation of {@link PointListContainer}{@literal <}{@link PointList}{@literal >}. + * @author Georg Graßnick + * @version 2019.07.29 + */ +public class SimplePointListContainerImpl extends AbstractPointContainer<PointList> implements PointListContainer<PointList> { + + public SimplePointListContainerImpl() { + this(new LinkedList<>()); + } + + public SimplePointListContainerImpl(final List<PointList> initialElements) { + Objects.requireNonNull(initialElements); + mElements = new LinkedList<>(initialElements); + } +} diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/datacontainers/SimplePointListImpl.java b/src/main/java/de/tudresden/inf/mci/brailleplot/datacontainers/SimplePointListImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..278faef9e14388a1f41c95da276661c321ced7a9 --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/datacontainers/SimplePointListImpl.java @@ -0,0 +1,54 @@ +package de.tudresden.inf.mci.brailleplot.datacontainers; + +import de.tudresden.inf.mci.brailleplot.point.Point2DDouble; + +import java.util.LinkedList; +import java.util.List; +import java.util.ListIterator; +import java.util.Objects; + +/** + * A low effort implementation of {@link PointList}. + * @author Georg Graßnick + * @version 2019.07.29 + */ +public class SimplePointListImpl extends AbstractPointContainer<Point2DDouble> implements PointList { + + private String mName; + + public SimplePointListImpl() { + this(""); + } + + public SimplePointListImpl(final String name) { + this(name, new LinkedList<>()); + } + + public SimplePointListImpl(final String name, final List<Point2DDouble> initialElements) { + Objects.requireNonNull(name); + Objects.requireNonNull(initialElements); + mName = name; + mElements = new LinkedList<>(initialElements); + } + + @Override + public ListIterator<Point2DDouble> getListIterator() { + return mElements.listIterator(); + } + + @Override + public String getName() { + return mName; + } + + @Override + public void setName(final String newName) { + Objects.requireNonNull(newName); + mName = newName; + } + + @Override + protected String toRecursiveString(final int depth) { + return getName() + super.toRecursiveString(depth); + } +} diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/datacontainers/package-info.java b/src/main/java/de/tudresden/inf/mci/brailleplot/datacontainers/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..1a76036c7f0b5f77ad65fdf25cd3c3f98a3fb283 --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/datacontainers/package-info.java @@ -0,0 +1,8 @@ +/** + * Contains classes for input data representation. + * Included container classes are generated and filled by the the input file parsers + * (e.g. {@link de.tudresden.inf.mci.brailleplot.csvparser.CsvParser}) and read by the rasterizer. + * @author Georg Graßnick + * @version 2019.07.29 + */ +package de.tudresden.inf.mci.brailleplot.datacontainers; \ No newline at end of file diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/diagrams/BarChart.java b/src/main/java/de/tudresden/inf/mci/brailleplot/diagrams/BarChart.java new file mode 100644 index 0000000000000000000000000000000000000000..f78bb04d913e27b5f20c04c6aaa4df66b9d18bec --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/diagrams/BarChart.java @@ -0,0 +1,72 @@ +package de.tudresden.inf.mci.brailleplot.diagrams; + +import de.tudresden.inf.mci.brailleplot.datacontainers.Named; +import de.tudresden.inf.mci.brailleplot.datacontainers.PointContainer; +import de.tudresden.inf.mci.brailleplot.datacontainers.PointList; +import de.tudresden.inf.mci.brailleplot.datacontainers.PointListContainer; +import de.tudresden.inf.mci.brailleplot.rendering.Renderable; + +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * Representation of a bar chart with basic data functions. Implements Renderable. + * @author Richard Schmidt, Georg Graßnick + * @version 2019.07.29 + */ +public class BarChart implements Renderable { + private PointListContainer<PointList> mData; + + public BarChart(final PointListContainer<PointList> data) { + Objects.requireNonNull(data); + mData = data; + } + + /** + * Getter for the total number of categories. + * + * @return int number of categories + */ + public int getCategoryCount() { + return mData.getSize(); + } + + /** + * Getter for the category names in a list. + * + * @return list with category names as strings + */ + public List<String> getCategoryNames() { + return mData.stream() + .map(Named::getName) + .collect(Collectors.toUnmodifiableList()); + } + + /** + * Getter for the minimum y-value. + * + * @return double minimum y-value + */ + public double getMinY() { + return mData.getMinY(); + } + + /** + * Getter for the maximum y-value. + * + * @return double maximum y-value + */ + public double getMaxY() { + return mData.getMaxY(); + } + + /** + * Getter for a list with x-y-Pairs: x is the index (always just counts from 0 up), y is the value. + * @return PointList with the corresponding data set + */ + public PointContainer<PointList> getDataSet() { + return mData; + } +} + diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/diagrams/Diagram.java.txt b/src/main/java/de/tudresden/inf/mci/brailleplot/diagrams/Diagram.java.txt new file mode 100644 index 0000000000000000000000000000000000000000..458955c5b0d3a937970cb2c9bf3a020eca921b71 --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/diagrams/Diagram.java.txt @@ -0,0 +1,64 @@ +package de.tudresden.inf.mci.brailleplot.diagrams; + +import de.tudresden.inf.mci.brailleplot.datacontainers.PointListList; +import de.tudresden.inf.mci.brailleplot.rendering.Renderable; + +/** + * General representation of both scatter and line plots with basic data functions. Classes LinePlot and ScatterPlot extend this class. + * Implements Renderable. + * + * @author Richard Schmidt + */ +public class Diagram implements Renderable { + public PointListList mP; + + /** + * Getter for the minimum x-value. + * @return double minimum x-value + */ + public double getMinX() { + return mP.getMinX(); + } + + /** + * Getter for the maximum x-value. + * @return double maximum x-value + */ + public double getMaxX() { + return mP.getMaxX(); + } + + /** + * Getter for the minimum y-value. + * @return double minimum y-value + */ + public double getMinY() { + return mP.getMinY(); + } + + /** + * Getter for the maximum y-value. + * @return double maximum y-value + */ + public double getMaxY() { + return mP.getMaxY(); + } + + /** + * Getter for a data set by index. + * @param index int + * @return PointList with the corresponding data set + */ + public PointListList.PointList getDataSet(final int index) { + return (PointListList.PointList) mP.get(index); + } + + /** + * Getter for the name of a data set by index. + * @param index int + * @return name of the data set as a string + */ + public String getDataSetName(final int index) { + return mP.get(index).getName(); + } +} diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/diagrams/LinePlot.java.txt b/src/main/java/de/tudresden/inf/mci/brailleplot/diagrams/LinePlot.java.txt new file mode 100644 index 0000000000000000000000000000000000000000..bf78209fc59c683453d258c3f3529c9a0c67c7cf --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/diagrams/LinePlot.java.txt @@ -0,0 +1,15 @@ +package de.tudresden.inf.mci.brailleplot.diagrams; + +import de.tudresden.inf.mci.brailleplot.datacontainers.PointListList; + +/** + * Representation of a line plot. Inherits from Diagram. + * @author Richard Schmidt + */ +public class LinePlot extends Diagram { + + public LinePlot(final PointListList p) { + this.mP = p; + p.updateMinMax(); + } +} diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/diagrams/ScatterPlot.java.txt b/src/main/java/de/tudresden/inf/mci/brailleplot/diagrams/ScatterPlot.java.txt new file mode 100644 index 0000000000000000000000000000000000000000..d9183eff118ec8b8862aab291f783ceb141e2acd --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/diagrams/ScatterPlot.java.txt @@ -0,0 +1,15 @@ +package de.tudresden.inf.mci.brailleplot.diagrams; + +import de.tudresden.inf.mci.brailleplot.datacontainers.PointListList; + +/** + * Representation for scatter plots. Inherits from Diagram. + * @author Richard Schmidt + */ +public class ScatterPlot extends Diagram { + + public ScatterPlot(final PointListList p) { + this.mP = p; + p.updateMinMax(); + } +} diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/diagrams/package-info.java b/src/main/java/de/tudresden/inf/mci/brailleplot/diagrams/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..ce8e1c1e6da3c312c3973e5b65c22b86bcda8801 --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/diagrams/package-info.java @@ -0,0 +1,4 @@ +/** + * Classes for diagram representation with with basic data functions. + */ +package de.tudresden.inf.mci.brailleplot.diagrams; diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/point/MinMaxPos2D.java b/src/main/java/de/tudresden/inf/mci/brailleplot/point/MinMaxPos2D.java new file mode 100644 index 0000000000000000000000000000000000000000..c58f107319ccffdb5de4a6fbd47074ef44284f2b --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/point/MinMaxPos2D.java @@ -0,0 +1,39 @@ +package de.tudresden.inf.mci.brailleplot.point; + +/** + * Interface for classes supporting a minimum and maximum value for x, as well as y values. + * @author Georg Graßnick + * @version 2019.07.29 + * @param <T> The type of the values. + */ +public interface MinMaxPos2D<T> { + + /** + * Get the current minimum on the x axis. + * @return The current minimum on the x axis. + */ + T getMinX(); + /** + * Get the current maximum on the x axis. + * @return The current maximum on the x axis. + */ + T getMaxX(); + + /** + * Get the current minimum on the y axis. + * @return The current minimum on the y axis. + */ + T getMinY(); + + /** + * Get the current maximum on the y axis. + * @return The current maximum on the y axis. + */ + T getMaxY(); + + /** + * Enforce the recalculation of the minimum and maximum value of this object. + */ + void calculateExtrema(); + +} diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/printabledata/Point2D.java b/src/main/java/de/tudresden/inf/mci/brailleplot/point/Point2D.java similarity index 64% rename from src/main/java/de/tudresden/inf/mci/brailleplot/printabledata/Point2D.java rename to src/main/java/de/tudresden/inf/mci/brailleplot/point/Point2D.java index 6bcf6401ae76d18b5cf355702617700c92d2a016..3d4e4780b3960d40b57bd82005ac7b3488c10245 100644 --- a/src/main/java/de/tudresden/inf/mci/brailleplot/printabledata/Point2D.java +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/point/Point2D.java @@ -1,29 +1,27 @@ -package de.tudresden.inf.mci.brailleplot.printabledata; +package de.tudresden.inf.mci.brailleplot.point; -import javax.measure.Quantity; -import javax.measure.quantity.Length; import java.util.Objects; /** * Representation of a 2 dimensional point. * Encapsulates a position on x and y axis. + * @param <T> The type used to represent the position. * @author Georg Graßnick - * @version 2019.06.26 + * @version 2019.07.29 */ -public class Point2D { +public class Point2D<T> implements MinMaxPos2D<T> { - private final Quantity<Length> mX; - private final Quantity<Length> mY; + private final T mX; + private final T mY; /** * Constructor. * @param x Position on the x axis. * @param y Position on the y axis. */ - public Point2D(final Quantity<Length> x, final Quantity<Length> y) { - if (x == null || y == null) { - throw new NullPointerException(); - } + public Point2D(final T x, final T y) { + Objects.requireNonNull(x); + Objects.requireNonNull(y); mX = x; mY = y; } @@ -32,7 +30,7 @@ public class Point2D { * Getter. * @return The position on the x axis. */ - public final Quantity<Length> getX() { + public final T getX() { return mX; } @@ -40,7 +38,7 @@ public class Point2D { * Getter. * @return The position on the y axis. */ - public final Quantity<Length> getY() { + public final T getY() { return mY; } @@ -74,4 +72,29 @@ public class Point2D { public String toString() { return "(" + mX + ", " + mY + ")"; } + + @Override + public T getMinX() { + return mX; + } + + @Override + public T getMaxX() { + return mX; + } + + @Override + public T getMinY() { + return mY; + } + + @Override + public T getMaxY() { + return mY; + } + + @Override + public void calculateExtrema() { + + } } diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/point/Point2DDouble.java b/src/main/java/de/tudresden/inf/mci/brailleplot/point/Point2DDouble.java new file mode 100644 index 0000000000000000000000000000000000000000..6d3cb3e952a8ce1efb271db6d17b085ba50cd86b --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/point/Point2DDouble.java @@ -0,0 +1,13 @@ +package de.tudresden.inf.mci.brailleplot.point; + +/** + * An instance of a {@link Point2D}{@literal <}{@link Double}{@literal >}. + * @author Georg Graßnick + * @version 2019.07.29 + */ +public class Point2DDouble extends Point2D<Double> { + + public Point2DDouble(final double x, final double y) { + super(x, y); + } +} diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/printabledata/Point2DValued.java b/src/main/java/de/tudresden/inf/mci/brailleplot/point/Point2DValued.java similarity index 73% rename from src/main/java/de/tudresden/inf/mci/brailleplot/printabledata/Point2DValued.java rename to src/main/java/de/tudresden/inf/mci/brailleplot/point/Point2DValued.java index 8b674c972cb3785bf681d03d02620089427ce2fc..b9fcffe2dcfa36193164e5e12c5ab3d42ae15689 100644 --- a/src/main/java/de/tudresden/inf/mci/brailleplot/printabledata/Point2DValued.java +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/point/Point2DValued.java @@ -1,20 +1,19 @@ -package de.tudresden.inf.mci.brailleplot.printabledata; +package de.tudresden.inf.mci.brailleplot.point; -import javax.measure.Quantity; -import javax.measure.quantity.Length; import java.util.Objects; /** * Representation of a 2 dimensional point with an associated value. * Encapsulates both the position on x and y axis, as well as a value (think of embossing intensity). - * @param <T> The type used for representing the intensity. Could be set to {@link Boolean} for basic Braille support, + * @param <T> The type used to represent the position. + * @param <U> The type used for representing the intensity. Could be set to {@link Boolean} for basic Braille support, * but could also by set to {@link Short} if different embossing strengths are required. * @author Georg Graßnick - * @version 2019.06.26 + * @version 2019.07.28 */ -public class Point2DValued<T> extends Point2D { +public class Point2DValued<T, U> extends Point2D<T> { - private final T mVal; + private final U mVal; /** * Constructor. @@ -22,11 +21,9 @@ public class Point2DValued<T> extends Point2D { * @param y Position on the y axis. * @param val The value of the dot */ - public Point2DValued(final Quantity<Length> x, final Quantity<Length> y, final T val) { + public Point2DValued(final T x, final T y, final U val) { super(x, y); - if (val == null) { - throw new NullPointerException(); - } + Objects.requireNonNull(val); mVal = val; } @@ -34,7 +31,7 @@ public class Point2DValued<T> extends Point2D { * Getter. * @return The value that is associated with this point. */ - public final T getVal() { + public final U getVal() { return mVal; } @@ -52,7 +49,7 @@ public class Point2DValued<T> extends Point2D { return false; } Point2D point = (Point2DValued) other; - return super.equals(other) && mVal.equals(((Point2DValued) other).mVal); + return super.equals(point) && mVal.equals(((Point2DValued) other).mVal); } @Override diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/point/package-info.java b/src/main/java/de/tudresden/inf/mci/brailleplot/point/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..2dced53f591f6d2fb5a018e473e57f4b980988d9 --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/point/package-info.java @@ -0,0 +1,7 @@ +/** + * Contains classes required to represent Points. + * Points are defined by the type of their value, as well as the position on a Cartesian coordinate system. + * @author Georg Graßnick + * @version 2019.07.29 + */ +package de.tudresden.inf.mci.brailleplot.point; diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/printabledata/BrailleCell6.java b/src/main/java/de/tudresden/inf/mci/brailleplot/printabledata/BrailleCell6.java index 31b8b971ba8674ab972895467c5b1d8cff32afba..8f9bcdc6d8f73e2bc504f0bbe2f43ce8939cd5a3 100644 --- a/src/main/java/de/tudresden/inf/mci/brailleplot/printabledata/BrailleCell6.java +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/printabledata/BrailleCell6.java @@ -101,4 +101,20 @@ public final class BrailleCell6<T> { } return sb.toString(); } + /** + * Method for getting the Bit Representation of the Cell (110001). Should only be used if T is boolean. + * @return String containing the Bit Representation. + */ + public String getBitRepresentationFromBool() { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < mDots.length; i++) { + if (Boolean.parseBoolean(mDots[i].toString())) { + sb.append("1"); + } else { + sb.append("0"); + } + + } + return sb.toString(); + } } diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/printabledata/FloatingPointData.java b/src/main/java/de/tudresden/inf/mci/brailleplot/printabledata/FloatingPointData.java index 67a34488e35a42ed95c58ce66038c044b52841a7..1338e42aa1f7731671aeaacfb849671885a66cc1 100644 --- a/src/main/java/de/tudresden/inf/mci/brailleplot/printabledata/FloatingPointData.java +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/printabledata/FloatingPointData.java @@ -1,15 +1,19 @@ package de.tudresden.inf.mci.brailleplot.printabledata; +import de.tudresden.inf.mci.brailleplot.point.Point2DValued; + +import javax.measure.Quantity; +import javax.measure.quantity.Length; import java.util.Iterator; /** * This data is used to describe the data for the "Floating Dot Area" print mode. - * For each dot to emboss, there is one {@link Point2D} object which encapsulates both the position in width and height, + * For each dot to emboss, there is one {@link Point2DValued} object which encapsulates both the position in width and height, * as well as the intensity of the point. * @param <T> The type used for representing the intensity. Could be set to {@link Boolean} for basic Braille support, * but could also by set to {@link Short} if different embossing strengths are required. * @author Georg Graßnick - * @version 2019.06.26 + * @version 2019.07.29 */ public interface FloatingPointData<T> extends PrintableData { @@ -17,11 +21,11 @@ public interface FloatingPointData<T> extends PrintableData { * Returns an iterator over all {@link Point2DValued}. * @return An iterator over all points. */ - Iterator<Point2DValued<T>> getIterator(); + Iterator<Point2DValued<Quantity<Length>, T>> getIterator(); /** * Add a point to the data structure. * @param point The point to be inserted. */ - void addPoint(Point2DValued<T> point); + void addPoint(Point2DValued<Quantity<Length>, T> point); } diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/printabledata/SimpleFloatingPointDataImpl.java b/src/main/java/de/tudresden/inf/mci/brailleplot/printabledata/SimpleFloatingPointDataImpl.java index a8a61648047214203c61be32c81d7a033b4514b2..897a39fcf0d169c4ec95a5de4f8e299505fd59d5 100644 --- a/src/main/java/de/tudresden/inf/mci/brailleplot/printabledata/SimpleFloatingPointDataImpl.java +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/printabledata/SimpleFloatingPointDataImpl.java @@ -2,9 +2,14 @@ package de.tudresden.inf.mci.brailleplot.printabledata; import java.util.Iterator; import java.util.LinkedList; +import java.util.Objects; import de.tudresden.inf.mci.brailleplot.configparser.Printer; import de.tudresden.inf.mci.brailleplot.configparser.Format; +import de.tudresden.inf.mci.brailleplot.point.Point2DValued; + +import javax.measure.Quantity; +import javax.measure.quantity.Length; /** * A low effort implementation of the {@link FloatingPointData} interface. @@ -12,11 +17,11 @@ import de.tudresden.inf.mci.brailleplot.configparser.Format; * @param <T> The type used for representing the intensity. Could be set to {@link Boolean} for basic Braille support, * but could also by set to {@link Short} if different embossing strengths are required. * @author Georg Graßnick - * @version 2019.06.26 + * @version 2019.07.29 */ public class SimpleFloatingPointDataImpl<T> extends AbstractPrintableData implements FloatingPointData<T> { - private LinkedList<Point2DValued<T>> mPoints; + private LinkedList<Point2DValued<Quantity<Length>, T>> mPoints; public SimpleFloatingPointDataImpl(final Printer printer, final Format format) { super(printer, format); @@ -24,15 +29,13 @@ public class SimpleFloatingPointDataImpl<T> extends AbstractPrintableData implem } @Override - public Iterator<Point2DValued<T>> getIterator() { + public Iterator<Point2DValued<Quantity<Length>, T>> getIterator() { return mPoints.iterator(); } @Override - public void addPoint(final Point2DValued<T> point) { - if (point == null) { - throw new NullPointerException(); - } + public void addPoint(final Point2DValued<Quantity<Length>, T> point) { + Objects.requireNonNull(point); mPoints.addLast(point); } } diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/printabledata/SimpleMatrixDataImpl.java b/src/main/java/de/tudresden/inf/mci/brailleplot/printabledata/SimpleMatrixDataImpl.java index 64f2c39f47547cd6e06d6d22c1ada5ab1cb47868..7f89e382d7d1ad18183759fbab7f7f6651b68477 100644 --- a/src/main/java/de/tudresden/inf/mci/brailleplot/printabledata/SimpleMatrixDataImpl.java +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/printabledata/SimpleMatrixDataImpl.java @@ -102,6 +102,24 @@ public class SimpleMatrixDataImpl<T> extends AbstractPrintableData implements Ma return sb.toString(); } + // TODO: Remove, once svgexporter is implemented + public final String toBoolString() { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < getRowCount(); i++) { + for (int j = 0; j < getColumnCount(); j++) { + Boolean val = (Boolean) getValue(i, j); + if (val) { + sb.append("o"); + } else { + sb.append(" "); + } + sb.append(" "); + } + sb.append("\n"); + } + return sb.toString(); + } + /** * Iterator that iterates all elements of the matrix in a pattern that iterates Braille cells of specified height * and width from left to right and top to bottom. diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/printerbackend/AbstractDocumentBuilder.java b/src/main/java/de/tudresden/inf/mci/brailleplot/printerbackend/AbstractDocumentBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..c16ce44b1fd0002ebff4eecf5a21bb38d1187479 --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/printerbackend/AbstractDocumentBuilder.java @@ -0,0 +1,52 @@ +package de.tudresden.inf.mci.brailleplot.printerbackend; +import de.tudresden.inf.mci.brailleplot.brailleparser.AbstractBrailleTableParser; +import de.tudresden.inf.mci.brailleplot.brailleparser.JsonParser; +import de.tudresden.inf.mci.brailleplot.brailleparser.PropertiesParser; +import de.tudresden.inf.mci.brailleplot.brailleparser.XmlParser; +import de.tudresden.inf.mci.brailleplot.configparser.Printer; +import de.tudresden.inf.mci.brailleplot.printabledata.MatrixData; + +/** + * This class provides an extension point for further implementation + * and protocol building for documents that need to be send to the printer. + * The common Interface is the getDocument() and assemble() method. + * Its usable for all braille printers. + * @param <T> Type of MatrixData. + * @author Andrey Ruzhanskiy + * @version 28.05.2019 + */ + +abstract class AbstractDocumentBuilder<T> { + + MatrixData<T> mData; + + + AbstractBrailleTableParser mParser; + + /** + * Complex method for complex construction of an document for the printer. + * @param data Raw data to be printed without any escapes equences + * @return Fully build document as byte[] + */ + abstract byte[] assemble(MatrixData<T> data); + + /** + * Method for setting the correct parser. Reads the file from the printer configuration, then checks + * if the file extension is supported. + * @throws NotSupportedFileExtensionException If the file extension is not supported. + */ + void setParser() throws NotSupportedFileExtensionException { + //read braille table path + Printer printer = mData.getPrinterConfig(); + String brailleTablePath = printer.getProperty("brailletable").toString(); + + //read which kind of parser is needed (properties, json, xml,...) + String fileEnding = brailleTablePath.split("\\.")[1]; + switch (fileEnding) { + case "properties": mParser = new PropertiesParser(printer.getProperty("brailletable").toString()); break; + case "json": mParser = new JsonParser(printer.getProperty("brailletable").toString()); break; + case "xml": mParser = new XmlParser(printer.getProperty("brailletable").toString()); break; + default: throw new NotSupportedFileExtensionException("The Fileextension " + fileEnding + "is currently not supported."); + } + } +} diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/printerbackend/AbstractIndexV4Builder.java b/src/main/java/de/tudresden/inf/mci/brailleplot/printerbackend/AbstractIndexV4Builder.java new file mode 100644 index 0000000000000000000000000000000000000000..b79ba6a7bd627ac0db6f1adb17ecf564ad7b1c7b --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/printerbackend/AbstractIndexV4Builder.java @@ -0,0 +1,262 @@ +package de.tudresden.inf.mci.brailleplot.printerbackend; + +/** + * Abstract class for Documents, that need special escape sequences for the Index Everest-V4. + * All special documents (i.e. Floating Dot Area) should implement this class. All information taken + * from the Index PrinterCapability Interface Protocol V5_V4 2ß16-05-13. All the variables with the respective values have no + * particular order (except mStartTemporaryDoc, which must be at the beginning). All the variable names are set to + * final, these are PrinterCapability specific values that should not be changed. + * @author Andrey Ruzhanskiy + * @version 31.05.2019 + */ + +@SuppressWarnings("checkstyle:MagicNumber") +abstract class AbstractIndexV4Builder extends AbstractDocumentBuilder { + + + + /** + * Standard byte Sequence to announce StartTemporary document ([ESC]D). + * Must be always at the beginning. + */ + + final byte[] mStartTemporaryDoc = new byte[] {0x1B, 0x44}; + + /** + * Standard variable name for binding margin (BI). + */ + + final byte[] mBindingMarginName = new byte[] {0x42, 0x49}; + + /** + * Standard value for Everest-V4 A4 Paper Size(4). Possible Values: + * 0 + * to + * 10, + * whereas the number encodes the #charracters to leave empty on the line to the + * left and right. + */ + + byte[] mBindingMarginValue = new byte[] {0x34}; + + /** + * Standard variable name for characters per line (CH). + */ + + final byte[] mCharsPerLineName = new byte[] {0x43, 0x48}; + + /** + * Standard value for Everest-V4 A4 Paper Size(30).If used, there must be also + * a corresponding binding margin. Possible values are: + * 0: may not be usefull + * to + * 48:Absolute maximum due to printer heads total movement and only applicable to the printers + * that can use papers that big. + */ + + byte[] mCharsPerLineValue = new byte[] {0x33, 0x30}; + + /** + * Standard variable name for PageMode (Duplex) (DP). + */ + + final byte[] mPageModeName = new byte[] {0x44, 0x50}; + + /** + * Standard value for page mode (2, double sided). + * Possible values are: + * 1 Single sided (normal horizontal printing) + * 2 Double sided (normal horizontal printing) + * 3 Double sided z-folding (normal horizontal printing) + * 5 Single sided z-folding (normal horizontal printing) + * 6 Double sided sideways z-folding (vertical printing) + * 7 Single sided sideways z-folding (vertical printing) + */ + + byte[] mPageModeValue = new byte[] {0x32}; + + /** + * Standard variable name for braille table (BT). + */ + + final byte[] mBrailleTableName = new byte[] {0x42, 0x54}; + + /** + * Currently, there is no standard braille table. + */ + byte[] mBrailleTableValue = null; + + /** + * Standard variable name for Driver Version (DV). + */ + + final byte[] mDriverVersionName = new byte[] {0x44, 0x56}; + + /** + * Standard value for driver version (not used currently TODO). + */ + + byte[] mDriverVersion = null; + + /** + * Standard variable name for first line offset (FO). + */ + + final byte[] mFirstLineOffsetName = new byte[] {0x46, 0x4F}; + + /** + * Standard value for first line offset (~50/60). + * Possible values: equal or greater then 0. + * The value is specified in tenths of mm. + * + */ + + byte[] mFirstLineOffsetValue = null; + + /** + * Standard variable name for graphic dot distance (GD). + */ + + final byte[] mGraphicDotDistanceName = new byte[] {0x47, 0x44}; + + /** + * Standard value for graphic dot distance. Possible values are 0, 1, 2. + * 0 = 2.0 mm + * 1 = 2.5 mm + * 2 = 1.6 mm + * Standard is 1 (2.5 mm). + */ + + byte[] mGraphicDotDistanceValue = new byte[] {0x31}; + + /** + * Standard variable name for lines per page (LP). + */ + + final byte[] mLinesPerPageName = new byte[] {0x4C, 0x50}; + + /** + * Standard value for lines per page (28). If this parameter is set, one must include + * the TM parameter as well. + */ + + byte[] mLinesPerPageValue = new byte[] {0x32, 0x38}; + + /** + * Standard variable name for line spacing (LS). + */ + + final byte[] mLineSpacingName = new byte[] {0x4C, 0x53}; + + /** + * Standard value for line spacing (GD). This parameter can only be specified in the beginning of a document + * and is ignored if a row has been added to the first page. Line spacing is ignored if DP is set to DP4 and DP8. + * Possible values are: + * 50: 5.0 mm (single -normal) + * to + * 100: 10.0 mm (double) + */ + + byte[] mLineSpacingValue = new byte[] {0x35, 0x30}; + + /** + * Standard variable name for multiple copies (MC). + */ + + final byte[] mMultipleCopiesName = new byte[] {0x4D, 0x43}; + + /** + * Standard value for multiple copies (1). Possible values are: + * 1 + * to + * 10000 + */ + + byte[] mMultipleCopiesValue = new byte[] {0x31}; + + /** + * Standard variable name for multiple impact (MI). + */ + + final byte[] mMultipleImpactName = new byte[] {0x4D, 0x49}; + + /** + * Standard value for multiple impact (1).To impact the hammers multiple times + * for a braille row this parameter can be specified. Possible values are: + * 1 + * to + * 3. + */ + + byte[] mMultipleImpactValue = new byte[] {0x31}; + + /** + * Standard variable name for page number (PN). + */ + + final byte[] mPageNumberName = new byte[] {0x50, 0x4E}; + + /** + * Standard value for page number (0). This parameter needs to be specified before the first row is added + * to the first page. Possible values are: + * 0: None + * 1: Top (require top margin greater than 0) + * 2: Top-left (require top margin greater than 0) + * 3: Top-right (require top margin greater than 0) + * 4: Bottom (require bottom margin greater than 0) + * 5: Bottom left (require bottom margin greater than 0) + * 6: Bottom right (require bottom margin greater than 0) + */ + + byte[] mPageNumberValue = new byte[] {0x30}; + + /** + * Standard variable name for braille cell size (TD). + */ + + final byte[] mBrailleCellSizeName = new byte[] {0x54, 0x44}; + + /** + * Standard value for braille cell size (0). Possible values are: + * 0: 2.5 mm + * 1: 2.2 mm + * 2: 3.2 mm + */ + + byte[] mBrailleCellSizeValue = new byte[] {0x30}; + + /** + * Standard variable name for top margin (TM). + */ + + final byte[] mTopMarginName = new byte[] {0x54, 0x4D}; + + /** + * Standard value for top margin(not researched). The top margin is + * always specified in lines. Possible values are: + * 0 + * to + * 10 + */ + + byte[] mTopMarginValue = null; + + /** + * Separator for values (,). + */ + final byte[] mComma = new byte[] {0x2C}; + + + /** + * Colon character. + */ + final byte[] mColon = new byte[] {0x3A}; + + + + /** + * End of escape sequence (;). Must be always at the end. + */ + + final byte[] mSemicolon = new byte[] {0x3B}; +} diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/printerbackend/FloatingDotAreaBuilder.java b/src/main/java/de/tudresden/inf/mci/brailleplot/printerbackend/FloatingDotAreaBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..b16826be2e92e2ace441eafc47927548f932a5f1 --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/printerbackend/FloatingDotAreaBuilder.java @@ -0,0 +1,28 @@ +package de.tudresden.inf.mci.brailleplot.printerbackend; + + +import de.tudresden.inf.mci.brailleplot.printabledata.MatrixData; + +/** + * Class representing the FloatingDotAre protocol for the braille Index Everest V4 for printing + * variable areas on paper via coordinates. + * @author Andrey Ruzhanskiy, Leonard Kupper + * @version 29.05.2019 + */ + +class FloatingDotAreaBuilder extends AbstractIndexV4Builder { + + /** + * Constructor. Does not have any functionality. Should only be used in {@link PrintDirector} + */ + FloatingDotAreaBuilder() { } + + /** + * Currently not implemented. + * @param data Raw data to be printed without any escape sequences + * @return Exception. + */ + byte[] assemble(final MatrixData data) { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/printerbackend/GraphicPrintBuilder.java b/src/main/java/de/tudresden/inf/mci/brailleplot/printerbackend/GraphicPrintBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..a51107b5ca0fa00cee02ff52dc7ef6038d187afd --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/printerbackend/GraphicPrintBuilder.java @@ -0,0 +1,26 @@ +package de.tudresden.inf.mci.brailleplot.printerbackend; + + +import de.tudresden.inf.mci.brailleplot.printabledata.MatrixData; + +/** + * Class representing the graphic mode protocol from braille Index Everest D4. + * @author Andrey Ruzhanskiy + */ +class GraphicPrintBuilder extends AbstractIndexV4Builder { + + /** + * Constructor. Does not have any functionality. Should only be used in {@link PrintDirector} + */ + GraphicPrintBuilder() { } + + /** + * Currently not implemented. + * @param data Raw data to be printed without any escape sequences + * @return Exception. + */ + @Override + byte[] assemble(final MatrixData data) { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/printerbackend/NormalBuilder.java b/src/main/java/de/tudresden/inf/mci/brailleplot/printerbackend/NormalBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..f33d1060dc507e74111463b67bd1160177fa6781 --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/printerbackend/NormalBuilder.java @@ -0,0 +1,80 @@ +package de.tudresden.inf.mci.brailleplot.printerbackend; + +import de.tudresden.inf.mci.brailleplot.printabledata.BrailleCell6; +import de.tudresden.inf.mci.brailleplot.printabledata.MatrixData; + +import java.io.ByteArrayOutputStream; +import java.util.Iterator; +import java.util.Objects; + + +/** + * Class representing a normal document (for example a .txt) that should be printed without + * any escape sequences. + * @author Andrey Ruzhanskiy + * @version 12.07.2019 + */ +@SuppressWarnings("checkstyle:MagicNumber") +class NormalBuilder extends AbstractDocumentBuilder<Boolean> { + + + /** + * Constructor. Does not have any functionality. Should only be used in {@link PrintDirector} + */ + NormalBuilder() { } + + /** + * Method for assembling the final document from the data parameter. + * In normalbuilder, it first sets the correct parser according to the file extension, then initializes the iterator + * from the {@link MatrixData} object and the stream for writing bytes into an array and lastly loops through the {@link MatrixData} + * to build the correct document. + * @param data Raw data to be printed without any escape sequences + * @return the final, printable document. + */ + @Override + byte[] assemble(final MatrixData<Boolean> data) { + + + //Check if null object was given. + mData = Objects.requireNonNull(data); + // Setting the right parser, catch if not found and throw RuntimeException which can be handled. + try { + setParser(); + } catch (NotSupportedFileExtensionException e) { + throw new RuntimeException(); + } + + // Get iterator for cells. + Iterator<BrailleCell6<Boolean>> iter = mData.getBrailleCell6Iterator(); + + // Set stream for final output. + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + + // Getting width in braille cells. + int width = mData.getColumnCount() / 2; + + // Declaration of local variables for better readability. + BrailleCell6 current; + String key; + int value; + + // Count variable for the loop + int i = 0; + + // Loop through data and write to stream. + while (iter.hasNext()) { + current = iter.next(); + key = current.getBitRepresentationFromBool(); + value = mParser.getValue(key); + stream.write(value); + i++; + // Setting the Linebreaks + if (i == width) { + i = 0; + stream.write(0x0D); + stream.write(0x0A); + } + } + return stream.toByteArray(); + } +} diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/printerbackend/NotSupportedFileExtensionException.java b/src/main/java/de/tudresden/inf/mci/brailleplot/printerbackend/NotSupportedFileExtensionException.java new file mode 100644 index 0000000000000000000000000000000000000000..1f2042e02d7a61c5bee54f27e96e92da8d64564b --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/printerbackend/NotSupportedFileExtensionException.java @@ -0,0 +1,25 @@ +package de.tudresden.inf.mci.brailleplot.printerbackend; + +/** + * Exception class for not recogniced/not supported file extension for braille tables. + * Used in {@link NormalBuilder}. + * @author Andrey Ruzhanskiy + * @version 11.07.2019 + */ + +public class NotSupportedFileExtensionException extends Exception { + + public NotSupportedFileExtensionException() { } + + public NotSupportedFileExtensionException(final String message) { + super(message); + } + + public NotSupportedFileExtensionException(final Throwable cause) { + super(cause); + } + + public NotSupportedFileExtensionException(final String message, final Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/printerbackend/PrintDirector.java b/src/main/java/de/tudresden/inf/mci/brailleplot/printerbackend/PrintDirector.java new file mode 100644 index 0000000000000000000000000000000000000000..501450bfef4078c97f60741b6bda2180c3c70ed1 --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/printerbackend/PrintDirector.java @@ -0,0 +1,145 @@ +package de.tudresden.inf.mci.brailleplot.printerbackend; + + +import de.tudresden.inf.mci.brailleplot.configparser.Printer; +import de.tudresden.inf.mci.brailleplot.printabledata.MatrixData; + +import javax.print.DocFlavor; +import javax.print.DocPrintJob; +import javax.print.PrintException; +import javax.print.PrintService; +import javax.print.PrintServiceLookup; +import javax.print.Doc; + +import javax.print.SimpleDoc; +import javax.print.attribute.HashPrintRequestAttributeSet; +import javax.print.attribute.PrintRequestAttributeSet; +import javax.print.attribute.standard.JobName; +import java.util.Objects; +/** + * Implements a variation of the GoF design pattern Builder. This class is used for setting the printer configuration and + * for printing. + * @author Andrey Ruzhanskiy + * @version 17.07.2019 + */ +public class PrintDirector { + + private AbstractDocumentBuilder mBuilder; + private final PrinterCapability mPrinter; + private PrintService mService; + private String mPrinterName; + private DocFlavor mDocflavor; + private DocPrintJob mPrintJob; + + + /** + * 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 printerCap Which {@link PrinterCapability} should be used. Normal printer assumes that no special features like + * GraphicMode or FloatindDotArea will be used. + * @param printerConfig The {@link Printer} object, used for extracting the name of the 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: + mBuilder = new GraphicPrintBuilder(); + break; + case INDEX_EVEREST_D_V4_FLOATINGDOT_PRINTER: + mBuilder = new FloatingDotAreaBuilder(); + break; + default: throw new IllegalArgumentException(); + } + + } + + /** + * Public method for printing the given document with the given data. + * @param data {@link de.tudresden.inf.mci.brailleplot.printabledata.MatrixData} to be printed. + * @param <T> The type of {@link MatrixData}. + */ + + + // Needed if someone tries to use a normal builder with something that is not a boolean. + + @SuppressWarnings("unchecked") + public <T> void print(final MatrixData<T> data) { + Objects.requireNonNull(data); + setUpDoc(); + setUpService(); + byte[] result; + try { + result = mBuilder.assemble(data); + } catch (ClassCastException e) { + throw new IllegalArgumentException(e.getMessage(), e); + } + print(result); + } + + /** + * 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 setUpDoc() { + mDocflavor = new DocFlavor("application/octet-stream", "[B"); + } + + + /** + * Method for setting the correct printer service for the printer name. + * @throws RuntimeException If the system cant find the service. + */ + + private void setUpService() { + Objects.requireNonNull(mPrinterName); + PrintService[] services = PrintServiceLookup.lookupPrintServices(null, null); + for (PrintService service: services) { + if (service.getName().equals(mPrinterName) || mPrinterName.equals("Dummy Printer")) { + mService = service; + return; + } + } + throw new RuntimeException("Cant register Printerservice for the printername : " + mPrinterName); + } + + /** + * 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 Data to be printed. + * @throws PrintException If the printing job could not be completed. + */ + + private void print(final byte[] data) { + Objects.requireNonNull(data); + Objects.requireNonNull(mService); + Objects.requireNonNull(mDocflavor); + Doc doc = new SimpleDoc(data, mDocflavor, null); + PrintRequestAttributeSet asset = new HashPrintRequestAttributeSet(); + DocPrintJob job = mService.createPrintJob(); + asset.add(new JobName("Braille Printing", null)); + try { + job.print(doc, asset); + mPrintJob = job; + } catch (PrintException pe) { + throw new RuntimeException(pe); + } + + } + + /** + * Static method to verify if the print service is activated on the system. + * @return true, if activated, false if not. + */ + public static boolean isPrintServiceOn() { + PrintService[] services = PrintServiceLookup.lookupPrintServices(null, null); + if (services.length == 0) { + return false; + } + return true; + } +} diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/printerbackend/PrinterCapability.java b/src/main/java/de/tudresden/inf/mci/brailleplot/printerbackend/PrinterCapability.java new file mode 100644 index 0000000000000000000000000000000000000000..5f29934cccab8711712527d8eabf3e33fdcd23ba --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/printerbackend/PrinterCapability.java @@ -0,0 +1,16 @@ +package de.tudresden.inf.mci.brailleplot.printerbackend; + +/** + * This enum provides means to differentiate between printer capabilities. + * This should be extended if new printers are supported. If its unknown, the standard should be NormalPrinter. This + * assumes that no special features are supported and hence, normal braille should be printed. + * Because not every printer supports the same functionality or uses the same Protocol for the same functionality, the + * names are embedded in the values (for example INDEX_EVEREST_D_V4_EXAMPLE_CAPABILITY). + * Currently used in {@link PrintDirector}. + * @author Andrey Ruzhanskiy + * @version 17.07.2019 + */ + +public enum PrinterCapability { + NORMALPRINTER, INDEX_EVEREST_D_V4_FLOATINGDOT_PRINTER, INDEX_EVEREST_D_V4_GRAPHIC_PRINTER +} diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/printerbackend/package-info.java b/src/main/java/de/tudresden/inf/mci/brailleplot/printerbackend/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..f14d3f1dacb3af8301ab36ee6d2a03771b22dbeb --- /dev/null +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/printerbackend/package-info.java @@ -0,0 +1,4 @@ +/** + * This package contains all the requiered classes and interfaces for printing and braille table parsing. + */ +package de.tudresden.inf.mci.brailleplot.printerbackend; diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/rendering/MasterRenderer.java b/src/main/java/de/tudresden/inf/mci/brailleplot/rendering/MasterRenderer.java index 5d1ec6f5286f53f6d00f6db7efc2430ea406f6a7..23fe3546fe6eaed4ffacc5c948a9bcd5b1d02e9a 100644 --- a/src/main/java/de/tudresden/inf/mci/brailleplot/rendering/MasterRenderer.java +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/rendering/MasterRenderer.java @@ -3,6 +3,7 @@ package de.tudresden.inf.mci.brailleplot.rendering; import de.tudresden.inf.mci.brailleplot.layout.InsufficientRenderingAreaException; import de.tudresden.inf.mci.brailleplot.layout.RasterCanvas; import de.tudresden.inf.mci.brailleplot.layout.SixDotBrailleRasterCanvas; +import de.tudresden.inf.mci.brailleplot.diagrams.BarChart; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -37,11 +38,11 @@ public final class MasterRenderer { mLogger.trace("Instantiating default rasterizers"); // Default Algorithms: - // Rasterizer<BarChart> uniformTexture = new UniformTextureBarChartRasterizer(); + Rasterizer<BarChart> uniformTexture = new UniformTextureBarChartRasterizer(); Rasterizer<Image> linearImageMapping = new ImageRasterizer(); mLogger.trace("Registering default rasterizers"); - // renderingBase.registerRasterizer(new FunctionalRasterizer<BarChart>(BarChart.class, uniformTexture)); + renderingBase.registerRasterizer(new FunctionalRasterizer<BarChart>(BarChart.class, uniformTexture)); renderingBase.registerRasterizer(new FunctionalRasterizer<Image>(Image.class, linearImageMapping)); //renderingBase.registerRasterizer(new FunctionalRasterizer<ScatterPlot>(ScatterPlot.class, ScatterPlotRasterizing::fooRasterizing)); //... diff --git a/src/main/java/de/tudresden/inf/mci/brailleplot/rendering/UniformTextureBarChartRasterizer.java.txt b/src/main/java/de/tudresden/inf/mci/brailleplot/rendering/UniformTextureBarChartRasterizer.java similarity index 95% rename from src/main/java/de/tudresden/inf/mci/brailleplot/rendering/UniformTextureBarChartRasterizer.java.txt rename to src/main/java/de/tudresden/inf/mci/brailleplot/rendering/UniformTextureBarChartRasterizer.java index 06f33fa6b4bd09044cd751b4d7d96901c94668db..8ed176c71febe33f66253b6658a1a80cd5e436f6 100644 --- a/src/main/java/de/tudresden/inf/mci/brailleplot/rendering/UniformTextureBarChartRasterizer.java.txt +++ b/src/main/java/de/tudresden/inf/mci/brailleplot/rendering/UniformTextureBarChartRasterizer.java @@ -1,5 +1,6 @@ package de.tudresden.inf.mci.brailleplot.rendering; +import de.tudresden.inf.mci.brailleplot.datacontainers.PointList; import de.tudresden.inf.mci.brailleplot.printabledata.MatrixData; import de.tudresden.inf.mci.brailleplot.diagrams.BarChart; @@ -7,13 +8,20 @@ import java.util.HashMap; import java.util.Map; import java.util.Objects; -import static java.lang.Math.*; +import static java.lang.Math.abs; +import static java.lang.Math.floor; +import static java.lang.Math.log10; +import static java.lang.Math.max; +import static java.lang.Math.min; +import static java.lang.Math.pow; +import static java.lang.Math.round; +import static java.lang.StrictMath.ceil; /** * A rasterizer for instances of {@link BarChart} which is based on an algorithm that constructs horizontal category * bars that are filled with a uniform texture. The rasterizer is 'cell' based, working on 6-dot or 8-dot layouts. - * @author Leonard Kupper - * @version 2019.07.20 + * @author Leonard Kupper, Georg Graßnick + * @version 2019.07.29 */ final class UniformTextureBarChartRasterizer implements Rasterizer<BarChart> { @@ -142,8 +150,8 @@ final class UniformTextureBarChartRasterizer implements Rasterizer<BarChart> { // 2. Draw the individual bars for each category. int refCellX = xAxisOriginPosition; // align bars with y-axis. int refCellY = barArea.intWrapper().getBottom(); // start with the bottommost bar. - for (int i = 0; i < mDiagram.getCategoryCount(); i++) { - double value = mDiagram.getDataSet(0).get(i).getY(); + for (PointList pl : mDiagram.getDataSet()) { + double value = pl.iterator().next().getY(); // calculate how to represent value with the current scaling int barLength = (int) round(value / xAxisStepWidth) * mTextureUnitSize; // draw the bar including its caption and then move the reference cell y position up @@ -185,6 +193,7 @@ final class UniformTextureBarChartRasterizer implements Rasterizer<BarChart> { // Layout help methods + @SuppressWarnings("checkstyle:MagicNumber") private double findAxisScaling(final double valueRangeSize, final int availableUnits) { double minRangePerUnit = valueRangeSize / availableUnits; // this range must fit into one 'axis step' double orderOfMagnitude = pow(10, ceil(log10(minRangePerUnit))); @@ -290,6 +299,8 @@ final class UniformTextureBarChartRasterizer implements Rasterizer<BarChart> { return mCanvas.getCellYFromDotY(upperY - (mBarDotPadding + 1)) - mExtraBarCellPadding; } + @SuppressWarnings("checkstyle:MagicNumber") + // TODO: use BrailleCell6 and BrailleCell8 class constants private void checkValidBrailleRaster() throws InsufficientRenderingAreaException { boolean isValidBrailleRaster = ((mCanvas.getCellWidth() == 2) && (mCanvas.getCellHeight() >= 3) && (mCanvas.getCellHeight() <= 4)); diff --git a/src/main/resources/config/default.properties b/src/main/resources/config/default.properties index fec2bdb6e2941fd9ba093f381f5317a099c5553e..0c016eff33d647637a5e6a6289cc72a437d771bd 100644 --- a/src/main/resources/config/default.properties +++ b/src/main/resources/config/default.properties @@ -13,7 +13,7 @@ # ATTENTION: Changes to this configuration will affect settings for ALL printer and format definitions which # are not overriding the defaults. -printer.mode=normal +printer.mode=normalprinter printer.brailletable=src/main/resources/mapping/eurobraille.properties printer.floatingDot.support=false diff --git a/src/main/resources/config/dummyPrinterConfig.properties b/src/main/resources/config/dummyPrinterConfig.properties new file mode 100644 index 0000000000000000000000000000000000000000..c079e544814bfa4455adee8281f2f62d9fde9913 --- /dev/null +++ b/src/main/resources/config/dummyPrinterConfig.properties @@ -0,0 +1,69 @@ +# JProperties Printer & Format Configuration +# +# Embosser: Index Everest-D V4 +# Version 1 Rev. 8 (19-07-19) +# +# Description: +# This is the main configuration file for use with the braille plot application +# when embossing with the 'Index Everest-D V4'. +# The configuration specifies the general printer abilities and defines +# pre-selectable formats for this embosser. +# +# https://gitlab.hrz.tu-chemnitz.de/s9444737--tu-dresden.de/brailleplot/wikis/Software%20Design#configuration-files +# ============================================================================= + +### General Printer Properties +### ========================== + +printer.name=Index Everest-D V4 +printer.mode=normalprinter +printer.brailletable=src/main/resources/mapping/eurobraille.properties +printer.floatingDot.support=true +printer.floatingDot.resolution=0.05 + +# The following values represent the fixed indentation and maximum technical printing area of the embosser. +# If the outputs don't fit on the page you might want to tweak this values. (Check the format too.) +printer.constraint.top=5.0 +printer.constraint.left=0 +#printer.constraint.width=? TODO: Check out manual, Conduct printing tests with bigger formats +#printer.constraint.height=? +# The second constraint in the printer.raster namespace helps to limit the available printing area in steps of +# whole cells, for example if the printer enforces a maximum char per line limit or borders are activated. +printer.raster.constraint.top=0 +printer.raster.constraint.left=1 +printer.raster.constraint.width=35 +printer.raster.constraint.height=29 + +# The following properties define the exact grid spacing. +printer.raster.cellDistance.horizontal=3.6 +printer.raster.cellDistance.vertical=4.8 +printer.raster.dotDistance.horizontal=2.5 +printer.raster.dotDistance.vertical=2.5 +printer.raster.dotDiameter=1.5 + +### Format Definitions +### ================== + +# A4 Format +format.A4.page.width=210 +format.A4.page.height=297 +format.A4.margin.top=0 +format.A4.margin.left=0 +format.A4.margin.bottom=0 +format.A4.margin.right=0 + +# A5 Format +format.A5.page.width=148 +format.A5.page.height=210 +format.A5.margin.top=0 +format.A5.margin.left=0 +format.A5.margin.bottom=0 +format.A5.margin.right=0 + +# Wide Format +format.wide.page.width=272 +format.wide.page.height=210 +format.wide.margin.top=0 +format.wide.margin.left=0 +format.wide.margin.bottom=0 +format.wide.margin.right=0 \ No newline at end of file diff --git a/src/main/resources/config/index_basic_d.properties b/src/main/resources/config/index_basic_d.properties index 0c98fba6901e5c999ba4d3621fc49593026d9e53..7cba7190b2273dc8ec201693411bbe62d20bd3c7 100644 --- a/src/main/resources/config/index_basic_d.properties +++ b/src/main/resources/config/index_basic_d.properties @@ -16,7 +16,7 @@ ### ========================== printer.name=Index Basic-D V3 -printer.mode=normal +printer.mode=normalprinter printer.brailletable=src/main/resources/mapping/mapping.properties printer.floatingDot.support=false diff --git a/src/main/resources/config/index_everest_d_v4.properties b/src/main/resources/config/index_everest_d_v4.properties index 3d6ad7a39662d5f08ea72f6ffe910daa926d4b09..24f7e749c193ad6b3ff3ac90d021720ba813680f 100644 --- a/src/main/resources/config/index_everest_d_v4.properties +++ b/src/main/resources/config/index_everest_d_v4.properties @@ -16,7 +16,7 @@ ### ========================== printer.name=Index Everest-D V4 -printer.mode=normal +printer.mode=normalprinter printer.brailletable=src/main/resources/mapping/eurobraille.properties printer.floatingDot.support=true printer.floatingDot.resolution=0.05 diff --git a/src/main/resources/examples/csv/0_bar_chart.csv b/src/main/resources/examples/csv/0_bar_chart.csv index b88106bb36c02100129b3a152ff48f6159d9667a..13d0acc6254a9e82761cac5fd56b2e08ba0b3542 100644 --- a/src/main/resources/examples/csv/0_bar_chart.csv +++ b/src/main/resources/examples/csv/0_bar_chart.csv @@ -1,2 +1,7 @@ -,a,b,c,d,e,f,g,h -Wert,500,36,357,473,75,-215,220,356 \ No newline at end of file +a, 1 +b, "2,2" +c, 3 +d, "4,4" +e, 5 +f, 6 +g, 7 diff --git a/src/main/resources/examples/csv/0_bar_chart_categorical.csv b/src/main/resources/examples/csv/0_bar_chart_categorical.csv new file mode 100644 index 0000000000000000000000000000000000000000..9804ec7a86ab4a6846f1343f90965280e5d5c688 --- /dev/null +++ b/src/main/resources/examples/csv/0_bar_chart_categorical.csv @@ -0,0 +1,5 @@ +, Reihe a , Reihe b , Reihe c, Reihe d +Kat.1 ,3 ,"2,5" ,1 ,3 +Kat.2 ,4 ,3 ,2 ,5 +Kat.3 ,"4,5" ,3 ,1,"0,2" +Kat.4 ,"4,5" ,3 ,1,"0,2" diff --git a/src/main/resources/examples/csv/0_bar_chart_categorical_vertical.csv b/src/main/resources/examples/csv/0_bar_chart_categorical_vertical.csv new file mode 100644 index 0000000000000000000000000000000000000000..4af2062281540534bcc3806841c68153c08aad24 --- /dev/null +++ b/src/main/resources/examples/csv/0_bar_chart_categorical_vertical.csv @@ -0,0 +1,5 @@ +Kat.1,Kat.2,Kat.3 +Reihe a,3,4,"4,5" +Reihe b,"2,5",3,3 +Reihe c,1,2,1 +Reihe d,3,5,"0,2" diff --git a/src/main/resources/examples/csv/1_scatter_plot.csv b/src/main/resources/examples/csv/1_scatter_plot.csv new file mode 100644 index 0000000000000000000000000000000000000000..904d14586cc75f52b04e835a7a1802ba6894570c --- /dev/null +++ b/src/main/resources/examples/csv/1_scatter_plot.csv @@ -0,0 +1,5 @@ +Linie1, ,1,7,9,2,10 + ,1,2,5,4,10 +Linie2, ,0,2,7,9,1,4 + ,3,9,4,2,5,7 + diff --git a/src/main/resources/examples/csv/2_line_plot.csv b/src/main/resources/examples/csv/2_line_plot.csv new file mode 100644 index 0000000000000000000000000000000000000000..c90c77fe69fa65fe7f492f6859dea5a2614b8031 --- /dev/null +++ b/src/main/resources/examples/csv/2_line_plot.csv @@ -0,0 +1,6 @@ +Erste Gruppe,"2,14577671155962","3,83957088149638","2,74381418592686","4,44040259535766","3,05835335915677","3,51347910532925","4,50752129340682","3,10684847076423" +,"1,86189289220467","0,845650622246947","1,62491581811196","0,716873892169058","1,07960644510134","1,25420442725184","0,868213570630901","0,3131242131342" +Zweite Gruppe,"2,13687514878477","1,0900468273911","0,202664216808808","-0,117994978447507","1,91197730783847","0,472235461102831","1,01858439429409","1,54912208686837" +,"0,983807817453276","2,34845526278731","0,785524371519466","0,220854402806683","1,77117365732932","3,01226487117459","-0,327141232914824","-0,210388758733043" +Dritte Gruppe,"4,11271848986168","4,99244908180646","5,98316851481515","4,95765061866595","4,00636404848764","5,49799175180235","4,34309770180236","5,36675690932105" +,"5,09261289722065","4,92838187744164","4,47540951345638","3,45104975190378","5,64998407245105","4,88914941630864","5,92876353824873","6,67452703834106" diff --git a/src/test/java/de/tudresden/inf/mci/brailleplot/AppTest.java b/src/test/java/de/tudresden/inf/mci/brailleplot/AppTest.java index 51ffe22bd2420dc57ba9fbe53f92e4a577a2f31b..b21ded69f42fc0361d53be1ffeb75b3bcd488404 100644 --- a/src/test/java/de/tudresden/inf/mci/brailleplot/AppTest.java +++ b/src/test/java/de/tudresden/inf/mci/brailleplot/AppTest.java @@ -1,5 +1,6 @@ package de.tudresden.inf.mci.brailleplot; +import de.tudresden.inf.mci.brailleplot.App; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/src/test/java/de/tudresden/inf/mci/brailleplot/brailleparser/PropertiesParserTest.java b/src/test/java/de/tudresden/inf/mci/brailleplot/brailleparser/PropertiesParserTest.java new file mode 100644 index 0000000000000000000000000000000000000000..c5ff403a49c3c1d72740f6338e5b4d64a9985e20 --- /dev/null +++ b/src/test/java/de/tudresden/inf/mci/brailleplot/brailleparser/PropertiesParserTest.java @@ -0,0 +1,34 @@ +package de.tudresden.inf.mci.brailleplot.brailleparser; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +/** + * Unit Tests for the PropertiesParser Class. + * @author Andrey Ruzhanskiy + * @version 15.07.2019 + */ +public class PropertiesParserTest { + + /** + * Test for giving a Null to the PropertiesParser Constructor. + * Expected: NullPointerException. + */ + @Test + public void testNullInConstructor(){ + Assertions.assertThrows(NullPointerException.class, () -> { + PropertiesParser parserF1 = new PropertiesParser(null); + }); + } + + /** + * Test for giving a non-existing Path to the PropertiesParser Constructor. + * Expected: RuntimeException. + */ + @Test + public void testNonValidPath(){ + Assertions.assertThrows(RuntimeException.class, () -> { + PropertiesParser parserF1 = new PropertiesParser("/C/D/E/F/G"); + }); + } +} diff --git a/src/test/java/de/tudresden/inf/mci/brailleplot/configparser/JavaPropertiesConfigurationParserTest.java b/src/test/java/de/tudresden/inf/mci/brailleplot/configparser/JavaPropertiesConfigurationParserTest.java index 2f49d59921288404fde73597d30aaa04bec440fb..f6851d38c53ba4c12f3dabed75599b140e9cf48b 100644 --- a/src/test/java/de/tudresden/inf/mci/brailleplot/configparser/JavaPropertiesConfigurationParserTest.java +++ b/src/test/java/de/tudresden/inf/mci/brailleplot/configparser/JavaPropertiesConfigurationParserTest.java @@ -28,12 +28,12 @@ public class JavaPropertiesConfigurationParserTest { @Test @BeforeAll public static void testSuccessfulParsing() { Assertions.assertDoesNotThrow(() -> { - // Parse concrete properties and defaults - ConfigurationParser parser = new JavaPropertiesConfigurationParser(mConcreteConfigPath, mDefaultConfigPath); - mPrinterConfig = parser.getPrinter(); - Set<String> properties = mPrinterConfig.getPropertyNames(); - Set<String> formats = parser.getFormatNames(); - mFormatConfig = parser.getFormat("A4"); + // Parse concrete properties and defaults + ConfigurationParser parser = new JavaPropertiesConfigurationParser(mConcreteConfigPath, mDefaultConfigPath); + mPrinterConfig = parser.getPrinter(); + Set<String> properties = mPrinterConfig.getPropertyNames(); + Set<String> formats = parser.getFormatNames(); + mFormatConfig = parser.getFormat("A4"); }); } @Test @@ -129,5 +129,4 @@ public class JavaPropertiesConfigurationParserTest { Assertions.assertThrows(NumberFormatException.class, () -> mPrinterConfig.getProperty("raster.cellDistance.horizontal").toInt()); Assertions.assertThrows(NumberFormatException.class, () -> mPrinterConfig.getProperty("name").toDouble()); } - } diff --git a/src/test/java/de/tudresden/inf/mci/brailleplot/csvparser/CsvDotParserTest.java b/src/test/java/de/tudresden/inf/mci/brailleplot/csvparser/CsvDotParserTest.java new file mode 100644 index 0000000000000000000000000000000000000000..dd713390a030f221d7ca00c0cc179a2c586f9938 --- /dev/null +++ b/src/test/java/de/tudresden/inf/mci/brailleplot/csvparser/CsvDotParserTest.java @@ -0,0 +1,32 @@ +package de.tudresden.inf.mci.brailleplot.csvparser; + +import de.tudresden.inf.mci.brailleplot.datacontainers.PointList; +import de.tudresden.inf.mci.brailleplot.datacontainers.PointListContainer; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.List; + +public class CsvDotParserTest { +/* + CsvDotParser parser = new CsvDotParser(); + List<? extends List<String>> csvDataHorizontal = ; + List<? extends List<String>> csvDataVertical = ; + PointListContainer<PointList> resultHorizontal = ; + PointListContainer<PointList> resultVertical = ; + + @Test + public void testHorizontalParsing () { + Assertions.assertEquals(resultHorizontal, () -> { + parser.parseAsHorizontalDataSets(csvDataHorizontal); + }); + } + + @Test + public void testVerticalParsing () { + Assertions.assertEquals(resultVertical, () -> { + parser.parseAsHorizontalDataSets(csvDataVertical); + }); + } +*/ +} diff --git a/src/test/java/de/tudresden/inf/mci/brailleplot/csvparser/CsvParseAlgorithmTest.java b/src/test/java/de/tudresden/inf/mci/brailleplot/csvparser/CsvParseAlgorithmTest.java new file mode 100644 index 0000000000000000000000000000000000000000..e3a9614f3cf23154a265b2f4a8746cb5aa2a0313 --- /dev/null +++ b/src/test/java/de/tudresden/inf/mci/brailleplot/csvparser/CsvParseAlgorithmTest.java @@ -0,0 +1,12 @@ +package de.tudresden.inf.mci.brailleplot.csvparser; + +import org.junit.jupiter.api.Test; + +public class CsvParseAlgorithmTest { +/* + @Test + public void testAddPoint() { + + } + */ +} diff --git a/src/test/java/de/tudresden/inf/mci/brailleplot/csvparser/CsvParserTest.java b/src/test/java/de/tudresden/inf/mci/brailleplot/csvparser/CsvParserTest.java new file mode 100644 index 0000000000000000000000000000000000000000..8f55f21349983a307c22dbac800ce16918674de1 --- /dev/null +++ b/src/test/java/de/tudresden/inf/mci/brailleplot/csvparser/CsvParserTest.java @@ -0,0 +1,17 @@ +package de.tudresden.inf.mci.brailleplot.csvparser; + +import org.junit.jupiter.api.Test; + +public class CsvParserTest { +/* + @Test + public void testCsvParser() { + + } + + @Test + public void testParse() { + + } + */ +} diff --git a/src/test/java/de/tudresden/inf/mci/brailleplot/csvparser/CsvXAlignedCategoriesParserTest.java b/src/test/java/de/tudresden/inf/mci/brailleplot/csvparser/CsvXAlignedCategoriesParserTest.java new file mode 100644 index 0000000000000000000000000000000000000000..00658031054c25ab967fa57c12ba50369bb0d7de --- /dev/null +++ b/src/test/java/de/tudresden/inf/mci/brailleplot/csvparser/CsvXAlignedCategoriesParserTest.java @@ -0,0 +1,32 @@ +package de.tudresden.inf.mci.brailleplot.csvparser; + +import de.tudresden.inf.mci.brailleplot.datacontainers.PointList; +import de.tudresden.inf.mci.brailleplot.datacontainers.PointListContainer; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.List; + +public class CsvXAlignedCategoriesParserTest { +/* + CsvXAlignedCategoriesParser parser = new CsvXAlignedCategoriesParser(); + List<? extends List<String>> csvDataHorizontal = ; + List<? extends List<String>> csvDataVertical = ; + PointListContainer<PointList> resultHorizontal = ; + PointListContainer<PointList> resultVertical = ; + + @Test + public void testHorizontalParsing () { + Assertions.assertEquals(resultHorizontal, () -> { + parser.parseAsHorizontalDataSets(csvDataHorizontal); + }); + } + + @Test + public void testVerticalParsing () { + Assertions.assertEquals(resultVertical, () -> { + parser.parseAsHorizontalDataSets(csvDataVertical); + }); + } + */ +} diff --git a/src/test/java/de/tudresden/inf/mci/brailleplot/csvparser/CsvXAlignedParserTest.java b/src/test/java/de/tudresden/inf/mci/brailleplot/csvparser/CsvXAlignedParserTest.java new file mode 100644 index 0000000000000000000000000000000000000000..3777b8c961901c6a5c2fd230232fc08a986a0e0d --- /dev/null +++ b/src/test/java/de/tudresden/inf/mci/brailleplot/csvparser/CsvXAlignedParserTest.java @@ -0,0 +1,32 @@ +package de.tudresden.inf.mci.brailleplot.csvparser; + +import de.tudresden.inf.mci.brailleplot.datacontainers.PointList; +import de.tudresden.inf.mci.brailleplot.datacontainers.PointListContainer; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.List; + +public class CsvXAlignedParserTest { +/* + CsvXAlignedParser parser = new CsvXAlignedParser(); + List<? extends List<String>> csvDataHorizontal = ; + List<? extends List<String>> csvDataVertical = ; + PointListContainer<PointList> resultHorizontal = ; + PointListContainer<PointList> resultVertical = ; + + @Test + public void testHorizontalParsing () { + Assertions.assertEquals(resultHorizontal, () -> { + parser.parseAsHorizontalDataSets(csvDataHorizontal); + }); + } + + @Test + public void testVerticalParsing () { + Assertions.assertEquals(resultVertical, () -> { + parser.parseAsHorizontalDataSets(csvDataVertical); + }); + } + */ +} diff --git a/src/test/java/de/tudresden/inf/mci/brailleplot/datacontainers/AbstractPointContainerTest.java b/src/test/java/de/tudresden/inf/mci/brailleplot/datacontainers/AbstractPointContainerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..bf2f2e2cd438ad1d895136831db216cb8cfb2a5d --- /dev/null +++ b/src/test/java/de/tudresden/inf/mci/brailleplot/datacontainers/AbstractPointContainerTest.java @@ -0,0 +1,11 @@ +package de.tudresden.inf.mci.brailleplot.datacontainers; + +import org.junit.jupiter.api.Test; + +public class AbstractPointContainerTest { + + @Test + public void testPushBack() { + + } +} diff --git a/src/test/java/de/tudresden/inf/mci/brailleplot/datacontainers/SimplePointListContainerImplTest.java b/src/test/java/de/tudresden/inf/mci/brailleplot/datacontainers/SimplePointListContainerImplTest.java new file mode 100644 index 0000000000000000000000000000000000000000..1fbfaaecdaaa2f037ade0f7cd02ec78e1e234998 --- /dev/null +++ b/src/test/java/de/tudresden/inf/mci/brailleplot/datacontainers/SimplePointListContainerImplTest.java @@ -0,0 +1,11 @@ +package de.tudresden.inf.mci.brailleplot.datacontainers; + +import org.junit.jupiter.api.Test; + +public class SimplePointListContainerImplTest { + + @Test + public void testSimplePointListContainerImpl() { + + } +} diff --git a/src/test/java/de/tudresden/inf/mci/brailleplot/datacontainers/SimplePointListImplTest.java b/src/test/java/de/tudresden/inf/mci/brailleplot/datacontainers/SimplePointListImplTest.java new file mode 100644 index 0000000000000000000000000000000000000000..2e3c05c0d59091b2718a0195488cced476706c91 --- /dev/null +++ b/src/test/java/de/tudresden/inf/mci/brailleplot/datacontainers/SimplePointListImplTest.java @@ -0,0 +1,11 @@ +package de.tudresden.inf.mci.brailleplot.datacontainers; + +import org.junit.jupiter.api.Test; + +public class SimplePointListImplTest { + + @Test + public void testSimplePointListImpl() { + + } +} diff --git a/src/test/java/de/tudresden/inf/mci/brailleplot/diagrams/BarChartTest.java b/src/test/java/de/tudresden/inf/mci/brailleplot/diagrams/BarChartTest.java new file mode 100644 index 0000000000000000000000000000000000000000..98818257562b0e38c1dd636b33f544672d176ded --- /dev/null +++ b/src/test/java/de/tudresden/inf/mci/brailleplot/diagrams/BarChartTest.java @@ -0,0 +1,17 @@ +package de.tudresden.inf.mci.brailleplot.diagrams; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class BarChartTest { + + @Test + public void testBarChart () { + + } + + @Test + public void testGetCategoryNames () { + + } +} diff --git a/src/test/java/de/tudresden/inf/mci/brailleplot/point/Point2DTest.java b/src/test/java/de/tudresden/inf/mci/brailleplot/point/Point2DTest.java new file mode 100644 index 0000000000000000000000000000000000000000..7856748013169024e84023c1b2839c507c6b7b4c --- /dev/null +++ b/src/test/java/de/tudresden/inf/mci/brailleplot/point/Point2DTest.java @@ -0,0 +1,21 @@ +package de.tudresden.inf.mci.brailleplot.point; + +import org.junit.jupiter.api.Test; + +public class Point2DTest { + + @Test + public void testPoint2D () { + + } + + @Test + public void testEquals () { + + } + + @Test + public void testHashCode () { + + } +} diff --git a/src/test/java/de/tudresden/inf/mci/brailleplot/point/Point2DValuedTest.java b/src/test/java/de/tudresden/inf/mci/brailleplot/point/Point2DValuedTest.java new file mode 100644 index 0000000000000000000000000000000000000000..be4a4379a6807f70d0ae15e15360772348272220 --- /dev/null +++ b/src/test/java/de/tudresden/inf/mci/brailleplot/point/Point2DValuedTest.java @@ -0,0 +1,16 @@ +package de.tudresden.inf.mci.brailleplot.point; + +import org.junit.jupiter.api.Test; + +public class Point2DValuedTest { + + @Test + public void testPoint2DValued () { + + } + + @Test + public void testEquals () { + + } +} diff --git a/src/test/java/de/tudresden/inf/mci/brailleplot/printabledata/Point2DValuedTest.java b/src/test/java/de/tudresden/inf/mci/brailleplot/printabledata/Point2DValuedTest.java index 5b607b8f0ec8dbf1782b69f71ef883522180323b..d3c0d0c95f0733b26c11052c1d6ad6249da07af1 100644 --- a/src/test/java/de/tudresden/inf/mci/brailleplot/printabledata/Point2DValuedTest.java +++ b/src/test/java/de/tudresden/inf/mci/brailleplot/printabledata/Point2DValuedTest.java @@ -1,5 +1,6 @@ package de.tudresden.inf.mci.brailleplot.printabledata; +import de.tudresden.inf.mci.brailleplot.point.Point2DValued; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import tec.units.ri.quantity.Quantities; @@ -31,7 +32,7 @@ class Point2DValuedTest { @Test void testSetGet() { - Point2DValued<Integer> point = new Point2DValued<>(length(), length(), integer()); + Point2DValued<Quantity<Length>, Integer> point = new Point2DValued<>(length(), length(), integer()); Assertions.assertEquals(point.getVal(), integer()); Assertions.assertEquals(point.getX(), length()); Assertions.assertEquals(point.getY(), length()); diff --git a/src/test/java/de/tudresden/inf/mci/brailleplot/printabledata/SimpleFloatingPointDataImplTest.java b/src/test/java/de/tudresden/inf/mci/brailleplot/printabledata/SimpleFloatingPointDataImplTest.java index 3564809d3a2441b84a18212deb0859579de45776..b4792dce6068aeec5d06b9636ae6e164896c097a 100644 --- a/src/test/java/de/tudresden/inf/mci/brailleplot/printabledata/SimpleFloatingPointDataImplTest.java +++ b/src/test/java/de/tudresden/inf/mci/brailleplot/printabledata/SimpleFloatingPointDataImplTest.java @@ -2,10 +2,13 @@ package de.tudresden.inf.mci.brailleplot.printabledata; import de.tudresden.inf.mci.brailleplot.configparser.Format; import de.tudresden.inf.mci.brailleplot.configparser.Printer; +import de.tudresden.inf.mci.brailleplot.point.Point2DValued; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import tec.units.ri.quantity.Quantities; +import javax.measure.Quantity; +import javax.measure.quantity.Length; import java.util.ArrayList; import java.util.Iterator; @@ -17,7 +20,7 @@ class SimpleFloatingPointDataImplTest { return new SimpleFloatingPointDataImpl<>(new Printer(new ArrayList<>()), new Format(new ArrayList<>())); } - Point2DValued<Integer> point2dInt(Integer one, Integer two, Integer val) { + Point2DValued<Quantity<Length>, Integer> point2dInt(Integer one, Integer two, Integer val) { return new Point2DValued<>(Quantities.getQuantity(one, METRE), Quantities.getQuantity(two, METRE), val); } @@ -35,10 +38,10 @@ class SimpleFloatingPointDataImplTest { for (int i = 0; i < 5; i++) { data.addPoint(point2dInt(i, i, i)); } - Iterator<Point2DValued<Integer>> it = data.getIterator(); + Iterator<Point2DValued<Quantity<Length>, Integer>> it = data.getIterator(); int i = 0; while (it.hasNext()) { - Point2DValued<Integer> point = it.next(); + Point2DValued<Quantity<Length>, Integer> point = it.next(); Assertions.assertEquals(point, point2dInt(i, i, i)); i++; } diff --git a/src/test/java/de/tudresden/inf/mci/brailleplot/printerbackend/NormalBuilderTest.java b/src/test/java/de/tudresden/inf/mci/brailleplot/printerbackend/NormalBuilderTest.java new file mode 100644 index 0000000000000000000000000000000000000000..ec37261b780eadad41e4049b6dd9bc70d4fe5be6 --- /dev/null +++ b/src/test/java/de/tudresden/inf/mci/brailleplot/printerbackend/NormalBuilderTest.java @@ -0,0 +1,25 @@ +package de.tudresden.inf.mci.brailleplot.printerbackend; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +/** + * Unit Tests for the NormalBuilder Class. + * @author Andrey Ruzhanskiy + * @version 15.07.2019 + */ +public class NormalBuilderTest { + + + /** + * Test for giving a Null to the NormalBuilder assemble Method. + * Expected: NullPointerException. + */ + @Test + public void testAssembleWithNull(){ + Assertions.assertThrows(NullPointerException.class, () -> { + NormalBuilder normalF1 = new NormalBuilder(); + normalF1.assemble(null); + }); + } +} diff --git a/src/test/java/de/tudresden/inf/mci/brailleplot/printerbackend/PrintDirectorTest.java b/src/test/java/de/tudresden/inf/mci/brailleplot/printerbackend/PrintDirectorTest.java new file mode 100644 index 0000000000000000000000000000000000000000..aa03f8c4eca555539429b295adee799accb3cae7 --- /dev/null +++ b/src/test/java/de/tudresden/inf/mci/brailleplot/printerbackend/PrintDirectorTest.java @@ -0,0 +1,32 @@ +package de.tudresden.inf.mci.brailleplot.printerbackend; + + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + + + +/** + * Unit Tests for the PrintDirector Class. + * @author Andrey Ruzhanskiy + * @version 15.07.2019 + */ + +public class PrintDirectorTest { + + /* Negative Tests + Because this componend depends heavily on almost all other components, the testcases will be more integration + tests then unittests. + */ + + /** + * Test for giving a Null to the PrintDirector-Constructor. + * Expected: NullPointerException. + */ + @Test + public void testNullInConstructor(){ + Assertions.assertThrows(NullPointerException.class, () -> { + PrintDirector printF1 = new PrintDirector(null, null); + }); + } +} diff --git a/src/test/resources/config/concrete.properties b/src/test/resources/config/concrete.properties index ae38765f32eda38856761c4cee4ebdcf10648804..404bd9c56a5031f31f3e7d7dc5220bc9642e42fd 100644 --- a/src/test/resources/config/concrete.properties +++ b/src/test/resources/config/concrete.properties @@ -16,7 +16,7 @@ ### ========================== printer.name=Dummy Printer -printer.mode=normal +printer.mode=normalprinter printer.brailletable=src/test/resources/mapping/mapping.properties printer.floatingDot.support=true printer.floatingDot.resolution=0.05 diff --git a/src/test/resources/config/default.properties b/src/test/resources/config/default.properties index 0ddc21c523dc8f81f018d8b6066d51f6fba2a8f9..beaf967cfa2b1489a984922cfb9f508466ee764e 100644 --- a/src/test/resources/config/default.properties +++ b/src/test/resources/config/default.properties @@ -13,7 +13,8 @@ # ATTENTION: Changes to this configuration will affect settings for ALL printer and format definitions which # are not overriding the defaults. -printer.mode=normal + +printer.mode=normalprinter printer.brailletable=src/test/resources/mapping/mapping.properties printer.floatingDot.support=false diff --git a/src/test/resources/config/illegalPropertyNameExample.properties b/src/test/resources/config/illegalPropertyNameExample.properties index c4418b850108ca3d3af4cb64d5bc1724df00088c..655c5559f060a614e334d2fa88b56afc134442f6 100644 --- a/src/test/resources/config/illegalPropertyNameExample.properties +++ b/src/test/resources/config/illegalPropertyNameExample.properties @@ -13,7 +13,8 @@ # ATTENTION: Changes to this configuration will affect settings for ALL printer and format definitions which # are not overriding the defaults. -printer.mode=normal + +printer.mode=normalprinter printer.brailletable=src/test/resources/mapping/mapping.properties printer.floatingDot.support=false diff --git a/src/test/resources/config/illegalPropertyValueExample.properties b/src/test/resources/config/illegalPropertyValueExample.properties index fb25331a6a6b51e1fb628c5c49fc0bd270ae49e5..d4adb7784a163e5a692af4234e02c65f0d0b40c9 100644 --- a/src/test/resources/config/illegalPropertyValueExample.properties +++ b/src/test/resources/config/illegalPropertyValueExample.properties @@ -13,7 +13,7 @@ # ATTENTION: Changes to this configuration will affect settings for ALL printer and format definitions which # are not overriding the defaults. -printer.mode=normal +printer.mode=normalprinter printer.brailletable=src/test/resources/mapping/mapping.properties printer.floatingDot.support=false diff --git a/src/test/resources/config/missingRequiredPropertyExample.properties b/src/test/resources/config/missingRequiredPropertyExample.properties index 8692f1bb122ee19fa58dafb6070dcac27c9faa45..35f9233d2627888a7fcf2a50e22d6bbba8d750f6 100644 --- a/src/test/resources/config/missingRequiredPropertyExample.properties +++ b/src/test/resources/config/missingRequiredPropertyExample.properties @@ -17,7 +17,7 @@ # Missing required property (not specified by default): # printer.name=Dummy Printer -printer.mode=normal +printer.mode=normalprinter printer.brailletable=src/test/resources/mapping/mapping.properties printer.floatingDot.support=true printer.floatingDot.resolution=0.05 diff --git a/src/test/resources/config/rasterizer_test_default.properties b/src/test/resources/config/rasterizer_test_default.properties index 27e44ceac3328bccd0b01f2f8bb07a7dc35600a1..71e78830bb16765ca3a5a33ef1bfe1751599ca25 100644 --- a/src/test/resources/config/rasterizer_test_default.properties +++ b/src/test/resources/config/rasterizer_test_default.properties @@ -9,8 +9,8 @@ # ============================================================================= # Define these here to have neat small concrete test configs. -printer.name=Dummy Default -printer.mode=normal +printer.name=Dummy Printer +printer.mode=normalprinter printer.brailletable=src/test/resources/mapping/eurobraille.properties printer.floatingDot.support=false printer.raster.type=6-dot diff --git a/src/test/resources/config/wrongPrinterModeExample.properties b/src/test/resources/config/wrongPrinterModeExample.properties new file mode 100644 index 0000000000000000000000000000000000000000..61e331d4e0e7487cfd42cd58f70d7daaef7a0b9b --- /dev/null +++ b/src/test/resources/config/wrongPrinterModeExample.properties @@ -0,0 +1,52 @@ +# JProperties Printer & Format Configuration +# +# Embosser: Dummy Printer +# Test Revision (19-07-18) (DON'T USE FOR PRINTING) +# +# Description: +# This is the main configuration file for use with the braille plot application +# when embossing with the 'Index Everest-D V4'. +# The configuration specifies the general printer abilities and defines +# pre-selectable formats for this embosser. +# +# https://gitlab.hrz.tu-chemnitz.de/s9444737--tu-dresden.de/brailleplot/wikis/Software%20Design#configuration-files +# ============================================================================= + +### General Printer Properties +### ========================== + +# Missing required property (not specified by default): +printer.name=Dummy Printer +printer.mode=normalprinterKek +printer.brailletable=src/test/resources/mapping.properties +printer.floatingDot.support=true +printer.floatingDot.resolution=0.05 + +# The following values represent the fixed indentation and maximum technical printing area of the embosser. +# If the outputs don't fit on the page you might want to tweak this values. (Check the format too.) +printer.constraint.top=5.0 +printer.constraint.left=0 + +# The following properties define the exact grid spacing. +printer.raster.cellDistance.horizontal=3.6 +printer.raster.cellDistance.vertical=4.8 +printer.raster.dotDistance.horizontal=2.5 +printer.raster.dotDistance.vertical=2.5 +printer.raster.dotDiameter=1.5 + +### Format Definitions +### ================== + +# A4 Format +format.A4.page.width=210 +format.A4.page.height=297 +format.A4.margin.left=0 + +# A5 Format +# Missing required property (not specified by default): +# format.A5.page.width=148 +format.A5.page.height=210 +format.A5.margin.top=0 +format.A5.margin.left=0 +format.A5.margin.bottom=0 +format.A5.margin.right=0 \ No newline at end of file