From 73cc8e7c5bf8098430415f495b7e3e918f6193dc Mon Sep 17 00:00:00 2001 From: TheDarkDesync <82680013+TheDarkDesync@users.noreply.github.com> Date: Mon, 27 Dec 2021 10:44:21 +0100 Subject: [PATCH] [feat] TrialData toJson() & fromJson() (#23) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [feat] toJson & fromJson TrialData * [test] toJson & fromJson Test TrialData * [fix] remove return from try catch * [fix] newline added * [fix] extra return removed * [fix] since updated * [fix] doppelte Konstruktoren gelöscht * [fix] since angepasst Co-authored-by: Joshua Jeschek <64850647+joshuajeschek@users.noreply.github.com> --- pom.xml | 6 + .../weichware10/util/data/DataPoint.java | 38 +++--- .../weichware10/util/data/TrialData.java | 121 +++++++++++++++--- .../weichware10/util/data/TrialDataTest.java | 49 +++++++ src/test/resources/testtrial-CODECHARTS.json | 23 ++++ src/test/resources/testtrial-ZOOMMAPS.json | 23 ++++ 6 files changed, 224 insertions(+), 36 deletions(-) create mode 100644 src/test/resources/testtrial-CODECHARTS.json create mode 100644 src/test/resources/testtrial-ZOOMMAPS.json diff --git a/pom.xml b/pom.xml index 15d7d17..fd634e4 100644 --- a/pom.xml +++ b/pom.xml @@ -23,6 +23,12 @@ jackson-databind 2.13.0 + + + com.fasterxml.jackson.datatype + jackson-datatype-joda + 2.13.0 + diff --git a/src/main/java/github/weichware10/util/data/DataPoint.java b/src/main/java/github/weichware10/util/data/DataPoint.java index 0ca7a50..3eda6aa 100644 --- a/src/main/java/github/weichware10/util/data/DataPoint.java +++ b/src/main/java/github/weichware10/util/data/DataPoint.java @@ -1,5 +1,7 @@ package github.weichware10.util.data; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; import java.util.Arrays; /** @@ -15,43 +17,49 @@ public class DataPoint { public final Float zoomLevel; /** - * Stores a single DataPoint with zoomLevel. + * Konstruktor für Jackson. * * @param dataId - the id of the dataPoint * @param timeOffset - the time since the trial started - * @param coordinates - the coordinates of the viewed picture + * @param coordinates - the coordinates on the viewed picture + * @param rasterSize - width and height of the raster * @param zoomLevel - how far the user is zoomed in * - * @since v0.2 + * @since v1.0 */ - public DataPoint(int dataId, int timeOffset, int[] coordinates, float zoomLevel) { + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + public DataPoint(@JsonProperty("dataId") int dataId, + @JsonProperty("timeOffset") int timeOffset, + @JsonProperty("coordinates") int[] coordinates, + @JsonProperty("rasterSize") int[] rasterSize, + @JsonProperty("zoomLevel") Float zoomLevel) { this.dataId = dataId; this.timeOffset = timeOffset; this.coordinates = coordinates; - this.rasterSize = null; + this.rasterSize = rasterSize; this.zoomLevel = zoomLevel; } /** - * Stores a single DataPoint without zoomLevel. + * Stores a single DataPoint with zoomLevel. * * @param dataId - the id of the dataPoint * @param timeOffset - the time since the trial started - * @param coordinates - the coordinates on the viewed picture - * @param rasterSize - width and height of the raster + * @param coordinates - the coordinates of the viewed picture + * @param zoomLevel - how far the user is zoomed in * * @since v0.2 */ - public DataPoint(int dataId, int timeOffset, int[] coordinates, int[] rasterSize) { + public DataPoint(int dataId, int timeOffset, int[] coordinates, float zoomLevel) { this.dataId = dataId; this.timeOffset = timeOffset; this.coordinates = coordinates; - this.rasterSize = rasterSize; - this.zoomLevel = null; + this.rasterSize = null; + this.zoomLevel = zoomLevel; } /** - * Stores a single DataPoint with everyting (for database). + * Stores a single DataPoint without zoomLevel. * * @param dataId - the id of the dataPoint * @param timeOffset - the time since the trial started @@ -60,14 +68,12 @@ public DataPoint(int dataId, int timeOffset, int[] coordinates, int[] rasterSize * * @since v0.3 */ - public DataPoint(int dataId, - int timeOffset, int[] coordinates, int[] rasterSize, - Float zoomLevel) { + public DataPoint(int dataId, int timeOffset, int[] coordinates, int[] rasterSize) { this.dataId = dataId; this.timeOffset = timeOffset; this.coordinates = coordinates; this.rasterSize = rasterSize; - this.zoomLevel = zoomLevel; + this.zoomLevel = null; } @Override diff --git a/src/main/java/github/weichware10/util/data/TrialData.java b/src/main/java/github/weichware10/util/data/TrialData.java index ac33b68..62cdba2 100644 --- a/src/main/java/github/weichware10/util/data/TrialData.java +++ b/src/main/java/github/weichware10/util/data/TrialData.java @@ -1,7 +1,19 @@ package github.weichware10.util.data; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.exc.StreamReadException; +import com.fasterxml.jackson.databind.DatabindException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.joda.JodaModule; import github.weichware10.util.Enums; import github.weichware10.util.Enums.ToolType; +import github.weichware10.util.Logger; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.joda.time.DateTime; @@ -22,44 +34,47 @@ public class TrialData { private List dataPoints; /** - * Stores the TrialData for the different tools internally. + * Konstruktor für Jackson. * - * @param toolType - the tooltype of the stored data - * @param trialId - the id of the trial - * @param configId - the configuration of the stored data + * @param toolType - the tooltype of the stored data + * @param trialId - the id of the trial + * @param configId - the configuration of the stored data + * @param startTime - Startzeitpunkt des Versuchs * - * @since v0.2 + * @since v1.0 */ - public TrialData(Enums.ToolType toolType, String trialId, String configId) { + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + public TrialData(@JsonProperty("toolType") Enums.ToolType toolType, + @JsonProperty("trialId") String trialId, @JsonProperty("configId") String configId, + @JsonProperty("startTime") DateTime startTime, @JsonProperty("answer") String answer, + @JsonProperty("data") List dataPoints) { this.toolType = toolType; this.trialId = trialId; this.configId = configId; - this.startTime = DateTime.now(); - this.dataPoints = new ArrayList(); + this.startTime = startTime; + this.answer = answer; + this.dataPoints = dataPoints; } /** * Stores the TrialData for the different tools internally. * - * @param toolType - the tooltype of the stored data - * @param trialId - the id of the trial - * @param configId - the configuration of the stored data - * @param startTime - Startzeitpunkt des Versuchs - * @param answer - Anwort des Versuchs - * @param dataPoints - Daten des Versuchs + * @param toolType - the tooltype of the stored data + * @param trialId - the id of the trial + * @param configId - the configuration of the stored data * - * @since v0.3 + * @since v0.2 */ - public TrialData(Enums.ToolType toolType, String trialId, String configId, - DateTime startTime, String answer, List dataPoints) { + public TrialData(Enums.ToolType toolType, String trialId, String configId) { this.toolType = toolType; this.trialId = trialId; this.configId = configId; - this.startTime = startTime; - this.answer = answer; - this.dataPoints = dataPoints; + this.startTime = DateTime.now(); + this.dataPoints = new ArrayList(); } + // --- GETTERS --- + /** * get the stored dataPoints. * @@ -82,6 +97,8 @@ public String getAnswer() { return answer; } + // --- SETTERS --- + /** * set the answer. * @@ -144,6 +161,70 @@ public void addDataPoint(int[] coordinates, float zoomLevel) { dataPoints.add(new DataPoint(dataPoints.size(), timeOffset, coordinates, zoomLevel)); } + /** + * Lädt eine Versuch/Trial aus einer JSON-Datei. + * + * @param location - Speicherort der Datei. + * + * @since v1.0 + */ + public static TrialData fromJson(String location) { + TrialData trialData = null; + try { + ObjectMapper mapper = new ObjectMapper(); + mapper.registerModule(new JodaModule()); + // read from file + trialData = mapper.readValue(new File(location), TrialData.class); + } catch (StreamReadException e) { + Logger.info("An error occured while loading a trial", e); + } catch (DatabindException e) { + Logger.info("An error occured while loading a trial", e); + } catch (IOException e) { + Logger.info("An error occured while loading a trial", e); + } + return trialData; + } + + /** + * Speichert eine {@link TrialData} in einer JSON-Datei. + * + * @param location - Speicherort der JSON-Datei + * @param trialData - den abzuspeichernden Versuch/Trial + * @return Erfolgsboolean + * + * @since v1.0 + */ + public static boolean toJson(String location, TrialData trialData) { + // only write to JSON files + if (!location.endsWith(".json")) { + return false; + } + try { + // umwandeln von TrialData zu JSON String + // ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter(); + ObjectMapper ow = new ObjectMapper(); + ow.registerModule(new JodaModule()); + ow.writer().withDefaultPrettyPrinter(); + String json = ow.writeValueAsString(trialData); + + // Öffnen der Datei + BufferedWriter writer = new BufferedWriter(new FileWriter(location, false)); + + // Schreiben des JSON + writer.append(json); + writer.close(); + + return true; // Schreiben war erfolgreich + } catch (JsonProcessingException e) { + Logger.info("An error occured while writing a trial", e); + } catch (IOException e) { + Logger.info("An error occured while writing a trial", e); + } + return false; // Schreiben war nicht erfolgreich + } + + // --- OVERRIDES --- + @Override public String toString() { return String.format(""" diff --git a/src/test/java/github/weichware10/util/data/TrialDataTest.java b/src/test/java/github/weichware10/util/data/TrialDataTest.java index 3bca806..d20d9c7 100644 --- a/src/test/java/github/weichware10/util/data/TrialDataTest.java +++ b/src/test/java/github/weichware10/util/data/TrialDataTest.java @@ -1,6 +1,7 @@ package github.weichware10.util.data; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; @@ -172,4 +173,52 @@ public void shouldGetDataCorrectly() { DataPoint dataPoint1 = data1.getData().get(0); assertTrue(data1.getData().get(0).equals(dataPoint1)); } + + @Test + public void toJsonShouldWork() { + TrialData data1 = new TrialData(ToolType.ZOOMMAPS, "trialId", "configId"); + data1.setAnswer("answer"); + data1.addDataPoint(new int[] { 1, 2 }, 3.0f); + data1.addDataPoint(new int[] { 4, 5 }, 6.0f); + assertTrue(TrialData.toJson("target/TD-ZOOMMAPS.json", data1)); + + TrialData data2 = new TrialData(ToolType.CODECHARTS, "trialId", "configId"); + data2.setAnswer("answer"); + data2.addDataPoint(new int[] { 1, 2 }, new int[] { 3, 4 }); + data2.addDataPoint(new int[] { 5, 6 }, new int[] { 7, 8 }); + assertTrue(TrialData.toJson("target/TD-CODECHARTS.json", data2)); + + assertFalse(TrialData.toJson("target/TD-ZOOMMAPS.jpg", data1)); + assertFalse(TrialData.toJson("target/TD-CODECHARTS.jpg", data2)); + } + + @Test + public void fromJsonShouldWork() { + assertEquals(TrialData.class, + TrialData.fromJson("src/test/resources/testtrial-ZOOMMAPS.json").getClass()); + assertEquals(TrialData.class, + TrialData.fromJson("src/test/resources/testtrial-CODECHARTS.json").getClass()); + + TrialData dataZm = TrialData.fromJson("src/test/resources/testtrial-ZOOMMAPS.json"); + + assertEquals(ToolType.ZOOMMAPS, dataZm.toolType); + assertEquals("trialId", dataZm.trialId); + assertEquals("configId", dataZm.configId); + assertEquals("answer", dataZm.getAnswer()); + assertEquals(2, dataZm.getData().size()); + assertEquals(40, dataZm.getData().get(0).timeOffset); + assertEquals(1, dataZm.getData().get(1).dataId); + System.out.println(dataZm.startTime); + + TrialData dataCc = TrialData.fromJson("src/test/resources/testtrial-CODECHARTS.json"); + + assertEquals(ToolType.CODECHARTS, dataCc.toolType); + assertEquals("trialId", dataCc.trialId); + assertEquals("configId", dataCc.configId); + assertEquals("answer", dataCc.getAnswer()); + assertEquals(2, dataCc.getData().size()); + assertEquals(0, dataCc.getData().get(0).timeOffset); + assertEquals(1, dataCc.getData().get(1).dataId); + System.out.println(dataCc.startTime); + } } diff --git a/src/test/resources/testtrial-CODECHARTS.json b/src/test/resources/testtrial-CODECHARTS.json new file mode 100644 index 0000000..7f5ad98 --- /dev/null +++ b/src/test/resources/testtrial-CODECHARTS.json @@ -0,0 +1,23 @@ +{ + "toolType": "CODECHARTS", + "trialId": "trialId", + "configId": "configId", + "startTime": 1640032273799, + "answer": "answer", + "data": [ + { + "dataId": 0, + "timeOffset": 0, + "coordinates": [ 1, 2 ], + "rasterSize": [ 3, 4 ], + "zoomLevel": null + }, + { + "dataId": 1, + "timeOffset": 0, + "coordinates": [ 5, 6 ], + "rasterSize": [ 7, 8 ], + "zoomLevel": null + } + ] +} \ No newline at end of file diff --git a/src/test/resources/testtrial-ZOOMMAPS.json b/src/test/resources/testtrial-ZOOMMAPS.json new file mode 100644 index 0000000..908a5c3 --- /dev/null +++ b/src/test/resources/testtrial-ZOOMMAPS.json @@ -0,0 +1,23 @@ +{ + "toolType": "ZOOMMAPS", + "trialId": "trialId", + "configId": "configId", + "startTime": 1640032273564, + "answer": "answer", + "data": [ + { + "dataId": 0, + "timeOffset": 40, + "zoomLevel": 3, + "coordinates": [ 1, 2 ], + "rasterSize": null + }, + { + "dataId": 1, + "timeOffset": 41, + "zoomLevel": 6, + "coordinates": [ 4, 5 ], + "rasterSize": null + } + ] +} \ No newline at end of file