From 6d13bede7a5d91b00716a90cb415aaf7c0df4065 Mon Sep 17 00:00:00 2001 From: David Guler Date: Thu, 20 Oct 2022 21:46:00 +0200 Subject: [PATCH] Minimum viable deserialization Added TaskTemplate type Added dummy data with (probably) usable format Used the java.time classes instead of the legacy util.Date --- build.gradle | 1 + .../io/JsonPlantDatabase.java | 16 +++- .../gartenverwaltung/types/GrowthPhase.java | 12 ++- .../types/GrowthPhaseType.java | 2 +- .../ch/zhaw/gartenverwaltung/types/Plant.java | 6 +- .../ch/zhaw/gartenverwaltung/types/Task.java | 24 +++-- .../gartenverwaltung/types/TaskTemplate.java | 57 +++++++++++ src/main/java/module-info.java | 2 +- .../ch/zhaw/gartenverwaltung/io/plantdb.json | 96 +++++++++++++++---- 9 files changed, 173 insertions(+), 43 deletions(-) create mode 100644 src/main/java/ch/zhaw/gartenverwaltung/types/TaskTemplate.java diff --git a/build.gradle b/build.gradle index 41f89ac..122bba0 100644 --- a/build.gradle +++ b/build.gradle @@ -38,6 +38,7 @@ dependencies { testImplementation("org.junit.jupiter:junit-jupiter-api:${junitVersion}") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${junitVersion}") implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.13.4' + implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.4' } test { diff --git a/src/main/java/ch/zhaw/gartenverwaltung/io/JsonPlantDatabase.java b/src/main/java/ch/zhaw/gartenverwaltung/io/JsonPlantDatabase.java index c889195..8882e8e 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/io/JsonPlantDatabase.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/io/JsonPlantDatabase.java @@ -3,11 +3,13 @@ package ch.zhaw.gartenverwaltung.io; import ch.zhaw.gartenverwaltung.types.HardinessZone; import ch.zhaw.gartenverwaltung.types.Plant; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.fasterxml.jackson.datatype.jsr310.deser.MonthDayDeserializer; import java.io.IOException; import java.net.URL; -import java.text.DateFormat; -import java.text.SimpleDateFormat; +import java.time.MonthDay; +import java.time.format.DateTimeFormatter; import java.util.Collections; import java.util.List; import java.util.Optional; @@ -15,14 +17,20 @@ import java.util.Optional; public class JsonPlantDatabase implements PlantDatabase { private final URL dataSource = getClass().getResource("plantdb.json"); + private final static JavaTimeModule timeModule = new JavaTimeModule(); + static { + DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("MM-dd"); + MonthDayDeserializer dateDeserializer = new MonthDayDeserializer(dateFormat); + timeModule.addDeserializer(MonthDay.class, dateDeserializer); + } + @Override public List getPlantList(HardinessZone zone) throws IOException { List result = Collections.emptyList(); if (dataSource != null) { ObjectMapper mapper = new ObjectMapper(); - DateFormat dateFormat = new SimpleDateFormat("MM-dd"); - mapper.setDateFormat(dateFormat); + mapper.registerModule(timeModule); result = mapper.readerForListOf(Plant.class).readValue(dataSource); } diff --git a/src/main/java/ch/zhaw/gartenverwaltung/types/GrowthPhase.java b/src/main/java/ch/zhaw/gartenverwaltung/types/GrowthPhase.java index da33b2a..71b4705 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/types/GrowthPhase.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/types/GrowthPhase.java @@ -4,12 +4,16 @@ import ch.zhaw.gartenverwaltung.json.GrowthPhaseTypeDeserializer; import ch.zhaw.gartenverwaltung.json.HardinessZoneDeserializer; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import java.util.Date; +import java.time.MonthDay; +import java.util.List; public record GrowthPhase( - Date startDate, - Date endDate, + MonthDay startDate, + MonthDay endDate, + int group, + Object wateringCycle, @JsonDeserialize(using = GrowthPhaseTypeDeserializer.class) GrowthPhaseType type, - @JsonDeserialize(using = HardinessZoneDeserializer.class) HardinessZone zone) { + @JsonDeserialize(using = HardinessZoneDeserializer.class) HardinessZone zone, + List taskTemplates) { } diff --git a/src/main/java/ch/zhaw/gartenverwaltung/types/GrowthPhaseType.java b/src/main/java/ch/zhaw/gartenverwaltung/types/GrowthPhaseType.java index 99e5d2b..96609cc 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/types/GrowthPhaseType.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/types/GrowthPhaseType.java @@ -1,5 +1,5 @@ package ch.zhaw.gartenverwaltung.types; public enum GrowthPhaseType { - SOW, PLANT, HARVEST + SOW, PLANT, REPLANT, HARVEST } diff --git a/src/main/java/ch/zhaw/gartenverwaltung/types/Plant.java b/src/main/java/ch/zhaw/gartenverwaltung/types/Plant.java index 612679c..27b1944 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/types/Plant.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/types/Plant.java @@ -7,10 +7,8 @@ public record Plant( String name, String description, int spacing, - Object water, int light, - List maintenance, - List specialTasks, - List pests, + String soil, + List pests, List lifecycle) { } diff --git a/src/main/java/ch/zhaw/gartenverwaltung/types/Task.java b/src/main/java/ch/zhaw/gartenverwaltung/types/Task.java index d85435b..90e00f4 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/types/Task.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/types/Task.java @@ -1,6 +1,7 @@ package ch.zhaw.gartenverwaltung.types; -import java.util.Date; + +import java.time.LocalDate; import java.util.Optional; /** @@ -11,14 +12,21 @@ public class Task { private long id; private final String name; private final String description; - private final Date startDate; + private final LocalDate startDate; private Integer interval; - private Date endDate; + private LocalDate endDate; - public Task(String name, String description, Date startDate) { + public Task(String name, String description, LocalDate startDate) { this.name = name; this.description = description; - this.startDate = endDate; + this.startDate = startDate; + } + public Task(String name, String description, LocalDate startDate, LocalDate endDate, int interval) { + this.name = name; + this.description = description; + this.startDate = startDate; + this.endDate = endDate; + this.interval = interval; } // Builder-pattern-style setters @@ -30,7 +38,7 @@ public class Task { this.interval = interval; return this; } - public Task withEndDate(Date endDate) { + public Task withEndDate(LocalDate endDate) { this.endDate = endDate; return this; } @@ -39,12 +47,12 @@ public class Task { public long getId() { return id; } public String getName() { return name; } public String getDescription() { return description; } - public Date getStartDate() { return startDate; } + public LocalDate getStartDate() { return startDate; } public Optional getInterval() { return Optional.ofNullable(interval); } - public Optional getEndDate() { + public Optional getEndDate() { return Optional.ofNullable(endDate); } } diff --git a/src/main/java/ch/zhaw/gartenverwaltung/types/TaskTemplate.java b/src/main/java/ch/zhaw/gartenverwaltung/types/TaskTemplate.java new file mode 100644 index 0000000..290175e --- /dev/null +++ b/src/main/java/ch/zhaw/gartenverwaltung/types/TaskTemplate.java @@ -0,0 +1,57 @@ +package ch.zhaw.gartenverwaltung.types; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.time.LocalDate; + +public class TaskTemplate { + @JsonProperty + private final String name; + @JsonProperty + private final String description; + @JsonProperty + private final int relativeStartDate; + @JsonProperty + private Integer relativeEndDate; + @JsonProperty + private Integer interval; + + // TODO: reconsider if we need this + @JsonProperty + private boolean isOptional = false; + + /** + * Default constructor + * (Used by deserializer) + */ + public TaskTemplate() { + this.name = ""; + this.description = ""; + this.relativeStartDate = 0; + } + + // Setters + public void setRelativeEndDate(Integer relativeEndDate) { + this.relativeEndDate = relativeEndDate; + } + public void setInterval(Integer interval) { + this.interval = interval; + } + + public TaskTemplate(String name, String description, int relativeStartDate) { + this.name = name; + this.description = description; + this.relativeStartDate = relativeStartDate; + } + + public Task generateTask(LocalDate realStartDate) { + Task task = new Task(name, description, realStartDate.plusDays(relativeStartDate)); + if (relativeEndDate != null) { + task.withEndDate(realStartDate.plusDays(relativeEndDate)); + } + if (interval != null) { + task.withInterval(interval); + } + return task; + } +} diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 2bb0935..8e02fc7 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -2,7 +2,7 @@ module ch.zhaw.gartenverwaltung { requires javafx.controls; requires javafx.fxml; requires com.fasterxml.jackson.databind; - + requires com.fasterxml.jackson.datatype.jsr310; opens ch.zhaw.gartenverwaltung to javafx.fxml; opens ch.zhaw.gartenverwaltung.types to com.fasterxml.jackson.databind; diff --git a/src/main/resources/ch/zhaw/gartenverwaltung/io/plantdb.json b/src/main/resources/ch/zhaw/gartenverwaltung/io/plantdb.json index 7eb3366..50b74f1 100644 --- a/src/main/resources/ch/zhaw/gartenverwaltung/io/plantdb.json +++ b/src/main/resources/ch/zhaw/gartenverwaltung/io/plantdb.json @@ -1,31 +1,85 @@ [ { + "id": 0, "name": "Potato", - "description": "Tasty tubers.", - "water": { - "amount": "27-55", - "interval": 7 - }, + "description": "The potato is a tuber, round or oval, with small white roots called 'eyes', that are growth buds. The size varies depending on the variety; the colour of the skin can be white, yellow or even purple.", "light": 6, - "maintenance": [], - "specialTasks": [], - "lifecycle": [ + "spacing": "35", + "soil": "sandy", + "pests": [ { - "startDate": "04-01", - "endDate": "05-31", - "type": "SOW", - "zone": "ZONE_8A" - }, - { - "startDate": "07-01", - "endDate": "08-31", - "type": "HARVEST", - "zone": "ZONE_8A" + "name": "Rot", + "description": "Rot, any of several plant diseases, caused by any of hundreds of species of soil-borne bacteria, fungi, and funguslike organisms (Oomycota). Rot diseases are characterized by plant decomposition and putrefaction. The decay may be hard, dry, spongy, watery, mushy, or slimy and may affect any plant part.", + "measures": "Less water." } ], - "spacing": 35, - "pests": [ - "Potato beetle" + "lifecycle": [ + { + "startDate": "03-10", + "endDate": "04-10", + "type": "SOW", + "zone": "ZONE_8A", + "group": 0, + "wateringCycle": { + "litersPerSqM": 0, + "interval": null, + "notes": [] + }, + "taskTemplates": [ + { + "name": "Germinate", + "relativeStartDate": -14, + "relativeEndDate": null, + "description": "\"Take an egg carton and fill it with soil. Put the seedling deep enaugh so its half covered with soil. Keep it in 10-15 * Celsius with lots of light.\"", + "interval": null, + "isOptional": false + } + ] + }, + { + "startDate": "04-10", + "endDate": "07-10", + "type": "PLANT", + "zone": "ZONE_8A", + "group": 0, + "wateringCycle": { + "litersPerSqM": 25, + "interval": 7, + "notes": [] + }, + "taskTemplates": [ + { + "name": "hilling", + "relativeStartDate": 0, + "relativeEndDate": null, + "description": "\"When the plants are 20 cm tall, begin hilling the potatoes by gently mounding the soil from the center of your rows around the stems of the plant. Mound up the soil around the plant until just the top few leaves show above the soil. Two weeks later, hill up the soil again when the plants grow another 20 cm.\"", + "interval": 21, + "isOptional": false + } + ] + }, + { + "startDate": "06-10", + "endDate": "08-10", + "type": "HARVEST", + "zone": "ZONE_8A", + "group": 0, + "wateringCycle": { + "litersPerSqM": 0, + "interval": null, + "notes": [] + }, + "taskTemplates": [ + { + "name": "Harvest", + "relativeStartDate": 0, + "relativeEndDate": null, + "description": "Once the foliage has wilted and dried completely, harvest on a dry day. Store in a dark and cool location.", + "interval": null, + "isOptional": false + } + ] + } ] } ] \ No newline at end of file