From cf59d52cba70742f1d4098c38b4c7a798b3d89fa Mon Sep 17 00:00:00 2001 From: sowgro Date: Sun, 16 Nov 2025 01:56:27 -0500 Subject: IMPORT-EXPORT WORKING!!!!!!!!!!!!!!!!!!!!!!!!!! --- pom.xml | 6 +- .../design/persistence/JSONLeagueDatabase.java | 45 ++-- .../design/persistence/JSONPersonalDatabase.java | 46 ++-- .../java/design/persistence/LeagueDatabase.java | 6 + .../java/design/persistence/PersonalDatabase.java | 6 + src/main/java/design/persistence/Serializers.java | 18 +- .../persistence/importexport/DataSource.java | 10 +- .../persistence/importexport/JSONHandler.java | 17 +- .../persistence/importexport/XMLHandler.java | 22 +- test.json | 10 - test.xml | 231 +++++++++++---------- 11 files changed, 229 insertions(+), 188 deletions(-) diff --git a/pom.xml b/pom.xml index abcd47f..2333fd8 100644 --- a/pom.xml +++ b/pom.xml @@ -45,7 +45,7 @@ com.fasterxml.jackson.dataformat jackson-dataformat-xml - 2.16.2 + 2.20.0 @@ -72,8 +72,8 @@ jacoco-maven-plugin 0.8.11 - /target/coverage-reports/jacoco-unit.exec - /target/coverage-reports/jacoco-unit.exec + /target/coverage-reports/jacoco-unit.exec + /target/coverage-reports/jacoco-unit.exec diff --git a/src/main/java/design/persistence/JSONLeagueDatabase.java b/src/main/java/design/persistence/JSONLeagueDatabase.java index 0891551..977e162 100644 --- a/src/main/java/design/persistence/JSONLeagueDatabase.java +++ b/src/main/java/design/persistence/JSONLeagueDatabase.java @@ -1,20 +1,15 @@ package design.persistence; -import com.fasterxml.jackson.annotation.*; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.module.SimpleModule; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; -import com.fasterxml.jackson.module.paramnames.ParameterNamesModule; import design.model.Course; import design.model.Golfer; import design.model.League; import java.io.File; import java.io.IOException; -import java.time.LocalDateTime; import java.util.Arrays; import java.util.HashMap; -import java.util.List; import java.util.Map; public class JSONLeagueDatabase implements LeagueDatabase { @@ -38,18 +33,8 @@ public class JSONLeagueDatabase implements LeagueDatabase { this.cache = new HashMap<>(); this.mapper = new ObjectMapper(); - SimpleModule module = new SimpleModule(); - module.addDeserializer(Course.class, new Serializers.CourseIdDeserializer()); - module.addSerializer(Course.class, new Serializers.CourseIdSerializer()); - module.addDeserializer(Golfer.class, new Serializers.GolferUsernameDeserializer()); - module.addSerializer(Golfer.class, new Serializers.GolferUsernameSerializer()); - module.addSerializer(LocalDateTime.class, new Serializers.DateTimeStringSerializer()); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); - mapper.registerModule(new ParameterNamesModule(JsonCreator.Mode.PROPERTIES)); - mapper.registerModule(new JavaTimeModule()); - mapper.registerModule(module); - mapper.configOverride(List.class).setSetterInfo(JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY)); + Serializers.configureMapper(mapper); + mapper.registerModule(this.getJacksonModule()); try { load(); @@ -101,8 +86,10 @@ public class JSONLeagueDatabase implements LeagueDatabase { } @Override - public void importData(JsonNode tree) throws IOException { - League[] data = mapper.treeToValue(tree, League[].class); + public void importData(Object rawData) throws IOException { + if (!(rawData instanceof League[] data)) { + throw new ClassCastException(); + } cache.clear(); for (League league : data) { cache.put(league.getId(), league); @@ -111,8 +98,22 @@ public class JSONLeagueDatabase implements LeagueDatabase { } @Override - public JsonNode exportData() { - Object[] data = cache.values().toArray(); - return mapper.valueToTree(data); + public League[] exportData() { + return getLeagues(); + } + + @Override + public SimpleModule getJacksonModule() { + SimpleModule module = new SimpleModule(); + module.addDeserializer(Course.class, new Serializers.CourseIdDeserializer()); + module.addSerializer(Course.class, new Serializers.CourseIdSerializer()); + module.addDeserializer(Golfer.class, new Serializers.GolferUsernameDeserializer()); + module.addSerializer(Golfer.class, new Serializers.GolferUsernameSerializer()); + return module; + } + + @Override + public Class getTargetClass() { + return League[].class; } } diff --git a/src/main/java/design/persistence/JSONPersonalDatabase.java b/src/main/java/design/persistence/JSONPersonalDatabase.java index bf0dda9..b92dddf 100644 --- a/src/main/java/design/persistence/JSONPersonalDatabase.java +++ b/src/main/java/design/persistence/JSONPersonalDatabase.java @@ -1,19 +1,14 @@ package design.persistence; -import com.fasterxml.jackson.annotation.*; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.module.SimpleModule; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; -import com.fasterxml.jackson.module.paramnames.ParameterNamesModule; import design.model.Course; import design.model.Golfer; import design.model.League; import java.io.File; import java.io.IOException; -import java.time.LocalDateTime; import java.util.HashMap; -import java.util.List; import java.util.Map; public class JSONPersonalDatabase implements PersonalDatabase { @@ -36,19 +31,8 @@ public class JSONPersonalDatabase implements PersonalDatabase { this.cache = new HashMap<>(); this.mapper = new ObjectMapper(); - - SimpleModule module = new SimpleModule(); - module.addDeserializer(Course.class, new Serializers.CourseIdDeserializer()); - module.addSerializer(Course.class, new Serializers.CourseIdSerializer()); - module.addSerializer(League.class, new Serializers.LeagueIDSerializer()); - module.addDeserializer(League.class, new Serializers.LeagueIDDeserializer()); - module.addSerializer(LocalDateTime.class, new Serializers.DateTimeStringSerializer()); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); - mapper.registerModule(new ParameterNamesModule(JsonCreator.Mode.PROPERTIES)); - mapper.registerModule(new JavaTimeModule()); - mapper.registerModule(module); - mapper.configOverride(List.class).setSetterInfo(JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY)); + Serializers.configureMapper(mapper); + mapper.registerModule(this.getJacksonModule()); try { load(); @@ -100,8 +84,10 @@ public class JSONPersonalDatabase implements PersonalDatabase { } @Override - public void importData(JsonNode tree) throws IOException { - Golfer[] data = mapper.treeToValue(tree, Golfer[].class); + public void importData(Object rawData) throws IOException { + if (!(rawData instanceof Golfer[] data)) { + throw new ClassCastException(); + } cache.clear(); for (Golfer golfer : data) { cache.put(golfer.getUsername(), golfer); @@ -110,8 +96,22 @@ public class JSONPersonalDatabase implements PersonalDatabase { } @Override - public JsonNode exportData() { - Object[] data = cache.values().toArray(); - return mapper.valueToTree(data); + public Golfer[] exportData() { + return getGolfers(); + } + + @Override + public SimpleModule getJacksonModule() { + SimpleModule module = new SimpleModule(); + module.addDeserializer(Course.class, new Serializers.CourseIdDeserializer()); + module.addSerializer(Course.class, new Serializers.CourseIdSerializer()); + module.addSerializer(League.class, new Serializers.LeagueIDSerializer()); + module.addDeserializer(League.class, new Serializers.LeagueIDDeserializer()); + return module; + } + + @Override + public Class getTargetClass() { + return Golfer[].class; } } diff --git a/src/main/java/design/persistence/LeagueDatabase.java b/src/main/java/design/persistence/LeagueDatabase.java index 9f835ff..ed6ddae 100644 --- a/src/main/java/design/persistence/LeagueDatabase.java +++ b/src/main/java/design/persistence/LeagueDatabase.java @@ -19,4 +19,10 @@ public interface LeagueDatabase extends DataSource { void removeLeague(League league) throws IOException; void updateLeague(League league) throws IOException; + + @Override + void importData(Object data) throws IOException; + + @Override + Object exportData() throws IOException; } diff --git a/src/main/java/design/persistence/PersonalDatabase.java b/src/main/java/design/persistence/PersonalDatabase.java index 77e43cc..70dd37d 100644 --- a/src/main/java/design/persistence/PersonalDatabase.java +++ b/src/main/java/design/persistence/PersonalDatabase.java @@ -20,4 +20,10 @@ public interface PersonalDatabase extends DataSource { void removeGolfer(Golfer golfer) throws IOException; void updateGolfer(Golfer golfer) throws IOException; + + @Override + void importData(Object data) throws IOException; + + @Override + Object exportData() throws IOException; } diff --git a/src/main/java/design/persistence/Serializers.java b/src/main/java/design/persistence/Serializers.java index 2f2b208..246dbf1 100644 --- a/src/main/java/design/persistence/Serializers.java +++ b/src/main/java/design/persistence/Serializers.java @@ -1,20 +1,20 @@ package design.persistence; +import com.fasterxml.jackson.annotation.*; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.util.DefaultIndenter; import com.fasterxml.jackson.core.util.DefaultPrettyPrinter; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.databind.*; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.fasterxml.jackson.module.paramnames.ParameterNamesModule; import design.model.Course; import design.model.Golfer; import design.model.League; import java.io.IOException; import java.time.LocalDateTime; +import java.util.List; public class Serializers { public static class CustomPrettyPrinter extends DefaultPrettyPrinter { @@ -85,4 +85,12 @@ public class Serializers { gen.writeString(value.toString()); } } + + public static void configureMapper(ObjectMapper mapper) { + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); + mapper.registerModule(new ParameterNamesModule(JsonCreator.Mode.PROPERTIES)); + mapper.registerModule(new JavaTimeModule()); + mapper.configOverride(List.class).setSetterInfo(JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY)); + } } diff --git a/src/main/java/design/persistence/importexport/DataSource.java b/src/main/java/design/persistence/importexport/DataSource.java index 5290e33..e735c7e 100644 --- a/src/main/java/design/persistence/importexport/DataSource.java +++ b/src/main/java/design/persistence/importexport/DataSource.java @@ -1,12 +1,16 @@ package design.persistence.importexport; -import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.module.SimpleModule; import java.io.IOException; public interface DataSource { - void importData(JsonNode tree) throws IOException; + void importData(Object data) throws IOException; - JsonNode exportData() throws IOException; + Object exportData() throws IOException; + + SimpleModule getJacksonModule(); + + Class getTargetClass(); } \ No newline at end of file diff --git a/src/main/java/design/persistence/importexport/JSONHandler.java b/src/main/java/design/persistence/importexport/JSONHandler.java index 239eb6b..9c04281 100644 --- a/src/main/java/design/persistence/importexport/JSONHandler.java +++ b/src/main/java/design/persistence/importexport/JSONHandler.java @@ -1,6 +1,7 @@ package design.persistence.importexport; -import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.json.JsonMapper; +import design.persistence.Serializers; import java.io.File; import java.io.IOException; @@ -8,22 +9,26 @@ import java.io.IOException; public class JSONHandler implements DataHandler { private final DataSource dataSource; - private final JsonMapper jsonMapper = new JsonMapper(); + private final ObjectMapper jsonMapper = new JsonMapper(); public JSONHandler(DataSource dataSource) { this.dataSource = dataSource; + + Serializers.configureMapper(jsonMapper); + jsonMapper.registerModule(dataSource.getJacksonModule()); } @Override public void importData(File file) throws IOException { - JsonNode tree = jsonMapper.readTree(file); - dataSource.importData(tree); + Object data = jsonMapper.readValue(file, dataSource.getTargetClass()); + dataSource.importData(data); } @Override public void exportData(File file) throws IOException{ - JsonNode tree = dataSource.exportData(); - jsonMapper.writerWithDefaultPrettyPrinter().writeValue(file, tree); + Object data = dataSource.exportData(); + jsonMapper.writer(new Serializers.CustomPrettyPrinter()) + .writeValue(file, data); } } diff --git a/src/main/java/design/persistence/importexport/XMLHandler.java b/src/main/java/design/persistence/importexport/XMLHandler.java index 1a16b90..0a07d6e 100644 --- a/src/main/java/design/persistence/importexport/XMLHandler.java +++ b/src/main/java/design/persistence/importexport/XMLHandler.java @@ -1,10 +1,11 @@ package design.persistence.importexport; import java.io.File; import java.io.IOException; +import java.time.LocalDateTime; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ObjectNode; +import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.dataformat.xml.XmlMapper; +import design.persistence.Serializers; public class XMLHandler implements DataHandler { @@ -13,21 +14,24 @@ public class XMLHandler implements DataHandler { public XMLHandler(DataSource dataSource) { this.dataSource = dataSource; + + Serializers.configureMapper(xmlMapper); + SimpleModule module = dataSource.getJacksonModule(); + module.addSerializer(LocalDateTime.class, new Serializers.DateTimeStringSerializer()); + xmlMapper.registerModule(module); } @Override public void importData(File file) throws IOException { - JsonNode tree = xmlMapper.readTree(file); - JsonNode unwrapped = tree.get("items"); - dataSource.importData(unwrapped); + Object data = xmlMapper.readValue(file, dataSource.getTargetClass()); + dataSource.importData(data); } @Override public void exportData(File file) throws IOException { - JsonNode tree = dataSource.exportData(); - ObjectNode wrapper = xmlMapper.createObjectNode(); - wrapper.set("items", tree); - xmlMapper.writerWithDefaultPrettyPrinter().withRootName("export").writeValue(file, wrapper); + Object data = dataSource.exportData(); + xmlMapper.writerWithDefaultPrettyPrinter() + .writeValue(file, data); } } diff --git a/test.json b/test.json index b171eba..4e42e0d 100644 --- a/test.json +++ b/test.json @@ -19,16 +19,6 @@ "rounds": [], "invites": [] }, - { - "clubs": [], - "nextClubId": 1, - "username": "GUYHERE2", - "passwordHash": 3556498, - "fullName": "GUYHERE2", - "courses": [], - "rounds": [], - "invites" : [] - }, { "clubs": [ { diff --git a/test.xml b/test.xml index 0f508ef..4701977 100644 --- a/test.xml +++ b/test.xml @@ -1,127 +1,144 @@ - - + + + 1 test 3556498 test - - + + + + + + 1 GUYHERE 3556498 GUYHERE - - + + + + + - 1 - Bobby - swen 261 - DRIVER - - - 2 - Bobby - swen 262 - PUTTER - - - 3 - sowclub - man - WOOD + + 1 + Bobby + swen 261 + DRIVER + + + 2 + Bobby + swen 262 + PUTTER + + + 3 + sowclub + man + WOOD + 4 john_doe 46792755 John Doe - 2 - 1 - - 1 - 2025 - 10 - 7 - 13 - 54 - 37 - 429963500 - - 1 - 5 - - - 1 - - 100 - 1 - - - 5 - 2 - - - 1 - 2 - - 3 - 106 - - - 2 - - 1000 - 1 - - - 2 - 1 - - 2 - 1002 - - 2 - 5 - 1108.0 - - 3 - 4 - - + + 2 + 1 + - 1 - 2025 - 10 - 8 - 20 - 19 - 38 - 968996400 - - 9 - 3 - - - 9 - - 204 - 1 - - 1 - 204 - - 9 - 1 - 204.0 - - 10 - 3 - + + 1 + 2025-10-07T13:54:37.429963500 + + 1 + 5 + + + + 1 + + + 100 + 1 + + + 5 + 2 + + + 1 + 2 + + + 3 + 106 + + + 2 + + + 1000 + 1 + + + 2 + 1 + + + 2 + 1002 + + + 2 + 5 + 1108.0 + + 3 + 4 + + + + 1 + 2025-10-08T20:19:38.968996400 + + 9 + 3 + + + + 9 + + + 204 + 1 + + + 1 + 204 + + + 9 + 1 + 204.0 + + 10 + 3 + + - - + + + + 1 sowgro -896456343 sowgro - - + + + + + -- cgit v1.2.3