From d56146304da259de8d390388e143dbb98c0f85e7 Mon Sep 17 00:00:00 2001 From: Hallvard Traetteberg <hal@ntnu.no> Date: Wed, 3 Jan 2018 22:31:21 +0100 Subject: [PATCH] Issue #4. --- .../app/core/GeoLocationsPersistence.java | 10 +++ .../json/GeoLocationsJsonDeserializer.java | 69 +++++++++++++++++++ .../app/json/GeoLocationsJsonPersistence.java | 35 ++++++++++ .../app/json/GeoLocationsJsonSerializer.java | 42 +++++++++++ .../app/core/GeoLocationsPersistenceTest.java | 56 +++++++++++++++ .../tdt4140/gr1800/app/core/geoLocations.json | 17 +++++ 6 files changed, 229 insertions(+) create mode 100644 tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/GeoLocationsPersistence.java create mode 100644 tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/json/GeoLocationsJsonDeserializer.java create mode 100644 tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/json/GeoLocationsJsonPersistence.java create mode 100644 tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/json/GeoLocationsJsonSerializer.java create mode 100644 tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/GeoLocationsPersistenceTest.java create mode 100644 tdt4140-gr1800/app.core/src/test/resources/tdt4140/gr1800/app/core/geoLocations.json diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/GeoLocationsPersistence.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/GeoLocationsPersistence.java new file mode 100644 index 0000000..27798ef --- /dev/null +++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/GeoLocationsPersistence.java @@ -0,0 +1,10 @@ +package tdt4140.gr1800.app.core; + +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Collection; + +public interface GeoLocationsPersistence { + public Collection<GeoLocations> loadLocations(InputStream inputStream) throws Exception; + public void saveLocations(Collection<GeoLocations> geoLocations, OutputStream outputStream) throws Exception; +} diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/json/GeoLocationsJsonDeserializer.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/json/GeoLocationsJsonDeserializer.java new file mode 100644 index 0000000..c5f0e3d --- /dev/null +++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/json/GeoLocationsJsonDeserializer.java @@ -0,0 +1,69 @@ +package tdt4140.gr1800.app.json; + +import java.io.IOException; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + +import tdt4140.gr1800.app.core.GeoLocations; +import tdt4140.gr1800.app.core.LatLong; + +public class GeoLocationsJsonDeserializer extends StdDeserializer<GeoLocations> { + + public GeoLocationsJsonDeserializer() { + super(GeoLocations.class); + } + + @Override + public GeoLocations deserialize(JsonParser jsonParser, DeserializationContext deserContext) throws IOException, JsonProcessingException { + JsonNode jsonNode = jsonParser.getCodec().readTree(jsonParser); + return deserialize(jsonNode); + } + + private GeoLocations deserialize(JsonNode jsonNode) throws IOException, JsonProcessingException { + if (jsonNode instanceof ObjectNode) { + ObjectNode objectNode = (ObjectNode) jsonNode; + String name = objectNode.get(GeoLocationsJsonSerializer.NAME_FIELD_NAME).asText(); + GeoLocations geoLocations = new GeoLocations(name); + JsonNode pathNode = objectNode.get(GeoLocationsJsonSerializer.PATH_FIELD_NAME); + geoLocations.setPath(pathNode != null && pathNode.asBoolean(false)); + JsonNode locationsNode = objectNode.get(GeoLocationsJsonSerializer.LOCATIONS_FIELD_NAME); + if (locationsNode instanceof ArrayNode) { + for (JsonNode locationNode : (ArrayNode) locationsNode) { + LatLong latLong = decodeLatLong(locationNode); + geoLocations.addLocation(latLong); + } + } else { + LatLong latLong = decodeLatLong(locationsNode); + geoLocations.addLocation(latLong); + } + return geoLocations; + } + return null; + } + + private LatLong decodeLatLong(JsonNode locationNode) { + LatLong latLong = null; + if (locationNode instanceof ObjectNode) { + ObjectNode objectNode = (ObjectNode) locationNode; + if (objectNode.has(GeoLocationsJsonSerializer.LATITUDE_FIELD_NAME) && objectNode.has(GeoLocationsJsonSerializer.LONGITUDE_FIELD_NAME)) { + double lat = objectNode.get(GeoLocationsJsonSerializer.LATITUDE_FIELD_NAME).asDouble(); + double lon = objectNode.get(GeoLocationsJsonSerializer.LONGITUDE_FIELD_NAME).asDouble(); + latLong = new LatLong(lat, lon); + } + } else if (locationNode instanceof ArrayNode) { + ArrayNode arrayNode = (ArrayNode) locationNode; + if (arrayNode.size() == 2) { + double lat = arrayNode.get(0).asDouble(); + double lon = arrayNode.get(1).asDouble(); + latLong = new LatLong(lat, lon); + } + } + return latLong; + } +} diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/json/GeoLocationsJsonPersistence.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/json/GeoLocationsJsonPersistence.java new file mode 100644 index 0000000..48804fb --- /dev/null +++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/json/GeoLocationsJsonPersistence.java @@ -0,0 +1,35 @@ +package tdt4140.gr1800.app.json; + +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Collection; +import java.util.List; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; + +import tdt4140.gr1800.app.core.GeoLocations; +import tdt4140.gr1800.app.core.GeoLocationsPersistence; + +public class GeoLocationsJsonPersistence implements GeoLocationsPersistence { + + private final ObjectMapper objectMapper; + + public GeoLocationsJsonPersistence() { + objectMapper = new ObjectMapper(); + SimpleModule module = new SimpleModule(); + module.addSerializer(new GeoLocationsJsonSerializer()); + module.addDeserializer(GeoLocations.class, new GeoLocationsJsonDeserializer()); + objectMapper.registerModule(module); + } + + @Override + public Collection<GeoLocations> loadLocations(InputStream inputStream) throws Exception { + return objectMapper.readValue(inputStream, objectMapper.getTypeFactory().constructCollectionType(List.class, GeoLocations.class)); + } + + @Override + public void saveLocations(Collection<GeoLocations> geoLocations, OutputStream outputStream) throws Exception { + objectMapper.writeValue(outputStream, geoLocations); + } +} diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/json/GeoLocationsJsonSerializer.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/json/GeoLocationsJsonSerializer.java new file mode 100644 index 0000000..da7aa07 --- /dev/null +++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/json/GeoLocationsJsonSerializer.java @@ -0,0 +1,42 @@ +package tdt4140.gr1800.app.json; + +import java.io.IOException; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; + +import tdt4140.gr1800.app.core.GeoLocations; +import tdt4140.gr1800.app.core.LatLong; + +public class GeoLocationsJsonSerializer extends StdSerializer<GeoLocations> { + + public static final String LONGITUDE_FIELD_NAME = "longitude"; + public static final String LATITUDE_FIELD_NAME = "latitude"; + public static final String LOCATIONS_FIELD_NAME = "locations"; + public static final String PATH_FIELD_NAME = "path"; + public static final String NAME_FIELD_NAME = "name"; + + public GeoLocationsJsonSerializer() { + super(GeoLocations.class); + } + + @Override + public void serialize(GeoLocations geoLocations, JsonGenerator jsonGen, SerializerProvider serProvider) throws IOException { + jsonGen.writeStartObject(); + jsonGen.writeFieldName(NAME_FIELD_NAME); + jsonGen.writeString(geoLocations.getName()); + jsonGen.writeFieldName(PATH_FIELD_NAME); + jsonGen.writeBoolean(geoLocations.isPath()); + jsonGen.writeFieldName(LOCATIONS_FIELD_NAME); + jsonGen.writeStartArray(); + for (LatLong latLon : geoLocations) { + jsonGen.writeStartArray(); + jsonGen.writeNumber(latLon.latitude); + jsonGen.writeNumber(latLon.longitude); + jsonGen.writeEndArray(); + } + jsonGen.writeEndArray(); + jsonGen.writeEndObject(); + } +} diff --git a/tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/GeoLocationsPersistenceTest.java b/tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/GeoLocationsPersistenceTest.java new file mode 100644 index 0000000..08f6125 --- /dev/null +++ b/tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/GeoLocationsPersistenceTest.java @@ -0,0 +1,56 @@ +package tdt4140.gr1800.app.core; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import tdt4140.gr1800.app.json.GeoLocationsJsonPersistence; + +public class GeoLocationsPersistenceTest { + + private GeoLocationsPersistence persistence; + + @Before + public void setUp() { + persistence = new GeoLocationsJsonPersistence(); + } + + @Test + public void testLoadLocations() { + testLoadLocations(getClass().getResourceAsStream("geoLocations.json")); + } + + private void testLoadLocations(InputStream inputStream) { + try { + Collection<GeoLocations> geoLocations = persistence.loadLocations(inputStream); + Assert.assertEquals(2, geoLocations.size()); + Iterator<GeoLocations> it = geoLocations.iterator(); + GeoLocationsTest.assertGeoLocations(it.next(), new LatLong(63, 10), new LatLong(63.1, 10.1)); + GeoLocationsTest.assertGeoLocations(it.next(), new LatLong(64, 11), new LatLong(64.1, 11.1)); + } catch (Exception e) { + Assert.fail(e.getMessage()); + } + } + + @Test + public void testSaveLocations() { + Collection<GeoLocations> geoLocations = new ArrayList<GeoLocations>(); + geoLocations.add(new GeoLocations("1", new LatLong(63, 10), new LatLong(63.1, 10.1))); + geoLocations.add(new GeoLocations("2", new LatLong(64, 11), new LatLong(64.1, 11.1))); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + try { + persistence.saveLocations(geoLocations, outputStream); + outputStream.close(); + testLoadLocations(new ByteArrayInputStream(outputStream.toByteArray())); + } catch (Exception e) { + Assert.fail(e.getMessage()); + } + } +} diff --git a/tdt4140-gr1800/app.core/src/test/resources/tdt4140/gr1800/app/core/geoLocations.json b/tdt4140-gr1800/app.core/src/test/resources/tdt4140/gr1800/app/core/geoLocations.json new file mode 100644 index 0000000..bfda7a4 --- /dev/null +++ b/tdt4140-gr1800/app.core/src/test/resources/tdt4140/gr1800/app/core/geoLocations.json @@ -0,0 +1,17 @@ +[ + { + "name" : "1", + "locations" : [ + { "latitude" : "63", "longitude" : "10" }, + [ "63.1", "10.1" ] + ] + }, + { + "name" : "2", + "path" : "true", + "locations" : [ + { "latitude" : "64", "longitude" : "11" }, + [ "64.1", "11.1" ] + ] + } +] -- GitLab